void CdsJson::translateCluster()

in source/common/config/cds_json.cc [102:224]


void CdsJson::translateCluster(const Json::Object& json_cluster,
                               const absl::optional<envoy::api::v2::core::ConfigSource>& eds_config,
                               envoy::api::v2::Cluster& cluster,
                               const Stats::StatsOptions& stats_options) {
  json_cluster.validateSchema(Json::Schema::CLUSTER_SCHEMA);

  const std::string name = json_cluster.getString("name");
  Utility::checkObjNameLength("Invalid cluster name", name, stats_options);
  cluster.set_name(name);

  const std::string string_type = json_cluster.getString("type");
  auto set_dns_hosts = [&json_cluster, &cluster] {
    const auto hosts = json_cluster.getObjectArray("hosts");
    std::transform(hosts.cbegin(), hosts.cend(),
                   Protobuf::RepeatedPtrFieldBackInserter(cluster.mutable_hosts()),
                   [](const Json::ObjectSharedPtr& host) {
                     envoy::api::v2::core::Address address;
                     AddressJson::translateAddress(host->getString("url"), true, false, address);
                     return address;
                   });
  };
  if (string_type == "static") {
    cluster.set_type(envoy::api::v2::Cluster::STATIC);
    const auto hosts = json_cluster.getObjectArray("hosts");
    std::transform(hosts.cbegin(), hosts.cend(),
                   Protobuf::RepeatedPtrFieldBackInserter(cluster.mutable_hosts()),
                   [](const Json::ObjectSharedPtr& host) {
                     envoy::api::v2::core::Address address;
                     AddressJson::translateAddress(host->getString("url"), true, true, address);
                     return address;
                   });
  } else if (string_type == "strict_dns") {
    cluster.set_type(envoy::api::v2::Cluster::STRICT_DNS);
    set_dns_hosts();
  } else if (string_type == "logical_dns") {
    cluster.set_type(envoy::api::v2::Cluster::LOGICAL_DNS);
    set_dns_hosts();
  } else if (string_type == "original_dst") {
    if (json_cluster.hasObject("hosts")) {
      throw EnvoyException("original_dst clusters must have no hosts configured");
    }
    cluster.set_type(envoy::api::v2::Cluster::ORIGINAL_DST);
  } else {
    ASSERT(string_type == "sds");
    if (!eds_config) {
      throw EnvoyException("cannot create sds cluster with no sds config");
    }
    cluster.set_type(envoy::api::v2::Cluster::EDS);
    cluster.mutable_eds_cluster_config()->mutable_eds_config()->CopyFrom(eds_config.value());
    JSON_UTIL_SET_STRING(json_cluster, *cluster.mutable_eds_cluster_config(), service_name);
  }

  JSON_UTIL_SET_DURATION(json_cluster, cluster, cleanup_interval);
  JSON_UTIL_SET_DURATION(json_cluster, cluster, connect_timeout);
  JSON_UTIL_SET_INTEGER(json_cluster, cluster, per_connection_buffer_limit_bytes);

  const std::string lb_type = json_cluster.getString("lb_type");
  if (lb_type == "round_robin") {
    cluster.set_lb_policy(envoy::api::v2::Cluster::ROUND_ROBIN);
  } else if (lb_type == "least_request") {
    cluster.set_lb_policy(envoy::api::v2::Cluster::LEAST_REQUEST);
  } else if (lb_type == "random") {
    cluster.set_lb_policy(envoy::api::v2::Cluster::RANDOM);
  } else if (lb_type == "original_dst_lb") {
    cluster.set_lb_policy(envoy::api::v2::Cluster::ORIGINAL_DST_LB);
  } else {
    ASSERT(lb_type == "ring_hash");
    cluster.set_lb_policy(envoy::api::v2::Cluster::RING_HASH);
  }

  if (json_cluster.hasObject("ring_hash_lb_config")) {
    translateRingHashLbConfig(*json_cluster.getObject("ring_hash_lb_config"),
                              *cluster.mutable_ring_hash_lb_config());
  }

  if (json_cluster.hasObject("health_check")) {
    translateHealthCheck(*json_cluster.getObject("health_check"),
                         *cluster.mutable_health_checks()->Add());
  }

  JSON_UTIL_SET_INTEGER(json_cluster, cluster, max_requests_per_connection);
  if (json_cluster.hasObject("circuit_breakers")) {
    translateCircuitBreakers(*json_cluster.getObject("circuit_breakers"),
                             *cluster.mutable_circuit_breakers());
  }

  if (json_cluster.hasObject("ssl_context")) {
    TlsContextJson::translateUpstreamTlsContext(*json_cluster.getObject("ssl_context"),
                                                *cluster.mutable_tls_context());
  }

  if (json_cluster.getString("features", "") == "http2" ||
      json_cluster.hasObject("http2_settings")) {
    ProtocolJson::translateHttp2ProtocolOptions(*json_cluster.getObject("http2_settings", true),
                                                *cluster.mutable_http2_protocol_options());
  }

  JSON_UTIL_SET_DURATION(json_cluster, cluster, dns_refresh_rate);
  const std::string dns_lookup_family = json_cluster.getString("dns_lookup_family", "v4_only");
  if (dns_lookup_family == "auto") {
    cluster.set_dns_lookup_family(envoy::api::v2::Cluster::AUTO);
  } else if (dns_lookup_family == "v6_only") {
    cluster.set_dns_lookup_family(envoy::api::v2::Cluster::V6_ONLY);
  } else {
    ASSERT(dns_lookup_family == "v4_only");
    cluster.set_dns_lookup_family(envoy::api::v2::Cluster::V4_ONLY);
  }
  if (json_cluster.hasObject("dns_resolvers")) {
    const auto dns_resolvers = json_cluster.getStringArray("dns_resolvers");
    std::transform(dns_resolvers.cbegin(), dns_resolvers.cend(),
                   Protobuf::RepeatedPtrFieldBackInserter(cluster.mutable_dns_resolvers()),
                   [](const std::string& json_address) {
                     envoy::api::v2::core::Address address;
                     AddressJson::translateAddress(json_address, false, true, address);
                     return address;
                   });
  }

  if (json_cluster.hasObject("outlier_detection")) {
    translateOutlierDetection(*json_cluster.getObject("outlier_detection"),
                              *cluster.mutable_outlier_detection());
  }
}