Line data Source code
1 : #pragma once 2 : 3 : #include <memory> 4 : 5 : #include "envoy/config/cluster/v3/cluster.pb.h" 6 : #include "envoy/config/core/v3/base.pb.h" 7 : #include "envoy/config/core/v3/config_source.pb.h" 8 : #include "envoy/config/eds_resources_cache.h" 9 : #include "envoy/config/endpoint/v3/endpoint.pb.h" 10 : #include "envoy/config/endpoint/v3/endpoint.pb.validate.h" 11 : #include "envoy/config/subscription.h" 12 : #include "envoy/config/subscription_factory.h" 13 : #include "envoy/local_info/local_info.h" 14 : #include "envoy/registry/registry.h" 15 : #include "envoy/secret/secret_manager.h" 16 : #include "envoy/service/discovery/v3/discovery.pb.h" 17 : #include "envoy/stats/scope.h" 18 : #include "envoy/upstream/locality.h" 19 : 20 : #include "source/common/config/subscription_base.h" 21 : #include "source/common/upstream/cluster_factory_impl.h" 22 : #include "source/common/upstream/upstream_impl.h" 23 : #include "source/extensions/clusters/eds/leds.h" 24 : 25 : namespace Envoy { 26 : namespace Upstream { 27 : 28 : /** 29 : * Cluster implementation that reads host information from the Endpoint Discovery Service. 30 : */ 31 : class EdsClusterImpl 32 : : public BaseDynamicClusterImpl, 33 : Envoy::Config::SubscriptionBase<envoy::config::endpoint::v3::ClusterLoadAssignment>, 34 : private Config::EdsResourceRemovalCallback { 35 : public: 36 : EdsClusterImpl(const envoy::config::cluster::v3::Cluster& cluster, 37 : ClusterFactoryContext& cluster_context); 38 : ~EdsClusterImpl() override; 39 : 40 : // Upstream::Cluster 41 56 : InitializePhase initializePhase() const override { return initialize_phase_; } 42 : 43 : private: 44 : // Config::SubscriptionCallbacks 45 : absl::Status onConfigUpdate(const std::vector<Config::DecodedResourceRef>& resources, 46 : const std::string& version_info) override; 47 : absl::Status onConfigUpdate(const std::vector<Config::DecodedResourceRef>& added_resources, 48 : const Protobuf::RepeatedPtrField<std::string>& removed_resources, 49 : const std::string& system_version_info) override; 50 : void onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason, 51 : const EnvoyException* e) override; 52 : using LocalityWeightsMap = absl::node_hash_map<envoy::config::core::v3::Locality, uint32_t, 53 : LocalityHash, LocalityEqualTo>; 54 : bool updateHostsPerLocality(const uint32_t priority, bool weighted_priority_health, 55 : const uint32_t overprovisioning_factor, const HostVector& new_hosts, 56 : LocalityWeightsMap& locality_weights_map, 57 : LocalityWeightsMap& new_locality_weights_map, 58 : PriorityStateManager& priority_state_manager, 59 : const HostMap& all_hosts, 60 : const absl::flat_hash_set<std::string>& all_new_hosts); 61 : bool validateUpdateSize(int num_resources); 62 56 : const std::string& edsServiceName() const { 63 56 : const std::string& name = info_->edsServiceName(); 64 56 : return !name.empty() ? name : info_->name(); 65 56 : } 66 : 67 : // Updates the internal data structures with a given cluster load assignment. 68 : void update(const envoy::config::endpoint::v3::ClusterLoadAssignment& cluster_load_assignment); 69 : 70 : // EdsResourceRemovalCallback 71 : void onCachedResourceRemoved(absl::string_view resource_name) override; 72 : 73 : // ClusterImplBase 74 : void reloadHealthyHostsHelper(const HostSharedPtr& host) override; 75 : void startPreInit() override; 76 : void onAssignmentTimeout(); 77 : 78 : // Returns true iff all the LEDS based localities were updated. 79 : bool validateAllLedsUpdated() const; 80 : 81 : class BatchUpdateHelper : public PrioritySet::BatchUpdateCb { 82 : public: 83 : BatchUpdateHelper( 84 : EdsClusterImpl& parent, 85 : const envoy::config::endpoint::v3::ClusterLoadAssignment& cluster_load_assignment) 86 28 : : parent_(parent), cluster_load_assignment_(cluster_load_assignment) {} 87 : 88 : // Upstream::PrioritySet::BatchUpdateCb 89 : void batchUpdate(PrioritySet::HostUpdateCb& host_update_cb) override; 90 : 91 : private: 92 : void updateLocalityEndpoints( 93 : const envoy::config::endpoint::v3::LbEndpoint& lb_endpoint, 94 : const envoy::config::endpoint::v3::LocalityLbEndpoints& locality_lb_endpoint, 95 : PriorityStateManager& priority_state_manager, 96 : absl::flat_hash_set<std::string>& all_new_hosts); 97 : 98 : EdsClusterImpl& parent_; 99 : const envoy::config::endpoint::v3::ClusterLoadAssignment& cluster_load_assignment_; 100 : }; 101 : 102 : Config::SubscriptionPtr subscription_; 103 : const LocalInfo::LocalInfo& local_info_; 104 : std::vector<LocalityWeightsMap> locality_weights_map_; 105 : Event::TimerPtr assignment_timeout_; 106 : InitializePhase initialize_phase_; 107 : using LedsConfigSet = absl::flat_hash_set<envoy::config::endpoint::v3::LedsClusterLocalityConfig, 108 : MessageUtil, MessageUtil>; 109 : using LedsConfigMap = absl::flat_hash_map<envoy::config::endpoint::v3::LedsClusterLocalityConfig, 110 : LedsSubscriptionPtr, MessageUtil, MessageUtil>; 111 : // Maps between a LEDS configuration (ConfigSource + collection name) to the locality endpoints 112 : // data. 113 : LedsConfigMap leds_localities_; 114 : // TODO(adisuissa): Avoid saving the entire cluster load assignment, only the 115 : // relevant parts of the config for each locality. Note that this field must 116 : // be set when LEDS is used. 117 : std::unique_ptr<envoy::config::endpoint::v3::ClusterLoadAssignment> cluster_load_assignment_; 118 : 119 : // An optional cache for the EDS resources. 120 : // Upon a (warming) timeout, a cached resource will be used. 121 : Config::EdsResourcesCacheOptRef eds_resources_cache_; 122 : 123 : // Tracks whether a cached resource is used as the current EDS resource. 124 : bool using_cached_resource_{false}; 125 : }; 126 : 127 : using EdsClusterImplSharedPtr = std::shared_ptr<EdsClusterImpl>; 128 : 129 : class EdsClusterFactory : public ClusterFactoryImplBase { 130 : public: 131 13 : EdsClusterFactory() : ClusterFactoryImplBase("envoy.cluster.eds") {} 132 : 133 : private: 134 : absl::StatusOr<std::pair<ClusterImplBaseSharedPtr, ThreadAwareLoadBalancerPtr>> 135 : createClusterImpl(const envoy::config::cluster::v3::Cluster& cluster, 136 : ClusterFactoryContext& context) override; 137 : }; 138 : 139 : DECLARE_FACTORY(EdsClusterFactory); 140 : 141 : } // namespace Upstream 142 : } // namespace Envoy