Avoid panic applying TProxy Envoy extensions#17537
Conversation
f8b8034 to
8c30455
Compare
There was a problem hiding this comment.
All the filter chain patching code turned out to be identical except for the removed check for VIPs below (which is not necessary for the BasicEnvoyExtender, because UpstreamEnvoyExtender now handles extensions - Lambda and Validate - configured via an upstream of the local proxy).
There was a problem hiding this comment.
This line was the source of the panic. We wouldn't expect config.Upstreams[config.ServiceName] to exist except if the local service has itself configured as an upstream; regardless, it's not necessary here.
Removing this check fixes the second regression in which TProxy filters were not patched by BasicEnvoyExtender (Lua).
There was a problem hiding this comment.
Guards against the same bug without removing the VIP check, which is necessary in this case.
| } | ||
|
|
||
| func TestConfigSnapshotTransparentProxyDestinationHTTP(t testing.T) *ConfigSnapshot { | ||
| func TestConfigSnapshotTransparentProxyDestinationHTTP(t testing.T, nsFn func(ns *structs.NodeService)) *ConfigSnapshot { |
There was a problem hiding this comment.
This allows us to configure the Lua extension for the local service, which will target TProxy upstreams.
| "name": "envoy.filters.http.lua", | ||
| "typedConfig": { | ||
| "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua", | ||
| "inlineCode": "\nfunction envoy_on_request(request_handle)\n request_handle:headers():add(\"test\", \"test\")\nend" | ||
| } |
There was a problem hiding this comment.
Patched HTTP upstream 1/2
| "name": "envoy.filters.http.lua", | ||
| "typedConfig": { | ||
| "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua", | ||
| "inlineCode": "\nfunction envoy_on_request(request_handle)\n request_handle:headers():add(\"test\", \"test\")\nend" | ||
| } |
There was a problem hiding this comment.
Patched HTTP upstream 2/2
hashi-derek
left a comment
There was a problem hiding this comment.
This looks fine to me if you're certain that the removed code in the basic envoy extender wasn't needed for anything.
cthain
left a comment
There was a problem hiding this comment.
Great work. I'm super glad that you caught this.
When UpstreamEnvoyExtender was introduced, some code was left duplicated between it and BasicEnvoyExtender. One path in that code panics when a TProxy listener patch is attempted due to no upstream data in RuntimeConfig matching the local service (which would only happen in rare cases). Instead, we can remove the special handling of upstream VIPs from BasicEnvoyExtender entirely, greatly simplifying the listener filter patch code and avoiding the panic. UpstreamEnvoyExtender, which needs this code to function, is modified to ensure a panic does not occur. This also fixes a second regression in which the Lua extension was not applied to TProxy outbound listeners.
8c30455 to
c66703f
Compare
| func (b *BasicEnvoyExtender) patchListenerFilterChains(config *RuntimeConfig, l *envoy_listener_v3.Listener, nameOrSNI string) (*envoy_listener_v3.Listener, error) { | ||
| func (b *BasicEnvoyExtender) patchSupportedListenerFilterChains(config *RuntimeConfig, l *envoy_listener_v3.Listener, nameOrSNI string) (*envoy_listener_v3.Listener, error) { | ||
| switch config.Kind { | ||
| case api.ServiceKindTerminatingGateway: | ||
| return b.patchTerminatingGatewayListenerFilterChains(config, l, nameOrSNI) | ||
| case api.ServiceKindConnectProxy: | ||
| return b.patchConnectProxyListenerFilterChains(config, l, nameOrSNI) | ||
| case api.ServiceKindTerminatingGateway, api.ServiceKindConnectProxy: | ||
| return b.patchListenerFilterChains(config, l, nameOrSNI) |
There was a problem hiding this comment.
After double checking the original change that introduced this switch and the matching one above, I restored it to align with that and reduce changes here (I'd originally thought it was more copy-pasta). This could prevent a future bug if we were to support more proxy types for extensions in general without aligning that support with listeners specifically.
No other changes since the last review. I've also re-tested by hand w/ this change.
When
UpstreamEnvoyExtenderwas introduced, some code was left duplicated between it andBasicEnvoyExtender. One path in that code panics when a TProxy listener patch is attempted due to no upstream data inRuntimeConfigmatching the local service (which would only happen in rare cases).Instead, we can remove the special handling of upstream VIPs from
BasicEnvoyExtenderentirely, greatly simplifying the listener filter patch code and avoiding the panic.UpstreamEnvoyExtender, which needs this code to function, is modified to ensure a panic does not occur.This also fixes a second regression in which the Lua extension was not applied to TProxy outbound listeners.
Description
This fixes two regressions caused by #17415.
Testing & Reproduction steps
I've hand-tested this fix in addition to adding tests to guard against the regressions.
PR Checklist