Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 4 additions & 4 deletions source/common/config/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ void Utility::translateApiConfigSource(

void Utility::checkCluster(absl::string_view error_prefix, absl::string_view cluster_name,
Upstream::ClusterManager& cm, bool allow_added_via_api) {
Upstream::ThreadLocalCluster* cluster = cm.get(cluster_name);
if (cluster == nullptr) {
auto clusters = cm.clusters();
const auto& it = clusters.find(std::string(cluster_name));
if (it == clusters.end()) {
throw EnvoyException(fmt::format("{}: unknown cluster '{}'", error_prefix, cluster_name));
}

if (!allow_added_via_api && cluster->info()->addedViaApi()) {
if (!allow_added_via_api && it->second.get().info()->addedViaApi()) {
throw EnvoyException(fmt::format("{}: invalid cluster '{}': currently only "
"static (non-CDS) clusters are supported",
error_prefix, cluster_name));
Expand Down
1 change: 1 addition & 0 deletions source/common/grpc/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ envoy_cc_library(
"//include/envoy/singleton:manager_interface",
"//include/envoy/thread_local:thread_local_interface",
"//include/envoy/upstream:cluster_manager_interface",
"//source/common/config:utility_lib",
] + envoy_select_google_grpc([":google_async_client_lib"]),
)

Expand Down
13 changes: 3 additions & 10 deletions source/common/grpc/async_client_manager_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "envoy/config/core/v3/grpc_service.pb.h"
#include "envoy/stats/scope.h"

#include "common/config/utility.h"
#include "common/grpc/async_client_impl.h"

#ifdef ENVOY_GOOGLE_GRPC
Expand All @@ -19,16 +20,8 @@ AsyncClientFactoryImpl::AsyncClientFactoryImpl(Upstream::ClusterManager& cm,
if (skip_cluster_check) {
return;
}

const std::string& cluster_name = config.envoy_grpc().cluster_name();
auto clusters = cm_.clusters();
const auto& it = clusters.find(cluster_name);
if (it == clusters.end()) {
throw EnvoyException(fmt::format("Unknown gRPC client cluster '{}'", cluster_name));
}
if (it->second.get().info()->addedViaApi()) {
throw EnvoyException(fmt::format("gRPC client cluster '{}' is not static", cluster_name));
}
Config::Utility::checkCluster("AsyncClientFactory", config.envoy_grpc().cluster_name(), cm_,
false);
}

AsyncClientManagerImpl::AsyncClientManagerImpl(Upstream::ClusterManager& cm,
Expand Down
32 changes: 32 additions & 0 deletions test/common/config/utility_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,38 @@ TEST(UtilityTest, EmptyToEmptyConfig) {
EXPECT_THAT(out, ProtoEq(envoy::extensions::filters::http::cors::v3::Cors()));
}

// Validates CheckCluster functionality.
TEST(UtilityTest, CheckCluster) {
Upstream::MockClusterManager cm;
Upstream::ClusterManager::ClusterInfoMap cluster_map;

// Validate that proper error is thrown, when cluster is not available.
EXPECT_CALL(cm, clusters()).WillOnce(Return(cluster_map));
EXPECT_THROW_WITH_MESSAGE(Utility::checkCluster("prefix", "foo", cm, false), EnvoyException,
"prefix: unknown cluster 'foo'");

// Validate that proper error is thrown, when dynamic cluster is passed when it is not expected.
Upstream::MockClusterMockPrioritySet api_cluster;
cluster_map.emplace("foo", api_cluster);
EXPECT_CALL(cm, clusters()).Times(2).WillRepeatedly(Return(cluster_map));
EXPECT_CALL(api_cluster, info());
EXPECT_CALL(*api_cluster.info_, addedViaApi()).WillOnce(Return(true));
EXPECT_THROW_WITH_MESSAGE(Utility::checkCluster("prefix", "foo", cm, false), EnvoyException,
"prefix: invalid cluster 'foo': currently only "
"static (non-CDS) clusters are supported");
EXPECT_NO_THROW(Utility::checkCluster("prefix", "foo", cm, true));

// Validate that bootstrap cluster does not throw any exceptions.
cluster_map.clear();
Upstream::MockClusterMockPrioritySet bootstrap_cluster;
cluster_map.emplace("foo", bootstrap_cluster);
EXPECT_CALL(cm, clusters()).Times(2).WillRepeatedly(Return(cluster_map));
EXPECT_CALL(bootstrap_cluster, info());
EXPECT_CALL(*bootstrap_cluster.info_, addedViaApi()).WillOnce(Return(false));
EXPECT_NO_THROW(Utility::checkCluster("prefix", "foo", cm, true));
EXPECT_NO_THROW(Utility::checkCluster("prefix", "foo", cm, false));
}

TEST(CheckApiConfigSourceSubscriptionBackingClusterTest, GrpcClusterTestAcrossTypes) {
envoy::config::core::v3::ConfigSource config;
auto* api_config_source = config.mutable_api_config_source();
Expand Down
5 changes: 3 additions & 2 deletions test/common/grpc/async_client_manager_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ TEST_F(AsyncClientManagerImplTest, EnvoyGrpcUnknown) {
EXPECT_CALL(cm_, clusters());
EXPECT_THROW_WITH_MESSAGE(
async_client_manager_.factoryForGrpcService(grpc_service, scope_, false), EnvoyException,
"Unknown gRPC client cluster 'foo'");
"AsyncClientFactory: unknown cluster 'foo'");
}

TEST_F(AsyncClientManagerImplTest, EnvoyGrpcDynamicCluster) {
Expand All @@ -69,7 +69,8 @@ TEST_F(AsyncClientManagerImplTest, EnvoyGrpcDynamicCluster) {
EXPECT_CALL(*cluster.info_, addedViaApi()).WillOnce(Return(true));
EXPECT_THROW_WITH_MESSAGE(
async_client_manager_.factoryForGrpcService(grpc_service, scope_, false), EnvoyException,
"gRPC client cluster 'foo' is not static");
"AsyncClientFactory: invalid cluster 'foo': currently only static (non-CDS) clusters are "
"supported");
}

TEST_F(AsyncClientManagerImplTest, GoogleGrpc) {
Expand Down