Line data Source code
1 : #pragma once 2 : 3 : #include <array> 4 : #include <atomic> 5 : #include <chrono> 6 : #include <cstdint> 7 : #include <functional> 8 : #include <list> 9 : #include <memory> 10 : #include <string> 11 : #include <utility> 12 : #include <vector> 13 : 14 : #include "envoy/config/cluster/v3/cluster.pb.h" 15 : #include "envoy/config/typed_metadata.h" 16 : #include "envoy/event/timer.h" 17 : #include "envoy/local_info/local_info.h" 18 : #include "envoy/network/dns.h" 19 : #include "envoy/runtime/runtime.h" 20 : #include "envoy/secret/secret_manager.h" 21 : #include "envoy/server/options.h" 22 : #include "envoy/server/transport_socket_config.h" 23 : #include "envoy/ssl/context_manager.h" 24 : #include "envoy/stats/scope.h" 25 : #include "envoy/thread_local/thread_local.h" 26 : #include "envoy/upstream/cluster_factory.h" 27 : #include "envoy/upstream/cluster_manager.h" 28 : #include "envoy/upstream/health_checker.h" 29 : #include "envoy/upstream/load_balancer.h" 30 : #include "envoy/upstream/locality.h" 31 : #include "envoy/upstream/upstream.h" 32 : 33 : #include "source/common/common/callback_impl.h" 34 : #include "source/common/common/enum_to_int.h" 35 : #include "source/common/common/logger.h" 36 : #include "source/common/config/metadata.h" 37 : #include "source/common/config/utility.h" 38 : #include "source/common/config/well_known_names.h" 39 : #include "source/common/network/utility.h" 40 : #include "source/common/protobuf/utility.h" 41 : #include "source/common/stats/isolated_store_impl.h" 42 : #include "source/common/upstream/load_balancer_impl.h" 43 : #include "source/common/upstream/outlier_detection_impl.h" 44 : #include "source/common/upstream/resource_manager_impl.h" 45 : #include "source/common/upstream/upstream_impl.h" 46 : #include "source/server/transport_socket_config_impl.h" 47 : 48 : namespace Envoy { 49 : namespace Upstream { 50 : 51 : class ClusterFactoryContextImpl : public ClusterFactoryContext { 52 : public: 53 : using LazyCreateDnsResolver = std::function<Network::DnsResolverSharedPtr()>; 54 : 55 : ClusterFactoryContextImpl(Server::Configuration::ServerFactoryContext& server_context, 56 : ClusterManager& cm, LazyCreateDnsResolver dns_resolver_fn, 57 : Ssl::ContextManager& ssl_context_manager, 58 : Outlier::EventLoggerSharedPtr outlier_event_logger, bool added_via_api) 59 : : server_context_(server_context), cluster_manager_(cm), dns_resolver_fn_(dns_resolver_fn), 60 : ssl_context_manager_(ssl_context_manager), 61 : outlier_event_logger_(std::move(outlier_event_logger)), 62 : validation_visitor_( 63 : added_via_api ? server_context.messageValidationContext().dynamicValidationVisitor() 64 : : server_context.messageValidationContext().staticValidationVisitor()), 65 159 : added_via_api_(added_via_api) {} 66 : 67 : // ClusterFactoryContext 68 1272 : Server::Configuration::ServerFactoryContext& serverFactoryContext() override { 69 1272 : return server_context_; 70 1272 : } 71 505 : ClusterManager& clusterManager() override { return cluster_manager_; } 72 187 : ProtobufMessage::ValidationVisitor& messageValidationVisitor() override { 73 187 : return validation_visitor_; 74 187 : } 75 159 : Ssl::ContextManager& sslContextManager() override { return ssl_context_manager_; } 76 0 : Network::DnsResolverSharedPtr dnsResolver() override { 77 0 : if (!dns_resolver_) { 78 0 : dns_resolver_ = dns_resolver_fn_(); 79 0 : } 80 0 : return dns_resolver_; 81 0 : } 82 159 : Outlier::EventLoggerSharedPtr outlierEventLogger() override { return outlier_event_logger_; } 83 159 : bool addedViaApi() override { return added_via_api_; } 84 : 85 : private: 86 : Server::Configuration::ServerFactoryContext& server_context_; 87 : ClusterManager& cluster_manager_; 88 : Network::DnsResolverSharedPtr dns_resolver_; 89 : LazyCreateDnsResolver dns_resolver_fn_; 90 : Ssl::ContextManager& ssl_context_manager_; 91 : Outlier::EventLoggerSharedPtr outlier_event_logger_; 92 : ProtobufMessage::ValidationVisitor& validation_visitor_; 93 : const bool added_via_api_; 94 : }; 95 : 96 : /** 97 : * Base class for all cluster factory implementation. This class can be directly extended if the 98 : * custom cluster does not have any custom configuration. For custom cluster with custom 99 : * configuration, use ConfigurableClusterFactoryBase instead. 100 : */ 101 : class ClusterFactoryImplBase : public ClusterFactory { 102 : public: 103 : using LazyCreateDnsResolver = std::function<Network::DnsResolverSharedPtr()>; 104 : /** 105 : * Static method to get the registered cluster factory and create an instance of cluster. 106 : */ 107 : static absl::StatusOr<std::pair<ClusterSharedPtr, ThreadAwareLoadBalancerPtr>> 108 : create(const envoy::config::cluster::v3::Cluster& cluster, 109 : Server::Configuration::ServerFactoryContext& server_context, ClusterManager& cm, 110 : LazyCreateDnsResolver dns_resolver_fn, Ssl::ContextManager& ssl_context_manager, 111 : Outlier::EventLoggerSharedPtr outlier_event_logger, bool added_via_api); 112 : 113 : /** 114 : * Create a dns resolver to be used by the cluster. 115 : */ 116 : Network::DnsResolverSharedPtr 117 : selectDnsResolver(const envoy::config::cluster::v3::Cluster& cluster, 118 : ClusterFactoryContext& context); 119 : 120 : // Upstream::ClusterFactory 121 : absl::StatusOr<std::pair<ClusterSharedPtr, ThreadAwareLoadBalancerPtr>> 122 : create(const envoy::config::cluster::v3::Cluster& cluster, 123 : ClusterFactoryContext& context) override; 124 39 : std::string name() const override { return name_; } 125 : 126 : protected: 127 39 : ClusterFactoryImplBase(const std::string& name) : name_(name) {} 128 : 129 : private: 130 : /** 131 : * Create an instance of ClusterImplBase or return failure. 132 : */ 133 : virtual absl::StatusOr<std::pair<ClusterImplBaseSharedPtr, ThreadAwareLoadBalancerPtr>> 134 : createClusterImpl(const envoy::config::cluster::v3::Cluster& cluster, 135 : ClusterFactoryContext& context) PURE; 136 : const std::string name_; 137 : }; 138 : 139 : /** 140 : * Common base class for custom cluster factory with custom configuration. 141 : * @param ConfigProto is the configuration protobuf. 142 : */ 143 : template <class ConfigProto> class ConfigurableClusterFactoryBase : public ClusterFactoryImplBase { 144 : public: 145 : /** 146 : * @return ProtobufTypes::MessagePtr create empty config proto message. 147 : */ 148 0 : virtual ProtobufTypes::MessagePtr createEmptyConfigProto() { 149 0 : return std::make_unique<ConfigProto>(); 150 0 : } 151 : 152 : protected: 153 7 : ConfigurableClusterFactoryBase(const std::string& name) : ClusterFactoryImplBase(name) {} 154 : 155 : private: 156 : absl::StatusOr<std::pair<ClusterImplBaseSharedPtr, ThreadAwareLoadBalancerPtr>> 157 : createClusterImpl(const envoy::config::cluster::v3::Cluster& cluster, 158 0 : ClusterFactoryContext& context) override { 159 0 : ProtobufTypes::MessagePtr config = createEmptyConfigProto(); 160 0 : Config::Utility::translateOpaqueConfig(cluster.cluster_type().typed_config(), 161 0 : context.messageValidationVisitor(), *config); 162 0 : return createClusterWithConfig(cluster, 163 0 : MessageUtil::downcastAndValidate<const ConfigProto&>( 164 0 : *config, context.messageValidationVisitor()), 165 0 : context); 166 0 : } 167 : 168 : virtual absl::StatusOr<std::pair<ClusterImplBaseSharedPtr, ThreadAwareLoadBalancerPtr>> 169 : createClusterWithConfig(const envoy::config::cluster::v3::Cluster& cluster, 170 : const ConfigProto& proto_config, ClusterFactoryContext& context) PURE; 171 : }; 172 : 173 : } // namespace Upstream 174 : } // namespace Envoy