|
|
|
@ -57,6 +57,7 @@ |
|
|
|
|
#include "src/core/lib/gpr/string.h" |
|
|
|
|
#include "src/core/lib/gprpp/env.h" |
|
|
|
|
#include "src/core/lib/gprpp/host_port.h" |
|
|
|
|
#include "src/core/lib/gprpp/match.h" |
|
|
|
|
#include "src/core/lib/gprpp/ref_counted_ptr.h" |
|
|
|
|
#include "src/core/lib/gprpp/time.h" |
|
|
|
|
#include "src/core/lib/gprpp/validation_errors.h" |
|
|
|
@ -89,33 +90,35 @@ bool XdsHostOverrideEnabled() { |
|
|
|
|
|
|
|
|
|
std::string XdsClusterResource::ToString() const { |
|
|
|
|
std::vector<std::string> contents; |
|
|
|
|
switch (cluster_type) { |
|
|
|
|
case EDS: |
|
|
|
|
contents.push_back("cluster_type=EDS"); |
|
|
|
|
if (!eds_service_name.empty()) { |
|
|
|
|
contents.push_back(absl::StrCat("eds_service_name=", eds_service_name)); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case LOGICAL_DNS: |
|
|
|
|
contents.push_back("cluster_type=LOGICAL_DNS"); |
|
|
|
|
contents.push_back(absl::StrCat("dns_hostname=", dns_hostname)); |
|
|
|
|
break; |
|
|
|
|
case AGGREGATE: |
|
|
|
|
contents.push_back("cluster_type=AGGREGATE"); |
|
|
|
|
contents.push_back( |
|
|
|
|
absl::StrCat("prioritized_cluster_names=[", |
|
|
|
|
absl::StrJoin(prioritized_cluster_names, ", "), "]")); |
|
|
|
|
Match( |
|
|
|
|
type, |
|
|
|
|
[&](const Eds& eds) { |
|
|
|
|
contents.push_back("type=EDS"); |
|
|
|
|
if (!eds.eds_service_name.empty()) { |
|
|
|
|
contents.push_back( |
|
|
|
|
absl::StrCat("eds_service_name=", eds.eds_service_name)); |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
[&](const LogicalDns& logical_dns) { |
|
|
|
|
contents.push_back("type=LOGICAL_DNS"); |
|
|
|
|
contents.push_back(absl::StrCat("dns_hostname=", logical_dns.hostname)); |
|
|
|
|
}, |
|
|
|
|
[&](const Aggregate& aggregate) { |
|
|
|
|
contents.push_back("type=AGGREGATE"); |
|
|
|
|
contents.push_back(absl::StrCat( |
|
|
|
|
"prioritized_cluster_names=[", |
|
|
|
|
absl::StrJoin(aggregate.prioritized_cluster_names, ", "), "]")); |
|
|
|
|
}); |
|
|
|
|
contents.push_back( |
|
|
|
|
absl::StrCat("lb_policy_config=", Json{lb_policy_config}.Dump())); |
|
|
|
|
if (lrs_load_reporting_server.has_value()) { |
|
|
|
|
contents.push_back(absl::StrCat("lrs_load_reporting_server_name=", |
|
|
|
|
lrs_load_reporting_server->server_uri())); |
|
|
|
|
} |
|
|
|
|
if (!common_tls_context.Empty()) { |
|
|
|
|
contents.push_back( |
|
|
|
|
absl::StrCat("common_tls_context=", common_tls_context.ToString())); |
|
|
|
|
} |
|
|
|
|
if (lrs_load_reporting_server.has_value()) { |
|
|
|
|
contents.push_back(absl::StrCat("lrs_load_reporting_server_name=", |
|
|
|
|
lrs_load_reporting_server->server_uri())); |
|
|
|
|
} |
|
|
|
|
contents.push_back( |
|
|
|
|
absl::StrCat("lb_policy_config=", Json{lb_policy_config}.Dump())); |
|
|
|
|
contents.push_back( |
|
|
|
|
absl::StrCat("max_concurrent_requests=", max_concurrent_requests)); |
|
|
|
|
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}"); |
|
|
|
@ -172,8 +175,9 @@ CommonTlsContext UpstreamTlsContextParse( |
|
|
|
|
return common_tls_context; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EdsConfigParse(const envoy_config_cluster_v3_Cluster* cluster, |
|
|
|
|
XdsClusterResource* cds_update, ValidationErrors* errors) { |
|
|
|
|
XdsClusterResource::Eds EdsConfigParse( |
|
|
|
|
const envoy_config_cluster_v3_Cluster* cluster, ValidationErrors* errors) { |
|
|
|
|
XdsClusterResource::Eds eds; |
|
|
|
|
ValidationErrors::ScopedField field(errors, ".eds_cluster_config"); |
|
|
|
|
const envoy_config_cluster_v3_Cluster_EdsClusterConfig* eds_cluster_config = |
|
|
|
|
envoy_config_cluster_v3_Cluster_eds_cluster_config(cluster); |
|
|
|
@ -196,20 +200,22 @@ void EdsConfigParse(const envoy_config_cluster_v3_Cluster* cluster, |
|
|
|
|
envoy_config_cluster_v3_Cluster_EdsClusterConfig_service_name( |
|
|
|
|
eds_cluster_config); |
|
|
|
|
if (service_name.size != 0) { |
|
|
|
|
cds_update->eds_service_name = UpbStringToStdString(service_name); |
|
|
|
|
eds.eds_service_name = UpbStringToStdString(service_name); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return eds; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void LogicalDnsParse(const envoy_config_cluster_v3_Cluster* cluster, |
|
|
|
|
XdsClusterResource* cds_update, ValidationErrors* errors) { |
|
|
|
|
XdsClusterResource::LogicalDns LogicalDnsParse( |
|
|
|
|
const envoy_config_cluster_v3_Cluster* cluster, ValidationErrors* errors) { |
|
|
|
|
XdsClusterResource::LogicalDns logical_dns; |
|
|
|
|
ValidationErrors::ScopedField field(errors, ".load_assignment"); |
|
|
|
|
const auto* load_assignment = |
|
|
|
|
envoy_config_cluster_v3_Cluster_load_assignment(cluster); |
|
|
|
|
if (load_assignment == nullptr) { |
|
|
|
|
errors->AddError("field not present for LOGICAL_DNS cluster"); |
|
|
|
|
return; |
|
|
|
|
return logical_dns; |
|
|
|
|
} |
|
|
|
|
ValidationErrors::ScopedField field2(errors, ".endpoints"); |
|
|
|
|
size_t num_localities; |
|
|
|
@ -220,7 +226,7 @@ void LogicalDnsParse(const envoy_config_cluster_v3_Cluster* cluster, |
|
|
|
|
errors->AddError(absl::StrCat( |
|
|
|
|
"must contain exactly one locality for LOGICAL_DNS cluster, found ", |
|
|
|
|
num_localities)); |
|
|
|
|
return; |
|
|
|
|
return logical_dns; |
|
|
|
|
} |
|
|
|
|
ValidationErrors::ScopedField field3(errors, "[0].lb_endpoints"); |
|
|
|
|
size_t num_endpoints; |
|
|
|
@ -231,27 +237,27 @@ void LogicalDnsParse(const envoy_config_cluster_v3_Cluster* cluster, |
|
|
|
|
errors->AddError(absl::StrCat( |
|
|
|
|
"must contain exactly one endpoint for LOGICAL_DNS cluster, found ", |
|
|
|
|
num_endpoints)); |
|
|
|
|
return; |
|
|
|
|
return logical_dns; |
|
|
|
|
} |
|
|
|
|
ValidationErrors::ScopedField field4(errors, "[0].endpoint"); |
|
|
|
|
const auto* endpoint = |
|
|
|
|
envoy_config_endpoint_v3_LbEndpoint_endpoint(endpoints[0]); |
|
|
|
|
if (endpoint == nullptr) { |
|
|
|
|
errors->AddError("field not present"); |
|
|
|
|
return; |
|
|
|
|
return logical_dns; |
|
|
|
|
} |
|
|
|
|
ValidationErrors::ScopedField field5(errors, ".address"); |
|
|
|
|
const auto* address = envoy_config_endpoint_v3_Endpoint_address(endpoint); |
|
|
|
|
if (address == nullptr) { |
|
|
|
|
errors->AddError("field not present"); |
|
|
|
|
return; |
|
|
|
|
return logical_dns; |
|
|
|
|
} |
|
|
|
|
ValidationErrors::ScopedField field6(errors, ".socket_address"); |
|
|
|
|
const auto* socket_address = |
|
|
|
|
envoy_config_core_v3_Address_socket_address(address); |
|
|
|
|
if (socket_address == nullptr) { |
|
|
|
|
errors->AddError("field not present"); |
|
|
|
|
return; |
|
|
|
|
return logical_dns; |
|
|
|
|
} |
|
|
|
|
if (envoy_config_core_v3_SocketAddress_resolver_name(socket_address).size != |
|
|
|
|
0) { |
|
|
|
@ -269,30 +275,32 @@ void LogicalDnsParse(const envoy_config_cluster_v3_Cluster* cluster, |
|
|
|
|
ValidationErrors::ScopedField field(errors, ".port_value"); |
|
|
|
|
errors->AddError("field not present"); |
|
|
|
|
} |
|
|
|
|
cds_update->dns_hostname = JoinHostPort( |
|
|
|
|
logical_dns.hostname = JoinHostPort( |
|
|
|
|
address_str, |
|
|
|
|
envoy_config_core_v3_SocketAddress_port_value(socket_address)); |
|
|
|
|
return logical_dns; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AggregateClusterParse(const XdsResourceType::DecodeContext& context, |
|
|
|
|
absl::string_view serialized_config, |
|
|
|
|
XdsClusterResource* cds_update, |
|
|
|
|
ValidationErrors* errors) { |
|
|
|
|
XdsClusterResource::Aggregate AggregateClusterParse( |
|
|
|
|
const XdsResourceType::DecodeContext& context, |
|
|
|
|
absl::string_view serialized_config, ValidationErrors* errors) { |
|
|
|
|
XdsClusterResource::Aggregate aggregate; |
|
|
|
|
const auto* aggregate_cluster_config = |
|
|
|
|
envoy_extensions_clusters_aggregate_v3_ClusterConfig_parse( |
|
|
|
|
serialized_config.data(), serialized_config.size(), context.arena); |
|
|
|
|
if (aggregate_cluster_config == nullptr) { |
|
|
|
|
errors->AddError("can't parse aggregate cluster config"); |
|
|
|
|
return; |
|
|
|
|
return aggregate; |
|
|
|
|
} |
|
|
|
|
size_t size; |
|
|
|
|
const upb_StringView* clusters = |
|
|
|
|
envoy_extensions_clusters_aggregate_v3_ClusterConfig_clusters( |
|
|
|
|
aggregate_cluster_config, &size); |
|
|
|
|
for (size_t i = 0; i < size; ++i) { |
|
|
|
|
cds_update->prioritized_cluster_names.emplace_back( |
|
|
|
|
aggregate.prioritized_cluster_names.emplace_back( |
|
|
|
|
UpbStringToStdString(clusters[i])); |
|
|
|
|
} |
|
|
|
|
return aggregate; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ParseLbPolicyConfig(const XdsResourceType::DecodeContext& context, |
|
|
|
@ -402,12 +410,10 @@ absl::StatusOr<XdsClusterResource> CdsResourceParse( |
|
|
|
|
// Check the cluster discovery type.
|
|
|
|
|
if (envoy_config_cluster_v3_Cluster_type(cluster) == |
|
|
|
|
envoy_config_cluster_v3_Cluster_EDS) { |
|
|
|
|
cds_update.cluster_type = XdsClusterResource::ClusterType::EDS; |
|
|
|
|
EdsConfigParse(cluster, &cds_update, &errors); |
|
|
|
|
cds_update.type = EdsConfigParse(cluster, &errors); |
|
|
|
|
} else if (envoy_config_cluster_v3_Cluster_type(cluster) == |
|
|
|
|
envoy_config_cluster_v3_Cluster_LOGICAL_DNS) { |
|
|
|
|
cds_update.cluster_type = XdsClusterResource::ClusterType::LOGICAL_DNS; |
|
|
|
|
LogicalDnsParse(cluster, &cds_update, &errors); |
|
|
|
|
cds_update.type = LogicalDnsParse(cluster, &errors); |
|
|
|
|
} else if (envoy_config_cluster_v3_Cluster_has_cluster_type(cluster)) { |
|
|
|
|
ValidationErrors::ScopedField field(&errors, ".cluster_type"); |
|
|
|
|
const auto* custom_cluster_type = |
|
|
|
@ -428,14 +434,14 @@ absl::StatusOr<XdsClusterResource> CdsResourceParse( |
|
|
|
|
errors.AddError( |
|
|
|
|
absl::StrCat("unknown cluster_type extension: ", type_url)); |
|
|
|
|
} else { |
|
|
|
|
cds_update.cluster_type = XdsClusterResource::ClusterType::AGGREGATE; |
|
|
|
|
// Retrieve aggregate clusters.
|
|
|
|
|
ValidationErrors::ScopedField field( |
|
|
|
|
&errors, |
|
|
|
|
".value[envoy.extensions.clusters.aggregate.v3.ClusterConfig]"); |
|
|
|
|
absl::string_view serialized_config = |
|
|
|
|
UpbStringToAbsl(google_protobuf_Any_value(typed_config)); |
|
|
|
|
AggregateClusterParse(context, serialized_config, &cds_update, &errors); |
|
|
|
|
cds_update.type = |
|
|
|
|
AggregateClusterParse(context, serialized_config, &errors); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|