Skip to content

Commit

Permalink
route config: use clusters() instead of get() for route validation
Browse files Browse the repository at this point in the history
This is a follow up to #13906. It replaces use of the thread local
clusters with the main thread clusters() output for static route
validation. This will enable further cleanups in the cluster manager
code.

Signed-off-by: Matt Klein <[email protected]>
  • Loading branch information
mattklein123 committed Nov 28, 2020
1 parent dee245d commit c5b0559
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 46 deletions.
7 changes: 6 additions & 1 deletion include/envoy/upstream/cluster_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,13 @@ class ClusterManager {
virtual void
initializeSecondaryClusters(const envoy::config::bootstrap::v3::Bootstrap& bootstrap) PURE;

using ClusterInfoMap = absl::node_hash_map<std::string, std::reference_wrapper<const Cluster>>;
using ClusterInfoMap = absl::flat_hash_map<std::string, std::reference_wrapper<const Cluster>>;
struct ClusterInfoMaps {
bool hasCluster(absl::string_view cluster) const {
return active_clusters_.find(cluster) != active_clusters_.end() ||
warming_clusters_.find(cluster) != warming_clusters_.end();
}

ClusterInfoMap active_clusters_;
ClusterInfoMap warming_clusters_;
};
Expand Down
30 changes: 18 additions & 12 deletions source/common/router/config_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,8 @@ RouteConstSharedPtr RouteEntryImplBase::clusterEntry(const Http::HeaderMap& head
true);
}

void RouteEntryImplBase::validateClusters(Upstream::ClusterManager& cm) const {
void RouteEntryImplBase::validateClusters(
const Upstream::ClusterManager::ClusterInfoMaps& cluster_info_maps) const {
if (isDirectResponse()) {
return;
}
Expand All @@ -914,12 +915,12 @@ void RouteEntryImplBase::validateClusters(Upstream::ClusterManager& cm) const {
// In the future we might decide to also have a config option that turns off checks for static
// route tables. This would enable the all CDS with static route table case.
if (!cluster_name_.empty()) {
if (!cm.get(cluster_name_)) {
if (!cluster_info_maps.hasCluster(cluster_name_)) {
throw EnvoyException(fmt::format("route: unknown cluster '{}'", cluster_name_));
}
} else if (!weighted_clusters_.empty()) {
for (const WeightedClusterEntrySharedPtr& cluster : weighted_clusters_) {
if (!cm.get(cluster->clusterName())) {
if (!cluster_info_maps.hasCluster(cluster->clusterName())) {
throw EnvoyException(
fmt::format("route: unknown weighted cluster '{}'", cluster->clusterName()));
}
Expand Down Expand Up @@ -1075,11 +1076,12 @@ RouteConstSharedPtr ConnectRouteEntryImpl::matches(const Http::RequestHeaderMap&
return nullptr;
}

VirtualHostImpl::VirtualHostImpl(const envoy::config::route::v3::VirtualHost& virtual_host,
const ConfigImpl& global_route_config,
Server::Configuration::ServerFactoryContext& factory_context,
Stats::Scope& scope, ProtobufMessage::ValidationVisitor& validator,
bool validate_clusters)
VirtualHostImpl::VirtualHostImpl(
const envoy::config::route::v3::VirtualHost& virtual_host,
const ConfigImpl& global_route_config,
Server::Configuration::ServerFactoryContext& factory_context, Stats::Scope& scope,
ProtobufMessage::ValidationVisitor& validator,
const absl::optional<Upstream::ClusterManager::ClusterInfoMaps>& validation_clusters)
: stat_name_pool_(factory_context.scope().symbolTable()),
stat_name_(stat_name_pool_.add(virtual_host.name())),
vcluster_scope_(scope.createScope(virtual_host.name() + ".vcluster")),
Expand Down Expand Up @@ -1142,11 +1144,11 @@ VirtualHostImpl::VirtualHostImpl(const envoy::config::route::v3::VirtualHost& vi
NOT_REACHED_GCOVR_EXCL_LINE;
}

if (validate_clusters) {
routes_.back()->validateClusters(factory_context.clusterManager());
if (validation_clusters.has_value()) {
routes_.back()->validateClusters(*validation_clusters);
for (const auto& shadow_policy : routes_.back()->shadowPolicies()) {
ASSERT(!shadow_policy->cluster().empty());
if (!factory_context.clusterManager().get(shadow_policy->cluster())) {
if (!validation_clusters->hasCluster(shadow_policy->cluster())) {
throw EnvoyException(
fmt::format("route: unknown shadow cluster '{}'", shadow_policy->cluster()));
}
Expand Down Expand Up @@ -1228,10 +1230,14 @@ RouteMatcher::RouteMatcher(const envoy::config::route::v3::RouteConfiguration& r
Server::Configuration::ServerFactoryContext& factory_context,
ProtobufMessage::ValidationVisitor& validator, bool validate_clusters)
: vhost_scope_(factory_context.scope().createScope("vhost")) {
absl::optional<Upstream::ClusterManager::ClusterInfoMaps> validation_clusters;
if (validate_clusters) {
validation_clusters = factory_context.clusterManager().clusters();
}
for (const auto& virtual_host_config : route_config.virtual_hosts()) {
VirtualHostSharedPtr virtual_host(new VirtualHostImpl(virtual_host_config, global_route_config,
factory_context, *vhost_scope_, validator,
validate_clusters));
validation_clusters));
for (const std::string& domain_name : virtual_host_config.domains()) {
const std::string domain = Http::LowerCaseString(domain_name).get();
bool duplicate_found = false;
Expand Down
12 changes: 7 additions & 5 deletions source/common/router/config_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,12 @@ class ConfigImpl;
*/
class VirtualHostImpl : public VirtualHost {
public:
VirtualHostImpl(const envoy::config::route::v3::VirtualHost& virtual_host,
const ConfigImpl& global_route_config,
Server::Configuration::ServerFactoryContext& factory_context, Stats::Scope& scope,
ProtobufMessage::ValidationVisitor& validator, bool validate_clusters);
VirtualHostImpl(
const envoy::config::route::v3::VirtualHost& virtual_host,
const ConfigImpl& global_route_config,
Server::Configuration::ServerFactoryContext& factory_context, Stats::Scope& scope,
ProtobufMessage::ValidationVisitor& validator,
const absl::optional<Upstream::ClusterManager::ClusterInfoMaps>& validation_clusters);

RouteConstSharedPtr getRouteFromEntries(const RouteCallback& cb,
const Http::RequestHeaderMap& headers,
Expand Down Expand Up @@ -461,7 +463,7 @@ class RouteEntryImplBase : public RouteEntry,

bool matchRoute(const Http::RequestHeaderMap& headers, const StreamInfo::StreamInfo& stream_info,
uint64_t random_value) const;
void validateClusters(Upstream::ClusterManager& cm) const;
void validateClusters(const Upstream::ClusterManager::ClusterInfoMaps& cluster_info_maps) const;

// Router::RouteEntry
const std::string& clusterName() const override;
Expand Down
Loading

0 comments on commit c5b0559

Please sign in to comment.