LCOV - code coverage report
Current view: top level - source/common/upstream - cluster_factory_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 37 80 46.2 %
Date: 2024-01-05 06:35:25 Functions: 2 3 66.7 %

          Line data    Source code
       1             : #include "source/common/upstream/cluster_factory_impl.h"
       2             : 
       3             : #include "envoy/config/cluster/v3/cluster.pb.h"
       4             : #include "envoy/server/options.h"
       5             : 
       6             : #include "source/common/http/utility.h"
       7             : #include "source/common/network/address_impl.h"
       8             : #include "source/common/network/dns_resolver/dns_factory_util.h"
       9             : #include "source/common/network/resolver_impl.h"
      10             : #include "source/common/network/socket_option_factory.h"
      11             : #include "source/common/upstream/health_checker_impl.h"
      12             : #include "source/server/transport_socket_config_impl.h"
      13             : 
      14             : namespace Envoy {
      15             : namespace Upstream {
      16             : 
      17             : absl::StatusOr<std::pair<ClusterSharedPtr, ThreadAwareLoadBalancerPtr>>
      18             : ClusterFactoryImplBase::create(const envoy::config::cluster::v3::Cluster& cluster,
      19             :                                Server::Configuration::ServerFactoryContext& server_context,
      20             :                                ClusterManager& cm, LazyCreateDnsResolver dns_resolver_fn,
      21             :                                Ssl::ContextManager& ssl_context_manager,
      22             :                                Outlier::EventLoggerSharedPtr outlier_event_logger,
      23         159 :                                bool added_via_api) {
      24         159 :   std::string cluster_type;
      25             : 
      26         159 :   if (!cluster.has_cluster_type()) {
      27         159 :     switch (cluster.type()) {
      28           0 :       PANIC_ON_PROTO_ENUM_SENTINEL_VALUES;
      29         131 :     case envoy::config::cluster::v3::Cluster::STATIC:
      30         131 :       cluster_type = "envoy.cluster.static";
      31         131 :       break;
      32           0 :     case envoy::config::cluster::v3::Cluster::STRICT_DNS:
      33           0 :       cluster_type = "envoy.cluster.strict_dns";
      34           0 :       break;
      35           0 :     case envoy::config::cluster::v3::Cluster::LOGICAL_DNS:
      36           0 :       cluster_type = "envoy.cluster.logical_dns";
      37           0 :       break;
      38           0 :     case envoy::config::cluster::v3::Cluster::ORIGINAL_DST:
      39           0 :       cluster_type = "envoy.cluster.original_dst";
      40           0 :       break;
      41          28 :     case envoy::config::cluster::v3::Cluster::EDS:
      42          28 :       cluster_type = "envoy.cluster.eds";
      43          28 :       break;
      44         159 :     }
      45         159 :   } else {
      46           0 :     cluster_type = cluster.cluster_type().name();
      47           0 :   }
      48             : 
      49         159 :   if (cluster.common_lb_config().has_consistent_hashing_lb_config() &&
      50         159 :       cluster.common_lb_config().consistent_hashing_lb_config().use_hostname_for_hashing() &&
      51         159 :       cluster.type() != envoy::config::cluster::v3::Cluster::STRICT_DNS) {
      52           0 :     return absl::InvalidArgumentError(fmt::format(
      53           0 :         "Cannot use hostname for consistent hashing loadbalancing for cluster of type: '{}'",
      54           0 :         cluster_type));
      55           0 :   }
      56         159 :   ClusterFactory* factory = Registry::FactoryRegistry<ClusterFactory>::getFactory(cluster_type);
      57             : 
      58         159 :   if (factory == nullptr) {
      59           0 :     return absl::InvalidArgumentError(fmt::format(
      60           0 :         "Didn't find a registered cluster factory implementation for name: '{}'", cluster_type));
      61           0 :   }
      62             : 
      63         159 :   ClusterFactoryContextImpl context(server_context, cm, dns_resolver_fn, ssl_context_manager,
      64         159 :                                     std::move(outlier_event_logger), added_via_api);
      65         159 :   return factory->create(cluster, context);
      66         159 : }
      67             : 
      68             : Network::DnsResolverSharedPtr
      69             : ClusterFactoryImplBase::selectDnsResolver(const envoy::config::cluster::v3::Cluster& cluster,
      70           0 :                                           ClusterFactoryContext& context) {
      71             :   // We make this a shared pointer to deal with the distinct ownership
      72             :   // scenarios that can exist: in one case, we pass in the "default"
      73             :   // DNS resolver that is owned by the Server::Instance. In the case
      74             :   // where 'dns_resolvers' is specified, we have per-cluster DNS
      75             :   // resolvers that are created here but ownership resides with
      76             :   // StrictDnsClusterImpl/LogicalDnsCluster.
      77           0 :   if ((cluster.has_typed_dns_resolver_config() &&
      78           0 :        !(cluster.typed_dns_resolver_config().typed_config().type_url().empty())) ||
      79           0 :       (cluster.has_dns_resolution_config() &&
      80           0 :        !cluster.dns_resolution_config().resolvers().empty()) ||
      81           0 :       !cluster.dns_resolvers().empty()) {
      82             : 
      83           0 :     envoy::config::core::v3::TypedExtensionConfig typed_dns_resolver_config;
      84           0 :     Network::DnsResolverFactory& dns_resolver_factory =
      85           0 :         Network::createDnsResolverFactoryFromProto(cluster, typed_dns_resolver_config);
      86           0 :     auto& server_context = context.serverFactoryContext();
      87           0 :     return dns_resolver_factory.createDnsResolver(server_context.mainThreadDispatcher(),
      88           0 :                                                   server_context.api(), typed_dns_resolver_config);
      89           0 :   }
      90             : 
      91           0 :   return context.dnsResolver();
      92           0 : }
      93             : 
      94             : absl::StatusOr<std::pair<ClusterSharedPtr, ThreadAwareLoadBalancerPtr>>
      95             : ClusterFactoryImplBase::create(const envoy::config::cluster::v3::Cluster& cluster,
      96         159 :                                ClusterFactoryContext& context) {
      97             : 
      98         159 :   absl::StatusOr<std::pair<ClusterImplBaseSharedPtr, ThreadAwareLoadBalancerPtr>>
      99         159 :       status_or_cluster = createClusterImpl(cluster, context);
     100         159 :   RETURN_IF_STATUS_NOT_OK(status_or_cluster);
     101         159 :   std::pair<ClusterImplBaseSharedPtr, ThreadAwareLoadBalancerPtr>& new_cluster_pair =
     102         159 :       status_or_cluster.value();
     103             : 
     104         159 :   auto& server_context = context.serverFactoryContext();
     105             : 
     106         159 :   if (!cluster.health_checks().empty()) {
     107             :     // TODO(htuch): Need to support multiple health checks in v2.
     108           0 :     if (cluster.health_checks().size() != 1) {
     109           0 :       return absl::InvalidArgumentError("Multiple health checks not supported");
     110           0 :     } else {
     111           0 :       auto checker_or_error = HealthCheckerFactory::create(cluster.health_checks()[0],
     112           0 :                                                            *new_cluster_pair.first, server_context);
     113           0 :       RETURN_IF_STATUS_NOT_OK(checker_or_error);
     114           0 :       new_cluster_pair.first->setHealthChecker(checker_or_error.value());
     115           0 :     }
     116           0 :   }
     117             : 
     118         159 :   auto detector_or_error = Outlier::DetectorImplFactory::createForCluster(
     119         159 :       *new_cluster_pair.first, cluster, server_context.mainThreadDispatcher(),
     120         159 :       server_context.runtime(), context.outlierEventLogger(),
     121         159 :       server_context.api().randomGenerator());
     122         159 :   RETURN_IF_STATUS_NOT_OK(detector_or_error);
     123         159 :   new_cluster_pair.first->setOutlierDetector(detector_or_error.value());
     124             : 
     125         159 :   return status_or_cluster;
     126         159 : }
     127             : 
     128             : } // namespace Upstream
     129             : } // namespace Envoy

Generated by: LCOV version 1.15