feat(listenerpolicy): allow configuring Envoy local replies#14146
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds support for configuring Envoy's LocalReplyConfig via ListenerPolicy.httpSettings.localReplies and HTTPListenerPolicy.localReplies. Refactors shared body-format and header-filter helpers into reusable utilities and moves BodyFormat into the shared API package.
Changes:
- New
LocalReplyConfig/LocalReplyMappertypes and translation to EnvoyLocalReplyConfig(with merge support across HTTP listener policies). - Extracts
BodyFormat, header-filter conversion, and access-log filter conversion into sharedpluginutils/common.gohelpers and updates DirectResponse + TrafficPolicy header modifiers to use them. - Adds CRD updates (including
int32→uint32for ComparisonFilter value), translator test fixtures, and an e2e test suite for local replies.
Reviewed changes
Copilot reviewed 23 out of 26 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| api/v1alpha1/kgateway/listener_policy_types.go | Adds LocalReplyConfig/LocalReplyMapper; changes ComparisonFilter Value to uint32. |
| api/v1alpha1/kgateway/direct_response_types.go | Moves BodyFormat to shared package and reuses it. |
| api/v1alpha1/shared/shared_types.go | Introduces shared BodyFormat type. |
| pkg/kgateway/extensions2/pluginutils/pluginutils.go | Adds EnvoyBodyFormat helper. |
| pkg/kgateway/extensions2/pluginutils/headers.go | Adds ConvertHeaderFilter, ConvertMutationsToOptions, resolveHeader. |
| pkg/kgateway/extensions2/plugins/trafficpolicy/header_modifiers.go | Refactored to use shared header-filter helpers. |
| pkg/kgateway/extensions2/plugins/directresponse/direct_response_plugin.go | Uses pluginutils.EnvoyBodyFormat. |
| pkg/kgateway/extensions2/plugins/listenerpolicy/local_reply_converter.go | New translator for local reply config. |
| pkg/kgateway/extensions2/plugins/listenerpolicy/common.go | Moves access-log filter translation here for reuse. |
| pkg/kgateway/extensions2/plugins/listenerpolicy/access_logging_converter.go | Removes filter translation now in common.go. |
| pkg/kgateway/extensions2/plugins/listenerpolicy/http.go | Wires localReplyConfig into IR/Equals. |
| pkg/kgateway/extensions2/plugins/listenerpolicy/listener_plugin.go | Applies LocalReplyConfig to HCM. |
| pkg/kgateway/extensions2/plugins/listenerpolicy/merge_http.go | Adds merge function for local reply config. |
| install/helm/kgateway-crds/templates/gateway.kgateway.dev_httplistenerpolicies.yaml | CRD updates for new fields and uint32 value format. |
| pkg/kgateway/translator/gateway/gateway_translator_test.go | New translator tests for local reply config. |
| pkg/kgateway/translator/gateway/testutils/inputs/{,http}listenerpolicy/local-reply-config.yaml | Translator test inputs. |
| pkg/kgateway/translator/gateway/testutils/outputs/{,http}listenerpolicy/local-reply-config.yaml | Expected translator outputs. |
| test/e2e/features/listener_policy/{suite,types}.go | E2E test cases and manifest registration. |
| test/e2e/features/listener_policy/testdata/{listener-policy-local-reply-config,local-reply-httproute}.yaml | E2E manifests. |
Files not reviewed (2)
- api/v1alpha1/kgateway/zz_generated.deepcopy.go: Language not supported
- api/v1alpha1/shared/zz_generated.deepcopy.go: Language not supported
5dc034e to
9dff0bb
Compare
509a702 to
7e8e3b3
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 29 out of 32 changed files in this pull request and generated 7 comments.
Files not reviewed (2)
- api/v1alpha1/kgateway/zz_generated.deepcopy.go: Language not supported
- api/v1alpha1/shared/zz_generated.deepcopy.go: Language not supported
|
/retest |
|
This is a feature we really would appreciate. Any way of nudging it along to release? PS. Thank you for your work @marvin-roesch |
|
@marvin-roesch can you please rebase with the latest main? Thanks |
cb1f4b2 to
5a5d1ed
Compare
|
Rebased, @davidjumani. |
Signed-off-by: Marvin Rösch <[email protected]>
Signed-off-by: Marvin Rösch <[email protected]>
Signed-off-by: Marvin Rösch <[email protected]>
Signed-off-by: Marvin Rösch <[email protected]>
Signed-off-by: Marvin Rösch <[email protected]>
Signed-off-by: Marvin Rösch <[email protected]>
5a5d1ed to
252957f
Compare
252957f to
12baa37
Compare
|
@puertomontt I have rebased onto |
Signed-off-by: Marvin Rösch <[email protected]>
12baa37 to
7876b0a
Compare
|
/retest |
Description
Motivation: Envoy by default produces plaintext local replies for errors etc., which can lead to unexpected output on endpoints that expose e.g. a JSON-based API. Being able to configure a custom default format but also adjusting individual replies based on filters (e.g. changing 403 replies from RBAC filters into 404s) is very helpful for these scenarious.
What changed: We implement an extension of the
ListenerPolicyHTTP settings that maps to Envoy's local reply config. It shares types with the access log filter config as these are also shared in Envoy's API.Related issues: Closes #3466
Change Type
Changelog
Additional Notes
This has some overlap with #13436. The custom response filter can cover what the local reply config does using the newly introduced
envoy.matching.inputs.local_replyinput. However, there currently is a bug (envoyproxy/envoy#45346`) where Envoy does not expose the original local reply body within that filter, so it has limited utility, unfortunately.This does not prevent a policy extension for the custom response filter to be introduced later, however. The features complement each other, where the local reply config applies to all replies generated by a listener, including those not covered by any filter.