Extensions: Network filter to set upstream cluster from SNI#4489
Extensions: Network filter to set upstream cluster from SNI#4489lizan merged 20 commits intoenvoyproxy:masterfrom
Conversation
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
| /** | ||
| * Per-connection TCP Proxy Filter configuration. | ||
| */ | ||
| class PerConnectionTcpProxyConfig : public Envoy::RequestInfo::FilterState::Object { |
There was a problem hiding this comment.
I'd name this PerConnectionCluster. It's already in namespace TcpProxy, and we don't want this to grow to include more stuff. If there's more stuff to set on TcpProxy it should be set as separate per-connection values, so that it doesn't all have to be set by the same filter.
There was a problem hiding this comment.
But can't filters retrieve and modify the same object? Having the settings in the same object does not preclude multiple filters from using it does it?
There was a problem hiding this comment.
It makes the interface a little stranger. Instead of just setting a thing, you have to test if it exists first, and if it does take one path, else create a new one and insert it.
There was a problem hiding this comment.
Fair point, but this is based on the assumption that multiple filters will be setting independent things. Now, even in that scenario, given that any other filter could have set the variable before mine, to prevent an exception, I would have to do the check-if-it-exists and then set the thing. [The interface throws an error if I try to set an object that already exists].
Make sense? the check before update will be part of the normal pattern in a scenario where there could be multiple filters. Given that, I feel having a standard check if the umbrella object exists and then do setters/getters is cleaner than check if my object exists and then update..
I don't have strong feelings about this as I don't have data to support either side. So, if you feel like per conn cluster is better, I will happily change it.. We can always consolidate if need be
|
Also, we should clearly document this behavior (overriding the cluster), but I'm not sure where. Possibilities: https://www.envoyproxy.io/docs/envoy/latest/configuration/network_filters/tcp_proxy_filter#config-network-filters-tcp-proxy |
|
I added a doc file describing the filter and it’s purpose. It should be in the PR. Does that suffice ? |
|
gentle ping :) |
lizan
left a comment
There was a problem hiding this comment.
Can you also figure out who will be the sponsor per extension policy and add a line to CODEOWNERS?
| /** | ||
| * Per-connection TCP Proxy Filter configuration. | ||
| */ | ||
| class PerConnectionTcpProxyConfig : public Envoy::RequestInfo::FilterState::Object { |
There was a problem hiding this comment.
nit: No need Envoy:: prefix. +1 to name @ggreenway suggested.
| static const std::string CLUSTER_KEY; | ||
|
|
||
| private: | ||
| std::string cluster_; |
There was a problem hiding this comment.
This is set by the filter isn't it? And it could be changed by other filters before hitting tcp proxy.
There was a problem hiding this comment.
The design of the perConnectionState() requires that only a single filter set the given field, and accessors only get a const reference. So no later filter may modify the value.
There was a problem hiding this comment.
Oh stupid me. That explains why you wanted PerConnectionCluster. Does it make sense to change the design to return non-const reference to the ConnectionState object ?
There was a problem hiding this comment.
I think that would be outside the scope of this PR.
| } | ||
|
|
||
| ProtobufTypes::MessagePtr SniClusterNetworkFilterConfigFactory::createEmptyConfigProto() { | ||
| return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()}; |
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
|
|
||
| const std::string& Config::getRegularRouteFromEntries(Network::Connection& connection) { | ||
| // First check if the per-connection state to see if we need to route to a pre-selected cluster | ||
| if (connection.perConnectionState().hasData<PerConnectionCluster>(PerConnectionCluster::KEY)) { |
There was a problem hiding this comment.
not directly with this PR, but seems this pattern (hasData, then getData) would be common, is there any way to avoid double lookup?
There was a problem hiding this comment.
I had this thought too, but was thinking we should fix it in a separate PR. Probably just make the accessor return a const pointer instead of const ref, so that it can be nullptr when it isn't found. And maybe throw if the item is found, but has an incompatible type (I think that always indicates a programmer error).
| SniClusterNetworkFilterConfigFactory::createFilterFactory(const Json::Object&, | ||
| Server::Configuration::FactoryContext&) { | ||
| // Only used in v1 filters. | ||
| NOT_IMPLEMENTED_GCOVR_EXCL_LINE; |
There was a problem hiding this comment.
Since v1 will be completely removed soon, should we mark this method non-PURE and in NamedNetworkFilterConfigFactory and make it NOT_IMPLEMENTED?
There was a problem hiding this comment.
I was waiting for the 1.8 cycle. after that, we could remove these methods entirely from everywhere.
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Description: Use the SNI value as the upstream cluster name. This is similar to the cluster_header feature in HCM. Leverages the perConnectionState to dynamically control the cluster used by tcp_proxy filter. We plan to use this in Istio, where Pilot would manage two kubernetes setups, such that the envoys will have the same set of clusters, but the non-local clusters will have the IP of a Gateway envoy (edge/front envoy). mTLS traffic arriving at the gateway envoy will be routed to the internal (envoy)clusters based on the SNI value
Depends on #4454
Risk Level: Low
Testing: Unit tests
Docs Changes: yes
Release Notes: yes
Signed-off-by: Shriram Rajagopalan shriramr@vmware.com