Skip to content

Support HTTP tunneling on all Upstreams#10712

Merged
ryanrolds merged 32 commits intomainfrom
rolds/remote_jwks_upstream_tunneling
Apr 3, 2025
Merged

Support HTTP tunneling on all Upstreams#10712
ryanrolds merged 32 commits intomainfrom
rolds/remote_jwks_upstream_tunneling

Conversation

@ryanrolds
Copy link

@ryanrolds ryanrolds commented Mar 19, 2025

Description

Refactors the HTTP tunneling plugin to support all Upstreams. I have a PR that confirms a tunnel can be used with a remote JWKS (customer use case). This is Solution 3 in the design document.

While working on tests for the customer use case I discovered that the lifecycle differences with krt require introducing a new plugin interface that was krt-safe. After talking with Yuval, I implemented my understanding of his recommendation. This work should help with other uses of GeneratedResources in gateway2/kgateway as well.

The plugin has two paths that use common logic to transforming and creating the additional clusters/listeners:

  1. Edge uses the now deprecated (not-krt-safe) GeneratedResources
  2. Gateway uses the krt-safe UpstreamGeneratedResources

Tests for the customer case have been added to https://github.com/solo-io/solo-projects/pull/8080.

Last week I added kubernetes/e2e tests that confirm the works in Edge and GW APIs. This work refactors it to work in more cases. My plan is to add additional kubernetes/e2e tests to solo-projects to confirm that the tunneling works for the specific customer case (remote JWKS).

Changes:

  • Added Gateway test to CI that was missed in an earlier PR
  • Added ClusterResult (holds the additional clusters/listeners) and plumbed through the gateway2 translator and syncer
  • Plumbed the reporter through GeneratedResources so that the plugin could report issues with specific Upstreams
  • Adjusted the tunnel tests to tear down the gateway, forcing the tunnel closed and triggering the logs in Squid
  • Added golden YAML tests for gateway2 translation.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works

@solo-changelog-bot
Copy link

Issues linked to changelog:
https://github.com/solo-io/solo-projects/issues/7497

@ryanrolds ryanrolds changed the title Support HTTP tunneling on all upstreams Support HTTP tunneling on all Upstreams Mar 19, 2025
@ryanrolds ryanrolds marked this pull request as ready for review March 20, 2025 15:15
@ryanrolds ryanrolds changed the title Support HTTP tunneling on all Upstreams [DRAFT] Support HTTP tunneling on all Upstreams Mar 20, 2025
@github-actions
Copy link

github-actions bot commented Mar 20, 2025

Visit the preview URL for this PR (updated for commit 63a5227):

https://gloo-edge--pr10712-rolds-remote-jwks-up-43q77f4s.web.app

(expires Wed, 09 Apr 2025 22:24:34 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 77c2b86e287749579b7ff9cadb81e099042ef677

@ryanrolds ryanrolds changed the title [DRAFT] Support HTTP tunneling on all Upstreams Support HTTP tunneling on all Upstreams Mar 21, 2025
Copy link

@sam-heilbron sam-heilbron left a comment

Choose a reason for hiding this comment

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

We have an in-memory e2e test: https://github.com/solo-io/gloo/blob/main/test/e2e/dynamic_forward_proxy_test.go. Now that we support a new use case, is it worth it to add a test to prove that case?

@ryanrolds
Copy link
Author

We have an in-memory e2e test: https://github.com/solo-io/gloo/blob/main/test/e2e/dynamic_forward_proxy_test.go. Now that we support a new use case, is it worth it to add a test to prove that case?

Will do.

@ryanrolds
Copy link
Author

We have an in-memory e2e test: https://github.com/solo-io/gloo/blob/main/test/e2e/dynamic_forward_proxy_test.go. Now that we support a new use case, is it worth it to add a test to prove that case?

I think those tests are unrelated. There are in-memory E2E tests for HTTP tunneling. I understand your ask to be that you would like a non-route bound Upstream to be confirmed to work.

@ryanrolds
Copy link
Author

@sam-heilbron, I looked at non-EE cases to test and it's pretty much tracing. As noted in the description, I'm working on adding a test for the customer's case. Does this work or would you really like two tests to confirm that routes and non-routed Upstreams work in Gloo even though both use the same code path?

@ryanrolds ryanrolds requested a review from sam-heilbron March 24, 2025 20:28
Copy link

@sam-heilbron sam-heilbron left a comment

Choose a reason for hiding this comment

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

LGTM! I like the testing plan you proposed

func (p *plugin) GeneratedResources(params plugins.Params,
func (p *plugin) GeneratedResources(
params plugins.Params,
proxy *v1.Proxy,

Choose a reason for hiding this comment

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

I really like this change! I feel like it makes the plugin more self-contained, and a set of resources are associated with the Proxy resource anyway, so I think this makes a lot of sense

cfg, err := utils.NewSslConfigTranslator().ResolveUpstreamSslConfig(params.Snapshot.Secrets,
us.GetHttpConnectSslConfig())
if err != nil {
// if we are configured to warn on missing tls secret and we match that error, add a

Choose a reason for hiding this comment

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

I like the idea here, and we may be required to have this logic built into this plugin. What I wish existed, was that we could just compile errors and warnings in reports (and basically not make plugins aware of how they are consumed), and then when we process them, we would inspect the validation settings and processes/consume those reports differently.

https://github.com/solo-io/gloo/blob/main/projects/gloo/pkg/translator/reporting.go#L173 is that in practice, https://github.com/solo-io/gloo/blob/main/projects/gloo/pkg/plugins/configuration_error.go.

Do you know if there is a way to ensure that plugins can be unaware of high-level settings like this?

Copy link
Author

Choose a reason for hiding this comment

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

The plugin does need to know about setting as the behavior (not standing-up the tunnel) depends on the setting and error.

It may be possible to push the check down into the Resolve<X>SslConfig methods, but the need to check for the error and branch is still needed. I'm not sure if we want to tightly couple the error for those methods to the ResourceReports.

@ryanrolds ryanrolds marked this pull request as draft March 26, 2025 22:34
@ryanrolds
Copy link
Author

/kick-ci

@ryanrolds ryanrolds changed the title Support HTTP tunneling on all Upstreams [DRAFT] Support HTTP tunneling on all Upstreams Mar 27, 2025
@ryanrolds ryanrolds marked this pull request as ready for review March 27, 2025 20:17
@ryanrolds
Copy link
Author

I've merged a refactor that should support gateway2. I will be confirming it works with my solo-projects PR once CI finishes.

@ryanrolds ryanrolds changed the title [DRAFT] Support HTTP tunneling on all Upstreams Support HTTP tunneling on all Upstreams Mar 31, 2025
newInClusterName := clusterName + OriginalClusterSuffix

// use an in-memory pipe to ourselves (only works on linux)
forwardingPipe := "@/" + clusterName

Choose a reason for hiding this comment

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

Could consider

https://www.envoyproxy.io/docs/envoy/latest/configuration/other_features/internal_listener

at some point, not truly proposing this now

Copy link
Author

Choose a reason for hiding this comment

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

I will add a comment nudging future engineers to consider switching to an internal listener.

endpoints = append(endpoints, generatedEndpoints...)
routeConfigs = append(routeConfigs, generatedRouteConfigs...)
listeners = append(listeners, generatedListeners...)
newClusters, newEndpoints, newRouteConfigs, newListeners := plugin.GeneratedResources(params, proxy,

Choose a reason for hiding this comment

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

GeneratedResources has a comment about being deprecated, this (the only non-test caller) doesn't have anything like a if (is ggv2) continue? Should we have that? Otherwise maybe we should clarify the deprecation comment.

Copy link
Author

Choose a reason for hiding this comment

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

There are a few other plugins that use GeneratedResources in the gateway2 translation path, so we can't skip it. The check here prevents the HTTP tunnel plugin from double adding the clusters.

When the other plugins are updated, we can pull what you're highlghting out and only use UpstreamGeneratedResources for both the gloo and gateway2 translation paths.

I will add a comment clarifying the intended approach to removing this.

Copy link
Author

Choose a reason for hiding this comment

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

I'm adding:

// GeneratedResources is deprecated and being replaced by UpstreamGeneratedResources
// The plan is to move the few remaining plugins in Gloo/EE to use the new
// interface. Once that is done and the new interface is called in the Gloo translation
// path, we can remove this code.
// During this transition period, gateway2 will call both interfaces and it's translator
// has (must have) checks that prevent duplicate resources from being added.

Copy link

@stevenctl stevenctl left a comment

Choose a reason for hiding this comment

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

It would also be good to have some of the YAML-only goldenfile style tests for this: see ggv2setup_test.go and assoc testdata.

@ryanrolds
Copy link
Author

It would also be good to have some of the YAML-only goldenfile style tests for this: see ggv2setup_test.go and assoc testdata.

Great callout. I will make sure that happens.

@ryanrolds ryanrolds requested a review from stevenctl April 2, 2025 15:47
@ryanrolds ryanrolds merged commit 078715c into main Apr 3, 2025
20 checks passed
@ryanrolds ryanrolds deleted the rolds/remote_jwks_upstream_tunneling branch April 3, 2025 18:02
ymesika pushed a commit that referenced this pull request Apr 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants