// Copyright 2017 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef GRPC_TEST_CPP_END2END_XDS_XDS_UTILS_H #define GRPC_TEST_CPP_END2END_XDS_XDS_UTILS_H #include #include #include "absl/strings/string_view.h" #include "src/proto/grpc/testing/xds/v3/cluster.pb.h" #include "src/proto/grpc/testing/xds/v3/endpoint.pb.h" #include "src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h" #include "src/proto/grpc/testing/xds/v3/listener.pb.h" #include "src/proto/grpc/testing/xds/v3/route.pb.h" #include "test/cpp/end2end/xds/xds_server.h" namespace grpc { namespace testing { // A builder for the xDS bootstrap config. class XdsBootstrapBuilder { public: XdsBootstrapBuilder() {} XdsBootstrapBuilder& SetIgnoreResourceDeletion() { ignore_resource_deletion_ = true; return *this; } // If ignore_if_set is true, sets the default server only if it has // not already been set. XdsBootstrapBuilder& SetDefaultServer(const std::string& server, bool ignore_if_set = false) { if (!ignore_if_set || top_server_.empty()) top_server_ = server; return *this; } XdsBootstrapBuilder& SetXdsChannelCredentials(const std::string& type) { xds_channel_creds_type_ = type; return *this; } XdsBootstrapBuilder& SetClientDefaultListenerResourceNameTemplate( const std::string& client_default_listener_resource_name_template) { client_default_listener_resource_name_template_ = client_default_listener_resource_name_template; return *this; } XdsBootstrapBuilder& AddCertificateProviderPlugin( const std::string& key, const std::string& name, const std::string& plugin_config = "") { plugins_[key] = {name, plugin_config}; return *this; } XdsBootstrapBuilder& AddAuthority( const std::string& authority, const std::string& server = "", const std::string& client_listener_resource_name_template = "") { authorities_[authority] = {server, client_listener_resource_name_template}; return *this; } XdsBootstrapBuilder& SetServerListenerResourceNameTemplate( const std::string& server_listener_resource_name_template = "") { server_listener_resource_name_template_ = server_listener_resource_name_template; return *this; } std::string Build(); private: struct PluginInfo { std::string name; std::string plugin_config; }; struct AuthorityInfo { std::string server; std::string client_listener_resource_name_template; }; std::string MakeXdsServersText(absl::string_view server_uri); std::string MakeNodeText(); std::string MakeCertificateProviderText(); std::string MakeAuthorityText(); bool ignore_resource_deletion_ = false; std::string top_server_; std::string xds_channel_creds_type_ = "fake"; std::string client_default_listener_resource_name_template_; std::map plugins_; std::map authorities_; std::string server_listener_resource_name_template_ = "grpc/server?xds.resource.listening_address=%s"; }; // Utilities for constructing xDS resources. class XdsResourceUtils { public: using HttpConnectionManager = envoy::extensions::filters::network:: http_connection_manager::v3::HttpConnectionManager; using Listener = envoy::config::listener::v3::Listener; using RouteConfiguration = envoy::config::route::v3::RouteConfiguration; using Cluster = envoy::config::cluster::v3::Cluster; using ClusterLoadAssignment = envoy::config::endpoint::v3::ClusterLoadAssignment; // Interface for accessing HttpConnectionManager config in Listener. class HcmAccessor { public: virtual ~HcmAccessor() = default; virtual HttpConnectionManager Unpack(const Listener& listener) const = 0; virtual void Pack(const HttpConnectionManager& hcm, Listener* listener) const = 0; }; // Client-side impl. class ClientHcmAccessor : public HcmAccessor { public: HttpConnectionManager Unpack(const Listener& listener) const override; void Pack(const HttpConnectionManager& hcm, Listener* listener) const override; }; // Server-side impl. class ServerHcmAccessor : public HcmAccessor { public: HttpConnectionManager Unpack(const Listener& listener) const override; void Pack(const HttpConnectionManager& hcm, Listener* listener) const override; }; // Default values for locality fields. static const char kDefaultLocalityRegion[]; static const char kDefaultLocalityZone[]; static const uint32_t kDefaultLocalityWeight = 3; static const int kDefaultLocalityPriority = 0; // Default resource names. static const char kServerName[]; static const char kDefaultRouteConfigurationName[]; static const char kDefaultClusterName[]; static const char kDefaultEdsServiceName[]; static const char kDefaultServerRouteConfigurationName[]; // Returns default xDS resources. static Listener DefaultListener(); static RouteConfiguration DefaultRouteConfig(); static Cluster DefaultCluster(); static Listener DefaultServerListener(); static RouteConfiguration DefaultServerRouteConfig(); static HttpConnectionManager DefaultHcm(); // Returns the name of the server-side xDS Listener resource for a // backend on the specified port. static std::string GetServerListenerName(int port); // Returns a copy of listener_template with the server-side resource // name and the port in the socket address populated. static Listener PopulateServerListenerNameAndPort( const Listener& listener_template, int port); // Sets the Listener and RouteConfiguration resource on the specified // balancer. If RDS is in use, they will be set as separate resources; // otherwise, the RouteConfig will be inlined into the Listener. static void SetListenerAndRouteConfiguration( AdsServiceImpl* ads_service, Listener listener, const RouteConfiguration& route_config, bool use_rds = false, const HcmAccessor& hcm_accessor = ClientHcmAccessor()); // A convenient wrapper for setting the Listener and // RouteConfiguration resources on the server side. static void SetServerListenerNameAndRouteConfiguration( AdsServiceImpl* ads_service, Listener listener, int port, const RouteConfiguration& route_config, bool use_rds = false) { SetListenerAndRouteConfiguration( ads_service, PopulateServerListenerNameAndPort(listener, port), route_config, use_rds, ServerHcmAccessor()); } // Sets the RouteConfiguration resource on the specified balancer. // If RDS is in use, it will be set directly as an independent // resource; otherwise, it will be inlined into a Listener resource // (either listener_to_copy, or if that is null, default_listener_). static void SetRouteConfiguration(AdsServiceImpl* ads_service, const RouteConfiguration& route_config, bool use_rds = false, const Listener* listener_to_copy = nullptr); // Arguments for constructing an EDS resource. struct EdsResourceArgs { // An individual endpoint for a backend running on a specified port. struct Endpoint { explicit Endpoint(int port, ::envoy::config::core::v3::HealthStatus health_status = ::envoy::config::core::v3::HealthStatus::UNKNOWN, int lb_weight = 1, std::vector additional_ports = {}) : port(port), health_status(health_status), lb_weight(lb_weight), additional_ports(std::move(additional_ports)) {} int port; ::envoy::config::core::v3::HealthStatus health_status; int lb_weight; std::vector additional_ports; }; // A locality. struct Locality { Locality(std::string sub_zone, std::vector endpoints, uint32_t lb_weight = kDefaultLocalityWeight, int priority = kDefaultLocalityPriority) : sub_zone(std::move(sub_zone)), endpoints(std::move(endpoints)), lb_weight(lb_weight), priority(priority) {} const std::string sub_zone; std::vector endpoints; uint32_t lb_weight; int priority; }; EdsResourceArgs() = default; explicit EdsResourceArgs(std::vector locality_list) : locality_list(std::move(locality_list)) {} std::vector locality_list; std::map drop_categories; ::envoy::type::v3::FractionalPercent::DenominatorType drop_denominator = ::envoy::type::v3::FractionalPercent::MILLION; }; // Constructs an EDS resource. static ClusterLoadAssignment BuildEdsResource( const EdsResourceArgs& args, absl::string_view eds_service_name = kDefaultEdsServiceName); }; } // namespace testing } // namespace grpc #endif // GRPC_TEST_CPP_END2END_XDS_XDS_UTILS_H