|
|
@ -115,11 +115,58 @@ bool XdsAggregateAndLogicalDnsClusterEnabled() { |
|
|
|
return parse_succeeded && parsed_value; |
|
|
|
return parse_succeeded && parsed_value; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO(yashykt): Remove once RBAC is no longer experimental
|
|
|
|
|
|
|
|
bool XdsRbacEnabled() { |
|
|
|
|
|
|
|
char* value = gpr_getenv("GRPC_XDS_EXPERIMENTAL_RBAC"); |
|
|
|
|
|
|
|
bool parsed_value; |
|
|
|
|
|
|
|
bool parse_succeeded = gpr_parse_bool_value(value, &parsed_value); |
|
|
|
|
|
|
|
gpr_free(value); |
|
|
|
|
|
|
|
return parse_succeeded && parsed_value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// XdsApi::RetryPolicy
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::RetryPolicy::RetryBackOff::ToString() const { |
|
|
|
|
|
|
|
std::vector<std::string> contents; |
|
|
|
|
|
|
|
contents.push_back( |
|
|
|
|
|
|
|
absl::StrCat("RetryBackOff Base: ", base_interval.ToString())); |
|
|
|
|
|
|
|
contents.push_back( |
|
|
|
|
|
|
|
absl::StrCat("RetryBackOff max: ", max_interval.ToString())); |
|
|
|
|
|
|
|
return absl::StrJoin(contents, ","); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::RetryPolicy::ToString() const { |
|
|
|
|
|
|
|
std::vector<std::string> contents; |
|
|
|
|
|
|
|
contents.push_back(absl::StrFormat("num_retries=%d", num_retries)); |
|
|
|
|
|
|
|
contents.push_back(retry_back_off.ToString()); |
|
|
|
|
|
|
|
return absl::StrCat("{", absl::StrJoin(contents, ","), "}"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// XdsApi::Route::Matchers
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::Route::Matchers::ToString() const { |
|
|
|
|
|
|
|
std::vector<std::string> contents; |
|
|
|
|
|
|
|
contents.push_back( |
|
|
|
|
|
|
|
absl::StrFormat("PathMatcher{%s}", path_matcher.ToString())); |
|
|
|
|
|
|
|
for (const HeaderMatcher& header_matcher : header_matchers) { |
|
|
|
|
|
|
|
contents.push_back(header_matcher.ToString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (fraction_per_million.has_value()) { |
|
|
|
|
|
|
|
contents.push_back(absl::StrFormat("Fraction Per Million %d", |
|
|
|
|
|
|
|
fraction_per_million.value())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return absl::StrJoin(contents, "\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// XdsApi::Route::HashPolicy
|
|
|
|
// XdsApi::Route::RouteAction::HashPolicy
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
XdsApi::Route::HashPolicy::HashPolicy(const HashPolicy& other) |
|
|
|
XdsApi::Route::RouteAction::HashPolicy::HashPolicy(const HashPolicy& other) |
|
|
|
: type(other.type), |
|
|
|
: type(other.type), |
|
|
|
header_name(other.header_name), |
|
|
|
header_name(other.header_name), |
|
|
|
regex_substitution(other.regex_substitution) { |
|
|
|
regex_substitution(other.regex_substitution) { |
|
|
@ -129,8 +176,8 @@ XdsApi::Route::HashPolicy::HashPolicy(const HashPolicy& other) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
XdsApi::Route::HashPolicy& XdsApi::Route::HashPolicy::operator=( |
|
|
|
XdsApi::Route::RouteAction::HashPolicy& |
|
|
|
const HashPolicy& other) { |
|
|
|
XdsApi::Route::RouteAction::HashPolicy::operator=(const HashPolicy& other) { |
|
|
|
type = other.type; |
|
|
|
type = other.type; |
|
|
|
header_name = other.header_name; |
|
|
|
header_name = other.header_name; |
|
|
|
if (other.regex != nullptr) { |
|
|
|
if (other.regex != nullptr) { |
|
|
@ -141,14 +188,14 @@ XdsApi::Route::HashPolicy& XdsApi::Route::HashPolicy::operator=( |
|
|
|
return *this; |
|
|
|
return *this; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
XdsApi::Route::HashPolicy::HashPolicy(HashPolicy&& other) noexcept |
|
|
|
XdsApi::Route::RouteAction::HashPolicy::HashPolicy(HashPolicy&& other) noexcept |
|
|
|
: type(other.type), |
|
|
|
: type(other.type), |
|
|
|
header_name(std::move(other.header_name)), |
|
|
|
header_name(std::move(other.header_name)), |
|
|
|
regex(std::move(other.regex)), |
|
|
|
regex(std::move(other.regex)), |
|
|
|
regex_substitution(std::move(other.regex_substitution)) {} |
|
|
|
regex_substitution(std::move(other.regex_substitution)) {} |
|
|
|
|
|
|
|
|
|
|
|
XdsApi::Route::HashPolicy& XdsApi::Route::HashPolicy::operator=( |
|
|
|
XdsApi::Route::RouteAction::HashPolicy& |
|
|
|
HashPolicy&& other) noexcept { |
|
|
|
XdsApi::Route::RouteAction::HashPolicy::operator=(HashPolicy&& other) noexcept { |
|
|
|
type = other.type; |
|
|
|
type = other.type; |
|
|
|
header_name = std::move(other.header_name); |
|
|
|
header_name = std::move(other.header_name); |
|
|
|
regex = std::move(other.regex); |
|
|
|
regex = std::move(other.regex); |
|
|
@ -156,7 +203,7 @@ XdsApi::Route::HashPolicy& XdsApi::Route::HashPolicy::operator=( |
|
|
|
return *this; |
|
|
|
return *this; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool XdsApi::Route::HashPolicy::HashPolicy::operator==( |
|
|
|
bool XdsApi::Route::RouteAction::HashPolicy::HashPolicy::operator==( |
|
|
|
const HashPolicy& other) const { |
|
|
|
const HashPolicy& other) const { |
|
|
|
if (type != other.type) return false; |
|
|
|
if (type != other.type) return false; |
|
|
|
if (type == Type::HEADER) { |
|
|
|
if (type == Type::HEADER) { |
|
|
@ -172,7 +219,7 @@ bool XdsApi::Route::HashPolicy::HashPolicy::operator==( |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::Route::HashPolicy::ToString() const { |
|
|
|
std::string XdsApi::Route::RouteAction::HashPolicy::ToString() const { |
|
|
|
std::vector<std::string> contents; |
|
|
|
std::vector<std::string> contents; |
|
|
|
switch (type) { |
|
|
|
switch (type) { |
|
|
|
case Type::HEADER: |
|
|
|
case Type::HEADER: |
|
|
@ -193,43 +240,10 @@ std::string XdsApi::Route::HashPolicy::ToString() const { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// XdsApi::Route::RetryPolicy
|
|
|
|
// XdsApi::Route::RouteAction::ClusterWeight
|
|
|
|
//
|
|
|
|
|
|
|
|
std::string XdsApi::Route::RetryPolicy::RetryBackOff::ToString() const { |
|
|
|
|
|
|
|
std::vector<std::string> contents; |
|
|
|
|
|
|
|
contents.push_back( |
|
|
|
|
|
|
|
absl::StrCat("RetryBackOff Base: ", base_interval.ToString())); |
|
|
|
|
|
|
|
contents.push_back( |
|
|
|
|
|
|
|
absl::StrCat("RetryBackOff max: ", max_interval.ToString())); |
|
|
|
|
|
|
|
return absl::StrJoin(contents, ","); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::Route::RetryPolicy::ToString() const { |
|
|
|
|
|
|
|
std::vector<std::string> contents; |
|
|
|
|
|
|
|
contents.push_back(absl::StrFormat("num_retries=%d", num_retries)); |
|
|
|
|
|
|
|
contents.push_back(retry_back_off.ToString()); |
|
|
|
|
|
|
|
return absl::StrJoin(contents, ","); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// XdsApi::Route
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::Route::Matchers::ToString() const { |
|
|
|
std::string XdsApi::Route::RouteAction::ClusterWeight::ToString() const { |
|
|
|
std::vector<std::string> contents; |
|
|
|
|
|
|
|
contents.push_back( |
|
|
|
|
|
|
|
absl::StrFormat("PathMatcher{%s}", path_matcher.ToString())); |
|
|
|
|
|
|
|
for (const HeaderMatcher& header_matcher : header_matchers) { |
|
|
|
|
|
|
|
contents.push_back(header_matcher.ToString()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (fraction_per_million.has_value()) { |
|
|
|
|
|
|
|
contents.push_back(absl::StrFormat("Fraction Per Million %d", |
|
|
|
|
|
|
|
fraction_per_million.value())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return absl::StrJoin(contents, "\n"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::Route::ClusterWeight::ToString() const { |
|
|
|
|
|
|
|
std::vector<std::string> contents; |
|
|
|
std::vector<std::string> contents; |
|
|
|
contents.push_back(absl::StrCat("cluster=", name)); |
|
|
|
contents.push_back(absl::StrCat("cluster=", name)); |
|
|
|
contents.push_back(absl::StrCat("weight=", weight)); |
|
|
|
contents.push_back(absl::StrCat("weight=", weight)); |
|
|
@ -246,15 +260,17 @@ std::string XdsApi::Route::ClusterWeight::ToString() const { |
|
|
|
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}"); |
|
|
|
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::Route::ToString() const { |
|
|
|
//
|
|
|
|
|
|
|
|
// XdsApi::Route::RouteAction
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::Route::RouteAction::ToString() const { |
|
|
|
std::vector<std::string> contents; |
|
|
|
std::vector<std::string> contents; |
|
|
|
contents.push_back(matchers.ToString()); |
|
|
|
|
|
|
|
for (const HashPolicy& hash_policy : hash_policies) { |
|
|
|
for (const HashPolicy& hash_policy : hash_policies) { |
|
|
|
contents.push_back(absl::StrCat("hash_policy=", hash_policy.ToString())); |
|
|
|
contents.push_back(absl::StrCat("hash_policy=", hash_policy.ToString())); |
|
|
|
} |
|
|
|
} |
|
|
|
if (retry_policy.has_value()) { |
|
|
|
if (retry_policy.has_value()) { |
|
|
|
contents.push_back( |
|
|
|
contents.push_back(absl::StrCat("retry_policy=", retry_policy->ToString())); |
|
|
|
absl::StrCat("retry_policy={", retry_policy->ToString(), "}")); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
if (!cluster_name.empty()) { |
|
|
|
if (!cluster_name.empty()) { |
|
|
|
contents.push_back(absl::StrFormat("Cluster name: %s", cluster_name)); |
|
|
|
contents.push_back(absl::StrFormat("Cluster name: %s", cluster_name)); |
|
|
@ -265,6 +281,25 @@ std::string XdsApi::Route::ToString() const { |
|
|
|
if (max_stream_duration.has_value()) { |
|
|
|
if (max_stream_duration.has_value()) { |
|
|
|
contents.push_back(max_stream_duration->ToString()); |
|
|
|
contents.push_back(max_stream_duration->ToString()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// XdsApi::Route
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string XdsApi::Route::ToString() const { |
|
|
|
|
|
|
|
std::vector<std::string> contents; |
|
|
|
|
|
|
|
contents.push_back(matchers.ToString()); |
|
|
|
|
|
|
|
auto* route_action = absl::get_if<XdsApi::Route::RouteAction>(&action); |
|
|
|
|
|
|
|
if (route_action != nullptr) { |
|
|
|
|
|
|
|
contents.push_back(absl::StrCat("route=", route_action->ToString())); |
|
|
|
|
|
|
|
} else if (absl::holds_alternative<XdsApi::Route::NonForwardingAction>( |
|
|
|
|
|
|
|
action)) { |
|
|
|
|
|
|
|
contents.push_back("non_forwarding_action={}"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
contents.push_back("unknown_action={}"); |
|
|
|
|
|
|
|
} |
|
|
|
if (!typed_per_filter_config.empty()) { |
|
|
|
if (!typed_per_filter_config.empty()) { |
|
|
|
contents.push_back("typed_per_filter_config={"); |
|
|
|
contents.push_back("typed_per_filter_config={"); |
|
|
|
for (const auto& p : typed_per_filter_config) { |
|
|
|
for (const auto& p : typed_per_filter_config) { |
|
|
@ -1528,9 +1563,9 @@ XdsApi::Duration DurationParse(const google_protobuf_Duration* proto_duration) { |
|
|
|
grpc_error_handle RetryPolicyParse( |
|
|
|
grpc_error_handle RetryPolicyParse( |
|
|
|
const EncodingContext& context, |
|
|
|
const EncodingContext& context, |
|
|
|
const envoy_config_route_v3_RetryPolicy* retry_policy, |
|
|
|
const envoy_config_route_v3_RetryPolicy* retry_policy, |
|
|
|
absl::optional<XdsApi::Route::RetryPolicy>* retry) { |
|
|
|
absl::optional<XdsApi::RetryPolicy>* retry) { |
|
|
|
std::vector<grpc_error_handle> errors; |
|
|
|
std::vector<grpc_error_handle> errors; |
|
|
|
XdsApi::Route::RetryPolicy retry_to_return; |
|
|
|
XdsApi::RetryPolicy retry_to_return; |
|
|
|
auto retry_on = UpbStringToStdString( |
|
|
|
auto retry_on = UpbStringToStdString( |
|
|
|
envoy_config_route_v3_RetryPolicy_retry_on(retry_policy)); |
|
|
|
envoy_config_route_v3_RetryPolicy_retry_on(retry_policy)); |
|
|
|
std::vector<absl::string_view> codes = absl::StrSplit(retry_on, ','); |
|
|
|
std::vector<absl::string_view> codes = absl::StrSplit(retry_on, ','); |
|
|
@ -1610,11 +1645,8 @@ grpc_error_handle RetryPolicyParse( |
|
|
|
|
|
|
|
|
|
|
|
grpc_error_handle RouteActionParse(const EncodingContext& context, |
|
|
|
grpc_error_handle RouteActionParse(const EncodingContext& context, |
|
|
|
const envoy_config_route_v3_Route* route_msg, |
|
|
|
const envoy_config_route_v3_Route* route_msg, |
|
|
|
XdsApi::Route* route, bool* ignore_route) { |
|
|
|
XdsApi::Route::RouteAction* route, |
|
|
|
if (!envoy_config_route_v3_Route_has_route(route_msg)) { |
|
|
|
bool* ignore_route) { |
|
|
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
|
|
|
"No RouteAction found in route."); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
const envoy_config_route_v3_RouteAction* route_action = |
|
|
|
const envoy_config_route_v3_RouteAction* route_action = |
|
|
|
envoy_config_route_v3_Route_route(route_msg); |
|
|
|
envoy_config_route_v3_Route_route(route_msg); |
|
|
|
// Get the cluster or weighted_clusters in the RouteAction.
|
|
|
|
// Get the cluster or weighted_clusters in the RouteAction.
|
|
|
@ -1643,7 +1675,7 @@ grpc_error_handle RouteActionParse(const EncodingContext& context, |
|
|
|
for (size_t j = 0; j < clusters_size; ++j) { |
|
|
|
for (size_t j = 0; j < clusters_size; ++j) { |
|
|
|
const envoy_config_route_v3_WeightedCluster_ClusterWeight* |
|
|
|
const envoy_config_route_v3_WeightedCluster_ClusterWeight* |
|
|
|
cluster_weight = clusters[j]; |
|
|
|
cluster_weight = clusters[j]; |
|
|
|
XdsApi::Route::ClusterWeight cluster; |
|
|
|
XdsApi::Route::RouteAction::ClusterWeight cluster; |
|
|
|
cluster.name = UpbStringToStdString( |
|
|
|
cluster.name = UpbStringToStdString( |
|
|
|
envoy_config_route_v3_WeightedCluster_ClusterWeight_name( |
|
|
|
envoy_config_route_v3_WeightedCluster_ClusterWeight_name( |
|
|
|
cluster_weight)); |
|
|
|
cluster_weight)); |
|
|
@ -1712,7 +1744,7 @@ grpc_error_handle RouteActionParse(const EncodingContext& context, |
|
|
|
for (size_t i = 0; i < size; ++i) { |
|
|
|
for (size_t i = 0; i < size; ++i) { |
|
|
|
const envoy_config_route_v3_RouteAction_HashPolicy* hash_policy = |
|
|
|
const envoy_config_route_v3_RouteAction_HashPolicy* hash_policy = |
|
|
|
hash_policies[i]; |
|
|
|
hash_policies[i]; |
|
|
|
XdsApi::Route::HashPolicy policy; |
|
|
|
XdsApi::Route::RouteAction::HashPolicy policy; |
|
|
|
policy.terminal = |
|
|
|
policy.terminal = |
|
|
|
envoy_config_route_v3_RouteAction_HashPolicy_terminal(hash_policy); |
|
|
|
envoy_config_route_v3_RouteAction_HashPolicy_terminal(hash_policy); |
|
|
|
const envoy_config_route_v3_RouteAction_HashPolicy_Header* header; |
|
|
|
const envoy_config_route_v3_RouteAction_HashPolicy_Header* header; |
|
|
@ -1720,7 +1752,7 @@ grpc_error_handle RouteActionParse(const EncodingContext& context, |
|
|
|
filter_state; |
|
|
|
filter_state; |
|
|
|
if ((header = envoy_config_route_v3_RouteAction_HashPolicy_header( |
|
|
|
if ((header = envoy_config_route_v3_RouteAction_HashPolicy_header( |
|
|
|
hash_policy)) != nullptr) { |
|
|
|
hash_policy)) != nullptr) { |
|
|
|
policy.type = XdsApi::Route::HashPolicy::Type::HEADER; |
|
|
|
policy.type = XdsApi::Route::RouteAction::HashPolicy::Type::HEADER; |
|
|
|
policy.header_name = UpbStringToStdString( |
|
|
|
policy.header_name = UpbStringToStdString( |
|
|
|
envoy_config_route_v3_RouteAction_HashPolicy_Header_header_name( |
|
|
|
envoy_config_route_v3_RouteAction_HashPolicy_Header_header_name( |
|
|
|
header)); |
|
|
|
header)); |
|
|
@ -1764,7 +1796,7 @@ grpc_error_handle RouteActionParse(const EncodingContext& context, |
|
|
|
envoy_config_route_v3_RouteAction_HashPolicy_FilterState_key( |
|
|
|
envoy_config_route_v3_RouteAction_HashPolicy_FilterState_key( |
|
|
|
filter_state)); |
|
|
|
filter_state)); |
|
|
|
if (key == "io.grpc.channel_id") { |
|
|
|
if (key == "io.grpc.channel_id") { |
|
|
|
policy.type = XdsApi::Route::HashPolicy::Type::CHANNEL_ID; |
|
|
|
policy.type = XdsApi::Route::RouteAction::HashPolicy::Type::CHANNEL_ID; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
"RouteAction HashPolicy contains policy specifier " |
|
|
|
"RouteAction HashPolicy contains policy specifier " |
|
|
@ -1783,7 +1815,7 @@ grpc_error_handle RouteActionParse(const EncodingContext& context, |
|
|
|
const envoy_config_route_v3_RetryPolicy* retry_policy = |
|
|
|
const envoy_config_route_v3_RetryPolicy* retry_policy = |
|
|
|
envoy_config_route_v3_RouteAction_retry_policy(route_action); |
|
|
|
envoy_config_route_v3_RouteAction_retry_policy(route_action); |
|
|
|
if (retry_policy != nullptr) { |
|
|
|
if (retry_policy != nullptr) { |
|
|
|
absl::optional<XdsApi::Route::RetryPolicy> retry; |
|
|
|
absl::optional<XdsApi::RetryPolicy> retry; |
|
|
|
grpc_error_handle error = RetryPolicyParse(context, retry_policy, &retry); |
|
|
|
grpc_error_handle error = RetryPolicyParse(context, retry_policy, &retry); |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
route->retry_policy = retry; |
|
|
|
route->retry_policy = retry; |
|
|
@ -1833,7 +1865,7 @@ grpc_error_handle RouteConfigParse( |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
} |
|
|
|
} |
|
|
|
// Parse retry policy.
|
|
|
|
// Parse retry policy.
|
|
|
|
absl::optional<XdsApi::Route::RetryPolicy> virtual_host_retry_policy; |
|
|
|
absl::optional<XdsApi::RetryPolicy> virtual_host_retry_policy; |
|
|
|
const envoy_config_route_v3_RetryPolicy* retry_policy = |
|
|
|
const envoy_config_route_v3_RetryPolicy* retry_policy = |
|
|
|
envoy_config_route_v3_VirtualHost_retry_policy(virtual_hosts[i]); |
|
|
|
envoy_config_route_v3_VirtualHost_retry_policy(virtual_hosts[i]); |
|
|
|
if (retry_policy != nullptr) { |
|
|
|
if (retry_policy != nullptr) { |
|
|
@ -1872,11 +1904,21 @@ grpc_error_handle RouteConfigParse( |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
error = RouteRuntimeFractionParse(match, &route); |
|
|
|
error = RouteRuntimeFractionParse(match, &route); |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
error = RouteActionParse(context, routes[j], &route, &ignore_route); |
|
|
|
if (envoy_config_route_v3_Route_has_route(routes[j])) { |
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
route.action.emplace<XdsApi::Route::RouteAction>(); |
|
|
|
if (ignore_route) continue; |
|
|
|
auto& route_action = |
|
|
|
if (route.retry_policy == absl::nullopt && retry_policy != nullptr) { |
|
|
|
absl::get<XdsApi::Route::RouteAction>(route.action); |
|
|
|
route.retry_policy = virtual_host_retry_policy; |
|
|
|
error = |
|
|
|
|
|
|
|
RouteActionParse(context, routes[j], &route_action, &ignore_route); |
|
|
|
|
|
|
|
if (error != GRPC_ERROR_NONE) return error; |
|
|
|
|
|
|
|
if (ignore_route) continue; |
|
|
|
|
|
|
|
if (route_action.retry_policy == absl::nullopt && |
|
|
|
|
|
|
|
retry_policy != nullptr) { |
|
|
|
|
|
|
|
route_action.retry_policy = virtual_host_retry_policy; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (envoy_config_route_v3_Route_has_non_forwarding_action( |
|
|
|
|
|
|
|
routes[j])) { |
|
|
|
|
|
|
|
route.action.emplace<XdsApi::Route::NonForwardingAction>(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (context.use_v3) { |
|
|
|
if (context.use_v3) { |
|
|
|
grpc_error_handle error = ParseTypedPerFilterConfig< |
|
|
|
grpc_error_handle error = ParseTypedPerFilterConfig< |
|
|
@ -2233,32 +2275,47 @@ grpc_error_handle HttpConnectionManagerParse( |
|
|
|
absl::StrFormat("Filter %s is not supported on %s", filter_type, |
|
|
|
absl::StrFormat("Filter %s is not supported on %s", filter_type, |
|
|
|
is_client ? "clients" : "servers")); |
|
|
|
is_client ? "clients" : "servers")); |
|
|
|
} |
|
|
|
} |
|
|
|
if (i < num_filters - 1) { |
|
|
|
absl::StatusOr<XdsHttpFilterImpl::FilterConfig> filter_config = |
|
|
|
|
|
|
|
filter_impl->GenerateFilterConfig(google_protobuf_Any_value(any), |
|
|
|
|
|
|
|
context.arena); |
|
|
|
|
|
|
|
if (!filter_config.ok()) { |
|
|
|
|
|
|
|
return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat( |
|
|
|
|
|
|
|
"filter config for type ", filter_type, |
|
|
|
|
|
|
|
" failed to parse: ", filter_config.status().ToString())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
http_connection_manager->http_filters.emplace_back( |
|
|
|
|
|
|
|
XdsApi::LdsUpdate::HttpConnectionManager::HttpFilter{ |
|
|
|
|
|
|
|
std::string(name), std::move(*filter_config)}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (http_connection_manager->http_filters.empty()) { |
|
|
|
|
|
|
|
return GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
|
|
|
|
|
|
|
"Expected at least one HTTP filter"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Make sure that the last filter is terminal and non-last filters are
|
|
|
|
|
|
|
|
// non-terminal. Note that this check is being performed in a separate loop
|
|
|
|
|
|
|
|
// to take care of the case where there are two terminal filters in the list
|
|
|
|
|
|
|
|
// out of which only one gets added in the final list.
|
|
|
|
|
|
|
|
for (const auto& http_filter : http_connection_manager->http_filters) { |
|
|
|
|
|
|
|
const XdsHttpFilterImpl* filter_impl = |
|
|
|
|
|
|
|
XdsHttpFilterRegistry::GetFilterForType( |
|
|
|
|
|
|
|
http_filter.config.config_proto_type_name); |
|
|
|
|
|
|
|
if (&http_filter != &http_connection_manager->http_filters.back()) { |
|
|
|
// Filters before the last filter must not be terminal.
|
|
|
|
// Filters before the last filter must not be terminal.
|
|
|
|
if (filter_impl->IsTerminalFilter()) { |
|
|
|
if (filter_impl->IsTerminalFilter()) { |
|
|
|
return GRPC_ERROR_CREATE_FROM_CPP_STRING( |
|
|
|
return GRPC_ERROR_CREATE_FROM_CPP_STRING( |
|
|
|
absl::StrCat("terminal filter for config type ", filter_type, |
|
|
|
absl::StrCat("terminal filter for config type ", |
|
|
|
|
|
|
|
http_filter.config.config_proto_type_name, |
|
|
|
" must be the last filter in the chain")); |
|
|
|
" must be the last filter in the chain")); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// The last filter must be terminal.
|
|
|
|
// The last filter must be terminal.
|
|
|
|
if (!filter_impl->IsTerminalFilter()) { |
|
|
|
if (!filter_impl->IsTerminalFilter()) { |
|
|
|
return GRPC_ERROR_CREATE_FROM_CPP_STRING( |
|
|
|
return GRPC_ERROR_CREATE_FROM_CPP_STRING( |
|
|
|
absl::StrCat("non-terminal filter for config type ", filter_type, |
|
|
|
absl::StrCat("non-terminal filter for config type ", |
|
|
|
|
|
|
|
http_filter.config.config_proto_type_name, |
|
|
|
" is the last filter in the chain")); |
|
|
|
" is the last filter in the chain")); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
absl::StatusOr<XdsHttpFilterImpl::FilterConfig> filter_config = |
|
|
|
|
|
|
|
filter_impl->GenerateFilterConfig(google_protobuf_Any_value(any), |
|
|
|
|
|
|
|
context.arena); |
|
|
|
|
|
|
|
if (!filter_config.ok()) { |
|
|
|
|
|
|
|
return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat( |
|
|
|
|
|
|
|
"filter config for type ", filter_type, |
|
|
|
|
|
|
|
" failed to parse: ", filter_config.status().ToString())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
http_connection_manager->http_filters.emplace_back( |
|
|
|
|
|
|
|
XdsApi::LdsUpdate::HttpConnectionManager::HttpFilter{ |
|
|
|
|
|
|
|
std::string(name), std::move(*filter_config)}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// If using a v2 config, we just hard-code a list containing only the
|
|
|
|
// If using a v2 config, we just hard-code a list containing only the
|
|
|
@ -2269,7 +2326,10 @@ grpc_error_handle HttpConnectionManagerParse( |
|
|
|
XdsApi::LdsUpdate::HttpConnectionManager::HttpFilter{ |
|
|
|
XdsApi::LdsUpdate::HttpConnectionManager::HttpFilter{ |
|
|
|
"router", {kXdsHttpRouterFilterConfigName, Json()}}); |
|
|
|
"router", {kXdsHttpRouterFilterConfigName, Json()}}); |
|
|
|
} |
|
|
|
} |
|
|
|
if (is_client) { |
|
|
|
// Guarding parsing of RouteConfig on the server side with the environmental
|
|
|
|
|
|
|
|
// variable since that's the first feature on the server side that will be
|
|
|
|
|
|
|
|
// using this.
|
|
|
|
|
|
|
|
if (is_client || XdsRbacEnabled()) { |
|
|
|
// Found inlined route_config. Parse it to find the cluster_name.
|
|
|
|
// Found inlined route_config. Parse it to find the cluster_name.
|
|
|
|
if (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_route_config( |
|
|
|
if (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_route_config( |
|
|
|
http_connection_manager_proto)) { |
|
|
|
http_connection_manager_proto)) { |
|
|
@ -2504,6 +2564,8 @@ grpc_error_handle FilterChainParse( |
|
|
|
filter_chain_match, &filter_chain->filter_chain_match); |
|
|
|
filter_chain_match, &filter_chain->filter_chain_match); |
|
|
|
if (error != GRPC_ERROR_NONE) errors.push_back(error); |
|
|
|
if (error != GRPC_ERROR_NONE) errors.push_back(error); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
filter_chain->filter_chain_data = |
|
|
|
|
|
|
|
std::make_shared<XdsApi::LdsUpdate::FilterChainData>(); |
|
|
|
// Parse the filters list. Currently we only support HttpConnectionManager.
|
|
|
|
// Parse the filters list. Currently we only support HttpConnectionManager.
|
|
|
|
size_t size = 0; |
|
|
|
size_t size = 0; |
|
|
|
auto* filters = |
|
|
|
auto* filters = |
|
|
@ -2539,8 +2601,6 @@ grpc_error_handle FilterChainParse( |
|
|
|
"Could not parse HttpConnectionManager config from filter " |
|
|
|
"Could not parse HttpConnectionManager config from filter " |
|
|
|
"typed_config")); |
|
|
|
"typed_config")); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
filter_chain->filter_chain_data = |
|
|
|
|
|
|
|
std::make_shared<XdsApi::LdsUpdate::FilterChainData>(); |
|
|
|
|
|
|
|
grpc_error_handle error = HttpConnectionManagerParse( |
|
|
|
grpc_error_handle error = HttpConnectionManagerParse( |
|
|
|
false /* is_client */, context, http_connection_manager, is_v2, |
|
|
|
false /* is_client */, context, http_connection_manager, is_v2, |
|
|
|
&filter_chain->filter_chain_data->http_connection_manager); |
|
|
|
&filter_chain->filter_chain_data->http_connection_manager); |
|
|
|