Skip to content

Extensions: Network filter to set upstream cluster from SNI#4489

Merged
lizan merged 20 commits intoenvoyproxy:masterfrom
rshriram:sni_cluster
Sep 26, 2018
Merged

Extensions: Network filter to set upstream cluster from SNI#4489
lizan merged 20 commits intoenvoyproxy:masterfrom
rshriram:sni_cluster

Conversation

@rshriram
Copy link
Copy Markdown
Member

@rshriram rshriram commented Sep 20, 2018

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

Shriram Rajagopalan added 6 commits September 19, 2018 21:47
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>
@rshriram
Copy link
Copy Markdown
Member Author

cc @htuch this should provide context for #4454

@rshriram
Copy link
Copy Markdown
Member Author

fyi @louiscryan @PiotrSikora @lizan

Shriram Rajagopalan added 6 commits September 21, 2018 00:35
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>
Comment thread source/extensions/filters/network/sni_cluster/sni_cluster.cc Outdated
Comment thread source/common/tcp_proxy/tcp_proxy.h Outdated
/**
* Per-connection TCP Proxy Filter configuration.
*/
class PerConnectionTcpProxyConfig : public Envoy::RequestInfo::FilterState::Object {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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

@ggreenway
Copy link
Copy Markdown
Member

@rshriram
Copy link
Copy Markdown
Member Author

I added a doc file describing the filter and it’s purpose. It should be in the PR. Does that suffice ?

@rshriram
Copy link
Copy Markdown
Member Author

gentle ping :)

Copy link
Copy Markdown
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

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

Can you also figure out who will be the sponsor per extension policy and add a line to CODEOWNERS?

Comment thread source/common/tcp_proxy/tcp_proxy.h Outdated
/**
* Per-connection TCP Proxy Filter configuration.
*/
class PerConnectionTcpProxyConfig : public Envoy::RequestInfo::FilterState::Object {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: No need Envoy:: prefix. +1 to name @ggreenway suggested.

Comment thread source/common/tcp_proxy/tcp_proxy.h Outdated
static const std::string CLUSTER_KEY;

private:
std::string cluster_;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

const?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is set by the filter isn't it? And it could be changed by other filters before hitting tcp proxy.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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 ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think that would be outside the scope of this PR.

}

ProtobufTypes::MessagePtr SniClusterNetworkFilterConfigFactory::createEmptyConfigProto() {
return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()};
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: no need Envoy::.

Shriram Rajagopalan added 5 commits September 25, 2018 02:27
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>
Comment thread source/common/tcp_proxy/tcp_proxy.cc Outdated
Comment thread source/common/tcp_proxy/tcp_proxy.cc Outdated

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)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

not directly with this PR, but seems this pattern (hasData, then getData) would be common, is there any way to avoid double lookup?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since v1 will be completely removed soon, should we mark this method non-PURE and in NamedNetworkFilterConfigFactory and make it NOT_IMPLEMENTED?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I was waiting for the 1.8 cycle. after that, we could remove these methods entirely from everywhere.

Comment thread source/extensions/filters/network/sni_cluster/config.cc Outdated
@lizan lizan self-assigned this Sep 25, 2018
Shriram Rajagopalan added 2 commits September 25, 2018 18:21
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
ggreenway
ggreenway previously approved these changes Sep 25, 2018
Copy link
Copy Markdown
Member

@ggreenway ggreenway left a comment

Choose a reason for hiding this comment

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

LGTM. @lizan any other comments/feedback?

Signed-off-by: Shriram Rajagopalan <shriramr@vmware.com>
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.

3 participants