Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions configs/envoy_service_to_service.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ static_resources:
config_source:
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
envoy_grpc:
cluster_name: "rds"
Expand Down Expand Up @@ -544,6 +545,7 @@ dynamic_resources:
cds_config:
api_config_source:
api_type: REST
transport_api_version: V3
cluster_names:
- cds_cluster
refresh_delay: 30s
Expand Down
1 change: 1 addition & 0 deletions configs/routing_helper.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
eds_config:
api_config_source:
api_type: REST
transport_api_version: V3
cluster_names:
- sds
refresh_delay: 30s
Expand Down
28 changes: 18 additions & 10 deletions source/common/config/subscription_factory_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,6 @@ SubscriptionPtr SubscriptionFactoryImpl::subscriptionFromConfigSource(
Config::Utility::checkLocalInfo(type_url, local_info_);
std::unique_ptr<Subscription> result;
SubscriptionStats stats = Utility::generateStats(scope);
auto& runtime_snapshot = runtime_.snapshot();

const auto transport_api_version = config.api_config_source().transport_api_version();
if (transport_api_version == envoy::config::core::v3::ApiVersion::V2 &&
runtime_snapshot.runtimeFeatureEnabled(
"envoy.reloadable_features.enable_deprecated_v2_api_warning")) {
runtime_.countDeprecatedFeatureUse();
ENVOY_LOG(warn,
"xDS of version v2 has been deprecated and will be removed in subsequent versions");
}

switch (config.config_source_specifier_case()) {
case envoy::config::core::v3::ConfigSource::ConfigSourceSpecifierCase::kPath: {
Expand All @@ -51,6 +41,24 @@ SubscriptionPtr SubscriptionFactoryImpl::subscriptionFromConfigSource(
const envoy::config::core::v3::ApiConfigSource& api_config_source = config.api_config_source();
Utility::checkApiConfigSourceSubscriptionBackingCluster(cm_.primaryClusters(),
api_config_source);
const auto transport_api_version = api_config_source.transport_api_version();
if (transport_api_version == envoy::config::core::v3::ApiVersion::AUTO ||
Comment thread
htuch marked this conversation as resolved.
transport_api_version == envoy::config::core::v3::ApiVersion::V2) {
runtime_.countDeprecatedFeatureUse();
const std::string& warning = fmt::format(
"V2 (and AUTO) xDS transport protocol versions are deprecated in {}. "
"The v2 xDS major version is deprecated and disabled by default. Support for v2 will be "
"removed from Envoy at the start of Q1 2021. You may make use of v2 in Q4 2020 by "
"setting '--bootstrap-version 2' on the CLI for a v2 bootstrap file or by enabling "
"the runtime envoy.reloadable_features.enable_deprecated_v2_api flag.",
config.DebugString());
Comment thread
htuch marked this conversation as resolved.
ENVOY_LOG(warn, warning);
auto& runtime_snapshot = runtime_.snapshot();
if (!runtime_snapshot.runtimeFeatureEnabled(
"envoy.reloadable_features.enable_deprecated_v2_api")) {
throw DeprecatedMajorVersionException(warning);
}
}

switch (api_config_source.api_type()) {
case envoy::config::core::v3::ApiConfigSource::hidden_envoy_deprecated_UNSUPPORTED_REST_LEGACY:
Expand Down
4 changes: 2 additions & 2 deletions source/common/protobuf/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ void MessageUtil::onVersionUpgradeDeprecation(absl::string_view desc, bool rejec
!Runtime::runtimeFeatureEnabled("envoy.reloadable_features.enable_deprecated_v2_api")) {
throw DeprecatedMajorVersionException(fmt::format(
"The v2 xDS major version is deprecated and disabled by default. Support for v2 will be "
"removed from Envoy at the start of Q1 2021. You may make use of v2 in Q3 2020 by setting "
"'--bootstrap-version 2' on the CLI for a v2 bootstrap file and also enabling the runtime "
"removed from Envoy at the start of Q1 2021. You may make use of v2 in Q4 2020 by setting "
"'--bootstrap-version 2' on the CLI for a v2 bootstrap file or by enabling the runtime "
"envoy.reloadable_features.enable_deprecated_v2_api flag. ({})",
desc));
}
Expand Down
1 change: 0 additions & 1 deletion source/common/runtime/runtime_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ constexpr const char* runtime_features[] = {
"envoy.reloadable_features.check_ocsp_policy",
"envoy.reloadable_features.disallow_unbounded_access_logs",
"envoy.reloadable_features.early_errors_via_hcm",
"envoy.reloadable_features.enable_deprecated_v2_api_warning",
"envoy.reloadable_features.enable_dns_cache_circuit_breakers",
"envoy.reloadable_features.fix_upgrade_response",
"envoy.reloadable_features.fix_wildcard_matching",
Expand Down
2 changes: 1 addition & 1 deletion source/server/config_validation/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void ValidationInstance::initialize(const Options& options,
bootstrap.node(), local_address, options.serviceZone(), options.serviceClusterName(),
options.serviceNodeName());

Configuration::InitialImpl initial_config(bootstrap);
Configuration::InitialImpl initial_config(bootstrap, options);
overload_manager_ = std::make_unique<OverloadManagerImpl>(
dispatcher(), stats(), threadLocal(), bootstrap.overload_manager(),
messageValidationContext().staticValidationVisitor(), *api_);
Expand Down
12 changes: 11 additions & 1 deletion source/server/configuration_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ WatchdogImpl::WatchdogImpl(const envoy::config::bootstrap::v3::Watchdog& watchdo
actions_ = watchdog.actions();
}

InitialImpl::InitialImpl(const envoy::config::bootstrap::v3::Bootstrap& bootstrap) {
InitialImpl::InitialImpl(const envoy::config::bootstrap::v3::Bootstrap& bootstrap,
const Options& options)
: enable_deprecated_v2_api_(options.bootstrapVersion() == 2) {
const auto& admin = bootstrap.admin();
admin_.access_log_path_ = admin.access_log_path();
admin_.profile_path_ =
Expand All @@ -201,6 +203,14 @@ InitialImpl::InitialImpl(const envoy::config::bootstrap::v3::Bootstrap& bootstra
} else {
Config::translateRuntime(bootstrap.hidden_envoy_deprecated_runtime(), layered_runtime_);
}
if (enable_deprecated_v2_api_) {
auto* enabled_deprecated_v2_api_layer = layered_runtime_.add_layers();
enabled_deprecated_v2_api_layer->set_name("enabled_deprecated_v2_api (auto-injected)");
auto* static_layer = enabled_deprecated_v2_api_layer->mutable_static_layer();
ProtobufWkt::Value val;
val.set_bool_value(true);
(*static_layer->mutable_fields())["envoy.reloadable_features.enable_deprecated_v2_api"] = val;
}
}

} // namespace Configuration
Expand Down
3 changes: 2 additions & 1 deletion source/server/configuration_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class WatchdogImpl : public Watchdog {
*/
class InitialImpl : public Initial {
public:
InitialImpl(const envoy::config::bootstrap::v3::Bootstrap& bootstrap);
InitialImpl(const envoy::config::bootstrap::v3::Bootstrap& bootstrap, const Options& options);

// Server::Configuration::Initial
Admin& admin() override { return admin_; }
Expand All @@ -175,6 +175,7 @@ class InitialImpl : public Initial {
Network::Socket::OptionsSharedPtr socket_options_;
};

const bool enable_deprecated_v2_api_;
AdminImpl admin_;
absl::optional<std::string> flags_path_;
envoy::config::bootstrap::v3::LayeredRuntime layered_runtime_;
Expand Down
2 changes: 1 addition & 1 deletion source/server/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ void InstanceImpl::initialize(const Options& options,
bootstrap_.node(), local_address, options.serviceZone(), options.serviceClusterName(),
options.serviceNodeName());

Configuration::InitialImpl initial_config(bootstrap_);
Configuration::InitialImpl initial_config(bootstrap_, options);

// Learn original_start_time_ if our parent is still around to inform us of it.
restarter_.sendParentAdminShutdownRequest(original_start_time_);
Expand Down
52 changes: 43 additions & 9 deletions test/common/config/subscription_factory_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ TEST_F(SubscriptionFactoryTest, RestClusterSingleton) {
Upstream::ClusterManager::ClusterSet primary_clusters;

config.mutable_api_config_source()->set_api_type(envoy::config::core::v3::ApiConfigSource::REST);
config.mutable_api_config_source()->set_transport_api_version(envoy::config::core::v3::V3);
config.mutable_api_config_source()->mutable_refresh_delay()->set_seconds(1);
config.mutable_api_config_source()->add_cluster_names("static_cluster");
primary_clusters.insert("static_cluster");
Expand All @@ -122,6 +123,7 @@ TEST_F(SubscriptionFactoryTest, GrpcClusterSingleton) {
Upstream::ClusterManager::ClusterSet primary_clusters;

config.mutable_api_config_source()->set_api_type(envoy::config::core::v3::ApiConfigSource::GRPC);
config.mutable_api_config_source()->set_transport_api_version(envoy::config::core::v3::V3);
config.mutable_api_config_source()->mutable_refresh_delay()->set_seconds(1);
config.mutable_api_config_source()->add_grpc_services()->mutable_envoy_grpc()->set_cluster_name(
"static_cluster");
Expand Down Expand Up @@ -227,6 +229,7 @@ TEST_F(SubscriptionFactoryTest, LegacySubscription) {
auto* api_config_source = config.mutable_api_config_source();
api_config_source->set_api_type(
envoy::config::core::v3::ApiConfigSource::hidden_envoy_deprecated_UNSUPPORTED_REST_LEGACY);
api_config_source->set_transport_api_version(envoy::config::core::v3::V3);
api_config_source->add_cluster_names("static_cluster");
Upstream::ClusterManager::ClusterSet primary_clusters;
primary_clusters.insert("static_cluster");
Expand All @@ -239,6 +242,7 @@ TEST_F(SubscriptionFactoryTest, HttpSubscriptionCustomRequestTimeout) {
envoy::config::core::v3::ConfigSource config;
auto* api_config_source = config.mutable_api_config_source();
api_config_source->set_api_type(envoy::config::core::v3::ApiConfigSource::REST);
api_config_source->set_transport_api_version(envoy::config::core::v3::V3);
api_config_source->add_cluster_names("static_cluster");
api_config_source->mutable_refresh_delay()->set_seconds(1);
api_config_source->mutable_request_timeout()->set_seconds(5);
Expand All @@ -257,6 +261,7 @@ TEST_F(SubscriptionFactoryTest, HttpSubscription) {
envoy::config::core::v3::ConfigSource config;
auto* api_config_source = config.mutable_api_config_source();
api_config_source->set_api_type(envoy::config::core::v3::ApiConfigSource::REST);
api_config_source->set_transport_api_version(envoy::config::core::v3::V3);
api_config_source->add_cluster_names("static_cluster");
api_config_source->mutable_refresh_delay()->set_seconds(1);
Upstream::ClusterManager::ClusterSet primary_clusters;
Expand All @@ -269,7 +274,7 @@ TEST_F(SubscriptionFactoryTest, HttpSubscription) {
const Http::AsyncClient::RequestOptions&) {
EXPECT_EQ("POST", request->headers().getMethodValue());
EXPECT_EQ("static_cluster", request->headers().getHostValue());
EXPECT_EQ("/v2/discovery:endpoints", request->headers().getPathValue());
EXPECT_EQ("/v3/discovery:endpoints", request->headers().getPathValue());
return &http_request_;
}));
EXPECT_CALL(http_request_, cancel());
Expand All @@ -281,6 +286,7 @@ TEST_F(SubscriptionFactoryTest, HttpSubscriptionNoRefreshDelay) {
envoy::config::core::v3::ConfigSource config;
auto* api_config_source = config.mutable_api_config_source();
api_config_source->set_api_type(envoy::config::core::v3::ApiConfigSource::REST);
api_config_source->set_transport_api_version(envoy::config::core::v3::V3);
api_config_source->add_cluster_names("static_cluster");
Upstream::ClusterManager::ClusterSet primary_clusters;
primary_clusters.insert("static_cluster");
Expand All @@ -294,6 +300,7 @@ TEST_F(SubscriptionFactoryTest, GrpcSubscription) {
envoy::config::core::v3::ConfigSource config;
auto* api_config_source = config.mutable_api_config_source();
api_config_source->set_api_type(envoy::config::core::v3::ApiConfigSource::GRPC);
api_config_source->set_transport_api_version(envoy::config::core::v3::V3);
api_config_source->add_grpc_services()->mutable_envoy_grpc()->set_cluster_name("static_cluster");
envoy::config::core::v3::GrpcService expected_grpc_service;
expected_grpc_service.mutable_envoy_grpc()->set_cluster_name("static_cluster");
Expand All @@ -317,27 +324,54 @@ TEST_F(SubscriptionFactoryTest, GrpcSubscription) {
subscriptionFromConfigSource(config)->start({"static_cluster"});
}

TEST_F(SubscriptionFactoryTest, LogWarningOnDeprecatedApi) {
// Use of the V2 transport fails by default.
TEST_F(SubscriptionFactoryTest, LogWarningOnDeprecatedV2Transport) {
envoy::config::core::v3::ConfigSource config;

config.mutable_api_config_source()->set_api_type(envoy::config::core::v3::ApiConfigSource::GRPC);
config.mutable_api_config_source()->set_transport_api_version(
envoy::config::core::v3::ApiVersion::V2);
config.mutable_api_config_source()->add_grpc_services()->mutable_envoy_grpc()->set_cluster_name(
"static_cluster");
NiceMock<Runtime::MockSnapshot> snapshot;
EXPECT_CALL(runtime_, snapshot()).WillRepeatedly(ReturnRef(snapshot));
EXPECT_CALL(snapshot, runtimeFeatureEnabled(_)).WillOnce(Return(false));
EXPECT_CALL(runtime_, countDeprecatedFeatureUse());

Upstream::ClusterManager::ClusterSet primary_clusters;
primary_clusters.insert("static_cluster");
EXPECT_CALL(cm_, primaryClusters()).WillOnce(ReturnRef(primary_clusters));

EXPECT_THROW_WITH_REGEX(subscription_factory_.subscriptionFromConfigSource(
config, Config::TypeUrl::get().ClusterLoadAssignment, stats_store_,
callbacks_, resource_decoder_),
EnvoyException,
"V2 .and AUTO. xDS transport protocol versions are deprecated in");
}

// Use of AUTO transport fails by default. This will encourage folks to upgrade to explicit V3.
TEST_F(SubscriptionFactoryTest, LogWarningOnDeprecatedAutoTransport) {
envoy::config::core::v3::ConfigSource config;

config.mutable_api_config_source()->set_api_type(envoy::config::core::v3::ApiConfigSource::GRPC);
config.mutable_api_config_source()->set_transport_api_version(
envoy::config::core::v3::ApiVersion::AUTO);
config.mutable_api_config_source()->add_grpc_services()->mutable_envoy_grpc()->set_cluster_name(
"static_cluster");
NiceMock<Runtime::MockSnapshot> snapshot;
EXPECT_CALL(runtime_, snapshot()).WillRepeatedly(ReturnRef(snapshot));
EXPECT_CALL(snapshot, runtimeFeatureEnabled(_)).WillOnce(Return(true));
EXPECT_CALL(snapshot, runtimeFeatureEnabled(_)).WillOnce(Return(false));
EXPECT_CALL(runtime_, countDeprecatedFeatureUse());

Upstream::ClusterManager::ClusterSet primary_clusters;
primary_clusters.insert("static_cluster");
EXPECT_CALL(cm_, primaryClusters()).WillOnce(ReturnRef(primary_clusters));

EXPECT_LOG_CONTAINS(
"warn", "xDS of version v2 has been deprecated", try {
subscription_factory_.subscriptionFromConfigSource(
config, Config::TypeUrl::get().ClusterLoadAssignment, stats_store_, callbacks_,
resource_decoder_);
} catch (EnvoyException&){/* expected, we pass an empty configuration */});
EXPECT_THROW_WITH_REGEX(subscription_factory_.subscriptionFromConfigSource(
config, Config::TypeUrl::get().ClusterLoadAssignment, stats_store_,
callbacks_, resource_decoder_),
EnvoyException,
"V2 .and AUTO. xDS transport protocol versions are deprecated in");
}

INSTANTIATE_TEST_SUITE_P(SubscriptionFactoryTestApiConfigSource,
Expand Down
1 change: 1 addition & 0 deletions test/common/upstream/cluster_manager_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ TEST_F(ClusterManagerImplTest, PrimaryClusters) {
eds_config:
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
envoy_grpc:
cluster_name: static_cluster
Expand Down
1 change: 1 addition & 0 deletions test/config/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ std::string ConfigHelper::discoveredClustersBootstrap(const std::string& api_typ
resource_api_version: V3
api_config_source:
api_type: {}
transport_api_version: V3
grpc_services:
envoy_grpc:
cluster_name: my_cds_cluster
Expand Down
2 changes: 1 addition & 1 deletion test/config_test/config_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class ConfigTest {
envoy::config::bootstrap::v3::Bootstrap bootstrap;
Server::InstanceUtil::loadBootstrapConfig(
bootstrap, options_, server_.messageValidationContext().staticValidationVisitor(), *api_);
Server::Configuration::InitialImpl initial_config(bootstrap);
Server::Configuration::InitialImpl initial_config(bootstrap, options);
Server::Configuration::MainImpl main_config;

cluster_manager_factory_ = std::make_unique<Upstream::ValidationClusterManagerFactory>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const std::string& config() {
resource_api_version: V3
api_config_source:
api_type: GRPC
transport_api_version: V3
grpc_services:
envoy_grpc:
cluster_name: my_cds_cluster
Expand Down
1 change: 1 addition & 0 deletions test/extensions/filters/http/lua/lua_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class LuaIntegrationTest : public testing::TestWithParam<Network::Address::IpVer
envoy::config::core::v3::ApiConfigSource* rds_api_config_source =
hcm.mutable_rds()->mutable_config_source()->mutable_api_config_source();
rds_api_config_source->set_api_type(envoy::config::core::v3::ApiConfigSource::GRPC);
rds_api_config_source->set_transport_api_version(envoy::config::core::v3::V3);
envoy::config::core::v3::GrpcService* grpc_service =
rds_api_config_source->add_grpc_services();
grpc_service->mutable_envoy_grpc()->set_cluster_name("xds_cluster");
Expand Down
19 changes: 19 additions & 0 deletions test/integration/ads_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,24 @@ TEST_P(AdsIntegrationTest, DuplicateWarmingListeners) {
test_server_->waitForCounterGe("listener_manager.lds.update_rejected", 1);
}

// Validate that the use of V2 transport version is rejected by default.
TEST_P(AdsIntegrationTest, RejectV2TransportConfigByDefault) {
initialize();

EXPECT_TRUE(compareDiscoveryRequest(Config::TypeUrl::get().Cluster, "", {}, {}, {}, true));
auto cluster = buildCluster("cluster_0");
auto* api_config_source =
cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_api_config_source();
api_config_source->set_api_type(envoy::config::core::v3::ApiConfigSource::GRPC);
api_config_source->set_transport_api_version(envoy::config::core::v3::V2);
envoy::config::core::v3::GrpcService* grpc_service = api_config_source->add_grpc_services();
setGrpcService(*grpc_service, "ads_cluster", xds_upstream_->localAddress());
sendDiscoveryResponse<envoy::config::cluster::v3::Cluster>(Config::TypeUrl::get().Cluster,
{cluster}, {cluster}, {}, "1");
test_server_->waitForCounterGe("cluster_manager.cds.update_rejected", 1);
EXPECT_EQ(1, test_server_->gauge("runtime.deprecated_feature_seen_since_process_start")->value());
}

// Regression test for the use-after-free crash when processing RDS update (#3953).
TEST_P(AdsIntegrationTest, RdsAfterLdsWithNoRdsChanges) {
initialize();
Expand Down Expand Up @@ -1386,6 +1404,7 @@ TEST_P(AdsClusterV2Test, RejectV2ConfigByDefault) {
sendDiscoveryResponse<envoy::config::cluster::v3::Cluster>(
cds_type_url, {buildCluster("cluster_0")}, {buildCluster("cluster_0")}, {}, "1", true);
test_server_->waitForCounterGe("cluster_manager.cds.update_rejected", 1);
EXPECT_EQ(1, test_server_->gauge("runtime.deprecated_feature_seen_since_process_start")->value());
}

// Verify CDS is paused during cluster warming.
Expand Down
2 changes: 2 additions & 0 deletions test/integration/api_version_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class ApiVersionIntegrationTest : public testing::TestWithParam<Params>,
tls_xds_upstream_ = false;
defer_listener_finalization_ = true;
skipPortUsageValidation();
// Keep using V2 bootstrap for now to allow V2 transport version.
v2_bootstrap_ = true;
}

static bool hasHiddenEnvoyDeprecated(const Protobuf::Message& message) {
Expand Down
7 changes: 4 additions & 3 deletions test/integration/cds_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ class CdsIntegrationTest : public Grpc::DeltaSotwIntegrationParamTest, public Ht
void verifyGrpcServiceMethod() {
EXPECT_TRUE(xds_stream_->waitForHeadersComplete());
Envoy::Http::LowerCaseString path_string(":path");
std::string expected_method(sotwOrDelta() == Grpc::SotwOrDelta::Sotw
? "/envoy.api.v2.ClusterDiscoveryService/StreamClusters"
: "/envoy.api.v2.ClusterDiscoveryService/DeltaClusters");
std::string expected_method(
sotwOrDelta() == Grpc::SotwOrDelta::Sotw
? "/envoy.service.cluster.v3.ClusterDiscoveryService/StreamClusters"
: "/envoy.service.cluster.v3.ClusterDiscoveryService/DeltaClusters");
EXPECT_EQ(xds_stream_->headers().get(path_string)[0]->value(), expected_method);
}

Expand Down
Loading