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

tcp_proxy: support command operators in tunneling_config.hostname #21067

Conversation

jewertow
Copy link
Contributor

@jewertow jewertow commented Apr 28, 2022

Signed-off-by: Jacek Ewertowski jacek.ewertowski1@gmail.com

Commit Message: tcp_proxy: support command operators in tunneling_config.hostname
Additional Description: This change enables dynamically setting tunneling_config.hostname with command operators.
Risk Level: Low
Testing: added unit tests
Docs Changes: done
Release Notes: done
Platform Specific Features: none
[Optional Fixes #19612 #21804]

This pull request is an alternative for auto_sni.

This change allows to configure TCP proxy as follows:

tunneling_config:
  hostname: %REQUESTED_SERVER_NAME%:443

@repokitteh-read-only
Copy link

As a reminder, PRs marked as draft will not be automatically assigned reviewers,
or be handled by maintainer-oncall triage.

Please mark your PR as ready when you want it to be reviewed!

🐱

Caused by: #21067 was opened by jewertow.

see: more, trace.

@jewertow
Copy link
Contributor Author

jewertow commented Apr 28, 2022

@ramaraochavali @lambdai what do you think?

Copy link
Contributor

@ramaraochavali ramaraochavali 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. LGTM

@jewertow jewertow force-pushed the tcp-proxy-tunneling-config-hostname-requested-server-name branch from a593ae9 to a1d758d Compare May 6, 2022 18:06
@jewertow jewertow marked this pull request as ready for review May 11, 2022 19:53
@jewertow
Copy link
Contributor Author

@alyssawilk could you take a look at this pull request? I didn't add integration test yet, but you can review the general idea and implementation. This approach makes it possible to support also other command operators if make sense. The advantage of this approach in contrary to overwriting Host header is that the hostname is not empty nor set to a dummy value what would be confusing.

I gave up the idea of auto_sni, because it's not backward compatible to wrap hostname and auto_sni in oneof. So the idea does not make sense, because it would be required to define empty or dummy hostname and I wanted to avoid it.

Copy link
Contributor

@kyessenov kyessenov left a comment

Choose a reason for hiding this comment

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

Please make sure exceptions are not thrown on the data path, otherwise, looks reasonable.

source/common/tcp_proxy/tcp_proxy.h Outdated Show resolved Hide resolved
source/common/tcp_proxy/tcp_proxy.h Outdated Show resolved Hide resolved
@kyessenov
Copy link
Contributor

/wait-any

@jewertow
Copy link
Contributor Author

Regarding to your comment: I would like to complete this feature. Are you okay with that? I also would be interested to extend this feature to support dynamic metadata in subsequent pull request.

@KBaichoo
Copy link
Contributor

KBaichoo commented Jun 1, 2022

@kyessenov I think this is waiting on your reply; PTAL

@jewertow seems like you need to merge main

@kyessenov
Copy link
Contributor

I spoke with @jewertow offline, and made suggestions to use the formatter library. I think either that or fixing this version to not throw on data path still needs to be added.

@kyessenov
Copy link
Contributor

/wait-any

@lambdai
Copy link
Contributor

lambdai commented Jun 9, 2022

Ping @jewertow
Are you still working on it? It's an easy one to remove the exception.

I'd like to propose the richer formatter on top of this change. Let me know if you want to complete this one

@lambdai
Copy link
Contributor

lambdai commented Jun 9, 2022

/wait-any restore the flag

@jewertow jewertow force-pushed the tcp-proxy-tunneling-config-hostname-requested-server-name branch from 940ec2a to 2a925c6 Compare June 21, 2022 15:40
@jewertow jewertow force-pushed the tcp-proxy-tunneling-config-hostname-requested-server-name branch 2 times, most recently from bd5f4e4 to 96dd84c Compare June 21, 2022 21:41
@jewertow jewertow changed the title Allow to set %REQUESTED_SERVER_NAME% in tunneling_config.hostname WIP: Allow to set %REQUESTED_SERVER_NAME% in tunneling_config.hostname Jun 21, 2022
Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
@jewertow jewertow force-pushed the tcp-proxy-tunneling-config-hostname-requested-server-name branch from 6825d7b to c0d27c1 Compare June 28, 2022 19:00
Copy link
Contributor

@kyessenov kyessenov left a comment

Choose a reason for hiding this comment

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

Generally looks good, but there are a few comments that could improve this I think.

@@ -32,6 +32,9 @@ behavior_changes:
Fixed metric tag extraction so that :ref:`stat_prefix <envoy_v3_api_field_extensions.filters.network.redis_proxy.v3.RedisProxy.stat_prefix>`
is properly extracted. This changes the Prometheus name from
envoy_redis_myprefix_command_pttl_latency_sum{} to envoy_redis_command_pttl_latency_sum{envoy_redis_prefix="myprefix"}.
- area: tcp_proxy
change: |
added support for command operators in :ref:`TunnelingConfig hostname <envoy_v3_api_field_envoy.config.filter.network.tcp_proxy.v3.TcpProxy.TunnelingConfig.hostname>` to dynamically set upstream hostname.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the label should be:
envoy_v3_api_field_extensions.filters.network.tcp_proxy.v3.TcpProxy.TunnelingConfig.hostname

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I fixed it.

bool usePost() const override { return use_post_; }
Envoy::Http::HeaderEvaluator& headerEvaluator() const override { return *header_parser_; }

private:
const std::string hostname_;
const bool use_post_;
std::unique_ptr<Envoy::Router::HeaderParser> header_parser_;
Formatter::FormatterPtr hostname_fmt_;
Copy link
Contributor

Choose a reason for hiding this comment

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

Make this const Formatter::FormatterPtr.

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 can't, because fromProtoConfig does not return const.

Copy link
Member

Choose a reason for hiding this comment

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

You can if you initialize this in initialization list and extract

envoy::config::core::v3::SubstitutionFormatString substitution_format_config;
  substitution_format_config.mutable_text_format_source()->set_inline_string(
      config_message.hostname());
  return Formatter::SubstitutionFormatStringUtils::fromProtoConfig(
      substitution_format_config, context);

to a helper function.

@@ -77,8 +79,14 @@ Config::SharedConfig::SharedConfig(
idle_timeout_ = std::chrono::hours(1);
}
if (config.has_tunneling_config()) {
tunneling_config_helper_ =
std::make_unique<TunnelingConfigHelperImpl>(config.tunneling_config());
envoy::config::core::v3::SubstitutionFormatString substitution_format_config;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this code could be made part of TunnelingConfigHelperImpl. E.g. add a function there, and initialize const formatter field with a function call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, I did it.

Formatter::FormatterPtr hostname_fmt =
Formatter::SubstitutionFormatStringUtils::fromProtoConfig(substitution_format_config,
context_);
config_ = std::make_unique<TunnelingConfigHelperImpl>(config_message_, std::move(hostname_fmt));
Copy link
Contributor

Choose a reason for hiding this comment

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

If you moved formatter construction into helper you wouldn't have to duplicate this logic several times.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@kyessenov
Copy link
Contributor

@jewertow Please don't force push. That makes it hard to track previous comments. Thanks.
/wait

jewertow added 3 commits June 29, 2022 17:47
Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
jewertow added 3 commits June 29, 2022 18:03
Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
@jewertow jewertow requested a review from kyessenov June 29, 2022 17:10
upstream_ = std::make_unique<T>(callbacks_, *this->config_, this->downstream_stream_info_);
}

void populateMetadata(envoy::config::core::v3::Metadata& metadata, const std::string ns,
const std::string key, const std::string value) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: these could be const std::string&

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

: hostname_(config_message.hostname()), use_post_(config_message.use_post()),
header_parser_(Envoy::Router::HeaderParser::configure(config_message.headers_to_add())) {}
const std::string& hostname() const override { return hostname_; }
config_message,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: It's better to move this implementation code to .cc file to prevent header pollution. also this-> is unusual, but not a big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I moved constructor and host method to .cc file.

kyessenov
kyessenov previously approved these changes Jun 29, 2022
Copy link
Contributor

@kyessenov kyessenov left a comment

Choose a reason for hiding this comment

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

LGTM, need @envoyproxy/api-shepherds approval for proto change, and a couple of code nits.

jewertow added 2 commits June 30, 2022 17:06
Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
…ader file to cc file

Signed-off-by: Jacek Ewertowski <jacek.ewertowski1@gmail.com>
@jewertow
Copy link
Contributor Author

@htuch you are familiar with the issue, so could you review this PR?

@jewertow
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #21067 (comment) was created by @jewertow.

see: more, trace.

Copy link
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.

/lgtm api

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.

Dynamic setting value of TcpProxy.tunneling_config.hostname
8 participants