Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

router: correct cluster name for ads in routes #2449

Merged
merged 11 commits into from
Feb 1, 2018

Conversation

ramaraochavali
Copy link
Contributor

Signed-off-by: Rama [email protected]
Fix Cluster name for ADS configured RDS in routes

Description:
When admin/routes displays the route table, configured with RDS, it shows the cluster name as "NOT_USING_CLUSTER". Fixed it to display "ADS_CLUSTER"

Risk Level: Low
Testing: Manual
Docs Changes: N/A
Release Notes: N/A

@@ -75,6 +75,8 @@ RdsRouteConfigProviderImpl::RdsRouteConfigProviderImpl(
// then there is no actual RDS server, and hence no RDS cluster name.
if (rds.has_config_source() && rds.config_source().has_api_config_source()) {
cluster_name_ = rds.config_source().api_config_source().cluster_names()[0];
} else if (rds.has_config_source() && rds.config_source().has_ads()) {
cluster_name_ = "ADS_CLUSTER";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to get the actual ads cluster name, but looks like it requires a bigger change, like adding ads cluster name while building the ClusterManager and have to introduce a public method in ClusterManager which may be overkill for this. Please let me know if you would like me to do it or if there is a simpler way to get the actual ads cluster name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually pretty tricky for a few reasons:

  1. We're migrating envoy.api.v2.ApiConfigSource (by which ADS) is configured away from using raw cluster names to envoy.api.v2.GrpcService.
  2. The ADS GrpcService might either use a cluster name (when using Envoy gRPC) or a raw address (when using Google gRPC). There is a stat_prefix in the latter case, which could be used for reporting, but I think this would be confusing semantics here.

I think including cluster name in the admin console is not the way to go long term. What we should do perhaps is include a JSON serialization of rds.config_source().api_config_source(), or elide it completely.

@junr03 can probably comment further on the original intention of this field and what it might be used for in a post-cluster centric view of gRPC endpoints.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will defer to @junr03 on the final solution here, but in general I think we need to move to a model where we just store the config in proto form and are able to spit it back out. See also #2421

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original purpose of that field was to be able to give a sense to someone operating the admin interface where the RDS config came from, given that the configuration might have come from an LDS response.

In general, #2421 and #2172 show that there is a need to be able to understand what is currently loaded in envoy and where it came from. There are a couple segmented pieces here and there but a comprehensive solution would be great.

As far as this particular change goes, I am ok with it in order to make the output of the /routes admin endpoint correct and more clear for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about just dumping the full rds.config_source.api_config_source() proto instead of cluster name? It seems this would kill multiple birds with one stone.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, in my comment above I meant it to mean your suggestion of dumping rds.config_source().api_config_source() -- I elided a sentence. However, I would do rds.config_source() so all three sources are covered by default?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM

@@ -130,7 +130,7 @@ class RdsRouteConfigProviderImpl
Upstream::ClusterManager& cm_;
std::unique_ptr<Envoy::Config::Subscription<envoy::api::v2::RouteConfiguration>> subscription_;
ThreadLocal::SlotPtr tls_;
std::string cluster_name_;
std::string cluster_config_;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@junr03 i have changed this variable name and method name to mean what we are doing here. let me know if you want to use any better names

@mattklein123
Copy link
Member

@ramaraochavali this LGTM in general. Can you provide an example of the admin endpoint output from curl? I'm mostly wonder if it looks OK or if we should try to do some pretty printing. (I can't recall whether we have that capability or not easily in the proto conversion path). cc @junr03 @htuch

} else {
cluster_name_ = "NOT_USING_CLUSTER";
cluster_config_ = "NOT_USING_CLUSTER";
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole if statement should now just be:

if (rds.has_config_source()) {
  cluster_source_ = MessageUtil::getJsonStringFromMessage(rds.config_source());
}

*/
virtual const std::string& clusterName() const PURE;
virtual const std::string& clusterConfig() const PURE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to configSource(), the cluster aspect is no longer true in general, this could be a non-cluster destination GrpcService.

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the improvement happening here, thanks @ramaraochavali!

@ramaraochavali
Copy link
Contributor Author

@htuch changed it to configSource also changed the text in /routes to config_source . PTAL and let me if any further changes are required.

@ramaraochavali
Copy link
Contributor Author

@mattklein123 Here is the curl output

[
{
"version_info": "1",
"route_config_name": "ingress_http2_route",
"config_source": {"ads":{}},
"route_table_dump": {"name":"ingress_http2_route","virtual_hosts":[{"name":"ingress_http2_route","domains":["*"],"routes":[{"match":{"prefix":"/"},"route":{"cluster":"local_service_grpc","retry_policy":{"retry_on":"5xx,connect-failure,refused-stream","num_retries":3}}}]}]}
}
,{
"version_info": "1",
"route_config_name": "egress_http2_route",
"config_source": {"ads":{}},
"route_table_dump": {"name":"egress_http2_route","virtual_hosts":[{"name":"egress_http2_route","domains":["*"],"routes":[{"match":{"prefix":"/"},"route":{"cluster_header":":authority","retry_policy":{"retry_on":"5xx,connect-failure,refused-stream,cancelled,deadline-exceeded,resource-exhausted","num_retries":3}}}]}]}
}
,{
"version_info": "1",
"route_config_name": "ingress_http1_route",
"config_source": {"ads":{}},
"route_table_dump": {"name":"ingress_http1_route","virtual_hosts":[{"name":"ingress_http1_route","domains":["*"],"routes":[{"match":{"prefix":"/"},"route":{"cluster":"local_service","retry_policy":{"retry_on":"5xx,connect-failure,refused-stream","num_retries":3}}}]}]}
}
]

Signed-off-by: Rama <[email protected]>
@mattklein123
Copy link
Member

OK I guess it's no worse than the route table dump output. In the future I wonder if we should pretty print, they I suppose the output can easily be piped through a JSON formatter.

@ramaraochavali
Copy link
Contributor Author

@mattklein123 implemented the pretty print support for JSON. Here is the output of /routes with. can you PTAL at the review?

[
{
"version_info": "1",
"route_config_name": "ingress_http2_route",
"config_source": {
 "ads": {}
}
,
"route_table_dump": {
 "name": "ingress_http2_route",
 "virtual_hosts": [
  {
   "name": "ingress_http2_route",
   "domains": [
    "*"
   ],
   "routes": [
    {
     "match": {
      "prefix": "/"
     },
     "route": {
      "cluster": "local_service_grpc",
      "retry_policy": {
       "retry_on": "5xx,connect-failure,refused-stream",
       "num_retries": 3
      }
     }
    }
   ]
  }
 ]
}

}
,{
"version_info": "1",
"route_config_name": "egress_http2_route",
"config_source": {
 "ads": {}
}
,
"route_table_dump": {
 "name": "egress_http2_route",
 "virtual_hosts": [
  {
   "name": "egress_http2_route",
   "domains": [
    "*"
   ],
   "routes": [
    {
     "match": {
      "prefix": "/"
     },
     "route": {
      "cluster_header": ":authority",
      "retry_policy": {
       "retry_on": "5xx,connect-failure,refused-stream,cancelled,deadline-exceeded,resource-exhausted",
       "num_retries": 3
      }
     }
    }
   ]
  }
 ]
}

}
,{
"version_info": "1",
"route_config_name": "ingress_http1_route",
"config_source": {
 "ads": {}
}
,
"route_table_dump": {
 "name": "ingress_http1_route",
 "virtual_hosts": [
  {
   "name": "ingress_http1_route",
   "domains": [
    "*"
   ],
   "routes": [
    {
     "match": {
      "prefix": "/"
     },
     "route": {
      "cluster": "local_service",
      "retry_policy": {
       "retry_on": "5xx,connect-failure,refused-stream",
       "num_retries": 3
      }
     }
    }
   ]
  }
 ]
}

}
]

@ramaraochavali
Copy link
Contributor Author

@mattklein123 once we agree on the format and code changes I will make changes to the rds_impl test to adhere to this format

htuch
htuch previously approved these changes Jan 28, 2018
Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo minor rename.

} else {
cluster_name_ = "NOT_USING_CLUSTER";
config_source_ = "NOT_USING_CLUSTER";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to NO_CONFIG_SOURCE.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! LGTM other than small comments.

* @return std::string of formatted JSON object.
*/
static std::string getJsonStringFromMessage(const Protobuf::Message& message,
const bool pretty_print);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I would just add pretty_print to the other definition and default it to false, then just remove this version.

@ramaraochavali
Copy link
Contributor Author

@mattklein123 @htuch addressed the minor comments. Fixed the test case to validate against the new format. Should be good to go. let me know if any thing else is missing on this.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice, thanks. Tiny nit.

@@ -51,10 +51,10 @@ class RdsRouteConfigProvider : public RouteConfigProvider {
virtual const std::string& routeConfigName() const PURE;

/**
* @return const std::string& the name of the cluster the RdsRouteConfigProvider is issuing RDS
* requests to.
* @return const std::string& the configuration of service the RdsRouteConfigProvider is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny nit: "the service"

Signed-off-by: Rama <[email protected]>
@ramaraochavali
Copy link
Contributor Author

@mattklein123 changed. PTAL.

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, just one more thing..

*/
static std::string getJsonStringFromMessage(const Protobuf::Message& message);
static std::string getJsonStringFromMessage(const Protobuf::Message& message,
const bool pretty_print = false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: const on method declarations doesn't do anything (it's OK in the definition though).

} else {
cluster_name_ = "NOT_USING_CLUSTER";
config_source_ = "NO_CONFIG_SOURCE";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this actually be an empty dictionary {} on second thoughts; JSON parsing will barf on this won't it?

@ramaraochavali
Copy link
Contributor Author

@htuch made those changes..PTAL.

htuch
htuch previously approved these changes Jan 30, 2018
@ramaraochavali
Copy link
Contributor Author

@htuch wait a min. looks like some problem. will correct that in a bit.

@ramaraochavali ramaraochavali changed the title correct cluster name for ads in routes router: correct cluster name for ads in routes Jan 30, 2018
@ramaraochavali
Copy link
Contributor Author

@mattklein123 @htuch should be good to go now.PTAL.

htuch
htuch previously approved these changes Jan 30, 2018
} else {
cluster_name_ = "NOT_USING_CLUSTER";
config_source_ = "{}";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry quick question: Is there a test that should have caught this (switching to {})? Is it easy to add one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattklein123 there is no test. Will look in to adding it. One more thing, /routes is not working for routes defined statically. It is only iterating through the RdsRouteConfigProviders. https://github.com/envoyproxy/envoy/blob/master/source/common/router/rds_impl.cc#L215. Also it does not store the StaticRouteConfigProviders any where. Is this intentional or a bug? @htuch your thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and the else block changing config_source = {}, I think we can get rid of the else block completely because if rds is configured, with out config_source, EnvoyException will be thrown. And that is validated with this test https://github.com/envoyproxy/envoy/blob/master/test/common/router/rds_impl_test.cc#L126.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also it does not store the StaticRouteConfigProviders any where. Is this intentional or a bug?

It just wasn't implemented. In the context of #2421 we will want to revisit this.

and the else block changing config_source = {}, I think we can get rid of the else block completely because if rds is configured, with out config_source, EnvoyException will be thrown.

Yup, great catch. If the code can't be hit just delete it and remove the if statement entirely. Thanks!

@ramaraochavali
Copy link
Contributor Author

@mattklein123 fixed. removed the comment as well as it is confusing there. PTAL. So /routes was implemented recently and for rds only?

@junr03
Copy link
Member

junr03 commented Feb 1, 2018

@ramaraochavali I can give context. yes /routes was implemented only for RDS given that you could get a dump of the static routes by looking at your config file. As Matt mentioned in the issue above. We would like to unify all of these disparate outputs into a more comprehensive solution.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Very nice.

@mattklein123 mattklein123 merged commit 2bce55f into envoyproxy:master Feb 1, 2018
@ramaraochavali ramaraochavali deleted the fix/rds-cluster-name branch February 2, 2018 05:13
Shikugawa pushed a commit to Shikugawa/envoy that referenced this pull request Mar 28, 2020
This file is often skipped when updating Envoy SHA in WORKSPACE.

Signed-off-by: Piotr Sikora <[email protected]>
jpsim added a commit that referenced this pull request Nov 28, 2022
Signed-off-by: GitHub Action <[email protected]>

Co-authored-by: jpsim <[email protected]>
Signed-off-by: JP Simard <[email protected]>
jpsim added a commit that referenced this pull request Nov 29, 2022
Signed-off-by: GitHub Action <[email protected]>

Co-authored-by: jpsim <[email protected]>
Signed-off-by: JP Simard <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants