Skip to content

Commit

Permalink
api: xDS API version specifier (envoyproxy#9468)
Browse files Browse the repository at this point in the history
It enables to specify API versioning for xDS for envoyproxy#8421, allow to write like this config

eds_cluster_config:
    eds_config:
       version: V2 
       api_config_source:
          api_type: GRPC
	  grpc_services:
            envoy_grpc:
               cluster_name: eds_cluster

Risk Level: Low
Testing: unit test(maybe it is needed to add integration test)

Signed-off-by: shikugawa <rei@tetrate.io>
Signed-off-by: Prakhar <prakhar_au@yahoo.com>
  • Loading branch information
Shikugawa authored and prakhag1 committed Jan 3, 2020
1 parent a946c83 commit dcc1814
Show file tree
Hide file tree
Showing 25 changed files with 260 additions and 58 deletions.
17 changes: 16 additions & 1 deletion api/envoy/api/v2/core/config_source.proto
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,20 @@ message RateLimitSettings {
// <arch_overview_service_discovery>` etc. may either be sourced from the
// filesystem or from an xDS API source. Filesystem configs are watched with
// inotify for updates.
// [#next-free-field: 6]
// [#next-free-field: 7]
message ConfigSource {
enum XdsApiVersion {
// use for describing explicitly that xDS API version is set automatically. In default, xDS API
// version is V2
AUTO = 0;

// use xDS v2 API
V2 = 1;

// use xDS v3alpha API
V3ALPHA = 2;
}

oneof config_source_specifier {
option (validate.required) = true;

Expand Down Expand Up @@ -150,4 +162,7 @@ message ConfigSource {
// means no timeout - Envoy will wait indefinitely for the first xDS config (unless another
// timeout applies). The default is 15s.
google.protobuf.Duration initial_fetch_timeout = 4;

// API version for xDS endpoint
XdsApiVersion xds_api_version = 6;
}
17 changes: 16 additions & 1 deletion api/envoy/api/v3alpha/core/config_source.proto
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,22 @@ message RateLimitSettings {
// <arch_overview_service_discovery>` etc. may either be sourced from the
// filesystem or from an xDS API source. Filesystem configs are watched with
// inotify for updates.
// [#next-free-field: 6]
// [#next-free-field: 7]
message ConfigSource {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.core.ConfigSource";

enum XdsApiVersion {
// use for describing explicitly that xDS API version is set automatically. In default, xDS API
// version is V2
AUTO = 0;

// use xDS v2 API
V2 = 1;

// use xDS v3alpha API
V3ALPHA = 2;
}

oneof config_source_specifier {
option (validate.required) = true;

Expand Down Expand Up @@ -162,4 +174,7 @@ message ConfigSource {
// means no timeout - Envoy will wait indefinitely for the first xDS config (unless another
// timeout applies). The default is 15s.
google.protobuf.Duration initial_fetch_timeout = 4;

// API version for xDS endpoint
XdsApiVersion xds_api_version = 6;
}
17 changes: 16 additions & 1 deletion generated_api_shadow/envoy/api/v2/core/config_source.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 16 additions & 1 deletion generated_api_shadow/envoy/api/v3alpha/core/config_source.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions source/common/router/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ envoy_cc_library(
"@envoy_api//envoy/api/v2:pkg_cc_proto",
"@envoy_api//envoy/api/v2/core:pkg_cc_proto",
"@envoy_api//envoy/api/v2/route:pkg_cc_proto",
"@envoy_api//envoy/api/v3alpha/route:pkg_cc_proto",
],
)

Expand Down Expand Up @@ -172,6 +173,8 @@ envoy_cc_library(
"//source/common/router:vhds_lib",
"@envoy_api//envoy/admin/v2alpha:pkg_cc_proto",
"@envoy_api//envoy/api/v2:pkg_cc_proto",
"@envoy_api//envoy/api/v2/core:pkg_cc_proto",
"@envoy_api//envoy/api/v3alpha:pkg_cc_proto",
"@envoy_api//envoy/config/filter/network/http_connection_manager/v2:pkg_cc_proto",
],
)
Expand Down Expand Up @@ -215,6 +218,7 @@ envoy_cc_library(
"@envoy_api//envoy/api/v2:pkg_cc_proto",
"@envoy_api//envoy/api/v2/core:pkg_cc_proto",
"@envoy_api//envoy/config/filter/network/http_connection_manager/v2:pkg_cc_proto",
"@envoy_api//envoy/service/route/v3alpha:pkg_cc_proto",
],
)

Expand Down
31 changes: 23 additions & 8 deletions source/common/router/rds_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "envoy/api/v2/discovery.pb.h"
#include "envoy/api/v2/rds.pb.h"
#include "envoy/api/v2/rds.pb.validate.h"
#include "envoy/api/v3alpha/rds.pb.h"
#include "envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.pb.h"

#include "common/common/assert.h"
Expand Down Expand Up @@ -61,22 +62,20 @@ RdsRouteConfigSubscription::RdsRouteConfigSubscription(
const uint64_t manager_identifier, Server::Configuration::ServerFactoryContext& factory_context,
ProtobufMessage::ValidationVisitor& validator, Init::Manager& init_manager,
const std::string& stat_prefix,
Envoy::Router::RouteConfigProviderManagerImpl& route_config_provider_manager)
Envoy::Router::RouteConfigProviderManagerImpl& route_config_provider_manager,
envoy::api::v2::core::ConfigSource::XdsApiVersion xds_api_version)
: route_config_name_(rds.route_config_name()), factory_context_(factory_context),
validator_(validator), init_manager_(init_manager),
init_target_(fmt::format("RdsRouteConfigSubscription {}", route_config_name_),
[this]() { subscription_->start({route_config_name_}); }),
scope_(factory_context.scope().createScope(stat_prefix + "rds." + route_config_name_ + ".")),
stat_prefix_(stat_prefix), stats_({ALL_RDS_STATS(POOL_COUNTER(*scope_))}),
route_config_provider_manager_(route_config_provider_manager),
manager_identifier_(manager_identifier) {
manager_identifier_(manager_identifier), xds_api_version_(xds_api_version) {

subscription_ =
factory_context.clusterManager().subscriptionFactory().subscriptionFromConfigSource(
rds.config_source(),
Grpc::Common::typeUrl(
API_NO_BOOST(envoy::api::v2::RouteConfiguration)().GetDescriptor()->full_name()),
*scope_, *this);
rds.config_source(), loadTypeUrl(), *scope_, *this);
config_update_info_ =
std::make_unique<RouteConfigUpdateReceiverImpl>(factory_context.timeSource(), validator);
}
Expand Down Expand Up @@ -122,7 +121,8 @@ void RdsRouteConfigSubscription::onConfigUpdate(
// TODO(dmitri-d): It's unsafe to depend directly on factory context here,
// the listener might have been torn down, need to remove this.
vhds_subscription_ = std::make_unique<VhdsSubscription>(
config_update_info_, factory_context_, stat_prefix_, route_config_providers_);
config_update_info_, factory_context_, stat_prefix_, route_config_providers_,
config_update_info_->routeConfiguration().vhds().config_source().xds_api_version());
vhds_subscription_->registerInitTargetWithInitManager(
noop_init_manager == nullptr ? getRdsConfigInitManager() : *noop_init_manager);
} else {
Expand Down Expand Up @@ -201,6 +201,21 @@ bool RdsRouteConfigSubscription::validateUpdateSize(int num_resources) {
return true;
}

std::string RdsRouteConfigSubscription::loadTypeUrl() {
switch (xds_api_version_) {
// automatically set api version as V2
case envoy::api::v2::core::ConfigSource::AUTO:
case envoy::api::v2::core::ConfigSource::V2:
return Grpc::Common::typeUrl(
API_NO_BOOST(envoy::api::v2::RouteConfiguration().GetDescriptor()->full_name()));
case envoy::api::v2::core::ConfigSource::V3ALPHA:
return Grpc::Common::typeUrl(
API_NO_BOOST(envoy::api::v3alpha::RouteConfiguration().GetDescriptor()->full_name()));
default:
throw EnvoyException(fmt::format("type {} is not supported", xds_api_version_));
}
}

RdsRouteConfigProviderImpl::RdsRouteConfigProviderImpl(
RdsRouteConfigSubscriptionSharedPtr&& subscription,
Server::Configuration::FactoryContext& factory_context)
Expand Down Expand Up @@ -274,7 +289,7 @@ Router::RouteConfigProviderSharedPtr RouteConfigProviderManagerImpl::createRdsRo
RdsRouteConfigSubscriptionSharedPtr subscription(new RdsRouteConfigSubscription(
rds, manager_identifier, factory_context.getServerFactoryContext(),
factory_context.messageValidationVisitor(), factory_context.initManager(), stat_prefix,
*this));
*this, rds.config_source().xds_api_version()));
init_manager.add(subscription->init_target_);
std::shared_ptr<RdsRouteConfigProviderImpl> new_provider{
new RdsRouteConfigProviderImpl(std::move(subscription), factory_context)};
Expand Down
8 changes: 6 additions & 2 deletions source/common/router/rds_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <unordered_set>

#include "envoy/admin/v2alpha/config_dump.pb.h"
#include "envoy/api/v2/core/config_source.pb.h"
#include "envoy/api/v2/discovery.pb.h"
#include "envoy/api/v2/rds.pb.h"
#include "envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.pb.h"
Expand Down Expand Up @@ -139,10 +140,12 @@ class RdsRouteConfigSubscription : Envoy::Config::SubscriptionCallbacks,
const uint64_t manager_identifier,
Server::Configuration::ServerFactoryContext& factory_context,
ProtobufMessage::ValidationVisitor& validator, Init::Manager& init_manager,
const std::string& stat_prefix,
RouteConfigProviderManagerImpl& route_config_provider_manager);
const std::string& stat_prefix, RouteConfigProviderManagerImpl& route_config_provider_manager,
const envoy::api::v2::core::ConfigSource::XdsApiVersion xds_api_version =
envoy::api::v2::core::ConfigSource::AUTO);

bool validateUpdateSize(int num_resources);
std::string loadTypeUrl();

Init::Manager& getRdsConfigInitManager() { return init_manager_; }

Expand All @@ -162,6 +165,7 @@ class RdsRouteConfigSubscription : Envoy::Config::SubscriptionCallbacks,
VhdsSubscriptionPtr vhds_subscription_;
RouteConfigUpdatePtr config_update_info_;
Common::CallbackManager<> update_callback_manager_;
envoy::api::v2::core::ConfigSource::XdsApiVersion xds_api_version_;

friend class RouteConfigProviderManagerImpl;
// Access to addUpdateCallback
Expand Down
25 changes: 19 additions & 6 deletions source/common/router/scoped_rds.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "envoy/api/v2/srds.pb.h"
#include "envoy/api/v2/srds.pb.validate.h"
#include "envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.pb.h"
#include "envoy/service/route/v3alpha/srds.pb.h"

#include "common/common/assert.h"
#include "common/common/cleanup.h"
Expand Down Expand Up @@ -99,14 +100,11 @@ ScopedRdsConfigSubscription::ScopedRdsConfigSubscription(
stats_({ALL_SCOPED_RDS_STATS(POOL_COUNTER(*scope_))}),
rds_config_source_(std::move(rds_config_source)),
validation_visitor_(factory_context.messageValidationVisitor()), stat_prefix_(stat_prefix),
route_config_provider_manager_(route_config_provider_manager) {
route_config_provider_manager_(route_config_provider_manager),
xds_api_version_(rds_config_source_.xds_api_version()) {
subscription_ =
factory_context.clusterManager().subscriptionFactory().subscriptionFromConfigSource(
scoped_rds.scoped_rds_config_source(),
Grpc::Common::typeUrl(API_NO_BOOST(envoy::api::v2::ScopedRouteConfiguration)()
.GetDescriptor()
->full_name()),
*scope_, *this);
scoped_rds.scoped_rds_config_source(), loadTypeUrl(), *scope_, *this);

initialize([scope_key_builder]() -> Envoy::Config::ConfigProvider::ConfigConstSharedPtr {
return std::make_shared<ScopedConfigImpl>(
Expand Down Expand Up @@ -345,6 +343,21 @@ void ScopedRdsConfigSubscription::onConfigUpdate(
onConfigUpdate(to_add_repeated, to_remove_repeated, version_info);
}

std::string ScopedRdsConfigSubscription::loadTypeUrl() {
switch (xds_api_version_) {
// automatically set api version as V2
case envoy::api::v2::core::ConfigSource::AUTO:
case envoy::api::v2::core::ConfigSource::V2:
return Grpc::Common::typeUrl(
API_NO_BOOST(envoy::api::v2::ScopedRouteConfiguration().GetDescriptor()->full_name()));
case envoy::api::v2::core::ConfigSource::V3ALPHA:
return Grpc::Common::typeUrl(API_NO_BOOST(
envoy::service::route::v3alpha::ScopedRouteConfiguration().GetDescriptor()->full_name()));
default:
throw EnvoyException(fmt::format("type {} is not supported", xds_api_version_));
}
}

ScopedRdsConfigProvider::ScopedRdsConfigProvider(
ScopedRdsConfigSubscriptionSharedPtr&& subscription)
: MutableConfigProviderCommonBase(std::move(subscription), ConfigProvider::ApiType::Delta) {}
Expand Down
2 changes: 2 additions & 0 deletions source/common/router/scoped_rds.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class ScopedRdsConfigSubscription : public Envoy::Config::DeltaConfigSubscriptio
std::string resourceName(const ProtobufWkt::Any& resource) override {
return MessageUtil::anyConvert<envoy::api::v2::ScopedRouteConfiguration>(resource).name();
}
std::string loadTypeUrl();
// Propagate RDS updates to ScopeConfigImpl in workers.
void onRdsConfigUpdate(const std::string& scope_name,
RdsRouteConfigSubscription& rds_subscription);
Expand All @@ -183,6 +184,7 @@ class ScopedRdsConfigSubscription : public Envoy::Config::DeltaConfigSubscriptio
ProtobufMessage::ValidationVisitor& validation_visitor_;
const std::string stat_prefix_;
RouteConfigProviderManager& route_config_provider_manager_;
envoy::api::v2::core::ConfigSource::XdsApiVersion xds_api_version_;
};

using ScopedRdsConfigSubscriptionSharedPtr = std::shared_ptr<ScopedRdsConfigSubscription>;
Expand Down
32 changes: 23 additions & 9 deletions source/common/router/vhds.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "envoy/api/v2/core/config_source.pb.h"
#include "envoy/api/v2/discovery.pb.h"
#include "envoy/api/v2/route/route.pb.h"
#include "envoy/api/v3alpha/route/route.pb.h"

#include "common/common/assert.h"
#include "common/common/fmt.h"
Expand All @@ -20,17 +21,18 @@ namespace Envoy {
namespace Router {

// Implements callbacks to handle DeltaDiscovery protocol for VirtualHostDiscoveryService
VhdsSubscription::VhdsSubscription(RouteConfigUpdatePtr& config_update_info,
Server::Configuration::ServerFactoryContext& factory_context,
const std::string& stat_prefix,
std::unordered_set<RouteConfigProvider*>& route_config_providers)
VhdsSubscription::VhdsSubscription(
RouteConfigUpdatePtr& config_update_info,
Server::Configuration::ServerFactoryContext& factory_context, const std::string& stat_prefix,
std::unordered_set<RouteConfigProvider*>& route_config_providers,
envoy::api::v2::core::ConfigSource::XdsApiVersion xds_api_version)
: config_update_info_(config_update_info),
scope_(factory_context.scope().createScope(stat_prefix + "vhds." +
config_update_info_->routeConfigName() + ".")),
stats_({ALL_VHDS_STATS(POOL_COUNTER(*scope_))}),
init_target_(fmt::format("VhdsConfigSubscription {}", config_update_info_->routeConfigName()),
[this]() { subscription_->start({}); }),
route_config_providers_(route_config_providers) {
route_config_providers_(route_config_providers), xds_api_version_(xds_api_version) {
const auto& config_source = config_update_info_->routeConfiguration()
.vhds()
.config_source()
Expand All @@ -42,10 +44,8 @@ VhdsSubscription::VhdsSubscription(RouteConfigUpdatePtr& config_update_info,

subscription_ =
factory_context.clusterManager().subscriptionFactory().subscriptionFromConfigSource(
config_update_info_->routeConfiguration().vhds().config_source(),
Grpc::Common::typeUrl(
API_NO_BOOST(envoy::api::v2::route::VirtualHost)().GetDescriptor()->full_name()),
*scope_, *this);
config_update_info_->routeConfiguration().vhds().config_source(), loadTypeUrl(), *scope_,
*this);
}

void VhdsSubscription::onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason,
Expand All @@ -72,5 +72,19 @@ void VhdsSubscription::onConfigUpdate(
init_target_.ready();
}

std::string VhdsSubscription::loadTypeUrl() {
switch (xds_api_version_) {
// automatically set api version as V2
case envoy::api::v2::core::ConfigSource::AUTO:
case envoy::api::v2::core::ConfigSource::V2:
return Grpc::Common::typeUrl(
API_NO_BOOST(envoy::api::v2::route::VirtualHost().GetDescriptor()->full_name()));
case envoy::api::v2::core::ConfigSource::V3ALPHA:
return Grpc::Common::typeUrl(
API_NO_BOOST(envoy::api::v2::route::VirtualHost().GetDescriptor()->full_name()));
default:
throw EnvoyException(fmt::format("type {} is not supported", xds_api_version_));
}
}
} // namespace Router
} // namespace Envoy
Loading

0 comments on commit dcc1814

Please sign in to comment.