Line data Source code
1 : #pragma once 2 : 3 : #include <chrono> 4 : #include <cstdint> 5 : #include <functional> 6 : #include <string> 7 : 8 : #include "envoy/config/cluster/v3/cluster.pb.h" 9 : #include "envoy/config/endpoint/v3/endpoint.pb.h" 10 : #include "envoy/config/endpoint/v3/endpoint_components.pb.h" 11 : #include "envoy/stats/scope.h" 12 : 13 : #include "source/common/common/empty_string.h" 14 : #include "source/common/upstream/cluster_factory_impl.h" 15 : #include "source/common/upstream/upstream_impl.h" 16 : #include "source/extensions/clusters/common/logical_host.h" 17 : 18 : namespace Envoy { 19 : namespace Upstream { 20 : 21 : class LogicalDnsClusterFactory; 22 : class LogicalDnsClusterTest; 23 : 24 : /** 25 : * The LogicalDnsCluster is a type of cluster that creates a single logical host that wraps 26 : * an async DNS resolver. The DNS resolver will continuously resolve, and swap in the first IP 27 : * address in the resolution set. However the logical owning host will not change. Any created 28 : * connections against this host will use the currently resolved IP. This means that a connection 29 : * pool using the logical host may end up with connections to many different real IPs. 30 : * 31 : * This cluster type is useful for large web services that use DNS in a round robin fashion, such 32 : * that DNS resolution may repeatedly return different results. A single connection pool can be 33 : * created that will internally have connections to different backends, while still allowing long 34 : * connection lengths and keep alive. The cluster type should only be used when an IP address change 35 : * means that connections using the IP should not drain. 36 : */ 37 : class LogicalDnsCluster : public ClusterImplBase { 38 : public: 39 : ~LogicalDnsCluster() override; 40 : 41 : // Upstream::Cluster 42 0 : InitializePhase initializePhase() const override { return InitializePhase::Primary; } 43 : 44 : private: 45 : friend class LogicalDnsClusterFactory; 46 : friend class LogicalDnsClusterTest; 47 : 48 : LogicalDnsCluster(const envoy::config::cluster::v3::Cluster& cluster, 49 : ClusterFactoryContext& context, Network::DnsResolverSharedPtr dns_resolver); 50 : 51 0 : const envoy::config::endpoint::v3::LocalityLbEndpoints& localityLbEndpoint() const { 52 : // This is checked in the constructor, i.e. at config load time. 53 0 : ASSERT(load_assignment_.endpoints().size() == 1); 54 0 : return load_assignment_.endpoints()[0]; 55 0 : } 56 : 57 0 : const envoy::config::endpoint::v3::LbEndpoint& lbEndpoint() const { 58 : // This is checked in the constructor, i.e. at config load time. 59 0 : ASSERT(localityLbEndpoint().lb_endpoints().size() == 1); 60 0 : return localityLbEndpoint().lb_endpoints()[0]; 61 0 : } 62 : 63 : void startResolve(); 64 : 65 : // ClusterImplBase 66 : void startPreInit() override; 67 : 68 : Network::DnsResolverSharedPtr dns_resolver_; 69 : const std::chrono::milliseconds dns_refresh_rate_ms_; 70 : BackOffStrategyPtr failure_backoff_strategy_; 71 : const bool respect_dns_ttl_; 72 : Network::DnsLookupFamily dns_lookup_family_; 73 : Event::TimerPtr resolve_timer_; 74 : std::string dns_address_; 75 : uint32_t dns_port_; 76 : std::string hostname_; 77 : Network::Address::InstanceConstSharedPtr current_resolved_address_; 78 : std::vector<Network::Address::InstanceConstSharedPtr> current_resolved_address_list_; 79 : LogicalHostSharedPtr logical_host_; 80 : Network::ActiveDnsQuery* active_dns_query_{}; 81 : const LocalInfo::LocalInfo& local_info_; 82 : const envoy::config::endpoint::v3::ClusterLoadAssignment load_assignment_; 83 : }; 84 : 85 : class LogicalDnsClusterFactory : public ClusterFactoryImplBase { 86 : public: 87 2 : LogicalDnsClusterFactory() : ClusterFactoryImplBase("envoy.cluster.logical_dns") {} 88 : 89 : private: 90 : friend class LogicalDnsClusterTest; 91 : absl::StatusOr<std::pair<ClusterImplBaseSharedPtr, ThreadAwareLoadBalancerPtr>> 92 : createClusterImpl(const envoy::config::cluster::v3::Cluster& cluster, 93 : ClusterFactoryContext& context) override; 94 : }; 95 : 96 : DECLARE_FACTORY(LogicalDnsClusterFactory); 97 : 98 : } // namespace Upstream 99 : } // namespace Envoy