From 6d4db011ee8c88d4c656ff2c42c65e75515a6578 Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 29 Jun 2026 13:16:06 +0800 Subject: [PATCH 01/18] split lua with listener and route - Added a Luas field to the listener-level EnvoyExtensions struct so listener-scoped Lua policies can be represented separately from per-route ones. - Refactored to add HCM placeholder filters for both per-route Lua slots and listener-level Lua filters (using named Lua HCM filters with empty default source). Listener filters are appended after route-slot filters to preserve ordering after HCM filter reversal. The Disabled: true flag was removed from listener Lua HCM filters since they are always active for the listener. - New implementation that injects listener-level Lua source code and filter context into RouteConfiguration.TypedPerFilterConfig, delivering script changes via RDS to avoid listener drains. Signed-off-by: zirain --- internal/gatewayapi/envoyextensionpolicy.go | 51 ++-- ...h-invalid-lua-validation-disabled.out.yaml | 5 +- ...ith-invalid-lua-validation-syntax.out.yaml | 5 +- ...yextensionpolicy-with-invalid-lua.out.yaml | 19 +- ...xtensionpolicy-with-lua-configmap.out.yaml | 49 +--- .../envoyextensionpolicy-with-lua.out.yaml | 18 +- internal/ir/xds.go | 6 +- internal/ir/zz_generated.deepcopy.go | 5 + internal/xds/translator/api_key_auth.go | 4 + internal/xds/translator/authorization.go | 4 + internal/xds/translator/bandwidth_limit.go | 4 + internal/xds/translator/basicauth.go | 4 + internal/xds/translator/compressor.go | 4 + internal/xds/translator/cors.go | 4 + internal/xds/translator/credentialInjector.go | 4 + internal/xds/translator/custom_response.go | 4 + .../xds/translator/dynamic_forward_proxy.go | 4 + internal/xds/translator/dynamicmodule.go | 4 + internal/xds/translator/extauth.go | 4 + internal/xds/translator/extproc.go | 4 + internal/xds/translator/fault.go | 4 + internal/xds/translator/geoip.go | 4 + internal/xds/translator/header_mutation.go | 4 + internal/xds/translator/healthcheck.go | 4 + internal/xds/translator/httpfilters.go | 21 +- internal/xds/translator/jwt.go | 4 + internal/xds/translator/listener.go | 2 + internal/xds/translator/local_ratelimit.go | 4 + internal/xds/translator/lua.go | 250 ++++++++++++++---- internal/xds/translator/oidc.go | 4 + internal/xds/translator/request_buffer.go | 4 + .../xds/translator/session_persistence.go | 4 + .../translator/testdata/in/xds-ir/lua.yaml | 82 ++++++ .../testdata/out/xds-ir/lua.clusters.yaml | 23 ++ .../testdata/out/xds-ir/lua.endpoints.yaml | 12 + .../testdata/out/xds-ir/lua.listeners.yaml | 85 ++++++ internal/xds/translator/translator.go | 4 + internal/xds/translator/wasm.go | 4 + test/e2e/testdata/lua-http.yaml | 19 ++ test/e2e/tests/lua_http.go | 84 +++--- 40 files changed, 651 insertions(+), 177 deletions(-) diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index 723dd57c3e..2fd6b2e36c 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -946,12 +946,35 @@ func (t *Translator) translateEnvoyExtensionPolicyForListeners( listenerNames.Insert(irListenerName(listener)) } - routesWithDirectResponse := sets.New[string]() + failed := luaError != nil + if wasmError != nil { + failed = failed || !wasmFailOpen + } + if extProcError != nil { + failed = failed || !extProcFailOpen + } + if dynamicModuleError != nil { + failed = true + } + for _, http := range x.HTTP { if !listenerNames.Has(http.Name) { continue } + // if already set - there's a specific level policy, so skip + if http.EnvoyExtensions != nil { + continue + } + + // TODO: move other extensions to listener level. + totalExtensions := len(luas) + if totalExtensions > 0 { + http.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ + Luas: luas, + } + } + // A Policy targeting the specific scope(xRoute rule, xRoute, Gateway // listener, ListenerSet listener) wins over a policy targeting a lesser // specific scope(Gateway/ListenerSet). @@ -961,43 +984,19 @@ func (t *Translator) translateEnvoyExtensionPolicyForListeners( continue } - failRoute := false - // Lua extension doesn't have a fail open option, so fail the route if there is a lua error - // TODO: we may also add fail open option for Lua extension to align with other extensions - if luaError != nil { - failRoute = true - } - if wasmError != nil { - failRoute = failRoute || !wasmFailOpen - } - if extProcError != nil { - failRoute = failRoute || !extProcFailOpen - } - if dynamicModuleError != nil { - failRoute = true - } - if failRoute { + if failed { r.DirectResponse = &ir.CustomResponse{ StatusCode: new(uint32(500)), } - routesWithDirectResponse.Insert(r.Name) } else { r.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ ExtProcs: extProcs, Wasms: wasms, - Luas: luas, DynamicModules: dynamicModules, } } } } - if len(routesWithDirectResponse) > 0 { - t.Logger.Info("setting 500 direct response in routes due to errors in EnvoyExtensionPolicy", - "policy", fmt.Sprintf("%s/%s", policy.Namespace, policy.Name), - "routes", sets.List(routesWithDirectResponse), - "error", errs, - ) - } return errs } diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua-validation-disabled.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua-validation-disabled.out.yaml index 68b4e397ba..0c418ae76a 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua-validation-disabled.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua-validation-disabled.out.yaml @@ -208,15 +208,14 @@ xdsIR: weight: 1 envoyExtensions: luas: - - Code: | + - code: | function envoy_on_response(response_handle) local value = 10 if value > 5 print("Value is greater than 5") end end - FilterContext: null - Name: envoyextensionpolicy/default/policy-for-http-route/lua/0 + name: envoyextensionpolicy/default/policy-for-http-route/lua/0 hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua-validation-syntax.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua-validation-syntax.out.yaml index b79ae5ac67..577c10e453 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua-validation-syntax.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua-validation-syntax.out.yaml @@ -298,7 +298,7 @@ xdsIR: weight: 1 envoyExtensions: luas: - - Code: | + - code: | local json = require("json") function envoy_on_response(response_handle) local content_type = response_handle:headers():get("content-type") @@ -317,8 +317,7 @@ xdsIR: end return envoy.lua.ResponseStatus.Continue end - FilterContext: null - Name: envoyextensionpolicy/default/policy-for-http-route/lua/0 + name: envoyextensionpolicy/default/policy-for-http-route/lua/0 hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml index 8c9e4d42ab..f99cfd8e77 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml @@ -253,6 +253,11 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') + end + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 externalPort: 80 hostnames: - '*' @@ -288,12 +293,7 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - luas: - - Code: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 + envoyExtensions: {} hostname: www.example.com isHTTP2: false metadata: @@ -324,12 +324,7 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 + envoyExtensions: {} hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml index df57f5706f..ea2cdfcc1e 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml @@ -425,6 +425,13 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo('Goodbye.') + end + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 externalPort: 80 hostnames: - '*' @@ -460,14 +467,7 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo('Goodbye.') - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 + envoyExtensions: {} hostname: www.example.com isHTTP2: false metadata: @@ -500,14 +500,7 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo('Goodbye.') - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 + envoyExtensions: {} hostname: www.example.com isHTTP2: false metadata: @@ -540,14 +533,7 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo('Goodbye.') - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 + envoyExtensions: {} hostname: www.example.com isHTTP2: false metadata: @@ -580,13 +566,13 @@ xdsIR: weight: 1 envoyExtensions: luas: - - Code: | + - code: | function envoy_on_response(response_handle) response_handle:logWarn('Goodbye.') end - FilterContext: + filterContext: token_header: x-session-token - Name: envoyextensionpolicy/default/policy-for-http-route/lua/0 + name: envoyextensionpolicy/default/policy-for-http-route/lua/0 hostname: www.example.com isHTTP2: false metadata: @@ -617,14 +603,7 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo('Goodbye.') - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 + envoyExtensions: {} hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml index 29bfd408e5..af0a07e945 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml @@ -244,6 +244,11 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') + end + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 externalPort: 80 hostnames: - '*' @@ -279,12 +284,12 @@ xdsIR: weight: 1 envoyExtensions: luas: - - Code: function envoy_on_response(response_handle) response_handle:logWarn('Goodbye.') + - code: function envoy_on_response(response_handle) response_handle:logWarn('Goodbye.') end - FilterContext: + filterContext: mode: strict token_header: x-api-key - Name: envoyextensionpolicy/default/policy-for-http-route/lua/0 + name: envoyextensionpolicy/default/policy-for-http-route/lua/0 hostname: www.example.com isHTTP2: false metadata: @@ -315,12 +320,7 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 + envoyExtensions: {} hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/ir/xds.go b/internal/ir/xds.go index a1cf02a509..b30abb792f 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -400,6 +400,8 @@ type HTTPListener struct { MatchBackendScheme bool `json:"matchBackendScheme,omitempty" yaml:"matchBackendScheme,omitempty"` // RequestID defines configuration for the UUID request ID extension. RequestID *RequestIDExtensionAction `json:"requestID,omitempty" yaml:"requestID,omitempty"` + // EnvoyExtension holds the features associated with EnvoyExtensionPolicy + EnvoyExtensions *EnvoyExtensionFeatures `json:"envoyExtensions,omitempty" yaml:"envoyExtensions,omitempty"` } // Validate the fields within the HTTPListener structure @@ -3893,10 +3895,10 @@ type Lua struct { // The xds translator only generates one Lua filter for each unique name Name string // Code is the Lua source code - Code *string + Code *string `json:"code,omitempty" yaml:"code,omitempty"` // FilterContext is the filter context configuration for the Lua script. // This is a JSON object passed to the Lua script via request_handle:filterContext(). - FilterContext *apiextensionsv1.JSON + FilterContext *apiextensionsv1.JSON `json:"filterContext,omitempty" yaml:"filterContext,omitempty"` } // Wasm holds the information associated with the Wasm extensions. diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 252d73c925..248aaa3b98 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2442,6 +2442,11 @@ func (in *HTTPListener) DeepCopyInto(out *HTTPListener) { *out = new(RequestIDExtensionAction) **out = **in } + if in.EnvoyExtensions != nil { + in, out := &in.EnvoyExtensions, &out.EnvoyExtensions + *out = new(EnvoyExtensionFeatures) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPListener. diff --git a/internal/xds/translator/api_key_auth.go b/internal/xds/translator/api_key_auth.go index cfbaf29152..a8c84835f4 100644 --- a/internal/xds/translator/api_key_auth.go +++ b/internal/xds/translator/api_key_auth.go @@ -176,3 +176,7 @@ func buildAPIKeyAuthFilterPerRouteConfig(apiKeyAuth *ir.APIKeyAuth) *apikeyauthv Forwarding: apiKeyAuthProto.Forwarding, } } + +func (*apiKeyAuth) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/authorization.go b/internal/xds/translator/authorization.go index d90257b090..b8a5a74af1 100644 --- a/internal/xds/translator/authorization.go +++ b/internal/xds/translator/authorization.go @@ -940,3 +940,7 @@ func wrapPredicateWithNot(predicate *matcherv3.Matcher_MatcherList_Predicate, in }, } } + +func (*rbac) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/bandwidth_limit.go b/internal/xds/translator/bandwidth_limit.go index 02e5d63bf8..605aaff883 100644 --- a/internal/xds/translator/bandwidth_limit.go +++ b/internal/xds/translator/bandwidth_limit.go @@ -182,3 +182,7 @@ func buildBandwidthLimitResponseProto(cfg *ir.BandwidthLimitConfig) *bwlimitv3.B } return proto } + +func (*bandwidthLimit) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/basicauth.go b/internal/xds/translator/basicauth.go index bbf4b3f511..a783bcbb4d 100644 --- a/internal/xds/translator/basicauth.go +++ b/internal/xds/translator/basicauth.go @@ -163,3 +163,7 @@ func basicAuthPerRouteConfig(basicAuth *ir.BasicAuth) *basicauthv3.BasicAuthPerR }, } } + +func (*basicAuth) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/compressor.go b/internal/xds/translator/compressor.go index ddc35d6d6a..02686c14fb 100644 --- a/internal/xds/translator/compressor.go +++ b/internal/xds/translator/compressor.go @@ -195,3 +195,7 @@ func compressorPerRouteConfig() *compressorv3.CompressorPerRoute { }, } } + +func (*compressor) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/cors.go b/internal/xds/translator/cors.go index 5aff0a80e9..ac79a5110e 100644 --- a/internal/xds/translator/cors.go +++ b/internal/xds/translator/cors.go @@ -202,3 +202,7 @@ func hasWildcard(array []string) bool { func (c *cors) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { return nil } + +func (*cors) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/credentialInjector.go b/internal/xds/translator/credentialInjector.go index d647e7f1a4..21a59713ba 100644 --- a/internal/xds/translator/credentialInjector.go +++ b/internal/xds/translator/credentialInjector.go @@ -160,3 +160,7 @@ func (*credentialInjector) patchRoute(route *routev3.Route, irRoute *ir.HTTPRout } return nil } + +func (*credentialInjector) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/custom_response.go b/internal/xds/translator/custom_response.go index 65977b6791..63b0c23260 100644 --- a/internal/xds/translator/custom_response.go +++ b/internal/xds/translator/custom_response.go @@ -524,3 +524,7 @@ func (c *customResponse) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, } return nil } + +func (c *customResponse) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/dynamic_forward_proxy.go b/internal/xds/translator/dynamic_forward_proxy.go index fe598d19b3..cdc67c45a9 100644 --- a/internal/xds/translator/dynamic_forward_proxy.go +++ b/internal/xds/translator/dynamic_forward_proxy.go @@ -234,3 +234,7 @@ func buildDFPLoopbackRBACPerRoute(irRoute *ir.HTTPRoute) (*rbacv3.RBACPerRoute, }, }, nil } + +func (*dynamicForwardProxy) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/dynamicmodule.go b/internal/xds/translator/dynamicmodule.go index c117d29054..a3474f1deb 100644 --- a/internal/xds/translator/dynamicmodule.go +++ b/internal/xds/translator/dynamicmodule.go @@ -210,3 +210,7 @@ func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ } return nil } + +func (*dynamicModule) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go index 2405ba505b..e6482f6993 100644 --- a/internal/xds/translator/extauth.go +++ b/internal/xds/translator/extauth.go @@ -329,3 +329,7 @@ func convertContextExtensions(irCtxExts []*ir.ContextExtention) map[string]strin return ctxExts } + +func (*extAuth) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go index 846796d76b..06b49325c4 100644 --- a/internal/xds/translator/extproc.go +++ b/internal/xds/translator/extproc.go @@ -276,3 +276,7 @@ func translateExtProcBodyProcessingMode(mode *ir.ExtProcBodyProcessingMode) extp } return extprocv3.ProcessingMode_NONE } + +func (*extProc) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/fault.go b/internal/xds/translator/fault.go index 142fd58ea1..2dadbc8a77 100644 --- a/internal/xds/translator/fault.go +++ b/internal/xds/translator/fault.go @@ -174,3 +174,7 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTP return nil } + +func (*fault) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/geoip.go b/internal/xds/translator/geoip.go index b70c98bf99..7eab5d2268 100644 --- a/internal/xds/translator/geoip.go +++ b/internal/xds/translator/geoip.go @@ -299,3 +299,7 @@ func (*geoip) patchRoute(*routev3.Route, *ir.HTTPRoute, *ir.HTTPListener) error func (*geoip) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { return nil } + +func (*geoip) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/header_mutation.go b/internal/xds/translator/header_mutation.go index 7281c3f645..c5bc0f8906 100644 --- a/internal/xds/translator/header_mutation.go +++ b/internal/xds/translator/header_mutation.go @@ -162,3 +162,7 @@ func buildHeaderMutationRules(addHeaders []ir.AddHeader, removeHeaders []string, return mutationRules } + +func (*headerMutation) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/healthcheck.go b/internal/xds/translator/healthcheck.go index 6551aa61fa..2daf1150b4 100644 --- a/internal/xds/translator/healthcheck.go +++ b/internal/xds/translator/healthcheck.go @@ -101,3 +101,7 @@ func (*healthCheck) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) func (*healthCheck) patchRoute(_ *routev3.Route, _ *ir.HTTPRoute, _ *ir.HTTPListener) error { return nil } + +func (*healthCheck) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index d365dcd866..c439433980 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -58,6 +58,9 @@ type httpFilter interface { // patchRoute patches the provide Route with a filter's Route level configuration. patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, httpListener *ir.HTTPListener) error + // patchRoute patches the provider RouteConfiguration. + patchRouteConfiguration(rc *routev3.RouteConfiguration, httpListener *ir.HTTPListener) error + // patchResources adds all the other needed resources referenced by this // filter to the resource version table. // for example: @@ -124,7 +127,12 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter { case isFilterType(filter, egv1a1.EnvoyFilterBuffer): order = 11 case isFilterType(filter, egv1a1.EnvoyFilterLua): - order = 12 + mustGetFilterIndex(filter.Name) + if strings.Contains(filter.Name, "/listener/") { + // Listener-level Lua runs before route-level Lua (12+idx vs 62+idx). + order = 12 + mustGetFilterIndex(filter.Name) + } else { + order = 62 + mustGetFilterIndex(filter.Name) + } case isFilterType(filter, egv1a1.EnvoyFilterExtProc): order = 100 + mustGetFilterIndex(filter.Name) case isFilterType(filter, egv1a1.EnvoyFilterWasm): @@ -339,6 +347,17 @@ func patchRouteWithPerRouteConfig(route *routev3.Route, irRoute *ir.HTTPRoute, h return nil } +// patchRouteConfiguration +func patchRouteConfiguration(rc *routev3.RouteConfiguration, httpListener *ir.HTTPListener) error { + for _, filter := range httpFilters { + if err := filter.patchRouteConfiguration(rc, httpListener); err != nil { + return err + } + } + + return nil +} + // isFilterType returns true if the filter is the provided filter type. func isFilterType(filter *hcmv3.HttpFilter, filterType egv1a1.EnvoyFilter) bool { // Multiple filters of the same types are added to the HCM filter chain, one for each diff --git a/internal/xds/translator/jwt.go b/internal/xds/translator/jwt.go index 1fe48a4944..45ab1fd5fd 100644 --- a/internal/xds/translator/jwt.go +++ b/internal/xds/translator/jwt.go @@ -508,3 +508,7 @@ func buildJwtFromHeaders(headers []egv1a1.JWTHeaderExtractor) []*jwtauthnv3.JwtH return jwtHeaders } + +func (*jwt) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index be3e2eb136..41e86b74db 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -1364,3 +1364,5 @@ func buildRequestIDExtension(requestID *ir.RequestIDExtensionAction) *hcmv3.Requ TypedConfig: requestIDConfig, } } + +const FilterChainFilterNamePrefixForEEP = "envoy.filters.http.filter_chain.eep." diff --git a/internal/xds/translator/local_ratelimit.go b/internal/xds/translator/local_ratelimit.go index f527740123..bc3570375d 100644 --- a/internal/xds/translator/local_ratelimit.go +++ b/internal/xds/translator/local_ratelimit.go @@ -483,3 +483,7 @@ func buildQueryParamMatchLocalRateLimitActions( *descriptorEntries = append(*descriptorEntries, entry) } } + +func (*localRateLimit) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/lua.go b/internal/xds/translator/lua.go index 3186afdb46..4e0e02a67b 100644 --- a/internal/xds/translator/lua.go +++ b/internal/xds/translator/lua.go @@ -7,15 +7,19 @@ package translator import ( "errors" + "fmt" + "slices" + "strconv" corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + filterchainv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/filter_chain/v3" luafilterv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/lua/v3" hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" + "k8s.io/utils/ptr" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" @@ -30,8 +34,20 @@ type lua struct{} var _ httpFilter = &lua{} -// patchHCM builds and appends the lua Filters to the HTTP Connection Manager -// Lua filters are created in disabled mode. +// patchHCM adds disabled envoy.filters.http.filter_chain placeholder filters to the HTTP +// Connection Manager: one for per-listener (per-connection) Lua and one for per-route Lua. +// +// Both placeholders are added together as soon as either scope has a Lua policy anywhere on +// this listener, even if the other scope currently has none. This keeps the HCM's filter set +// stable across that kind of policy churn too: e.g. adding a per-listener Lua policy later to +// a listener that already has per-route Lua only changes route/virtual host +// TypedPerFilterConfig (an RDS update), never the listener's filter list (which would require +// an LDS update and a connection drain). +// +// Envoy's LuaPerRoute API can only override one script for one filter instance, while EG's +// EnvoyExtensionPolicy API allows an ordered list of Lua filters per listener/route. The +// filter_chain filter wraps an ordered, named sub-chain of Lua filters that is supplied +// separately (per virtual host for listener-scoped Lua, per route for route-scoped Lua). func (*lua) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { if mgr == nil { return errors.New("hcm is nil") @@ -40,67 +56,81 @@ func (*lua) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListen return errors.New("ir listener is nil") } - var errs error - for _, route := range irListener.Routes { - if !routeContainsLua(route) { + hasListenerLua := irListener.EnvoyExtensions != nil && len(irListener.EnvoyExtensions.Luas) > 0 + hasRouteLua := slices.ContainsFunc(irListener.Routes, routeContainsLua) + if !hasListenerLua && !hasRouteLua { + return nil + } + + for _, filterName := range []string{luaListenerFCFilterName(), luaFCFilterName()} { + if hcmContainsFilter(mgr, filterName) { continue } - for _, ep := range route.EnvoyExtensions.Luas { - if hcmContainsFilter(mgr, luaFilterName(ep)) { - continue - } - filter, err := buildHCMLuaFilter(ep) - if err != nil { - errs = errors.Join(errs, err) - continue - } - mgr.HttpFilters = append(mgr.HttpFilters, filter) + filter, err := buildHCMFilterChainFilter(filterName) + if err != nil { + return err } + mgr.HttpFilters = append(mgr.HttpFilters, filter) } - return errs + return nil +} + +// luaFCFilterName returns the stable HCM-level filter name for the per-route Lua +// filter_chain placeholder. +func luaFCFilterName() string { + return FilterChainFilterNamePrefixForEEP + "lua" +} + +// luaListenerFCFilterName returns the stable HCM-level filter name for the per-listener +// (per-connection) Lua filter_chain placeholder. +func luaListenerFCFilterName() string { + return FilterChainFilterNamePrefixForEEP + "lua.listener" } -// buildHCMLuaFilter returns a Lua filter for HCM. -func buildHCMLuaFilter(lua ir.Lua) (*hcmv3.HttpFilter, error) { +func buildHCMFilterChainFilter(filterName string) (*hcmv3.HttpFilter, error) { var ( - luaProto *luafilterv3.Lua - luaAny *anypb.Any - err error + fcProto *filterchainv3.FilterChainConfig + fcAny *anypb.Any + err error ) - luaProto = &luafilterv3.Lua{ - DefaultSourceCode: &corev3.DataSource{ - Specifier: &corev3.DataSource_InlineString{ - InlineString: *lua.Code, - }, - }, - } - if err = luaProto.ValidateAll(); err != nil { + fcProto = &filterchainv3.FilterChainConfig{} + + if err = fcProto.ValidateAll(); err != nil { return nil, err } - if luaAny, err = anypb.New(luaProto); err != nil { + if fcAny, err = anypb.New(fcProto); err != nil { return nil, err } return &hcmv3.HttpFilter{ - Name: luaFilterName(lua), + Name: filterName, Disabled: true, ConfigType: &hcmv3.HttpFilter_TypedConfig{ - TypedConfig: luaAny, + TypedConfig: fcAny, }, }, nil } -func luaFilterName(lua ir.Lua) string { - return perRouteFilterName(egv1a1.EnvoyFilterLua, lua.Name) +// luaFilterName returns the stable top-level filter name for the per-route Lua slot index. +// The index is the execution slot within the ordered EnvoyExtensionPolicy Lua +// list, so route 0th scripts always bind to the same listener-level filter. +func luaFilterName(idx int) string { + return perRouteFilterName(egv1a1.EnvoyFilterLua, strconv.Itoa(idx)) +} + +// luaListenerFilterName returns the stable HCM-level filter name for a listener-level +// Lua slot. Using the envoy.filters.http.lua prefix (instead of the raw policy name) +// ensures sortHTTPFilters assigns it the correct order relative to route-level slots. +func luaListenerFilterName(idx int) string { + return fmt.Sprintf("%s/listener/%d", egv1a1.EnvoyFilterLua, idx) } -// routeContainsLua returns true if Luas exists for the provided route. +// routeContainsLua returns true if the route has any Lua extensions. func routeContainsLua(irRoute *ir.HTTPRoute) bool { if irRoute == nil { return false } - return irRoute.EnvoyExtensions != nil && len(irRoute.EnvoyExtensions.Luas) > 0 } @@ -109,8 +139,11 @@ func (*lua) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) err return nil } -// patchRoute patches the provided route so Lua filters are enabled if applicable. -func (*lua) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPListener) error { +// patchRoute patches the provided route with LuaPerRoute so the Lua filter runs with the route's script. +// Routes with no Lua entries fall back to the listener-level Lua inherited from the virtual host. +// Only routes with their own Lua entries disable the inherited listener-level Lua and install +// their own scripts in its place. +func (*lua) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener *ir.HTTPListener) error { if route == nil { return errors.New("xds route is nil") } @@ -121,32 +154,139 @@ func (*lua) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPLi return nil } - for _, ep := range irRoute.EnvoyExtensions.Luas { - filterName := luaFilterName(ep) - routeCfg, err := buildLuaRouteFilterConfig(ep) - if err != nil { + // Disable the inherited listener-level Lua whenever EnvoyExtensions was set by a + // more-specific route policy (FromGatewayPolicy is false/nil). The extension count + // is intentionally not checked here: an empty result (e.g. fail-open invalid Wasm) + // still represents a more-specific policy that owns this route and must suppress the + // lower-scope Lua. When FromGatewayPolicy is true the route-level extensions come + // from the same gateway/listener policy that also installed the listener Lua, so both coexist. + disableListenerLevelFilter := !ptr.Deref(irRoute.EnvoyExtensions.FromGatewayPolicy, false) + + // Route has its own Lua entries — disable the inherited listener-level Lua and + // install the route's scripts instead. + if irListener != nil && irListener.EnvoyExtensions != nil && len(irListener.EnvoyExtensions.Luas) > 0 && disableListenerLevelFilter { + if err := enableFilterOnRoute(route, luaListenerFCFilterName(), &routev3.FilterConfig{Disabled: true}); err != nil { return err } - if err := enableFilterOnRoute(route, filterName, routeCfg); err != nil { + } + + if route.TypedPerFilterConfig == nil { + route.TypedPerFilterConfig = make(map[string]*anypb.Any) + } + filterChainConfigPerRoute := &filterchainv3.FilterChainConfigPerRoute{ + FilterChain: &filterchainv3.FilterChain{}, + } + for idx, ep := range irRoute.EnvoyExtensions.Luas { + filterName := luaFilterName(idx) + luaOnFCFilter := &luafilterv3.Lua{ + DefaultSourceCode: &corev3.DataSource{ + Specifier: &corev3.DataSource_InlineString{ + InlineString: *ep.Code, + }, + }, + } + + // TODO: support filterContext in Lua filter make this simpler + if ep.FilterContext != nil && ep.FilterContext.Raw != nil { + luaPerRoute := &luafilterv3.LuaPerRoute{} + filterCtx := &structpb.Struct{} + if err := protojson.Unmarshal(ep.FilterContext.Raw, filterCtx); err != nil { + return err + } + luaPerRoute.FilterContext = filterCtx + luaPerRouteAny, err := anypb.New(luaPerRoute) + if err != nil { + return err + } + route.TypedPerFilterConfig[filterName] = luaPerRouteAny + } + luaOnFCFilterAny, err := anypb.New(luaOnFCFilter) + if err != nil { return err } + filterChainConfigPerRoute.FilterChain.Filters = append(filterChainConfigPerRoute.FilterChain.Filters, + &corev3.TypedExtensionConfig{ + Name: filterName, + TypedConfig: luaOnFCFilterAny, + }, + ) + } + + if len(filterChainConfigPerRoute.FilterChain.Filters) == 0 { + return nil + } + fcAny, err := anypb.New(filterChainConfigPerRoute) + if err != nil { + return err } + + route.TypedPerFilterConfig[luaFCFilterName()] = fcAny return nil } -func buildLuaRouteFilterConfig(lua ir.Lua) (proto.Message, error) { - if lua.FilterContext == nil || lua.FilterContext.Raw == nil { - return &routev3.FilterConfig{ - Config: &anypb.Any{}, - }, nil +// patchVirtualHost delivers listener-level Lua source at VirtualHost scope so that a listener's +// Lua policy does not bleed into virtual hosts belonging to a different listener that shares the +// same RouteConfiguration (cleartext listeners on the same port). Delivery via VirtualHost +// TypedPerFilterConfig still goes through RDS, so Lua script changes do not trigger listener drains. +func (*lua) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListener) error { + if httpListener.EnvoyExtensions == nil || len(httpListener.EnvoyExtensions.Luas) == 0 { + return nil } - filterCtx := &structpb.Struct{} - if err := protojson.Unmarshal(lua.FilterContext.Raw, filterCtx); err != nil { - return nil, err + filterName := luaListenerFCFilterName() + if vh.TypedPerFilterConfig != nil && vh.TypedPerFilterConfig[filterName] != nil { + // Already delivered for this VirtualHost, e.g. because patchVirtualHost was called + // again for a different IR listener sharing the same RouteConfiguration. + return nil } - return &luafilterv3.LuaPerRoute{ - FilterContext: filterCtx, - }, nil + if vh.TypedPerFilterConfig == nil { + vh.TypedPerFilterConfig = map[string]*anypb.Any{} + } + + filterChainConfigPerRoute := &filterchainv3.FilterChainConfigPerRoute{ + FilterChain: &filterchainv3.FilterChain{}, + } + for i, ep := range httpListener.EnvoyExtensions.Luas { + subFilterName := luaListenerFilterName(i) + luaOnFCFilter := &luafilterv3.Lua{ + DefaultSourceCode: &corev3.DataSource{ + Specifier: &corev3.DataSource_InlineString{ + InlineString: *ep.Code, + }, + }, + } + + // TODO: support filterContext in Lua filter make this simpler + if ep.FilterContext != nil && ep.FilterContext.Raw != nil { + luaPerRoute := &luafilterv3.LuaPerRoute{} + filterCtx := &structpb.Struct{} + if err := protojson.Unmarshal(ep.FilterContext.Raw, filterCtx); err != nil { + return err + } + luaPerRoute.FilterContext = filterCtx + luaPerRouteAny, err := anypb.New(luaPerRoute) + if err != nil { + return err + } + vh.TypedPerFilterConfig[subFilterName] = luaPerRouteAny + } + luaOnFCFilterAny, err := anypb.New(luaOnFCFilter) + if err != nil { + return err + } + filterChainConfigPerRoute.FilterChain.Filters = append(filterChainConfigPerRoute.FilterChain.Filters, + &corev3.TypedExtensionConfig{ + Name: subFilterName, + TypedConfig: luaOnFCFilterAny, + }, + ) + } + + fcAny, err := anypb.New(filterChainConfigPerRoute) + if err != nil { + return err + } + vh.TypedPerFilterConfig[filterName] = fcAny + return nil } diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index fba5f7da53..5a3a0e734a 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -600,3 +600,7 @@ func (*oidc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPL route.TypedPerFilterConfig[string(egv1a1.EnvoyFilterOAuth2)] = oauth2Any return nil } + +func (*oidc) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/request_buffer.go b/internal/xds/translator/request_buffer.go index 231506e34b..1ee01a56c7 100644 --- a/internal/xds/translator/request_buffer.go +++ b/internal/xds/translator/request_buffer.go @@ -145,3 +145,7 @@ func buildRequestBufferPerRouteProto(spec *ir.RequestBuffer) (*anypb.Any, error) func routeContainsRequestBuffer(route *ir.HTTPRoute) bool { return route.Traffic != nil && route.Traffic.RequestBuffer != nil } + +func (*requestBuffer) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/session_persistence.go b/internal/xds/translator/session_persistence.go index 114672a7cd..2709f228fd 100644 --- a/internal/xds/translator/session_persistence.go +++ b/internal/xds/translator/session_persistence.go @@ -232,3 +232,7 @@ func (s *sessionPersistence) patchRoute(route *routev3.Route, irRoute *ir.HTTPRo func (s *sessionPersistence) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) error { return nil } + +func (*sessionPersistence) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/internal/xds/translator/testdata/in/xds-ir/lua.yaml b/internal/xds/translator/testdata/in/xds-ir/lua.yaml index fddfa9a4a7..88f2d9d11a 100644 --- a/internal/xds/translator/testdata/in/xds-ir/lua.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/lua.yaml @@ -1,4 +1,5 @@ http: +# Lua filter per route only - address: 0.0.0.0 hostnames: - '*' @@ -61,3 +62,84 @@ http: response_handle:logError('Hello.') end name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/1 +# Lua filter per route +- address: 0.0.0.0 + hostnames: + - '*' + name: envoy-gateway/gateway-1/http-2 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) + request_handle:logInfo('Goodbye from gateway.') + end + name: envoyextensionpolicy/default/policy-for-gateway/lua/0 + filterContext: + token_header: x-api-key + mode: strict + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10081 + routes: + - destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-3/rule/0/backend/0 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-3/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) + request_handle:logInfo('Goodbye.') + end + name: envoyextensionpolicy/default/policy-for-http-route/lua/0 + filterContext: + token_header: x-api-key + mode: strict +# Lua filter per listener +- address: 0.0.0.0 + hostnames: + - '*' + name: envoy-gateway/gateway-1/http-3 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) + request_handle:logInfo('Goodbye from gateway.') + end + name: envoyextensionpolicy/default/policy-for-gateway/lua/0 + filterContext: + token_header: x-api-key + mode: strict + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10082 + routes: + - destination: + name: httproute/default/httproute-3/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-3/rule/0/backend/0 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-3/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml index d1b786402b..ad4ad66bbe 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml @@ -44,3 +44,26 @@ name: httproute/default/httproute-2/rule/0 perConnectionBufferLimitBytes: 32768 type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-3/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-3/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml index 05442a9a15..dadc93ba2d 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml @@ -22,3 +22,15 @@ loadBalancingWeight: 1 locality: region: httproute/default/httproute-2/rule/0/backend/0 +- clusterName: httproute/default/httproute-3/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-3/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml index d7d641dd2d..edf8da8056 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml @@ -54,3 +54,88 @@ maxConnectionsToAcceptPerSocketEvent: 1 name: envoy-gateway/gateway-1/http perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10081 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: "" + - name: envoy.filters.http.lua/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: "" + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-2 + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10081 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-2 + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-2 + perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10082 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: "" + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-3 + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10082 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-3 + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-3 + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 87f7ba4f9b..07aba956a0 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -511,6 +511,10 @@ func (t *Translator) processHTTPListenerXdsTranslation( } } + if err = patchRouteConfiguration(xdsRouteCfg, httpListener); err != nil { + errs = errors.Join(errs, err) + } + // Generate xDS virtual hosts and routes for the given HTTPListener, // and add them to the xDS route config. if err = t.addRouteToRouteConfig(tCtx, xdsRouteCfg, httpListener, metrics, http3Settings); err != nil { diff --git a/internal/xds/translator/wasm.go b/internal/xds/translator/wasm.go index 16b3500ab6..7d9d9e728b 100644 --- a/internal/xds/translator/wasm.go +++ b/internal/xds/translator/wasm.go @@ -214,3 +214,7 @@ func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPL } return nil } + +func (*wasm) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { + return nil +} diff --git a/test/e2e/testdata/lua-http.yaml b/test/e2e/testdata/lua-http.yaml index af509b24a4..c93669c4a1 100644 --- a/test/e2e/testdata/lua-http.yaml +++ b/test/e2e/testdata/lua-http.yaml @@ -7,6 +7,7 @@ metadata: spec: parentRefs: - name: same-namespace + - name: all-namespaces hostnames: ["www.example.com"] rules: - matches: @@ -43,6 +44,7 @@ metadata: spec: parentRefs: - name: same-namespace + - name: all-namespaces hostnames: ["www.example.com"] rules: - matches: @@ -101,6 +103,23 @@ data: --- apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy +metadata: + name: lua-for-gateway + namespace: gateway-conformance-infra +spec: + targetRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: same-namespace + lua: + - type: Inline + inline: | + function envoy_on_response(response_handle) + response_handle:headers():add("X-Custom-Response-Header", "gateway") + end +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyExtensionPolicy metadata: name: example-lua-1 namespace: gateway-conformance-infra diff --git a/test/e2e/tests/lua_http.go b/test/e2e/tests/lua_http.go index e2dc561ea4..066fe3355f 100644 --- a/test/e2e/tests/lua_http.go +++ b/test/e2e/tests/lua_http.go @@ -55,20 +55,15 @@ var HTTPLuaTest = suite.ConformanceTest{ Headers: map[string]string{ "X-Custom-Lua-Header": "lua_value_1", }, - AbsentHeaders: []string{"X-Custom-Lua-Another-Header"}, + AbsentHeaders: []string{ + "X-Custom-Response-Header", // gateway policy never took effect + "X-Custom-Lua-Another-Header", + }, }, Namespace: ns, } - req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") - cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) - if err != nil { - t.Errorf("failed to get expected response: %v", err) - } - - if err := http.CompareRoundTrip(t, &req, cReq, cResp, expectedResponse); err != nil { - t.Errorf("failed to compare request and response: %v", err) - } + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) }) t.Run("http route with lua filter 2", func(t *testing.T) { @@ -97,22 +92,17 @@ var HTTPLuaTest = suite.ConformanceTest{ "X-Custom-Lua-Header": "lua_value_2", "X-Custom-Lua-Another-Header": "lua_another_value", }, + AbsentHeaders: []string{ + "X-Custom-Response-Header", // gateway policy never took effect + }, }, Namespace: ns, } - req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") - cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) - if err != nil { - t.Errorf("failed to get expected response: %v", err) - } - - if err := http.CompareRoundTrip(t, &req, cReq, cResp, expectedResponse); err != nil { - t.Errorf("failed to compare request and response: %v", err) - } + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) }) - t.Run("http route without lua filter", func(t *testing.T) { + t.Run("http route fallback to gateway policy", func(t *testing.T) { ns := "gateway-conformance-infra" routeNN := types.NamespacedName{Name: "example-route-3-without-lua", Namespace: ns} gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} @@ -133,21 +123,18 @@ var HTTPLuaTest = suite.ConformanceTest{ Path: "/route3", }, Response: http.Response{ - StatusCodes: []int{200}, - AbsentHeaders: []string{"X-Custom-Lua-Header", "X-Custom-Lua-Another-Header"}, + StatusCodes: []int{200}, + Headers: map[string]string{ + "X-Custom-Response-Header": "gateway", // fallback to gateway policy + }, + AbsentHeaders: []string{ + "X-Custom-Lua-Header", "X-Custom-Lua-Another-Header", + }, }, Namespace: ns, } - req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") - cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) - if err != nil { - t.Errorf("failed to get expected response: %v", err) - } - - if err := http.CompareRoundTrip(t, &req, cReq, cResp, expectedResponse); err != nil { - t.Errorf("failed to compare request and response: %v", err) - } + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) }) t.Run("http route with lua filter context", func(t *testing.T) { @@ -174,6 +161,41 @@ var HTTPLuaTest = suite.ConformanceTest{ Headers: map[string]string{ "X-Lua-Filter-Context": "hello_from_filter_context", }, + AbsentHeaders: []string{ + "X-Custom-Response-Header", // gateway policy never took effect + }, + }, + Namespace: ns, + } + + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) + }) + + t.Run("http route without lua filter", func(t *testing.T) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "example-route-3-without-lua", Namespace: ns} + gwNN := types.NamespacedName{Name: "all-namespaces", Namespace: ns} + gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gwapiv1.HTTPRoute{}, false, routeNN) + + ancestorRef := gwapiv1.ParentReference{ + Group: gatewayapi.GroupPtr(gwapiv1.GroupName), + Kind: gatewayapi.KindPtr(resource.KindGateway), + Namespace: gatewayapi.NamespacePtr(gwNN.Namespace), + Name: gwapiv1.ObjectName(gwNN.Name), + } + EnvoyExtensionPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "example-lua-1", Namespace: ns}, suite.ControllerName, ancestorRef) + + expectedResponse := http.ExpectedResponse{ + Request: http.Request{ + Host: "www.example.com", + Path: "/route3", + }, + Response: http.Response{ + StatusCodes: []int{200}, + AbsentHeaders: []string{ + "X-Custom-Response-Header", // no policy for all-namespaces gatweway + "X-Custom-Lua-Header", "X-Custom-Lua-Another-Header", + }, }, Namespace: ns, } From 8c6fdc7914fea228715a5b5014ae351b159bf7bb Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 29 Jun 2026 14:36:58 +0800 Subject: [PATCH 02/18] fix: disable inherited Lua for any overridden route Signed-off-by: zirain --- .../envoyextensionpolicy-with-lua.in.yaml | 97 +++++ .../envoyextensionpolicy-with-lua.out.yaml | 373 ++++++++++++++++++ internal/xds/translator/api_key_auth.go | 2 +- internal/xds/translator/authorization.go | 2 +- internal/xds/translator/bandwidth_limit.go | 2 +- internal/xds/translator/basicauth.go | 2 +- internal/xds/translator/compressor.go | 2 +- internal/xds/translator/cors.go | 2 +- internal/xds/translator/credentialInjector.go | 2 +- internal/xds/translator/custom_response.go | 2 +- .../xds/translator/dynamic_forward_proxy.go | 2 +- internal/xds/translator/dynamicmodule.go | 2 +- internal/xds/translator/extauth.go | 2 +- internal/xds/translator/extproc.go | 2 +- internal/xds/translator/fault.go | 2 +- internal/xds/translator/geoip.go | 2 +- internal/xds/translator/header_mutation.go | 2 +- internal/xds/translator/healthcheck.go | 2 +- internal/xds/translator/httpfilters.go | 13 +- internal/xds/translator/jwt.go | 2 +- internal/xds/translator/local_ratelimit.go | 2 +- internal/xds/translator/oidc.go | 2 +- internal/xds/translator/request_buffer.go | 2 +- .../xds/translator/session_persistence.go | 2 +- .../translator/testdata/in/xds-ir/lua.yaml | 132 +++++++ .../testdata/out/xds-ir/lua.clusters.yaml | 122 ++++++ .../testdata/out/xds-ir/lua.endpoints.yaml | 53 +++ .../testdata/out/xds-ir/lua.listeners.yaml | 94 +++++ .../testdata/out/xds-ir/lua.routes.yaml | 139 +++++++ internal/xds/translator/translator.go | 8 +- internal/xds/translator/wasm.go | 2 +- 31 files changed, 1043 insertions(+), 32 deletions(-) diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.in.yaml index 763e770bfb..68bed58b38 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.in.yaml @@ -13,6 +13,29 @@ gateways: allowedRoutes: namespaces: from: All +# two listeners on the same port, each with a distinct Lua policy. +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-2 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-a + protocol: HTTP + port: 80 + hostname: "app-a.example.com" + allowedRoutes: + namespaces: + from: All + - name: http-b + protocol: HTTP + port: 80 + hostname: "app-b.example.com" + allowedRoutes: + namespaces: + from: All httpRoutes: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute @@ -52,6 +75,46 @@ httpRoutes: backendRefs: - name: service-1 port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-a + spec: + hostnames: + - app-a.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-2 + sectionName: http-a + rules: + - matches: + - path: + type: PathPrefix + value: "/" + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-b + spec: + hostnames: + - app-b.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-2 + sectionName: http-b + rules: + - matches: + - path: + type: PathPrefix + value: "/" + backendRefs: + - name: service-1 + port: 8080 envoyextensionpolicies: - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy @@ -88,3 +151,37 @@ envoyextensionpolicies: filterContext: token_header: x-api-key mode: strict +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway-a + generation: 30 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + sectionName: http-a + lua: + - type: Inline + inline: "function envoy_on_request(request_handle) + request_handle:logInfo('tenant-A script.') + end" +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway-b + generation: 30 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + sectionName: http-b + lua: + - type: Inline + inline: "function envoy_on_request(request_handle) + request_handle:logInfo('tenant-B script.') + end" diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml index af0a07e945..21bcf96ea4 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml @@ -39,6 +39,82 @@ envoyExtensionPolicies: status: "True" type: Warning controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + generation: 30 + name: policy-for-gateway-a + namespace: envoy-gateway + spec: + lua: + - inline: function envoy_on_request(request_handle) request_handle:logInfo('tenant-A + script.') end + type: Inline + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + sectionName: http-a + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + sectionName: http-a + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + observedGeneration: 30 + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + observedGeneration: 30 + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + generation: 30 + name: policy-for-gateway-b + namespace: envoy-gateway + spec: + lua: + - inline: function envoy_on_request(request_handle) request_handle:logInfo('tenant-B + script.') end + type: Inline + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + sectionName: http-b + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + sectionName: http-b + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + observedGeneration: 30 + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + observedGeneration: 30 + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -122,6 +198,76 @@ gateways: kind: HTTPRoute - group: gateway.networking.k8s.io kind: GRPCRoute +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-2 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + hostname: app-a.example.com + name: http-a + port: 80 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + hostname: app-b.example.com + name: http-b + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-a + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-b + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute httpRoutes: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute @@ -197,6 +343,82 @@ httpRoutes: name: gateway-1 namespace: envoy-gateway sectionName: http +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-a + namespace: default + spec: + hostnames: + - app-a.example.com + parentRefs: + - name: gateway-2 + namespace: envoy-gateway + sectionName: http-a + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + type: PathPrefix + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-2 + namespace: envoy-gateway + sectionName: http-a +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-b + namespace: default + spec: + hostnames: + - app-b.example.com + parentRefs: + - name: gateway-2 + namespace: envoy-gateway + sectionName: http-b + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + type: PathPrefix + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-2 + namespace: envoy-gateway + sectionName: http-b infraIR: envoy-gateway/gateway-1: proxy: @@ -216,6 +438,24 @@ infraIR: name: envoy-gateway-class name: envoy-gateway/gateway-1 namespace: envoy-gateway-system + envoy-gateway/gateway-2: + proxy: + listeners: + - name: envoy-gateway/gateway-2/http-a + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-2 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-2 + namespace: envoy-gateway-system xdsIR: envoy-gateway/gateway-1: accessLog: @@ -337,3 +577,136 @@ xdsIR: ipFamily: IPv4 path: /ready port: 19003 + envoy-gateway/gateway-2: + accessLog: + json: + - path: /dev/stdout + globalResources: + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-2-4a0e4eb9 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-2 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-2-4a0e4eb9 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-2 + protocol: TCP + http: + - address: 0.0.0.0 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) request_handle:logInfo('tenant-A + script.') end + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-a/lua/0 + externalPort: 80 + hostnames: + - app-a.example.com + metadata: + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + sectionName: http-a + name: envoy-gateway/gateway-2/http-a + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-a + namespace: default + name: httproute/default/httproute-a/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-a/rule/0/backend/0 + protocol: HTTP + weight: 1 + envoyExtensions: {} + hostname: app-a.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-a + namespace: default + name: httproute/default/httproute-a/rule/0/match/0/app-a_example_com + pathMatch: + distinct: false + name: "" + prefix: / + - address: 0.0.0.0 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) request_handle:logInfo('tenant-B + script.') end + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-b/lua/0 + externalPort: 80 + hostnames: + - app-b.example.com + metadata: + kind: Gateway + name: gateway-2 + namespace: envoy-gateway + sectionName: http-b + name: envoy-gateway/gateway-2/http-b + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-b + namespace: default + name: httproute/default/httproute-b/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-b/rule/0/backend/0 + protocol: HTTP + weight: 1 + envoyExtensions: {} + hostname: app-b.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-b + namespace: default + name: httproute/default/httproute-b/rule/0/match/0/app-b_example_com + pathMatch: + distinct: false + name: "" + prefix: / + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/xds/translator/api_key_auth.go b/internal/xds/translator/api_key_auth.go index a8c84835f4..bf545088b7 100644 --- a/internal/xds/translator/api_key_auth.go +++ b/internal/xds/translator/api_key_auth.go @@ -177,6 +177,6 @@ func buildAPIKeyAuthFilterPerRouteConfig(apiKeyAuth *ir.APIKeyAuth) *apikeyauthv } } -func (*apiKeyAuth) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*apiKeyAuth) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/authorization.go b/internal/xds/translator/authorization.go index b8a5a74af1..3cb29aea8d 100644 --- a/internal/xds/translator/authorization.go +++ b/internal/xds/translator/authorization.go @@ -941,6 +941,6 @@ func wrapPredicateWithNot(predicate *matcherv3.Matcher_MatcherList_Predicate, in } } -func (*rbac) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*rbac) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/bandwidth_limit.go b/internal/xds/translator/bandwidth_limit.go index 605aaff883..1a7120c9ba 100644 --- a/internal/xds/translator/bandwidth_limit.go +++ b/internal/xds/translator/bandwidth_limit.go @@ -183,6 +183,6 @@ func buildBandwidthLimitResponseProto(cfg *ir.BandwidthLimitConfig) *bwlimitv3.B return proto } -func (*bandwidthLimit) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*bandwidthLimit) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/basicauth.go b/internal/xds/translator/basicauth.go index a783bcbb4d..25799c8af5 100644 --- a/internal/xds/translator/basicauth.go +++ b/internal/xds/translator/basicauth.go @@ -164,6 +164,6 @@ func basicAuthPerRouteConfig(basicAuth *ir.BasicAuth) *basicauthv3.BasicAuthPerR } } -func (*basicAuth) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*basicAuth) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/compressor.go b/internal/xds/translator/compressor.go index 02686c14fb..3f447d0bf5 100644 --- a/internal/xds/translator/compressor.go +++ b/internal/xds/translator/compressor.go @@ -196,6 +196,6 @@ func compressorPerRouteConfig() *compressorv3.CompressorPerRoute { } } -func (*compressor) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*compressor) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/cors.go b/internal/xds/translator/cors.go index ac79a5110e..4c41bead94 100644 --- a/internal/xds/translator/cors.go +++ b/internal/xds/translator/cors.go @@ -203,6 +203,6 @@ func (c *cors) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) erro return nil } -func (*cors) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*cors) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/credentialInjector.go b/internal/xds/translator/credentialInjector.go index 21a59713ba..d14ddef9a2 100644 --- a/internal/xds/translator/credentialInjector.go +++ b/internal/xds/translator/credentialInjector.go @@ -161,6 +161,6 @@ func (*credentialInjector) patchRoute(route *routev3.Route, irRoute *ir.HTTPRout return nil } -func (*credentialInjector) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*credentialInjector) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/custom_response.go b/internal/xds/translator/custom_response.go index 63b0c23260..dec7020da7 100644 --- a/internal/xds/translator/custom_response.go +++ b/internal/xds/translator/custom_response.go @@ -525,6 +525,6 @@ func (c *customResponse) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, return nil } -func (c *customResponse) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*customResponse) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/dynamic_forward_proxy.go b/internal/xds/translator/dynamic_forward_proxy.go index cdc67c45a9..fb419f9018 100644 --- a/internal/xds/translator/dynamic_forward_proxy.go +++ b/internal/xds/translator/dynamic_forward_proxy.go @@ -235,6 +235,6 @@ func buildDFPLoopbackRBACPerRoute(irRoute *ir.HTTPRoute) (*rbacv3.RBACPerRoute, }, nil } -func (*dynamicForwardProxy) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*dynamicForwardProxy) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/dynamicmodule.go b/internal/xds/translator/dynamicmodule.go index a3474f1deb..1d4d56d4ed 100644 --- a/internal/xds/translator/dynamicmodule.go +++ b/internal/xds/translator/dynamicmodule.go @@ -211,6 +211,6 @@ func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ return nil } -func (*dynamicModule) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*dynamicModule) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go index e6482f6993..b9fbf3a1cd 100644 --- a/internal/xds/translator/extauth.go +++ b/internal/xds/translator/extauth.go @@ -330,6 +330,6 @@ func convertContextExtensions(irCtxExts []*ir.ContextExtention) map[string]strin return ctxExts } -func (*extAuth) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*extAuth) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go index 06b49325c4..0cb15bc073 100644 --- a/internal/xds/translator/extproc.go +++ b/internal/xds/translator/extproc.go @@ -277,6 +277,6 @@ func translateExtProcBodyProcessingMode(mode *ir.ExtProcBodyProcessingMode) extp return extprocv3.ProcessingMode_NONE } -func (*extProc) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*extProc) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/fault.go b/internal/xds/translator/fault.go index 2dadbc8a77..83dd9c4f2d 100644 --- a/internal/xds/translator/fault.go +++ b/internal/xds/translator/fault.go @@ -175,6 +175,6 @@ func (*fault) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTP return nil } -func (*fault) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*fault) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/geoip.go b/internal/xds/translator/geoip.go index 7eab5d2268..9cbffbaf8c 100644 --- a/internal/xds/translator/geoip.go +++ b/internal/xds/translator/geoip.go @@ -300,6 +300,6 @@ func (*geoip) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error return nil } -func (*geoip) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*geoip) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/header_mutation.go b/internal/xds/translator/header_mutation.go index c5bc0f8906..ddc9d970b9 100644 --- a/internal/xds/translator/header_mutation.go +++ b/internal/xds/translator/header_mutation.go @@ -163,6 +163,6 @@ func buildHeaderMutationRules(addHeaders []ir.AddHeader, removeHeaders []string, return mutationRules } -func (*headerMutation) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*headerMutation) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/healthcheck.go b/internal/xds/translator/healthcheck.go index 2daf1150b4..3db72fc2a1 100644 --- a/internal/xds/translator/healthcheck.go +++ b/internal/xds/translator/healthcheck.go @@ -102,6 +102,6 @@ func (*healthCheck) patchRoute(_ *routev3.Route, _ *ir.HTTPRoute, _ *ir.HTTPList return nil } -func (*healthCheck) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*healthCheck) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index c439433980..60640be8c2 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -58,8 +58,10 @@ type httpFilter interface { // patchRoute patches the provide Route with a filter's Route level configuration. patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, httpListener *ir.HTTPListener) error - // patchRoute patches the provider RouteConfiguration. - patchRouteConfiguration(rc *routev3.RouteConfiguration, httpListener *ir.HTTPListener) error + // patchVirtualHost patches the provided VirtualHost with a filter's VirtualHost level configuration. + // Note: this method may be called multiple times for the same VirtualHost when multiple IR listeners + // share the same RouteConfiguration (cleartext listeners on the same port). + patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListener) error // patchResources adds all the other needed resources referenced by this // filter to the resource version table. @@ -347,14 +349,13 @@ func patchRouteWithPerRouteConfig(route *routev3.Route, irRoute *ir.HTTPRoute, h return nil } -// patchRouteConfiguration -func patchRouteConfiguration(rc *routev3.RouteConfiguration, httpListener *ir.HTTPListener) error { +// patchVirtualHost calls each filter's patchVirtualHost to apply VirtualHost-level configuration. +func patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListener) error { for _, filter := range httpFilters { - if err := filter.patchRouteConfiguration(rc, httpListener); err != nil { + if err := filter.patchVirtualHost(vh, httpListener); err != nil { return err } } - return nil } diff --git a/internal/xds/translator/jwt.go b/internal/xds/translator/jwt.go index 45ab1fd5fd..045b71594f 100644 --- a/internal/xds/translator/jwt.go +++ b/internal/xds/translator/jwt.go @@ -509,6 +509,6 @@ func buildJwtFromHeaders(headers []egv1a1.JWTHeaderExtractor) []*jwtauthnv3.JwtH return jwtHeaders } -func (*jwt) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*jwt) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/local_ratelimit.go b/internal/xds/translator/local_ratelimit.go index bc3570375d..62391c303e 100644 --- a/internal/xds/translator/local_ratelimit.go +++ b/internal/xds/translator/local_ratelimit.go @@ -484,6 +484,6 @@ func buildQueryParamMatchLocalRateLimitActions( } } -func (*localRateLimit) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*localRateLimit) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 5a3a0e734a..0ec110a96a 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -601,6 +601,6 @@ func (*oidc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPL return nil } -func (*oidc) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*oidc) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/request_buffer.go b/internal/xds/translator/request_buffer.go index 1ee01a56c7..ec7b4e321d 100644 --- a/internal/xds/translator/request_buffer.go +++ b/internal/xds/translator/request_buffer.go @@ -146,6 +146,6 @@ func routeContainsRequestBuffer(route *ir.HTTPRoute) bool { return route.Traffic != nil && route.Traffic.RequestBuffer != nil } -func (*requestBuffer) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*requestBuffer) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/session_persistence.go b/internal/xds/translator/session_persistence.go index 2709f228fd..7d202cad59 100644 --- a/internal/xds/translator/session_persistence.go +++ b/internal/xds/translator/session_persistence.go @@ -233,6 +233,6 @@ func (s *sessionPersistence) patchResources(_ *types.ResourceVersionTable, _ []* return nil } -func (*sessionPersistence) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*sessionPersistence) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } diff --git a/internal/xds/translator/testdata/in/xds-ir/lua.yaml b/internal/xds/translator/testdata/in/xds-ir/lua.yaml index 88f2d9d11a..321b204e24 100644 --- a/internal/xds/translator/testdata/in/xds-ir/lua.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/lua.yaml @@ -143,3 +143,135 @@ http: distinct: false name: "" prefix: /foo +# Listener Lua with an ExtProc-only route override (EnvoyExtensions non-nil, Luas empty). +# The ExtProc route must disable the inherited listener Lua even though it has no route-level Lua. +- address: 0.0.0.0 + hostnames: + - '*' + name: envoy-gateway/gateway-1/http-4 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) + request_handle:logInfo('Goodbye from gateway.') + end + name: envoyextensionpolicy/default/policy-for-gateway/lua/0 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10083 + routes: + # This route has an ExtProc-only EnvoyExtensionPolicy (Luas is empty). + # Inherited listener Lua must be disabled so the more-specific policy fully governs this route. + - destination: + name: httproute/default/httproute-4/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-4/rule/0/backend/0 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-4/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + envoyExtensions: + extProcs: + - name: envoyextensionpolicy/default/policy-for-http-route/extproc/0 + authority: grpc-backend.default:8000 + destination: + name: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend + settings: + - protocol: GRPC + weight: 1 + name: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend/backend/0 + # This route has no EnvoyExtensionPolicy — it inherits the listener Lua normally. + - destination: + name: httproute/default/httproute-5/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-5/rule/0/backend/0 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-5/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /bar +# Two cleartext listeners sharing the same port — shared RouteConfiguration. +# Each listener's Lua script must be scoped to its own virtual hosts only. +# Listener A +- address: 0.0.0.0 + hostnames: + - 'app-a.example.com' + name: envoy-gateway/gateway-1/http-5 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) + request_handle:logInfo('tenant-A script.') + end + name: envoyextensionpolicy/default/policy-for-gateway-a/lua/0 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10084 + routes: + - destination: + name: httproute/default/httproute-6/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-6/rule/0/backend/0 + hostname: app-a.example.com + isHTTP2: false + name: httproute/default/httproute-6/rule/0/match/0/app-a_example_com + pathMatch: + distinct: false + name: "" + prefix: / +# Listener B — same port 10084, different hostname +- address: 0.0.0.0 + hostnames: + - 'app-b.example.com' + name: envoy-gateway/gateway-1/http-6 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) + request_handle:logInfo('tenant-B script.') + end + name: envoyextensionpolicy/default/policy-for-gateway-b/lua/0 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10084 + routes: + - destination: + name: httproute/default/httproute-7/rule/0 + settings: + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-7/rule/0/backend/0 + hostname: app-b.example.com + isHTTP2: false + name: httproute/default/httproute-7/rule/0/match/0/app-b_example_com + pathMatch: + distinct: false + name: "" + prefix: / diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml index ad4ad66bbe..defb5d672a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml @@ -67,3 +67,125 @@ name: httproute/default/httproute-3/rule/0 perConnectionBufferLimitBytes: 32768 type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-4/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-4/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-5/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-5/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-6/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-6/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-7/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-7/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml index dadc93ba2d..40b120366e 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml @@ -34,3 +34,56 @@ loadBalancingWeight: 1 locality: region: httproute/default/httproute-3/rule/0/backend/0 +- clusterName: httproute/default/httproute-4/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-4/rule/0/backend/0 +- clusterName: httproute/default/httproute-5/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-5/rule/0/backend/0 +- clusterName: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend/backend/0 +- clusterName: httproute/default/httproute-6/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-6/rule/0/backend/0 +- clusterName: httproute/default/httproute-7/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 8.8.8.8 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-7/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml index edf8da8056..44eaca268f 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml @@ -139,3 +139,97 @@ maxConnectionsToAcceptPerSocketEvent: 1 name: envoy-gateway/gateway-1/http-3 perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10083 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: "" + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.default:8000 + clusterName: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-4 + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10083 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-4 + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-4 + perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10084 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: "" + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-5 + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10084 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-5 + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-5 + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml index 7c681e4751..ced2639ef1 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml @@ -26,9 +26,148 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: +<<<<<<< HEAD envoy.filters.http.lua/envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} envoy.filters.http.lua/envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/1: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} +======= + envoy.filters.http.lua/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + sourceCode: + inlineString: function envoy_on_response(response_handle) response_handle:logWarn('Goodbye.') + end + envoy.filters.http.lua/1: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + sourceCode: + inlineString: function envoy_on_response(response_handle) response_handle:logError('Hello.') + end +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-2 + virtualHosts: + - domains: + - www.example.com + name: envoy-gateway/gateway-1/http-2/www_example_com + routes: + - match: + pathSeparatedPrefix: /foo + name: httproute/default/httproute-3/rule/0/match/0/www_example_com + route: + cluster: httproute/default/httproute-2/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.lua/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + filterContext: + mode: strict + token_header: x-api-key + sourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') + end + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + disabled: true + typedPerFilterConfig: + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + filterContext: + mode: strict + token_header: x-api-key + sourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye + from gateway.') end +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-3 + virtualHosts: + - domains: + - www.example.com + name: envoy-gateway/gateway-1/http-3/www_example_com + routes: + - match: + pathSeparatedPrefix: /foo + name: httproute/default/httproute-3/rule/0/match/0/www_example_com + route: + cluster: httproute/default/httproute-3/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + filterContext: + mode: strict + token_header: x-api-key + sourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye + from gateway.') end +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-4 + virtualHosts: + - domains: + - www.example.com + name: envoy-gateway/gateway-1/http-4/www_example_com + routes: + - match: + pathSeparatedPrefix: /foo + name: httproute/default/httproute-4/rule/0/match/0/www_example_com + route: + cluster: httproute/default/httproute-4/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - match: + pathSeparatedPrefix: /bar + name: httproute/default/httproute-5/rule/0/match/0/www_example_com + route: + cluster: httproute/default/httproute-5/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + sourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye + from gateway.') end +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-5 + virtualHosts: + - domains: + - app-a.example.com + name: envoy-gateway/gateway-1/http-5/app-a_example_com + routes: + - match: + prefix: / + name: httproute/default/httproute-6/rule/0/match/0/app-a_example_com + route: + cluster: httproute/default/httproute-6/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + sourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('tenant-A + script.') end + - domains: + - app-b.example.com + name: envoy-gateway/gateway-1/http-6/app-b_example_com + routes: + - match: + prefix: / + name: httproute/default/httproute-7/rule/0/match/0/app-b_example_com + route: + cluster: httproute/default/httproute-7/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + sourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('tenant-B + script.') end +>>>>>>> 9b269cbe5 (fix: disable inherited Lua for any overridden route) diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 07aba956a0..769dd1cd74 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -511,10 +511,6 @@ func (t *Translator) processHTTPListenerXdsTranslation( } } - if err = patchRouteConfiguration(xdsRouteCfg, httpListener); err != nil { - errs = errors.Join(errs, err) - } - // Generate xDS virtual hosts and routes for the given HTTPListener, // and add them to the xDS route config. if err = t.addRouteToRouteConfig(tCtx, xdsRouteCfg, httpListener, metrics, http3Settings); err != nil { @@ -736,6 +732,10 @@ func (t *Translator) addRouteToRouteConfig( } for _, vHost := range vHostList { + if err = patchVirtualHost(vHost, httpListener); err != nil { + errs = errors.Join(errs, err) + } + // Check if an extension want to modify the Virtual Host we just generated // If no extension exists (or it doesn't subscribe to this hook) then this is a quick no-op. if err = processExtensionPostVHostHook(vHost, t.ExtensionManager); err != nil { diff --git a/internal/xds/translator/wasm.go b/internal/xds/translator/wasm.go index 7d9d9e728b..0a2a2557b7 100644 --- a/internal/xds/translator/wasm.go +++ b/internal/xds/translator/wasm.go @@ -215,6 +215,6 @@ func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPL return nil } -func (*wasm) patchRouteConfiguration(_ *routev3.RouteConfiguration, _ *ir.HTTPListener) error { +func (*wasm) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } From 84d69d5b0e242d55bfb6ba3be377b310377aa1da Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 29 Jun 2026 18:22:15 +0800 Subject: [PATCH 03/18] fix listener-level Lua leaks onto routes claimed by a more-specific non-Lua policy Signed-off-by: zirain --- internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml index ced2639ef1..9d4bc48433 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml @@ -120,6 +120,9 @@ envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + disabled: true - match: pathSeparatedPrefix: /bar name: httproute/default/httproute-5/rule/0/match/0/www_example_com From 6919bc2199b665d5af3c3ce96011795cdbb766cc Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 30 Jun 2026 16:13:56 +0800 Subject: [PATCH 04/18] fix same-policy listener Lua for route extensions Signed-off-by: zirain --- internal/gatewayapi/envoyextensionpolicy.go | 7 +-- .../testdata/custom-filter-order.out.yaml | 1 + ...yextensionpolicy-override-replace.out.yaml | 1 + ...nsionpolicy-section-name-override.out.yaml | 2 + ...xtensionpolicy-with-dynamicmodule.out.yaml | 1 + ...ith-extproc-with-backendtlspolicy.out.yaml | 2 + ...yextensionpolicy-with-invalid-lua.out.yaml | 6 ++- ...xtensionpolicy-with-lua-configmap.out.yaml | 12 +++-- .../envoyextensionpolicy-with-lua.out.yaml | 9 ++-- ...xtensionpolicy-with-wasm-env-vars.out.yaml | 1 + ...y-with-wasm-invalid-configuration.out.yaml | 6 ++- ...ensionpolicy-with-wasm-targetrefs.out.yaml | 1 + .../envoyextensionpolicy-with-wasm.out.yaml | 1 + internal/ir/xds.go | 2 + internal/ir/zz_generated.deepcopy.go | 5 ++ .../translator/testdata/in/xds-ir/lua.yaml | 45 ++++++++++++++++ .../testdata/out/xds-ir/lua.clusters.yaml | 53 ++++++++++++++++++ .../testdata/out/xds-ir/lua.endpoints.yaml | 17 ++++++ .../testdata/out/xds-ir/lua.listeners.yaml | 54 +++++++++++++++++++ .../testdata/out/xds-ir/lua.routes.yaml | 27 ++++++++++ 20 files changed, 239 insertions(+), 14 deletions(-) diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index 2fd6b2e36c..a1bdc07088 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -990,9 +990,10 @@ func (t *Translator) translateEnvoyExtensionPolicyForListeners( } } else { r.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ - ExtProcs: extProcs, - Wasms: wasms, - DynamicModules: dynamicModules, + ExtProcs: extProcs, + Wasms: wasms, + DynamicModules: dynamicModules, + FromGatewayPolicy: new(true), } } } diff --git a/internal/gatewayapi/testdata/custom-filter-order.out.yaml b/internal/gatewayapi/testdata/custom-filter-order.out.yaml index 358921f346..122246db68 100644 --- a/internal/gatewayapi/testdata/custom-filter-order.out.yaml +++ b/internal/gatewayapi/testdata/custom-filter-order.out.yaml @@ -291,6 +291,7 @@ xdsIR: protocol: HTTP weight: 1 envoyExtensions: + fromGatewayPolicy: true wasms: - config: parameter1: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml index 1a5c92bfdf..cec0d86359 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml @@ -410,6 +410,7 @@ xdsIR: protocol: GRPC weight: 1 name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 + fromGatewayPolicy: true hostname: gateway.envoyproxy.io isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-section-name-override.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-section-name-override.out.yaml index 4fca32d00b..8f106a951a 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-section-name-override.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-section-name-override.out.yaml @@ -526,6 +526,7 @@ xdsIR: protocol: GRPC weight: 1 name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1-listener-1/extproc/0 + fromGatewayPolicy: true hostname: gateway.envoyproxy.io isHTTP2: false metadata: @@ -596,6 +597,7 @@ xdsIR: protocol: GRPC weight: 1 name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 + fromGatewayPolicy: true hostname: gateway.envoyproxy.io isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-dynamicmodule.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-dynamicmodule.out.yaml index 1eede11cad..e5e0faaae3 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-dynamicmodule.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-dynamicmodule.out.yaml @@ -434,6 +434,7 @@ xdsIR: sha256: abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 url: https://modules.example.com/libremote_auth.so terminalFilter: false + fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml index e638a63610..520a97ea8f 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml @@ -413,6 +413,7 @@ xdsIR: responseBodyProcessingMode: Streamed responseHeaderProcessing: true statusOnError: 503 + fromGatewayPolicy: true hostname: www.foo.com isHTTP2: false metadata: @@ -491,6 +492,7 @@ xdsIR: responseBodyProcessingMode: Streamed responseHeaderProcessing: true statusOnError: 503 + fromGatewayPolicy: true hostname: www.bar.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml index f99cfd8e77..81c75376eb 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml @@ -293,7 +293,8 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -324,7 +325,8 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml index ea2cdfcc1e..800eb241ed 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml @@ -467,7 +467,8 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -500,7 +501,8 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -533,7 +535,8 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -603,7 +606,8 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml index 21bcf96ea4..589c26ff13 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml @@ -560,7 +560,8 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -642,7 +643,8 @@ xdsIR: name: httproute/default/httproute-a/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: app-a.example.com isHTTP2: false metadata: @@ -693,7 +695,8 @@ xdsIR: name: httproute/default/httproute-b/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: app-b.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml index 73f2f7e136..fcd2c1a9da 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml @@ -348,6 +348,7 @@ xdsIR: protocol: HTTP weight: 1 envoyExtensions: + fromGatewayPolicy: true wasms: - config: null failOpen: false diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml index dcfca230a6..700fc84753 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml @@ -928,7 +928,8 @@ xdsIR: name: httproute/default/httproute-5/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.foo.com isHTTP2: false metadata: @@ -959,7 +960,8 @@ xdsIR: name: httproute/default/httproute-6/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: {} + envoyExtensions: + fromGatewayPolicy: true hostname: www.bar.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml index 3c9077b3a7..33b1fe86fb 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml @@ -320,6 +320,7 @@ xdsIR: protocol: HTTP weight: 1 envoyExtensions: + fromGatewayPolicy: true wasms: - config: parameter1: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml index cf73e95f12..1d6291159f 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml @@ -352,6 +352,7 @@ xdsIR: protocol: HTTP weight: 1 envoyExtensions: + fromGatewayPolicy: true wasms: - config: parameter1: diff --git a/internal/ir/xds.go b/internal/ir/xds.go index b30abb792f..f689db82dc 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -1265,6 +1265,8 @@ type EnvoyExtensionFeatures struct { Luas []Lua `json:"luas,omitempty" yaml:"luas,omitempty"` // Dynamic Module extensions DynamicModules []DynamicModule `json:"dynamicModules,omitempty" yaml:"dynamicModules,omitempty"` + // TODO: remove this after we moved all the extensions(e.g. extProc, Wasm, DYM) to use listener-level and route-level. + FromGatewayPolicy *bool `json:"fromGatewayPolicy,omitempty" yaml:"fromGatewayPolicy,omitempty"` } // UnstructuredRef holds unstructured data for an arbitrary k8s resource introduced by an extension diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 248aaa3b98..b75679458c 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1550,6 +1550,11 @@ func (in *EnvoyExtensionFeatures) DeepCopyInto(out *EnvoyExtensionFeatures) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.FromGatewayPolicy != nil { + in, out := &in.FromGatewayPolicy, &out.FromGatewayPolicy + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyExtensionFeatures. diff --git a/internal/xds/translator/testdata/in/xds-ir/lua.yaml b/internal/xds/translator/testdata/in/xds-ir/lua.yaml index 321b204e24..9244659315 100644 --- a/internal/xds/translator/testdata/in/xds-ir/lua.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/lua.yaml @@ -275,3 +275,48 @@ http: distinct: false name: "" prefix: / +# Gateway policy with Lua (at listener) + ExtProc (at route), both from the same policy. +# The route's ExtProc carries fromGatewayPolicy:true so the listener Lua must NOT be disabled. +- address: 0.0.0.0 + hostnames: + - '*' + name: envoy-gateway/gateway-1/http-7 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) + request_handle:logInfo('Gateway Lua.') + end + name: envoyextensionpolicy/default/policy-for-gateway/lua/0 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10085 + routes: + - destination: + name: httproute/default/httproute-8/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-8/rule/0/backend/0 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-8/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + envoyExtensions: + fromGatewayPolicy: true + extProcs: + - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 + authority: grpc-backend.default:8000 + destination: + name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend + settings: + - protocol: GRPC + weight: 1 + name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml index defb5d672a..837628b283 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml @@ -189,3 +189,56 @@ name: httproute/default/httproute-7/rule/0 perConnectionBufferLimitBytes: 32768 type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-8/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-8/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml index 40b120366e..527f66efa7 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml @@ -87,3 +87,20 @@ loadBalancingWeight: 1 locality: region: httproute/default/httproute-7/rule/0/backend/0 +- clusterName: httproute/default/httproute-8/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-8/rule/0/backend/0 +- clusterName: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml index 44eaca268f..fc83061b14 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml @@ -233,3 +233,57 @@ maxConnectionsToAcceptPerSocketEvent: 1 name: envoy-gateway/gateway-1/http-5 perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10085 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: "" + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-gateway/extproc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.default:8000 + clusterName: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-7 + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10085 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-7 + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-7 + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml index 9d4bc48433..c839762a4f 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml @@ -173,4 +173,31 @@ sourceCode: inlineString: function envoy_on_request(request_handle) request_handle:logInfo('tenant-B script.') end +<<<<<<< HEAD >>>>>>> 9b269cbe5 (fix: disable inherited Lua for any overridden route) +======= +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-7 + virtualHosts: + - domains: + - www.example.com + name: envoy-gateway/gateway-1/http-7/www_example_com + routes: + - match: + pathSeparatedPrefix: /foo + name: httproute/default/httproute-8/rule/0/match/0/www_example_com + route: + cluster: httproute/default/httproute-8/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-gateway/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + typedPerFilterConfig: + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + sourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Gateway + Lua.') end +>>>>>>> 72ee6d6a9 (fix same-policy listener Lua for route extensions) From f7d294373014cc965b675e25f71cd9e7e8b2588e Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 30 Jun 2026 17:05:40 +0800 Subject: [PATCH 05/18] fix Signed-off-by: zirain --- internal/gatewayapi/envoyextensionpolicy.go | 6 ++- ...cy-with-wasm-invalid-configuration.in.yaml | 3 ++ ...y-with-wasm-invalid-configuration.out.yaml | 3 ++ .../translator/testdata/in/xds-ir/lua.yaml | 36 +++++++++++++++++ .../testdata/out/xds-ir/lua.clusters.yaml | 23 +++++++++++ .../testdata/out/xds-ir/lua.endpoints.yaml | 12 ++++++ .../testdata/out/xds-ir/lua.listeners.yaml | 40 +++++++++++++++++++ .../testdata/out/xds-ir/lua.routes.yaml | 27 +++++++++++++ 8 files changed, 148 insertions(+), 2 deletions(-) diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index a1bdc07088..e1015a80f1 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -968,8 +968,10 @@ func (t *Translator) translateEnvoyExtensionPolicyForListeners( } // TODO: move other extensions to listener level. - totalExtensions := len(luas) - if totalExtensions > 0 { + // Only attach listener-level Lua when the policy succeeds; a fail-closed error in + // any other extension makes every route return a 500, so the Lua filter must not + // run on those synthetic error responses. + if len(luas) > 0 && !failed { http.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ Luas: luas, } diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.in.yaml index 11f01273bc..3fdf7e8033 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.in.yaml @@ -316,3 +316,6 @@ envoyExtensionPolicies: pullSecretRef: name: my-pull-secret-1 sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46 + lua: + - type: Inline + inline: "function envoy_on_request(request_handle) end" diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml index 700fc84753..3ce41b6c18 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml @@ -242,6 +242,9 @@ envoyExtensionPolicies: type: Image name: wasm-filter-1 rootID: my-root-id + lua: + - inline: function envoy_on_request(request_handle) end + type: Inline status: ancestors: - ancestorRef: diff --git a/internal/xds/translator/testdata/in/xds-ir/lua.yaml b/internal/xds/translator/testdata/in/xds-ir/lua.yaml index 9244659315..8fb2404882 100644 --- a/internal/xds/translator/testdata/in/xds-ir/lua.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/lua.yaml @@ -320,3 +320,39 @@ http: - protocol: GRPC weight: 1 name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend/backend/0 +# Listener Lua with a route that has a fail-open empty policy (EnvoyExtensions non-nil but all +# extension slices empty and no fromGatewayPolicy). The listener Lua must still be disabled +# because the more-specific route policy owns this route regardless of producing no extensions. +- address: 0.0.0.0 + hostnames: + - '*' + name: envoy-gateway/gateway-1/http-8 + envoyExtensions: + luas: + - code: function envoy_on_request(request_handle) + request_handle:logInfo('Gateway Lua.') + end + name: envoyextensionpolicy/default/policy-for-gateway/lua/0 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10086 + routes: + - destination: + name: httproute/default/httproute-9/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-9/rule/0/backend/0 + hostname: www.example.com + isHTTP2: false + name: httproute/default/httproute-9/rule/0/match/0/www_example_com + pathMatch: + distinct: false + name: "" + prefix: /foo + envoyExtensions: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml index 837628b283..376d420242 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.clusters.yaml @@ -242,3 +242,26 @@ http2ProtocolOptions: initialConnectionWindowSize: 1048576 initialStreamWindowSize: 65536 +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-9/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-9/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml index 527f66efa7..11449dbc2a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.endpoints.yaml @@ -104,3 +104,15 @@ - loadBalancingWeight: 1 locality: region: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend/backend/0 +- clusterName: httproute/default/httproute-9/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-9/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml index fc83061b14..dde4f2f11a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml @@ -287,3 +287,43 @@ maxConnectionsToAcceptPerSocketEvent: 1 name: envoy-gateway/gateway-1/http-7 perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10086 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: "" + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-8 + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10086 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-8 + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-8 + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml index c839762a4f..169cfc6314 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml @@ -200,4 +200,31 @@ sourceCode: inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Gateway Lua.') end +<<<<<<< HEAD >>>>>>> 72ee6d6a9 (fix same-policy listener Lua for route extensions) +======= +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-8 + virtualHosts: + - domains: + - www.example.com + name: envoy-gateway/gateway-1/http-8/www_example_com + routes: + - match: + pathSeparatedPrefix: /foo + name: httproute/default/httproute-9/rule/0/match/0/www_example_com + route: + cluster: httproute/default/httproute-9/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + disabled: true + typedPerFilterConfig: + envoy.filters.http.lua/listener/0: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + sourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Gateway + Lua.') end +>>>>>>> c8dc11cf7 (fix) From 3d7ea9bc4fa311125d35338e20b7caa739ccbf4f Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 30 Jun 2026 20:30:54 +0800 Subject: [PATCH 06/18] fix Signed-off-by: zirain --- ...y-with-wasm-invalid-configuration.out.yaml | 6 +- .../testdata/out/xds-ir/lua.listeners.yaml | 90 ++++----- .../testdata/out/xds-ir/lua.routes.yaml | 181 +++++++++++------- ...31-lua-xds-layout-per-route-filterchain.md | 1 + 4 files changed, 163 insertions(+), 115 deletions(-) create mode 100644 release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml index 3ce41b6c18..d1aadf0593 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml @@ -228,6 +228,9 @@ envoyExtensionPolicies: name: policy-for-gateway-3 namespace: default spec: + lua: + - inline: function envoy_on_request(request_handle) end + type: Inline targetRef: group: gateway.networking.k8s.io kind: Gateway @@ -242,9 +245,6 @@ envoyExtensionPolicies: type: Image name: wasm-filter-1 rootID: my-root-id - lua: - - inline: function envoy_on_request(request_handle) end - type: Inline status: ancestors: - ancestorRef: diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml index dde4f2f11a..cf0762092d 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml @@ -15,26 +15,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.lua/envoyextensionpolicy/default/policy-for-http-route/lua/0 + name: envoy.filters.http.filter_chain.eep.lua typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') - end + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.lua/envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0 + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: function envoy_on_response(response_handle) response_handle:logWarn('Goodbye.') - end - - disabled: true - name: envoy.filters.http.lua/envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/1 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: function envoy_on_response(response_handle) response_handle:logError('Hello.') - end + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -70,16 +57,14 @@ initialStreamWindowSize: 65536 maxConcurrentStreams: 100 httpFilters: - - name: envoy.filters.http.lua/listener/0 + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: "" - - name: envoy.filters.http.lua/0 + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: "" + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -115,11 +100,14 @@ initialStreamWindowSize: 65536 maxConcurrentStreams: 100 httpFilters: - - name: envoy.filters.http.lua/listener/0 + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: "" + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua.listener + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -155,11 +143,14 @@ initialStreamWindowSize: 65536 maxConcurrentStreams: 100 httpFilters: - - name: envoy.filters.http.lua/listener/0 + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: "" + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0 typedConfig: @@ -209,11 +200,14 @@ initialStreamWindowSize: 65536 maxConcurrentStreams: 100 httpFilters: - - name: envoy.filters.http.lua/listener/0 + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: "" + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -249,11 +243,14 @@ initialStreamWindowSize: 65536 maxConcurrentStreams: 100 httpFilters: - - name: envoy.filters.http.lua/listener/0 + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: "" + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua.listener + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-gateway/extproc/0 typedConfig: @@ -303,11 +300,14 @@ initialStreamWindowSize: 65536 maxConcurrentStreams: 100 httpFilters: - - name: envoy.filters.http.lua/listener/0 + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - defaultSourceCode: - inlineString: "" + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml index 169cfc6314..14d1e054b6 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml @@ -13,7 +13,17 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.lua/envoyextensionpolicy/default/policy-for-http-route/lua/0: + envoy.filters.http.filter_chain.eep.lua: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') + end + envoy.filters.http.lua/0: '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute filterContext: mode: strict @@ -26,24 +36,22 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: -<<<<<<< HEAD - envoy.filters.http.lua/envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.lua/envoyextensionpolicy/envoy-gateway/policy-for-gateway/lua/1: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} -======= - envoy.filters.http.lua/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - sourceCode: - inlineString: function envoy_on_response(response_handle) response_handle:logWarn('Goodbye.') - end - envoy.filters.http.lua/1: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - sourceCode: - inlineString: function envoy_on_response(response_handle) response_handle:logError('Hello.') - end + envoy.filters.http.filter_chain.eep.lua: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_response(response_handle) response_handle:logWarn('Goodbye.') + end + - name: envoy.filters.http.lua/1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_response(response_handle) response_handle:logError('Hello.') + end - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-2 virtualHosts: @@ -59,26 +67,40 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: + envoy.filters.http.filter_chain.eep.lua: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') + end + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + disabled: true envoy.filters.http.lua/0: '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute filterContext: mode: strict token_header: x-api-key - sourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') - end - envoy.filters.http.lua/listener/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - disabled: true typedPerFilterConfig: + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye + from gateway.') end envoy.filters.http.lua/listener/0: '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute filterContext: mode: strict token_header: x-api-key - sourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye - from gateway.') end - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-3 virtualHosts: @@ -94,14 +116,21 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye + from gateway.') end envoy.filters.http.lua/listener/0: '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute filterContext: mode: strict token_header: x-api-key - sourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye - from gateway.') end - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-4 virtualHosts: @@ -120,8 +149,8 @@ envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} - envoy.filters.http.lua/listener/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true - match: pathSeparatedPrefix: /bar @@ -131,11 +160,16 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.lua/listener/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - sourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye - from gateway.') end + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye + from gateway.') end - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-5 virtualHosts: @@ -151,11 +185,16 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.lua/listener/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - sourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('tenant-A - script.') end + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('tenant-A + script.') end - domains: - app-b.example.com name: envoy-gateway/gateway-1/http-6/app-b_example_com @@ -168,14 +207,16 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.lua/listener/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - sourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('tenant-B - script.') end -<<<<<<< HEAD ->>>>>>> 9b269cbe5 (fix: disable inherited Lua for any overridden route) -======= + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('tenant-B + script.') end - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-7 virtualHosts: @@ -195,14 +236,16 @@ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} typedPerFilterConfig: - envoy.filters.http.lua/listener/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - sourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Gateway - Lua.') end -<<<<<<< HEAD ->>>>>>> 72ee6d6a9 (fix same-policy listener Lua for route extensions) -======= + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Gateway + Lua.') end - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-8 virtualHosts: @@ -218,13 +261,17 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.lua/listener/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true typedPerFilterConfig: - envoy.filters.http.lua/listener/0: - '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - sourceCode: - inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Gateway - Lua.') end ->>>>>>> c8dc11cf7 (fix) + envoy.filters.http.filter_chain.eep.lua.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.lua/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + defaultSourceCode: + inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Gateway + Lua.') end diff --git a/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md b/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md new file mode 100644 index 0000000000..689dfdbfba --- /dev/null +++ b/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md @@ -0,0 +1 @@ +The xDS layout for Gateway/listener-targeted Lua EnvoyExtensionPolicies has changed: the Lua script is now delivered through a named HCM-level filter plus VirtualHost `TypedPerFilterConfig`, rather than being embedded directly in each route's `TypedPerFilterConfig`. Route-level Lua filter slots are now installed as disabled-by-default in the HCM filter chain and activated per-route. EnvoyPatchPolicy rules or extension-server logic that reads or patches the old per-route Lua config shape must be updated to target the new filter names (`envoy.filters.http.lua/listener/`) and VirtualHost-scoped overrides. From 7d3fb0ff3e3c8313bbe854988f6d9f90fc15852b Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 6 Jul 2026 11:08:49 +0800 Subject: [PATCH 07/18] add stats test case Signed-off-by: zirain --- test/e2e/tests/lua_http.go | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/test/e2e/tests/lua_http.go b/test/e2e/tests/lua_http.go index 066fe3355f..92c87438e7 100644 --- a/test/e2e/tests/lua_http.go +++ b/test/e2e/tests/lua_http.go @@ -8,18 +8,33 @@ package tests import ( + "context" + "fmt" "testing" + "time" + "github.com/prometheus/common/model" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/conformance/utils/http" "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" "sigs.k8s.io/gateway-api/conformance/utils/suite" + "sigs.k8s.io/gateway-api/conformance/utils/tlog" "github.com/envoyproxy/gateway/internal/gatewayapi" "github.com/envoyproxy/gateway/internal/gatewayapi/resource" + "github.com/envoyproxy/gateway/test/utils/prometheus" ) +// maxExpectedLuaVMCount bounds the "lua.lua_vm_count" gauge (added in +// https://github.com/envoyproxy/envoy/pull/45871) for this test's fixture. lua-http.yaml +// configures 4 distinct Lua scripts (gateway-level, route1, route2, route4), and each +// configured script accounts for at most (concurrency + 1) VMs. This is a generous cap on +// concurrency to catch a real blow-up (e.g. a VM created per-route or per-request) without +// being sensitive to the worker thread count of the CI machine. +const maxExpectedLuaVMCount = 4 * 33 + func init() { ConformanceTests = append(ConformanceTests, HTTPLuaTest) } @@ -202,5 +217,42 @@ var HTTPLuaTest = suite.ConformanceTest{ http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) }) + + // Regression check for https://github.com/envoyproxy/envoy/issues/9355-style VM blow-ups: + // the fixture above configures 4 distinct Lua scripts (gateway-level + 3 route-level), + // so the "lua.lua_vm_count" gauge should settle at a small, bounded value rather than + // growing per-route or per-request. + t.Run("lua vm count stays bounded", func(t *testing.T) { + // Sum across all "same-namespace" proxy replicas/pods so multi-replica setups + // don't produce more than one time series. + promQL := `sum(envoy_lua_lua_vm_count{app_kubernetes_io_component="proxy", app_kubernetes_io_managed_by="envoy-gateway", app_kubernetes_io_name="envoy", gateway_envoyproxy_io_owning_gateway_name="same-namespace"})` + + if err := wait.PollUntilContextTimeout(context.TODO(), time.Second, time.Minute, true, + func(_ context.Context) (done bool, err error) { + v, err := prometheus.QueryPrometheus(suite.Client, promQL) + if err != nil { + tlog.Logf(t, "failed to query prometheus: %v", err) + return false, nil + } + if v != nil && v.Type() == model.ValVector { + vectorVal := v.(model.Vector) + // Wait for the gauge to appear (present and non-zero) before judging it, + // since it's only populated once Envoy has loaded the Lua filter config. + if len(vectorVal) == 1 && vectorVal[0].Value > 0 { + tlog.Logf(t, "got lua_vm_count value: %v", vectorVal[0].Value) + if vectorVal[0].Value > maxExpectedLuaVMCount { + // Fail outright instead of retrying: once the gauge is reporting, + // exceeding the bound means VMs are leaking/duplicating, and more + // polling won't make that false. + return false, fmt.Errorf("lua_vm_count %v exceeds expected bound %d", vectorVal[0].Value, maxExpectedLuaVMCount) + } + return true, nil + } + } + return false, nil + }); err != nil { + t.Errorf("failed to get expected lua_vm_count metric: %v", err) + } + }) }, } From f87710b252e670b071ef21d67b89e0722c6608dd Mon Sep 17 00:00:00 2001 From: zirain Date: Fri, 10 Jul 2026 08:46:33 +0800 Subject: [PATCH 08/18] use filter_chain for listener level lua Signed-off-by: zirain --- internal/xds/translator/httpfilters.go | 12 ++++---- .../testdata/out/xds-ir/lua.listeners.yaml | 28 +++++++++---------- ...31-lua-xds-layout-per-route-filterchain.md | 2 +- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index 60640be8c2..1d7b2fa14e 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -128,13 +128,11 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter { order = 10 case isFilterType(filter, egv1a1.EnvoyFilterBuffer): order = 11 - case isFilterType(filter, egv1a1.EnvoyFilterLua): - if strings.Contains(filter.Name, "/listener/") { - // Listener-level Lua runs before route-level Lua (12+idx vs 62+idx). - order = 12 + mustGetFilterIndex(filter.Name) - } else { - order = 62 + mustGetFilterIndex(filter.Name) - } + case filter.Name == luaListenerFCFilterName(): + // Listener-level (per-connection) Lua runs before route-level Lua. + order = 12 + case filter.Name == luaFCFilterName(): + order = 13 case isFilterType(filter, egv1a1.EnvoyFilterExtProc): order = 100 + mustGetFilterIndex(filter.Name) case isFilterType(filter, egv1a1.EnvoyFilterWasm): diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml index cf0762092d..9a5d0bff46 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml @@ -15,11 +15,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.lua typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router @@ -58,11 +58,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.lua typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router @@ -101,11 +101,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.lua typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router @@ -144,11 +144,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.lua typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true @@ -201,11 +201,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.lua typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router @@ -244,11 +244,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.lua typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true @@ -301,11 +301,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.lua.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.lua typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router diff --git a/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md b/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md index 689dfdbfba..b8eb59bbac 100644 --- a/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md +++ b/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md @@ -1 +1 @@ -The xDS layout for Gateway/listener-targeted Lua EnvoyExtensionPolicies has changed: the Lua script is now delivered through a named HCM-level filter plus VirtualHost `TypedPerFilterConfig`, rather than being embedded directly in each route's `TypedPerFilterConfig`. Route-level Lua filter slots are now installed as disabled-by-default in the HCM filter chain and activated per-route. EnvoyPatchPolicy rules or extension-server logic that reads or patches the old per-route Lua config shape must be updated to target the new filter names (`envoy.filters.http.lua/listener/`) and VirtualHost-scoped overrides. +The xDS layout for Lua EnvoyExtensionPolicies (both Gateway/listener-targeted and HTTPRoute-targeted) has changed. Any EnvoyPatchPolicy rules or extension-server logic that reads or patches the old Lua filter names or per-route config shape will break and must be updated to match the new layout. From 50d7ae546b53056c3c13d00009cd1dfc7551fb63 Mon Sep 17 00:00:00 2001 From: zirain Date: Fri, 10 Jul 2026 09:17:25 +0800 Subject: [PATCH 09/18] fix: Prevent gateway Lua from bypassing listener overrides Signed-off-by: zirain --- internal/gatewayapi/envoyextensionpolicy.go | 11 +- .../envoyextensionpolicy-with-lua.in.yaml | 72 +++++ .../envoyextensionpolicy-with-lua.out.yaml | 271 ++++++++++++++++++ 3 files changed, 353 insertions(+), 1 deletion(-) diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index e1015a80f1..cf06406a2f 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -540,7 +540,7 @@ func (t *Translator) processEnvoyExtensionPolicyForGateway( } // Set conditions for translation error if it got any - if err := t.translateEnvoyExtensionPolicyForGateway(policy, currTarget, targetedGateway, xdsIR, resources); err != nil { + if err := t.translateEnvoyExtensionPolicyForGateway(policy, currTarget, targetedGateway, gatewayMap[gatewayNN].attachedToListeners, xdsIR, resources); err != nil { status.SetTranslationErrorForPolicyAncestor(&policy.Status, &ancestorRef, t.GatewayControllerName, @@ -875,6 +875,7 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway( policy *egv1a1.EnvoyExtensionPolicy, target policyTargetReferenceWithSectionName, gateway *GatewayContext, + attachedToListeners sets.Set[string], xdsIR resource.XdsIRMap, resources *resource.Resources, ) error { @@ -962,6 +963,14 @@ func (t *Translator) translateEnvoyExtensionPolicyForListeners( continue } + // A Gateway-wide policy must not apply to a listener that already has its own, + // more-specific listener policy attached — even when that listener policy carries no + // Lua of its own. Otherwise a Gateway-wide Lua policy could still be installed on the + // listener's HCM and run on routes that the listener policy is meant to fully govern. + if target.SectionName == nil && attachedToListeners.Has(http.Metadata.SectionName) { + continue + } + // if already set - there's a specific level policy, so skip if http.EnvoyExtensions != nil { continue diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.in.yaml index 68bed58b38..ece399e09d 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.in.yaml @@ -36,6 +36,24 @@ gateways: allowedRoutes: namespaces: from: All +# A listener with a listener-scoped policy that carries only a route-level extension (Wasm, +# no Lua), plus a Gateway-wide policy with Lua. The Gateway-wide Lua must not leak onto this +# listener since it's already fully governed by the more-specific listener policy. +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-3 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "gw3.example.com" + allowedRoutes: + namespaces: + from: All httpRoutes: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute @@ -115,6 +133,26 @@ httpRoutes: backendRefs: - name: service-1 port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-gw3 + spec: + hostnames: + - gw3.example.com + parentRefs: + - namespace: envoy-gateway + name: gateway-3 + sectionName: http + rules: + - matches: + - path: + type: PathPrefix + value: "/" + backendRefs: + - name: service-1 + port: 8080 envoyextensionpolicies: - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy @@ -185,3 +223,37 @@ envoyextensionpolicies: inline: "function envoy_on_request(request_handle) request_handle:logInfo('tenant-B script.') end" +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: envoy-gateway + name: policy-for-listener-wasm # listener-scoped, Wasm only, no Lua + generation: 40 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-3 + sectionName: http + wasm: + - name: wasm-filter-gw3 + code: + type: HTTP + http: + url: https://www.example.com/wasm-filter-gw3.wasm +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway-3 # Gateway-wide, must not leak Lua onto gateway-3/http + generation: 40 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-3 + lua: + - type: Inline + inline: "function envoy_on_request(request_handle) + request_handle:logInfo('should not run on gateway-3 listener.') + end" diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml index 589c26ff13..0fd19f58cf 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml @@ -115,6 +115,47 @@ envoyExtensionPolicies: status: "True" type: Warning controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + generation: 40 + name: policy-for-listener-wasm + namespace: envoy-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-3 + sectionName: http + wasm: + - code: + http: + sha256: null + url: https://www.example.com/wasm-filter-gw3.wasm + type: HTTP + name: wasm-filter-gw3 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-3 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + observedGeneration: 40 + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + observedGeneration: 40 + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyExtensionPolicy metadata: @@ -158,6 +199,49 @@ envoyExtensionPolicies: status: "True" type: Overridden controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + generation: 40 + name: policy-for-gateway-3 + namespace: envoy-gateway + spec: + lua: + - inline: function envoy_on_request(request_handle) request_handle:logInfo('should + not run on gateway-3 listener.') end + type: Inline + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-3 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-3 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + observedGeneration: 40 + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + observedGeneration: 40 + reason: DeprecatedField + status: "True" + type: Warning + - lastTransitionTime: null + message: 'This policy is being overridden by other envoyExtensionPolicies + for these listeners: [http]' + observedGeneration: 40 + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller gateways: - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway @@ -268,6 +352,46 @@ gateways: kind: HTTPRoute - group: gateway.networking.k8s.io kind: GRPCRoute +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-3 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + hostname: gw3.example.com + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute httpRoutes: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute @@ -419,6 +543,44 @@ httpRoutes: name: gateway-2 namespace: envoy-gateway sectionName: http-b +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-gw3 + namespace: default + spec: + hostnames: + - gw3.example.com + parentRefs: + - name: gateway-3 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + type: PathPrefix + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-3 + namespace: envoy-gateway + sectionName: http infraIR: envoy-gateway/gateway-1: proxy: @@ -456,6 +618,24 @@ infraIR: name: envoy-gateway-class name: envoy-gateway/gateway-2 namespace: envoy-gateway-system + envoy-gateway/gateway-3: + proxy: + listeners: + - name: envoy-gateway/gateway-3/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-3 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-3 + namespace: envoy-gateway-system xdsIR: envoy-gateway/gateway-1: accessLog: @@ -713,3 +893,94 @@ xdsIR: ipFamily: IPv4 path: /ready port: 19003 + envoy-gateway/gateway-3: + accessLog: + json: + - path: /dev/stdout + globalResources: + envoyClientCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + name: envoy-gateway-system/envoy + privateKey: '[redacted]' + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-3-32e857a6 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-3 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-3-32e857a6 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-3 + protocol: TCP + http: + - address: 0.0.0.0 + externalPort: 80 + hostnames: + - gw3.example.com + metadata: + kind: Gateway + name: gateway-3 + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/gateway-3/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-gw3 + namespace: default + name: httproute/default/httproute-gw3/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-gw3/rule/0/backend/0 + protocol: HTTP + weight: 1 + envoyExtensions: + fromGatewayPolicy: true + wasms: + - config: null + failOpen: false + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-gw3.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/6f443df69aab42a606fc6b8d18ce47bc6ed642c929cb2ed90adbaf509acf60f7.wasm + sha256: c377a55221a8fb8aacbac301b3e9f0cc0cb766a3442aebb32f39f38b72694027 + name: envoyextensionpolicy/envoy-gateway/policy-for-listener-wasm/wasm/0 + wasmName: wasm-filter-gw3 + hostname: gw3.example.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-gw3 + namespace: default + name: httproute/default/httproute-gw3/rule/0/match/0/gw3_example_com + pathMatch: + distinct: false + name: "" + prefix: / + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 From 4e84e16fde3bd21054fb891eb637657eaacf5baf Mon Sep 17 00:00:00 2001 From: zirain Date: Fri, 10 Jul 2026 09:57:22 +0800 Subject: [PATCH 10/18] fix filter order Signed-off-by: zirain --- internal/xds/translator/httpfilters.go | 23 +++++++++++++++------ internal/xds/translator/httpfilters_test.go | 23 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index 1d7b2fa14e..508649585d 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -128,11 +128,13 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter { order = 10 case isFilterType(filter, egv1a1.EnvoyFilterBuffer): order = 11 - case filter.Name == luaListenerFCFilterName(): - // Listener-level (per-connection) Lua runs before route-level Lua. - order = 12 - case filter.Name == luaFCFilterName(): - order = 13 + case isFilterType(filter, egv1a1.EnvoyFilterLua): + if strings.Contains(filter.Name, "listener") { + // Listener-level Lua runs before route-level Lua. + order = 12 + } else { + order = 62 + } case isFilterType(filter, egv1a1.EnvoyFilterExtProc): order = 100 + mustGetFilterIndex(filter.Name) case isFilterType(filter, egv1a1.EnvoyFilterWasm): @@ -362,7 +364,16 @@ func isFilterType(filter *hcmv3.HttpFilter, filterType egv1a1.EnvoyFilter) bool // Multiple filters of the same types are added to the HCM filter chain, one for each // route. The filter name is prefixed with the filter type, for example: // "envoy.filters.http.oauth2_first-route". - return strings.HasPrefix(filter.Name, string(filterType)) + if strings.HasPrefix(filter.Name, string(filterType)) { + return true + } + // Lua is delivered via envoy.filters.http.filter_chain placeholder filters + // (luaFCFilterName/luaListenerFCFilterName) rather than under the envoy.filters.http.lua + // prefix, so FilterOrder entries that reference EnvoyFilterLua need to match those names too. + if filterType == egv1a1.EnvoyFilterLua { + return filter.Name == luaFCFilterName() || filter.Name == luaListenerFCFilterName() + } + return false } // mustGetFilterIndex returns the index of the filter in its filter type. diff --git a/internal/xds/translator/httpfilters_test.go b/internal/xds/translator/httpfilters_test.go index 7e988be4c7..b663ca9c95 100644 --- a/internal/xds/translator/httpfilters_test.go +++ b/internal/xds/translator/httpfilters_test.go @@ -427,6 +427,29 @@ func Test_sortHTTPFilters(t *testing.T) { httpFilterForTest(egv1a1.EnvoyFilterRouter), }, }, + { + name: "custom filter order-lua-filter-chain-placeholder", + filters: []*hcmv3.HttpFilter{ + httpFilterForTest(egv1a1.EnvoyFilterRouter), + httpFilterForTest(egv1a1.EnvoyFilterExtProc + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(egv1a1.EnvoyFilter(luaFCFilterName())), + httpFilterForTest(egv1a1.EnvoyFilter(luaListenerFCFilterName())), + httpFilterForTest(egv1a1.EnvoyFilterWasm + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + }, + filterOrder: []egv1a1.FilterPosition{ + { + Name: egv1a1.EnvoyFilterLua, + After: new(egv1a1.EnvoyFilterWasm), + }, + }, + want: []*hcmv3.HttpFilter{ + httpFilterForTest(egv1a1.EnvoyFilterExtProc + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(egv1a1.EnvoyFilterWasm + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(egv1a1.EnvoyFilter(luaListenerFCFilterName())), + httpFilterForTest(egv1a1.EnvoyFilter(luaFCFilterName())), + httpFilterForTest(egv1a1.EnvoyFilterRouter), + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 89f81ac3baaf23b57fd306c42888ec7b6d094fc6 Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 13 Jul 2026 09:07:12 +0800 Subject: [PATCH 11/18] fix Signed-off-by: zirain --- internal/ir/xds.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ir/xds.go b/internal/ir/xds.go index f689db82dc..4b5eb72c49 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -3895,7 +3895,7 @@ type ExtProc struct { type Lua struct { // Name is a unique name for the LUa configuration. // The xds translator only generates one Lua filter for each unique name - Name string + Name string `json:"name" yaml:"name"` // Code is the Lua source code Code *string `json:"code,omitempty" yaml:"code,omitempty"` // FilterContext is the filter context configuration for the Lua script. From 2391cce17267f2c8365d35488451386c27d2cab8 Mon Sep 17 00:00:00 2001 From: zirain Date: Sun, 2 Aug 2026 16:23:53 +0800 Subject: [PATCH 12/18] fix after rebase Signed-off-by: zirain --- internal/gatewayapi/envoyextensionpolicy.go | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index cf06406a2f..e1015a80f1 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -540,7 +540,7 @@ func (t *Translator) processEnvoyExtensionPolicyForGateway( } // Set conditions for translation error if it got any - if err := t.translateEnvoyExtensionPolicyForGateway(policy, currTarget, targetedGateway, gatewayMap[gatewayNN].attachedToListeners, xdsIR, resources); err != nil { + if err := t.translateEnvoyExtensionPolicyForGateway(policy, currTarget, targetedGateway, xdsIR, resources); err != nil { status.SetTranslationErrorForPolicyAncestor(&policy.Status, &ancestorRef, t.GatewayControllerName, @@ -875,7 +875,6 @@ func (t *Translator) translateEnvoyExtensionPolicyForGateway( policy *egv1a1.EnvoyExtensionPolicy, target policyTargetReferenceWithSectionName, gateway *GatewayContext, - attachedToListeners sets.Set[string], xdsIR resource.XdsIRMap, resources *resource.Resources, ) error { @@ -963,14 +962,6 @@ func (t *Translator) translateEnvoyExtensionPolicyForListeners( continue } - // A Gateway-wide policy must not apply to a listener that already has its own, - // more-specific listener policy attached — even when that listener policy carries no - // Lua of its own. Otherwise a Gateway-wide Lua policy could still be installed on the - // listener's HCM and run on routes that the listener policy is meant to fully govern. - if target.SectionName == nil && attachedToListeners.Has(http.Metadata.SectionName) { - continue - } - // if already set - there's a specific level policy, so skip if http.EnvoyExtensions != nil { continue From 1b8aedd47408350dda723b2b9944463ba8fe6c4e Mon Sep 17 00:00:00 2001 From: zirain Date: Sun, 2 Aug 2026 20:47:20 +0800 Subject: [PATCH 13/18] apply filter_chain filter to all extensions Signed-off-by: zirain --- internal/gatewayapi/envoyextensionpolicy.go | 54 ++-- internal/gatewayapi/globalresources.go | 3 + .../testdata/custom-filter-order.out.yaml | 49 ++-- ...tensionpolicy-listenerset-invalid.out.yaml | 7 + ...y-listenerset-same-name-listeners.out.yaml | 45 ++-- .../envoyextensionpolicy-listenerset.out.yaml | 60 +++-- ...yextensionpolicy-override-replace.out.yaml | 47 ++-- ...extensionpolicy-route-listenerset.out.yaml | 54 ++-- ...nsionpolicy-section-name-override.out.yaml | 94 ++++--- ...xtensionpolicy-with-dynamicmodule.out.yaml | 41 ++- ...kendtlspolicy-per-resource-secret.out.yaml | 234 ++++++------------ ...th-backendtlspolicy-shared-secret.out.yaml | 234 ++++++------------ ...ith-extproc-with-backendtlspolicy.out.yaml | 146 ++++------- ...yextensionpolicy-with-invalid-lua.out.yaml | 4 - ...xtensionpolicy-with-lua-configmap.out.yaml | 8 - .../envoyextensionpolicy-with-lua.out.yaml | 29 +-- ...xtensionpolicy-with-wasm-env-vars.out.yaml | 67 +++-- ...y-with-wasm-invalid-configuration.out.yaml | 4 - ...ensionpolicy-with-wasm-targetrefs.out.yaml | 49 ++-- .../envoyextensionpolicy-with-wasm.out.yaml | 67 +++-- internal/ir/xds.go | 2 - internal/ir/zz_generated.deepcopy.go | 5 - internal/xds/translator/api_key_auth.go | 2 +- internal/xds/translator/authorization.go | 2 +- internal/xds/translator/bandwidth_limit.go | 2 +- internal/xds/translator/basicauth.go | 2 +- internal/xds/translator/compressor.go | 2 +- internal/xds/translator/cors.go | 2 +- internal/xds/translator/credentialInjector.go | 2 +- internal/xds/translator/custom_response.go | 2 +- .../xds/translator/dynamic_forward_proxy.go | 2 +- internal/xds/translator/dynamicmodule.go | 99 ++++++-- internal/xds/translator/extauth.go | 2 +- internal/xds/translator/extproc.go | 99 ++++++-- internal/xds/translator/fault.go | 2 +- internal/xds/translator/geoip.go | 2 +- internal/xds/translator/globalresources.go | 3 + internal/xds/translator/header_mutation.go | 2 +- internal/xds/translator/healthcheck.go | 2 +- internal/xds/translator/httpfilters.go | 6 +- internal/xds/translator/jwt.go | 2 +- internal/xds/translator/local_ratelimit.go | 2 +- internal/xds/translator/lua.go | 19 +- internal/xds/translator/oidc.go | 2 +- internal/xds/translator/request_buffer.go | 2 +- .../xds/translator/session_persistence.go | 2 +- .../testdata/in/xds-ir/dynamicmodule.yaml | 95 +++++++ .../testdata/in/xds-ir/ext-proc.yaml | 96 +++++++ .../translator/testdata/in/xds-ir/lua.yaml | 29 ++- .../translator/testdata/in/xds-ir/wasm.yaml | 96 +++++++ .../out/xds-ir/dynamicmodule.clusters.yaml | 117 +++++++++ .../out/xds-ir/dynamicmodule.endpoints.yaml | 36 +++ .../out/xds-ir/dynamicmodule.listeners.yaml | 57 +++++ .../out/xds-ir/dynamicmodule.routes.yaml | 43 ++++ .../out/xds-ir/ext-proc.clusters.yaml | 129 ++++++++++ .../out/xds-ir/ext-proc.endpoints.yaml | 46 ++++ .../out/xds-ir/ext-proc.listeners.yaml | 63 +++++ .../testdata/out/xds-ir/ext-proc.routes.yaml | 43 ++++ .../testdata/out/xds-ir/lua.routes.yaml | 7 +- .../testdata/out/xds-ir/wasm.clusters.yaml | 69 ++++++ .../testdata/out/xds-ir/wasm.endpoints.yaml | 36 +++ .../testdata/out/xds-ir/wasm.listeners.yaml | 83 +++++++ .../testdata/out/xds-ir/wasm.routes.yaml | 43 ++++ internal/xds/translator/translator.go | 2 +- internal/xds/translator/utils.go | 26 ++ internal/xds/translator/wasm.go | 80 +++++- ...31-lua-xds-layout-per-route-filterchain.md | 1 - .../9131-xds-layout-per-route-filterchain.md | 1 + 68 files changed, 1894 insertions(+), 871 deletions(-) delete mode 100644 release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md create mode 100644 release-notes/current/breaking_changes/9131-xds-layout-per-route-filterchain.md diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index e1015a80f1..0add78b51c 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -962,41 +962,39 @@ func (t *Translator) translateEnvoyExtensionPolicyForListeners( continue } - // if already set - there's a specific level policy, so skip + // A Policy targeting a more specific scope (xRoute rule, xRoute, Gateway + // listener, ListenerSet listener) wins over a policy targeting a lesser + // specific scope (Gateway/ListenerSet). A non-nil EnvoyExtensions means this + // listener is already owned by a more specific policy. if http.EnvoyExtensions != nil { continue } - // TODO: move other extensions to listener level. - // Only attach listener-level Lua when the policy succeeds; a fail-closed error in - // any other extension makes every route return a 500, so the Lua filter must not - // run on those synthetic error responses. - if len(luas) > 0 && !failed { - http.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ - Luas: luas, - } - } - - // A Policy targeting the specific scope(xRoute rule, xRoute, Gateway - // listener, ListenerSet listener) wins over a policy targeting a lesser - // specific scope(Gateway/ListenerSet). - for _, r := range http.Routes { - // if already set - there's a specific level policy, so skip - if r.EnvoyExtensions != nil { - continue - } - - if failed { + // Fail closed: a fail-closed error in any extension makes every route under + // this listener return a 500. No extension is attached at listener scope, so + // the filters do not run on those synthetic error responses. + if failed { + for _, r := range http.Routes { + // if already set - there's a specific level policy, so skip + if r.EnvoyExtensions != nil { + continue + } r.DirectResponse = &ir.CustomResponse{ StatusCode: new(uint32(500)), } - } else { - r.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ - ExtProcs: extProcs, - Wasms: wasms, - DynamicModules: dynamicModules, - FromGatewayPolicy: new(true), - } + } + continue + } + + // All extensions are attached at listener scope and delivered at VirtualHost + // scope by the xDS translator. Routes owned by a more specific policy carry + // their own EnvoyExtensions and fully override this one. + if len(extProcs) > 0 || len(wasms) > 0 || len(luas) > 0 || len(dynamicModules) > 0 { + http.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ + ExtProcs: extProcs, + Wasms: wasms, + Luas: luas, + DynamicModules: dynamicModules, } } } diff --git a/internal/gatewayapi/globalresources.go b/internal/gatewayapi/globalresources.go index 1000890724..71a8cc9262 100644 --- a/internal/gatewayapi/globalresources.go +++ b/internal/gatewayapi/globalresources.go @@ -116,6 +116,9 @@ func containsGlobalRateLimit(httpListeners []*ir.HTTPListener) bool { func containsWasm(httpListeners []*ir.HTTPListener) bool { for _, httpListener := range httpListeners { + if httpListener.EnvoyExtensions != nil && len(httpListener.EnvoyExtensions.Wasms) > 0 { + return true + } for _, route := range httpListener.Routes { if route.EnvoyExtensions != nil && len(route.EnvoyExtensions.Wasms) > 0 { diff --git a/internal/gatewayapi/testdata/custom-filter-order.out.yaml b/internal/gatewayapi/testdata/custom-filter-order.out.yaml index 122246db68..ee3cb2cc0b 100644 --- a/internal/gatewayapi/testdata/custom-filter-order.out.yaml +++ b/internal/gatewayapi/testdata/custom-filter-order.out.yaml @@ -257,6 +257,30 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + wasms: + - config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + failOpen: false + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 + wasmName: wasm-filter-1 + - config: + parameter1: value1 + parameter2: value2 + failOpen: false + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-2.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/593e4cc60a7e0fa4d4f86531a5e20e785213a52000f056a7a8b5c5afcb908052.wasm + sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 + wasmName: wasm-filter-2 externalPort: 80 hostnames: - '*' @@ -290,31 +314,6 @@ xdsIR: name: httproute/envoy-gateway/httproute-1/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true - wasms: - - config: - parameter1: - key1: value1 - key2: value2 - parameter2: value3 - failOpen: false - httpWasmCode: - originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm - sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 - wasmName: wasm-filter-1 - - config: - parameter1: value1 - parameter2: value2 - failOpen: false - httpWasmCode: - originalDownloadingURL: https://www.example.com/wasm-filter-2.wasm - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/593e4cc60a7e0fa4d4f86531a5e20e785213a52000f056a7a8b5c5afcb908052.wasm - sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 - wasmName: wasm-filter-2 hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset-invalid.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset-invalid.out.yaml index 67fff3b192..a37e2668b9 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset-invalid.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset-invalid.out.yaml @@ -331,6 +331,13 @@ xdsIR: mergeSlashes: true port: 10080 - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("listenerset-section") + end + name: envoyextensionpolicy/envoy-gateway/target-listenerset-section/lua/0 externalPort: 8081 hostnames: - '*' diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset-same-name-listeners.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset-same-name-listeners.out.yaml index e20142ef28..526e406cce 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset-same-name-listeners.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset-same-name-listeners.out.yaml @@ -423,6 +423,13 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("gateway-shared") + end + name: envoyextensionpolicy/envoy-gateway/target-gateway-shared/lua/0 externalPort: 80 hostnames: - '*' @@ -456,14 +463,6 @@ xdsIR: name: httproute/default/route-on-gateway/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("gateway-shared") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-gateway-shared/lua/0 hostname: '*' isHTTP2: false metadata: @@ -476,6 +475,13 @@ xdsIR: name: "" prefix: / - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("listenerset-shared") + end + name: envoyextensionpolicy/envoy-gateway/target-listenerset-shared/lua/0 externalPort: 8081 hostnames: - '*' @@ -509,14 +515,6 @@ xdsIR: name: httproute/default/route-on-listenerset/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("listenerset-shared") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-listenerset-shared/lua/0 hostname: '*' isHTTP2: false metadata: @@ -529,6 +527,13 @@ xdsIR: name: "" prefix: / - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("other-listenerset-shared") + end + name: envoyextensionpolicy/envoy-gateway/target-other-listenerset-shared/lua/0 externalPort: 8082 hostnames: - '*' @@ -562,14 +567,6 @@ xdsIR: name: httproute/default/route-on-other-listenerset/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("other-listenerset-shared") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-other-listenerset-shared/lua/0 hostname: '*' isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset.out.yaml index 3ec3c1f5b9..e652817f5b 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-listenerset.out.yaml @@ -441,6 +441,13 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("gateway") + end + name: envoyextensionpolicy/envoy-gateway/target-gw/lua/0 externalPort: 80 hostnames: - '*' @@ -474,14 +481,6 @@ xdsIR: name: httproute/default/route-on-gw/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("gateway") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-gw/lua/0 hostname: '*' isHTTP2: false metadata: @@ -494,6 +493,13 @@ xdsIR: name: "" prefix: / - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("gateway-section") + end + name: envoyextensionpolicy/envoy-gateway/target-gw-section/lua/0 externalPort: 8080 hostnames: - '*' @@ -527,14 +533,6 @@ xdsIR: name: httproute/default/route-on-gw/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("gateway-section") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-gw-section/lua/0 hostname: '*' isHTTP2: false metadata: @@ -547,6 +545,13 @@ xdsIR: name: "" prefix: / - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("listenerset-section") + end + name: envoyextensionpolicy/envoy-gateway/target-listenerset-section/lua/0 externalPort: 8081 hostnames: - '*' @@ -580,14 +585,6 @@ xdsIR: name: httproute/default/route-on-ls/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("listenerset-section") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-listenerset-section/lua/0 hostname: '*' isHTTP2: false metadata: @@ -600,6 +597,13 @@ xdsIR: name: "" prefix: / - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("listenerset") + end + name: envoyextensionpolicy/envoy-gateway/target-listenerset/lua/0 externalPort: 8082 hostnames: - '*' @@ -633,14 +637,6 @@ xdsIR: name: httproute/default/route-on-ls/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("listenerset") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-listenerset/lua/0 hostname: '*' isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml index cec0d86359..ea24901c3a 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-override-replace.out.yaml @@ -301,6 +301,29 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + extProcs: + - authority: grpc-backend.envoy-gateway:9000 + destination: + metadata: + kind: EnvoyExtensionPolicy + name: policy-for-gateway-1 + namespace: envoy-gateway + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.1 + port: 9000 + metadata: + kind: Service + name: grpc-backend + namespace: envoy-gateway + sectionName: "9000" + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0/backend/0 + protocol: GRPC + weight: 1 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 externalPort: 80 hostnames: - '*' @@ -387,30 +410,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - extProcs: - - authority: grpc-backend.envoy-gateway:9000 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway-1 - namespace: envoy-gateway - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.1 - port: 9000 - metadata: - kind: Service - name: grpc-backend - namespace: envoy-gateway - sectionName: "9000" - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0/backend/0 - protocol: GRPC - weight: 1 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 - fromGatewayPolicy: true hostname: gateway.envoyproxy.io isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-route-listenerset.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-route-listenerset.out.yaml index 376026565e..a67c1e45db 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-route-listenerset.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-route-listenerset.out.yaml @@ -478,6 +478,13 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("gateway") + end + name: envoyextensionpolicy/envoy-gateway/target-gw/lua/0 externalPort: 80 hostnames: - '*' @@ -511,14 +518,6 @@ xdsIR: name: httproute/default/route-on-gw/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("gateway") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-gw/lua/0 hostname: '*' isHTTP2: false metadata: @@ -531,6 +530,13 @@ xdsIR: name: "" prefix: / - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("gateway-section") + end + name: envoyextensionpolicy/envoy-gateway/target-gw-section/lua/0 externalPort: 8080 hostnames: - '*' @@ -564,14 +570,6 @@ xdsIR: name: httproute/default/route-on-gw/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - luas: - - Code: | - function envoy_on_request(request_handle) - request_handle:logInfo("gateway-section") - end - FilterContext: null - Name: envoyextensionpolicy/envoy-gateway/target-gw-section/lua/0 hostname: '*' isHTTP2: false metadata: @@ -584,6 +582,13 @@ xdsIR: name: "" prefix: / - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("listenerset-section") + end + name: envoyextensionpolicy/envoy-gateway/target-listenerset-section/lua/0 externalPort: 8081 hostnames: - '*' @@ -619,12 +624,11 @@ xdsIR: weight: 1 envoyExtensions: luas: - - Code: | + - code: | function envoy_on_request(request_handle) request_handle:logInfo("route") end - FilterContext: null - Name: envoyextensionpolicy/default/target-route/lua/0 + name: envoyextensionpolicy/default/target-route/lua/0 hostname: '*' isHTTP2: false metadata: @@ -637,6 +641,13 @@ xdsIR: name: "" prefix: / - address: 0.0.0.0 + envoyExtensions: + luas: + - code: | + function envoy_on_request(request_handle) + request_handle:logInfo("listenerset") + end + name: envoyextensionpolicy/envoy-gateway/target-listenerset/lua/0 externalPort: 8082 hostnames: - '*' @@ -672,12 +683,11 @@ xdsIR: weight: 1 envoyExtensions: luas: - - Code: | + - code: | function envoy_on_request(request_handle) request_handle:logInfo("route") end - FilterContext: null - Name: envoyextensionpolicy/default/target-route/lua/0 + name: envoyextensionpolicy/default/target-route/lua/0 hostname: '*' isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-section-name-override.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-section-name-override.out.yaml index 8f106a951a..dbccf89487 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-section-name-override.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-section-name-override.out.yaml @@ -359,6 +359,29 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + extProcs: + - authority: grpc-backend-2.envoy-gateway:8002 + destination: + metadata: + kind: EnvoyExtensionPolicy + name: policy-for-gateway-1-listener-1 + namespace: envoy-gateway + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1-listener-1/extproc/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.2 + port: 8002 + metadata: + kind: Service + name: grpc-backend-2 + namespace: envoy-gateway + sectionName: "8002" + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1-listener-1/extproc/0/backend/0 + protocol: GRPC + weight: 1 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1-listener-1/extproc/0 externalPort: 8081 hostnames: - '*' @@ -503,30 +526,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - extProcs: - - authority: grpc-backend-2.envoy-gateway:8002 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway-1-listener-1 - namespace: envoy-gateway - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1-listener-1/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.2 - port: 8002 - metadata: - kind: Service - name: grpc-backend-2 - namespace: envoy-gateway - sectionName: "8002" - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1-listener-1/extproc/0/backend/0 - protocol: GRPC - weight: 1 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1-listener-1/extproc/0 - fromGatewayPolicy: true hostname: gateway.envoyproxy.io isHTTP2: false metadata: @@ -540,6 +539,29 @@ xdsIR: name: "" prefix: /foo - address: 0.0.0.0 + envoyExtensions: + extProcs: + - authority: grpc-backend-1.envoy-gateway:8001 + destination: + metadata: + kind: EnvoyExtensionPolicy + name: policy-for-gateway-1 + namespace: envoy-gateway + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.1 + port: 8001 + metadata: + kind: Service + name: grpc-backend-1 + namespace: envoy-gateway + sectionName: "8001" + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0/backend/0 + protocol: GRPC + weight: 1 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 externalPort: 8082 hostnames: - '*' @@ -574,30 +596,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - extProcs: - - authority: grpc-backend-1.envoy-gateway:8001 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway-1 - namespace: envoy-gateway - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.1 - port: 8001 - metadata: - kind: Service - name: grpc-backend-1 - namespace: envoy-gateway - sectionName: "8001" - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0/backend/0 - protocol: GRPC - weight: 1 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 - fromGatewayPolicy: true hostname: gateway.envoyproxy.io isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-dynamicmodule.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-dynamicmodule.out.yaml index e5e0faaae3..d4c20c6bc4 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-dynamicmodule.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-dynamicmodule.out.yaml @@ -335,6 +335,26 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + dynamicModules: + - config: + authEndpoint: https://auth.example.com + doNotClose: false + filterName: auth-check + loadGlobally: false + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/dynamic-module/0 + path: /usr/lib/envoy/modules/my_auth.so + terminalFilter: false + - config: + authEndpoint: https://remote-auth.example.com + doNotClose: false + filterName: remote-auth-check + loadGlobally: false + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/dynamic-module/1 + remote: + sha256: abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 + url: https://modules.example.com/libremote_auth.so + terminalFilter: false externalPort: 80 hostnames: - '*' @@ -414,27 +434,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - dynamicModules: - - config: - authEndpoint: https://auth.example.com - doNotClose: false - filterName: auth-check - loadGlobally: false - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/dynamic-module/0 - path: /usr/lib/envoy/modules/my_auth.so - terminalFilter: false - - config: - authEndpoint: https://remote-auth.example.com - doNotClose: false - filterName: remote-auth-check - loadGlobally: false - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/dynamic-module/1 - remote: - sha256: abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 - url: https://modules.example.com/libremote_auth.so - terminalFilter: false - fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy-per-resource-secret.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy-per-resource-secret.out.yaml index 8f5c6ead3a..d404fd6e65 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy-per-resource-secret.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy-per-resource-secret.out.yaml @@ -369,6 +369,84 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + extProcs: + - allowModeOverride: true + authority: grpc-backend.envoy-gateway:8000 + destination: + metadata: + kind: EnvoyExtensionPolicy + name: policy-for-gateway + namespace: default + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8000 + metadata: + kind: Service + name: grpc-backend + namespace: envoy-gateway + sectionName: "8000" + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 + protocol: GRPC + tls: + alpnProtocols: null + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-grpc/envoy-gateway-ca + maxVersion: "1.3" + minVersion: "1.2" + sni: grpc-backend + weight: 1 + failOpen: true + forwardingMetadataNamespaces: + - envoy.filters.http.ext_authz + messageTimeout: 5s + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 + receivingMetadataNamespaces: + - envoy.filters.http.my_custom + requestAttributes: + - request.path + requestBodyProcessingMode: Buffered + requestHeaderProcessing: true + responseAttributes: + - xds.route_metadata + - connection.requested_server_name + responseBodyProcessingMode: Streamed + responseHeaderProcessing: true + - authority: grpc-backend-system-ca.default:9001 + destination: + metadata: + kind: EnvoyExtensionPolicy + name: policy-for-gateway + namespace: default + name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 + settings: + - addressType: IP + endpoints: + - host: 9.9.9.9 + port: 9001 + metadata: + kind: Service + name: grpc-backend-system-ca + namespace: default + sectionName: "9001" + name: envoyextensionpolicy/default/policy-for-gateway/extproc/1/backend/0 + protocol: GRPC + tls: + alpnProtocols: null + caCertificate: + name: policy-btls-grpc-system-ca/default-ca + maxVersion: "1.3" + minVersion: "1.2" + sni: grpc-backend-system-ca + useSystemTrustStore: true + weight: 1 + name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 + requestHeaderProcessing: true + responseHeaderProcessing: true externalPort: 80 hostnames: - '*' @@ -404,84 +482,6 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - extProcs: - - allowModeOverride: true - authority: grpc-backend.envoy-gateway:8000 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8000 - metadata: - kind: Service - name: grpc-backend - namespace: envoy-gateway - sectionName: "8000" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc/envoy-gateway-ca - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend - weight: 1 - failOpen: true - forwardingMetadataNamespaces: - - envoy.filters.http.ext_authz - messageTimeout: 5s - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - receivingMetadataNamespaces: - - envoy.filters.http.my_custom - requestAttributes: - - request.path - requestBodyProcessingMode: Buffered - requestHeaderProcessing: true - responseAttributes: - - xds.route_metadata - - connection.requested_server_name - responseBodyProcessingMode: Streamed - responseHeaderProcessing: true - - authority: grpc-backend-system-ca.default:9001 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 - settings: - - addressType: IP - endpoints: - - host: 9.9.9.9 - port: 9001 - metadata: - kind: Service - name: grpc-backend-system-ca - namespace: default - sectionName: "9001" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - name: policy-btls-grpc-system-ca/default-ca - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend-system-ca - useSystemTrustStore: true - weight: 1 - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 - requestHeaderProcessing: true - responseHeaderProcessing: true hostname: www.foo.com isHTTP2: false metadata: @@ -512,84 +512,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - extProcs: - - allowModeOverride: true - authority: grpc-backend.envoy-gateway:8000 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8000 - metadata: - kind: Service - name: grpc-backend - namespace: envoy-gateway - sectionName: "8000" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc/envoy-gateway-ca - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend - weight: 1 - failOpen: true - forwardingMetadataNamespaces: - - envoy.filters.http.ext_authz - messageTimeout: 5s - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - receivingMetadataNamespaces: - - envoy.filters.http.my_custom - requestAttributes: - - request.path - requestBodyProcessingMode: Buffered - requestHeaderProcessing: true - responseAttributes: - - xds.route_metadata - - connection.requested_server_name - responseBodyProcessingMode: Streamed - responseHeaderProcessing: true - - authority: grpc-backend-system-ca.default:9001 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 - settings: - - addressType: IP - endpoints: - - host: 9.9.9.9 - port: 9001 - metadata: - kind: Service - name: grpc-backend-system-ca - namespace: default - sectionName: "9001" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - name: policy-btls-grpc-system-ca/default-ca - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend-system-ca - useSystemTrustStore: true - weight: 1 - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 - requestHeaderProcessing: true - responseHeaderProcessing: true hostname: www.bar.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy-shared-secret.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy-shared-secret.out.yaml index e7507cf3d9..a01b2c5856 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy-shared-secret.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy-shared-secret.out.yaml @@ -369,6 +369,84 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + extProcs: + - allowModeOverride: true + authority: grpc-backend.envoy-gateway:8000 + destination: + metadata: + kind: EnvoyExtensionPolicy + name: policy-for-gateway + namespace: default + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8000 + metadata: + kind: Service + name: grpc-backend + namespace: envoy-gateway + sectionName: "8000" + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 + protocol: GRPC + tls: + alpnProtocols: null + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-grpc/envoy-gateway-ca + maxVersion: "1.3" + minVersion: "1.2" + sni: grpc-backend + weight: 1 + failOpen: true + forwardingMetadataNamespaces: + - envoy.filters.http.ext_authz + messageTimeout: 5s + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 + receivingMetadataNamespaces: + - envoy.filters.http.my_custom + requestAttributes: + - request.path + requestBodyProcessingMode: Buffered + requestHeaderProcessing: true + responseAttributes: + - xds.route_metadata + - connection.requested_server_name + responseBodyProcessingMode: Streamed + responseHeaderProcessing: true + - authority: grpc-backend-system-ca.default:9001 + destination: + metadata: + kind: EnvoyExtensionPolicy + name: policy-for-gateway + namespace: default + name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 + settings: + - addressType: IP + endpoints: + - host: 9.9.9.9 + port: 9001 + metadata: + kind: Service + name: grpc-backend-system-ca + namespace: default + sectionName: "9001" + name: envoyextensionpolicy/default/policy-for-gateway/extproc/1/backend/0 + protocol: GRPC + tls: + alpnProtocols: null + caCertificate: + name: system_ca_certificates + maxVersion: "1.3" + minVersion: "1.2" + sni: grpc-backend-system-ca + useSystemTrustStore: true + weight: 1 + name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 + requestHeaderProcessing: true + responseHeaderProcessing: true externalPort: 80 hostnames: - '*' @@ -404,84 +482,6 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - extProcs: - - allowModeOverride: true - authority: grpc-backend.envoy-gateway:8000 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8000 - metadata: - kind: Service - name: grpc-backend - namespace: envoy-gateway - sectionName: "8000" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc/envoy-gateway-ca - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend - weight: 1 - failOpen: true - forwardingMetadataNamespaces: - - envoy.filters.http.ext_authz - messageTimeout: 5s - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - receivingMetadataNamespaces: - - envoy.filters.http.my_custom - requestAttributes: - - request.path - requestBodyProcessingMode: Buffered - requestHeaderProcessing: true - responseAttributes: - - xds.route_metadata - - connection.requested_server_name - responseBodyProcessingMode: Streamed - responseHeaderProcessing: true - - authority: grpc-backend-system-ca.default:9001 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 - settings: - - addressType: IP - endpoints: - - host: 9.9.9.9 - port: 9001 - metadata: - kind: Service - name: grpc-backend-system-ca - namespace: default - sectionName: "9001" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - name: system_ca_certificates - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend-system-ca - useSystemTrustStore: true - weight: 1 - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 - requestHeaderProcessing: true - responseHeaderProcessing: true hostname: www.foo.com isHTTP2: false metadata: @@ -512,84 +512,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - extProcs: - - allowModeOverride: true - authority: grpc-backend.envoy-gateway:8000 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8000 - metadata: - kind: Service - name: grpc-backend - namespace: envoy-gateway - sectionName: "8000" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc/envoy-gateway-ca - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend - weight: 1 - failOpen: true - forwardingMetadataNamespaces: - - envoy.filters.http.ext_authz - messageTimeout: 5s - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - receivingMetadataNamespaces: - - envoy.filters.http.my_custom - requestAttributes: - - request.path - requestBodyProcessingMode: Buffered - requestHeaderProcessing: true - responseAttributes: - - xds.route_metadata - - connection.requested_server_name - responseBodyProcessingMode: Streamed - responseHeaderProcessing: true - - authority: grpc-backend-system-ca.default:9001 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 - settings: - - addressType: IP - endpoints: - - host: 9.9.9.9 - port: 9001 - metadata: - kind: Service - name: grpc-backend-system-ca - namespace: default - sectionName: "9001" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - name: system_ca_certificates - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend-system-ca - useSystemTrustStore: true - weight: 1 - name: envoyextensionpolicy/default/policy-for-gateway/extproc/1 - requestHeaderProcessing: true - responseHeaderProcessing: true hostname: www.bar.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml index 520a97ea8f..cbe3971b52 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml @@ -330,6 +330,54 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + extProcs: + - allowModeOverride: true + authority: grpc-backend.envoy-gateway:8000 + destination: + metadata: + kind: EnvoyExtensionPolicy + name: policy-for-gateway + namespace: default + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8000 + metadata: + kind: Service + name: grpc-backend + namespace: envoy-gateway + sectionName: "8000" + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 + protocol: GRPC + tls: + alpnProtocols: null + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-grpc/envoy-gateway-ca + maxVersion: "1.3" + minVersion: "1.2" + sni: grpc-backend + weight: 1 + failOpen: true + forwardingMetadataNamespaces: + - envoy.filters.http.ext_authz + messageTimeout: 5s + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 + receivingMetadataNamespaces: + - envoy.filters.http.my_custom + requestAttributes: + - request.path + requestBodyProcessingMode: Buffered + requestHeaderProcessing: true + responseAttributes: + - xds.route_metadata + - connection.requested_server_name + responseBodyProcessingMode: Streamed + responseHeaderProcessing: true + statusOnError: 503 externalPort: 80 hostnames: - '*' @@ -365,55 +413,6 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - extProcs: - - allowModeOverride: true - authority: grpc-backend.envoy-gateway:8000 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8000 - metadata: - kind: Service - name: grpc-backend - namespace: envoy-gateway - sectionName: "8000" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc/envoy-gateway-ca - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend - weight: 1 - failOpen: true - forwardingMetadataNamespaces: - - envoy.filters.http.ext_authz - messageTimeout: 5s - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - receivingMetadataNamespaces: - - envoy.filters.http.my_custom - requestAttributes: - - request.path - requestBodyProcessingMode: Buffered - requestHeaderProcessing: true - responseAttributes: - - xds.route_metadata - - connection.requested_server_name - responseBodyProcessingMode: Streamed - responseHeaderProcessing: true - statusOnError: 503 - fromGatewayPolicy: true hostname: www.foo.com isHTTP2: false metadata: @@ -444,55 +443,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - extProcs: - - allowModeOverride: true - authority: grpc-backend.envoy-gateway:8000 - destination: - metadata: - kind: EnvoyExtensionPolicy - name: policy-for-gateway - namespace: default - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8000 - metadata: - kind: Service - name: grpc-backend - namespace: envoy-gateway - sectionName: "8000" - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 - protocol: GRPC - tls: - alpnProtocols: null - caCertificate: - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc/envoy-gateway-ca - maxVersion: "1.3" - minVersion: "1.2" - sni: grpc-backend - weight: 1 - failOpen: true - forwardingMetadataNamespaces: - - envoy.filters.http.ext_authz - messageTimeout: 5s - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - receivingMetadataNamespaces: - - envoy.filters.http.my_custom - requestAttributes: - - request.path - requestBodyProcessingMode: Buffered - requestHeaderProcessing: true - responseAttributes: - - xds.route_metadata - - connection.requested_server_name - responseBodyProcessingMode: Streamed - responseHeaderProcessing: true - statusOnError: 503 - fromGatewayPolicy: true hostname: www.bar.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml index 81c75376eb..e8a0f6b7ab 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-invalid-lua.out.yaml @@ -293,8 +293,6 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -325,8 +323,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml index 800eb241ed..dc6adc46bf 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua-configmap.out.yaml @@ -467,8 +467,6 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -501,8 +499,6 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -535,8 +531,6 @@ xdsIR: weight: 1 directResponse: statusCode: 500 - envoyExtensions: - fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -606,8 +600,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml index 0fd19f58cf..c744c980a8 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-lua.out.yaml @@ -236,7 +236,7 @@ envoyExtensionPolicies: type: Warning - lastTransitionTime: null message: 'This policy is being overridden by other envoyExtensionPolicies - for these listeners: [http]' + for these gateway listeners: [envoy-gateway/gateway-3/http]' observedGeneration: 40 reason: Overridden status: "True" @@ -740,8 +740,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true hostname: www.example.com isHTTP2: false metadata: @@ -823,8 +821,6 @@ xdsIR: name: httproute/default/httproute-a/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true hostname: app-a.example.com isHTTP2: false metadata: @@ -875,8 +871,6 @@ xdsIR: name: httproute/default/httproute-b/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true hostname: app-b.example.com isHTTP2: false metadata: @@ -924,6 +918,16 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + wasms: + - config: null + failOpen: false + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-gw3.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/6f443df69aab42a606fc6b8d18ce47bc6ed642c929cb2ed90adbaf509acf60f7.wasm + sha256: c377a55221a8fb8aacbac301b3e9f0cc0cb766a3442aebb32f39f38b72694027 + name: envoyextensionpolicy/envoy-gateway/policy-for-listener-wasm/wasm/0 + wasmName: wasm-filter-gw3 externalPort: 80 hostnames: - gw3.example.com @@ -957,17 +961,6 @@ xdsIR: name: httproute/default/httproute-gw3/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true - wasms: - - config: null - failOpen: false - httpWasmCode: - originalDownloadingURL: https://www.example.com/wasm-filter-gw3.wasm - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/6f443df69aab42a606fc6b8d18ce47bc6ed642c929cb2ed90adbaf509acf60f7.wasm - sha256: c377a55221a8fb8aacbac301b3e9f0cc0cb766a3442aebb32f39f38b72694027 - name: envoyextensionpolicy/envoy-gateway/policy-for-listener-wasm/wasm/0 - wasmName: wasm-filter-gw3 hostname: gw3.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml index fcd2c1a9da..0a0c0906e7 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-env-vars.out.yaml @@ -271,6 +271,39 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + wasms: + - config: null + failOpen: false + hostKeys: + - SOME_KEY + - ANOTHER_KEY + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 + wasmName: wasm-filter-1 + - config: null + failOpen: false + hostKeys: + - SOME_KEY + - ANOTHER_KEY + httpWasmCode: + originalDownloadingURL: oci://www.example.com/wasm-filter-2:v1.0.0 + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm + sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 + rootID: my-root-id + wasmName: wasm-filter-2 + - config: null + failOpen: false + httpWasmCode: + originalDownloadingURL: oci://www.example.com:8080/wasm-filter-3:latest + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm + sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 + wasmName: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 externalPort: 80 hostnames: - '*' @@ -347,40 +380,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true - wasms: - - config: null - failOpen: false - hostKeys: - - SOME_KEY - - ANOTHER_KEY - httpWasmCode: - originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm - sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 - wasmName: wasm-filter-1 - - config: null - failOpen: false - hostKeys: - - SOME_KEY - - ANOTHER_KEY - httpWasmCode: - originalDownloadingURL: oci://www.example.com/wasm-filter-2:v1.0.0 - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm - sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 - rootID: my-root-id - wasmName: wasm-filter-2 - - config: null - failOpen: false - httpWasmCode: - originalDownloadingURL: oci://www.example.com:8080/wasm-filter-3:latest - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm - sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 - wasmName: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml index d1aadf0593..f7bfb1b28b 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml @@ -931,8 +931,6 @@ xdsIR: name: httproute/default/httproute-5/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true hostname: www.foo.com isHTTP2: false metadata: @@ -963,8 +961,6 @@ xdsIR: name: httproute/default/httproute-6/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true hostname: www.bar.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml index 33b1fe86fb..1ec50b0166 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-targetrefs.out.yaml @@ -232,6 +232,30 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + wasms: + - config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + failOpen: false + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 + wasmName: wasm-filter-1 + - config: + parameter1: value1 + parameter2: value2 + failOpen: false + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-2.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/593e4cc60a7e0fa4d4f86531a5e20e785213a52000f056a7a8b5c5afcb908052.wasm + sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 + wasmName: wasm-filter-2 externalPort: 80 hostnames: - '*' @@ -319,31 +343,6 @@ xdsIR: name: httproute/envoy-gateway/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true - wasms: - - config: - parameter1: - key1: value1 - key2: value2 - parameter2: value3 - failOpen: false - httpWasmCode: - originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm - sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 - wasmName: wasm-filter-1 - - config: - parameter1: value1 - parameter2: value2 - failOpen: false - httpWasmCode: - originalDownloadingURL: https://www.example.com/wasm-filter-2.wasm - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/593e4cc60a7e0fa4d4f86531a5e20e785213a52000f056a7a8b5c5afcb908052.wasm - sha256: 84274ca23246855cc491b3c6a657a89167e0b109a7ae380f1e64df77c910307e - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 - wasmName: wasm-filter-2 hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml index 1d6291159f..bd354da86a 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm.out.yaml @@ -273,6 +273,39 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: + wasms: + - config: + parameter1: + key1: value1 + key2: value2 + parameter2: value3 + failOpen: false + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 + wasmName: wasm-filter-1 + - config: + parameter1: value1 + parameter2: value2 + failOpen: false + httpWasmCode: + originalDownloadingURL: oci://www.example.com/wasm-filter-2:v1.0.0 + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm + sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 + rootID: my-root-id + wasmName: wasm-filter-2 + - config: null + failOpen: false + httpWasmCode: + originalDownloadingURL: oci://www.example.com:8080/wasm-filter-3:latest + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm + sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 + wasmName: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 externalPort: 80 hostnames: - '*' @@ -351,40 +384,6 @@ xdsIR: name: httproute/default/httproute-2/rule/0/backend/0 protocol: HTTP weight: 1 - envoyExtensions: - fromGatewayPolicy: true - wasms: - - config: - parameter1: - key1: value1 - key2: value2 - parameter2: value3 - failOpen: false - httpWasmCode: - originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm - sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 - wasmName: wasm-filter-1 - - config: - parameter1: value1 - parameter2: value2 - failOpen: false - httpWasmCode: - originalDownloadingURL: oci://www.example.com/wasm-filter-2:v1.0.0 - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm - sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46 - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 - rootID: my-root-id - wasmName: wasm-filter-2 - - config: null - failOpen: false - httpWasmCode: - originalDownloadingURL: oci://www.example.com:8080/wasm-filter-3:latest - servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm - sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 - wasmName: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 hostname: www.example.com isHTTP2: false metadata: diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 4b5eb72c49..24301bd420 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -1265,8 +1265,6 @@ type EnvoyExtensionFeatures struct { Luas []Lua `json:"luas,omitempty" yaml:"luas,omitempty"` // Dynamic Module extensions DynamicModules []DynamicModule `json:"dynamicModules,omitempty" yaml:"dynamicModules,omitempty"` - // TODO: remove this after we moved all the extensions(e.g. extProc, Wasm, DYM) to use listener-level and route-level. - FromGatewayPolicy *bool `json:"fromGatewayPolicy,omitempty" yaml:"fromGatewayPolicy,omitempty"` } // UnstructuredRef holds unstructured data for an arbitrary k8s resource introduced by an extension diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index b75679458c..248aaa3b98 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1550,11 +1550,6 @@ func (in *EnvoyExtensionFeatures) DeepCopyInto(out *EnvoyExtensionFeatures) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.FromGatewayPolicy != nil { - in, out := &in.FromGatewayPolicy, &out.FromGatewayPolicy - *out = new(bool) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyExtensionFeatures. diff --git a/internal/xds/translator/api_key_auth.go b/internal/xds/translator/api_key_auth.go index bf545088b7..f491dcf40f 100644 --- a/internal/xds/translator/api_key_auth.go +++ b/internal/xds/translator/api_key_auth.go @@ -84,7 +84,7 @@ func buildHCMAPIKeyAuthFilter(apiKeyAuth *ir.APIKeyAuth) (*hcmv3.HttpFilter, err }, nil } -func (*apiKeyAuth) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*apiKeyAuth) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/authorization.go b/internal/xds/translator/authorization.go index 3cb29aea8d..fea8945546 100644 --- a/internal/xds/translator/authorization.go +++ b/internal/xds/translator/authorization.go @@ -693,7 +693,7 @@ func buildJWTPredicate(jwt egv1a1.JWTPrincipal) ([]*matcherv3.Matcher_MatcherLis return jwtPredicate, nil } -func (c *rbac) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (c *rbac) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/bandwidth_limit.go b/internal/xds/translator/bandwidth_limit.go index 1a7120c9ba..c17982e438 100644 --- a/internal/xds/translator/bandwidth_limit.go +++ b/internal/xds/translator/bandwidth_limit.go @@ -106,7 +106,7 @@ func listenerContainsBandwidthLimitResponse(irListener *ir.HTTPListener) bool { return false } -func (*bandwidthLimit) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*bandwidthLimit) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/basicauth.go b/internal/xds/translator/basicauth.go index 25799c8af5..da4560b7f8 100644 --- a/internal/xds/translator/basicauth.go +++ b/internal/xds/translator/basicauth.go @@ -109,7 +109,7 @@ func basicAuthFilterName(basicAuth *ir.BasicAuth) string { return perRouteFilterName(egv1a1.EnvoyFilterBasicAuth, basicAuth.Name) } -func (*basicAuth) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*basicAuth) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/compressor.go b/internal/xds/translator/compressor.go index 3f447d0bf5..39dc0f20f3 100644 --- a/internal/xds/translator/compressor.go +++ b/internal/xds/translator/compressor.go @@ -131,7 +131,7 @@ func buildCompressorFilter(compression *ir.Compression) (*hcmv3.HttpFilter, erro }, nil } -func (*compressor) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*compressor) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/cors.go b/internal/xds/translator/cors.go index 4c41bead94..78bd8fa254 100644 --- a/internal/xds/translator/cors.go +++ b/internal/xds/translator/cors.go @@ -199,7 +199,7 @@ func hasWildcard(array []string) bool { return false } -func (c *cors) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (c *cors) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/credentialInjector.go b/internal/xds/translator/credentialInjector.go index d14ddef9a2..2096952a1d 100644 --- a/internal/xds/translator/credentialInjector.go +++ b/internal/xds/translator/credentialInjector.go @@ -110,7 +110,7 @@ func credentialSecretName(credentialInjection *ir.CredentialInjection) string { return fmt.Sprintf("credential_injector/credential/%s", credentialInjection.Name) } -func (*credentialInjector) patchResources(resource *types.ResourceVersionTable, routes []*ir.HTTPRoute) error { +func (*credentialInjector) patchResources(resource *types.ResourceVersionTable, _ *ir.HTTPListener, routes []*ir.HTTPRoute) error { var errs error for _, route := range routes { diff --git a/internal/xds/translator/custom_response.go b/internal/xds/translator/custom_response.go index dec7020da7..af56e97ca6 100644 --- a/internal/xds/translator/custom_response.go +++ b/internal/xds/translator/custom_response.go @@ -500,7 +500,7 @@ func (c *customResponse) routeContainsResponseOverride(irRoute *ir.HTTPRoute) bo return false } -func (c *customResponse) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) error { +func (c *customResponse) patchResources(_ *types.ResourceVersionTable, _ *ir.HTTPListener, _ []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/dynamic_forward_proxy.go b/internal/xds/translator/dynamic_forward_proxy.go index fb419f9018..e4589c0b9c 100644 --- a/internal/xds/translator/dynamic_forward_proxy.go +++ b/internal/xds/translator/dynamic_forward_proxy.go @@ -91,7 +91,7 @@ func (*dynamicForwardProxy) patchRoute(route *routev3.Route, irRoute *ir.HTTPRou return nil } -func (*dynamicForwardProxy) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) error { +func (*dynamicForwardProxy) patchResources(_ *types.ResourceVersionTable, _ *ir.HTTPListener, _ []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/dynamicmodule.go b/internal/xds/translator/dynamicmodule.go index 1d4d56d4ed..b59e16c4df 100644 --- a/internal/xds/translator/dynamicmodule.go +++ b/internal/xds/translator/dynamicmodule.go @@ -44,15 +44,13 @@ func (*dynamicModule) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir. return errors.New("ir listener is nil") } - for _, route := range irListener.Routes { - if !routeContainsDynamicModule(route) { - continue - } - for _, dm := range route.EnvoyExtensions.DynamicModules { - if hcmContainsFilter(mgr, dynamicModuleFilterName(&dm)) { + addFilters := func(dms []ir.DynamicModule) { + for i := range dms { + dm := &dms[i] + if hcmContainsFilter(mgr, dynamicModuleFilterName(dm)) { continue } - filter, err := buildHCMDynamicModuleFilter(&dm) + filter, err := buildHCMDynamicModuleFilter(dm) if err != nil { errs = errors.Join(errs, err) continue @@ -61,6 +59,19 @@ func (*dynamicModule) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir. } } + // Listener-scoped DynamicModules are enabled at VirtualHost scope; route-scoped + // DynamicModules are enabled per route. Both need their (disabled by default) filter + // present on the HCM. + if listenerContainsDynamicModule(irListener) { + addFilters(irListener.EnvoyExtensions.DynamicModules) + } + for _, route := range irListener.Routes { + if !routeContainsDynamicModule(route) { + continue + } + addFilters(route.EnvoyExtensions.DynamicModules) + } + return errs } @@ -162,34 +173,52 @@ func routeContainsDynamicModule(irRoute *ir.HTTPRoute) bool { return irRoute.EnvoyExtensions != nil && len(irRoute.EnvoyExtensions.DynamicModules) > 0 } +// listenerContainsDynamicModule returns true if DynamicModules exist at listener scope. +func listenerContainsDynamicModule(irListener *ir.HTTPListener) bool { + return irListener != nil && irListener.EnvoyExtensions != nil && len(irListener.EnvoyExtensions.DynamicModules) > 0 +} + // patchResources creates clusters for remote dynamic module sources. -func (*dynamicModule) patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRoute) error { +func (*dynamicModule) patchResources(tCtx *types.ResourceVersionTable, irListener *ir.HTTPListener, routes []*ir.HTTPRoute) error { if tCtx == nil || tCtx.XdsResources == nil { return errors.New("xds resource table is nil") } var errs error - for _, route := range routes { - if !routeContainsDynamicModule(route) { - continue - } - - for _, dm := range route.EnvoyExtensions.DynamicModules { + addClusters := func(dms []ir.DynamicModule) { + for _, dm := range dms { if dm.Remote == nil { continue } - if err := addClusterFromURL(dm.Remote.URL, nil, tCtx); err != nil { errs = errors.Join(errs, err) } } } + if listenerContainsDynamicModule(irListener) { + addClusters(irListener.EnvoyExtensions.DynamicModules) + } + for _, route := range routes { + if !routeContainsDynamicModule(route) { + continue + } + addClusters(route.EnvoyExtensions.DynamicModules) + } + return errs } // patchRoute enables the corresponding dynamic module filter for the provided route. -func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPListener) error { +// +// A nil EnvoyExtensions means no route-scoped policy owns this route: it keeps inheriting the +// listener-scoped DynamicModules delivered at VirtualHost scope by patchVirtualHost. +// +// A non-nil EnvoyExtensions means a more specific (xRoute or route rule) policy owns this route +// and fully replaces — never merges with — the listener-scoped policy. The extension count is +// intentionally not checked: an empty result (e.g. fail-open invalid Wasm) still represents a +// more specific policy that owns this route and must suppress the lower-scope DynamicModules. +func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener *ir.HTTPListener) error { if route == nil { return errors.New("xds route is nil") } @@ -200,6 +229,26 @@ func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ return nil } + own := make(map[string]struct{}, len(irRoute.EnvoyExtensions.DynamicModules)) + for i := range irRoute.EnvoyExtensions.DynamicModules { + own[dynamicModuleFilterName(&irRoute.EnvoyExtensions.DynamicModules[i])] = struct{}{} + } + + if listenerContainsDynamicModule(irListener) { + for i := range irListener.EnvoyExtensions.DynamicModules { + filterName := dynamicModuleFilterName(&irListener.EnvoyExtensions.DynamicModules[i]) + // A single EnvoyExtensionPolicy may target both this listener and this route via + // separate targetRefs, in which case the same filter name appears at both scopes and + // the route re-enables it below instead of disabling it. + if _, ok := own[filterName]; ok { + continue + } + if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{Disabled: true}); err != nil { + return err + } + } + } + for _, dm := range irRoute.EnvoyExtensions.DynamicModules { filterName := dynamicModuleFilterName(&dm) if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{ @@ -211,6 +260,22 @@ func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ return nil } -func (*dynamicModule) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { +// patchVirtualHost enables the listener-scoped DynamicModule filters at VirtualHost scope so a +// listener's policy does not bleed into virtual hosts belonging to a different listener that +// shares the same RouteConfiguration. Delivery via VirtualHost TypedPerFilterConfig goes through +// RDS, so policy changes do not trigger listener drains. +func (*dynamicModule) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListener) error { + if !listenerContainsDynamicModule(httpListener) { + return nil + } + + for i := range httpListener.EnvoyExtensions.DynamicModules { + dm := &httpListener.EnvoyExtensions.DynamicModules[i] + if err := enableFilterOnVirtualHost(vh, dynamicModuleFilterName(dm), &routev3.FilterConfig{ + Config: &anypb.Any{}, + }); err != nil { + return err + } + } return nil } diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go index b9fbf3a1cd..0625607f34 100644 --- a/internal/xds/translator/extauth.go +++ b/internal/xds/translator/extauth.go @@ -253,7 +253,7 @@ func routeContainsExtAuth(irRoute *ir.HTTPRoute) bool { // patchResources patches the cluster resources for the external auth services. func (*extAuth) patchResources(tCtx *types.ResourceVersionTable, - routes []*ir.HTTPRoute, + _ *ir.HTTPListener, routes []*ir.HTTPRoute, ) error { if tCtx == nil || tCtx.XdsResources == nil { return errors.New("xds resource table is nil") diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go index 0cb15bc073..bd4d0d0b0d 100644 --- a/internal/xds/translator/extproc.go +++ b/internal/xds/translator/extproc.go @@ -46,13 +46,9 @@ func (*extProc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPLi return errors.New("ir listener is nil") } - for _, route := range irListener.Routes { - if !routeContainsExtProc(route) { - continue - } - - for i := range route.EnvoyExtensions.ExtProcs { - ep := &route.EnvoyExtensions.ExtProcs[i] + addFilters := func(extProcs []ir.ExtProc) { + for i := range extProcs { + ep := &extProcs[i] if hcmContainsFilter(mgr, extProcFilterName(ep)) { continue } @@ -67,6 +63,18 @@ func (*extProc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPLi } } + // Listener-scoped ExtProcs are enabled at VirtualHost scope; route-scoped ExtProcs are + // enabled per route. Both need their (disabled by default) filter present on the HCM. + if listenerContainsExtProc(irListener) { + addFilters(irListener.EnvoyExtensions.ExtProcs) + } + for _, route := range irListener.Routes { + if !routeContainsExtProc(route) { + continue + } + addFilters(route.EnvoyExtensions.ExtProcs) + } + return errs } @@ -177,35 +185,52 @@ func routeContainsExtProc(irRoute *ir.HTTPRoute) bool { return irRoute.EnvoyExtensions != nil && len(irRoute.EnvoyExtensions.ExtProcs) > 0 } +// listenerContainsExtProc returns true if ExtProcs exist at listener scope. +func listenerContainsExtProc(irListener *ir.HTTPListener) bool { + return irListener != nil && irListener.EnvoyExtensions != nil && len(irListener.EnvoyExtensions.ExtProcs) > 0 +} + // patchResources patches the cluster resources for the external services. func (*extProc) patchResources(tCtx *types.ResourceVersionTable, - routes []*ir.HTTPRoute, + irListener *ir.HTTPListener, routes []*ir.HTTPRoute, ) error { if tCtx == nil || tCtx.XdsResources == nil { return errors.New("xds resource table is nil") } var errs error + addClusters := func(extProcs []ir.ExtProc) { + for i := range extProcs { + ep := extProcs[i] + if err := createExtServiceXDSCluster(&ep.Destination, ep.Traffic, tCtx); err != nil { + errs = errors.Join(errs, err) + } + } + } + + if listenerContainsExtProc(irListener) { + addClusters(irListener.EnvoyExtensions.ExtProcs) + } for _, route := range routes { if !routeContainsExtProc(route) { continue } - - for i := range route.EnvoyExtensions.ExtProcs { - ep := route.EnvoyExtensions.ExtProcs[i] - if err := createExtServiceXDSCluster( - &ep.Destination, ep.Traffic, tCtx); err != nil { - errs = errors.Join(errs, err) - } - } + addClusters(route.EnvoyExtensions.ExtProcs) } return errs } // patchRoute patches the provided route with the extProc config if applicable. -// Note: this method enables the corresponding extProc filter for the provided route. -func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPListener) error { +// +// A nil EnvoyExtensions means no route-scoped policy owns this route: it keeps inheriting the +// listener-scoped ExtProcs delivered at VirtualHost scope by patchVirtualHost. +// +// A non-nil EnvoyExtensions means a more specific (xRoute or route rule) policy owns this route +// and fully replaces — never merges with — the listener-scoped policy. The extension count is +// intentionally not checked: an empty result (e.g. fail-open invalid Wasm) still represents a +// more specific policy that owns this route and must suppress the lower-scope ExtProcs. +func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener *ir.HTTPListener) error { if route == nil { return errors.New("xds route is nil") } @@ -216,6 +241,26 @@ func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HT return nil } + own := make(map[string]struct{}, len(irRoute.EnvoyExtensions.ExtProcs)) + for i := range irRoute.EnvoyExtensions.ExtProcs { + own[extProcFilterName(&irRoute.EnvoyExtensions.ExtProcs[i])] = struct{}{} + } + + if listenerContainsExtProc(irListener) { + for i := range irListener.EnvoyExtensions.ExtProcs { + filterName := extProcFilterName(&irListener.EnvoyExtensions.ExtProcs[i]) + // A single EnvoyExtensionPolicy may target both this listener and this route via + // separate targetRefs, in which case the same filter name appears at both scopes and + // the route re-enables it below instead of disabling it. + if _, ok := own[filterName]; ok { + continue + } + if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{Disabled: true}); err != nil { + return err + } + } + } + for i := range irRoute.EnvoyExtensions.ExtProcs { ep := &irRoute.EnvoyExtensions.ExtProcs[i] filterName := extProcFilterName(ep) @@ -277,6 +322,22 @@ func translateExtProcBodyProcessingMode(mode *ir.ExtProcBodyProcessingMode) extp return extprocv3.ProcessingMode_NONE } -func (*extProc) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { +// patchVirtualHost enables the listener-scoped ExtProc filters at VirtualHost scope so a +// listener's policy does not bleed into virtual hosts belonging to a different listener that +// shares the same RouteConfiguration. Delivery via VirtualHost TypedPerFilterConfig goes through +// RDS, so policy changes do not trigger listener drains. +func (*extProc) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListener) error { + if !listenerContainsExtProc(httpListener) { + return nil + } + + for i := range httpListener.EnvoyExtensions.ExtProcs { + ep := &httpListener.EnvoyExtensions.ExtProcs[i] + if err := enableFilterOnVirtualHost(vh, extProcFilterName(ep), &routev3.FilterConfig{ + Config: &anypb.Any{}, + }); err != nil { + return err + } + } return nil } diff --git a/internal/xds/translator/fault.go b/internal/xds/translator/fault.go index 83dd9c4f2d..f1c281a577 100644 --- a/internal/xds/translator/fault.go +++ b/internal/xds/translator/fault.go @@ -100,7 +100,7 @@ func routeContainsFault(irRoute *ir.HTTPRoute) bool { return false } -func (*fault) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*fault) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/geoip.go b/internal/xds/translator/geoip.go index 9cbffbaf8c..255796ae05 100644 --- a/internal/xds/translator/geoip.go +++ b/internal/xds/translator/geoip.go @@ -296,7 +296,7 @@ func (*geoip) patchRoute(*routev3.Route, *ir.HTTPRoute, *ir.HTTPListener) error return nil } -func (*geoip) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*geoip) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/globalresources.go b/internal/xds/translator/globalresources.go index 2fa12a4fb3..088adc9930 100644 --- a/internal/xds/translator/globalresources.go +++ b/internal/xds/translator/globalresources.go @@ -222,6 +222,9 @@ func buildEnvoyClientTLSSocket(envoyClientCertificate *ir.TLSCertificate) (*core func containsWasm(httpListeners []*ir.HTTPListener) bool { for _, httpListener := range httpListeners { + if httpListener.EnvoyExtensions != nil && len(httpListener.EnvoyExtensions.Wasms) > 0 { + return true + } for _, route := range httpListener.Routes { if route.EnvoyExtensions != nil && len(route.EnvoyExtensions.Wasms) > 0 { diff --git a/internal/xds/translator/header_mutation.go b/internal/xds/translator/header_mutation.go index ddc9d970b9..8ef463794e 100644 --- a/internal/xds/translator/header_mutation.go +++ b/internal/xds/translator/header_mutation.go @@ -53,7 +53,7 @@ func (*headerMutation) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir return nil } -func (*headerMutation) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*headerMutation) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/healthcheck.go b/internal/xds/translator/healthcheck.go index 3db72fc2a1..7e7d18d3e8 100644 --- a/internal/xds/translator/healthcheck.go +++ b/internal/xds/translator/healthcheck.go @@ -94,7 +94,7 @@ func buildHealthCheckFilter(healthCheck *ir.HealthCheckSettings) (*hcmv3.HttpFil }, nil } -func (*healthCheck) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*healthCheck) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index 508649585d..2fbee4eb55 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -69,7 +69,7 @@ type httpFilter interface { // - a jwt filter needs to add the cluster for the jwks. // - an oidc filter needs to add the cluster for token endpoint and the secret // for the oauth2 client secret and the hmac secret. - patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRoute) error + patchResources(tCtx *types.ResourceVersionTable, irListener *ir.HTTPListener, routes []*ir.HTTPRoute) error } type OrderedHTTPFilter struct { @@ -391,9 +391,9 @@ func mustGetFilterIndex(filterName string) int { // for example: // - a jwt filter needs to add the cluster for the jwks. // - an oidc filter needs to add the secret for the oauth2 client secret. -func patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRoute) error { +func patchResources(tCtx *types.ResourceVersionTable, irListener *ir.HTTPListener, routes []*ir.HTTPRoute) error { for _, filter := range httpFilters { - if err := filter.patchResources(tCtx, routes); err != nil { + if err := filter.patchResources(tCtx, irListener, routes); err != nil { return err } } diff --git a/internal/xds/translator/jwt.go b/internal/xds/translator/jwt.go index 045b71594f..f40ef3be12 100644 --- a/internal/xds/translator/jwt.go +++ b/internal/xds/translator/jwt.go @@ -426,7 +426,7 @@ func (*jwt) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPLi } // patchResources creates JWKS clusters from the provided routes, if needed. -func (*jwt) patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRoute) error { +func (*jwt) patchResources(tCtx *types.ResourceVersionTable, _ *ir.HTTPListener, routes []*ir.HTTPRoute) error { if tCtx == nil || tCtx.XdsResources == nil { return errors.New("xds resource table is nil") } diff --git a/internal/xds/translator/local_ratelimit.go b/internal/xds/translator/local_ratelimit.go index 62391c303e..ca99cdc9e4 100644 --- a/internal/xds/translator/local_ratelimit.go +++ b/internal/xds/translator/local_ratelimit.go @@ -111,7 +111,7 @@ func routeContainsLocalRateLimit(irRoute *ir.HTTPRoute) bool { } func (*localRateLimit) patchResources(*types.ResourceVersionTable, - []*ir.HTTPRoute, + *ir.HTTPListener, []*ir.HTTPRoute, ) error { return nil } diff --git a/internal/xds/translator/lua.go b/internal/xds/translator/lua.go index 4e0e02a67b..38f688213a 100644 --- a/internal/xds/translator/lua.go +++ b/internal/xds/translator/lua.go @@ -19,7 +19,6 @@ import ( "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" - "k8s.io/utils/ptr" egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" "github.com/envoyproxy/gateway/internal/ir" @@ -135,7 +134,7 @@ func routeContainsLua(irRoute *ir.HTTPRoute) bool { } // patchResources patches the cluster resources for the http lua code source. -func (*lua) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) error { +func (*lua) patchResources(_ *types.ResourceVersionTable, _ *ir.HTTPListener, _ []*ir.HTTPRoute) error { return nil } @@ -154,17 +153,11 @@ func (*lua) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener * return nil } - // Disable the inherited listener-level Lua whenever EnvoyExtensions was set by a - // more-specific route policy (FromGatewayPolicy is false/nil). The extension count - // is intentionally not checked here: an empty result (e.g. fail-open invalid Wasm) - // still represents a more-specific policy that owns this route and must suppress the - // lower-scope Lua. When FromGatewayPolicy is true the route-level extensions come - // from the same gateway/listener policy that also installed the listener Lua, so both coexist. - disableListenerLevelFilter := !ptr.Deref(irRoute.EnvoyExtensions.FromGatewayPolicy, false) - - // Route has its own Lua entries — disable the inherited listener-level Lua and - // install the route's scripts instead. - if irListener != nil && irListener.EnvoyExtensions != nil && len(irListener.EnvoyExtensions.Luas) > 0 && disableListenerLevelFilter { + // A non-nil EnvoyExtensions means a more specific route policy owns this route and fully + // replaces the listener-scoped policy. The extension count is intentionally not checked + // here: an empty result (e.g. fail-open invalid Wasm) still represents a more specific + // policy that owns this route and must suppress the lower-scope Lua. + if irListener != nil && irListener.EnvoyExtensions != nil && len(irListener.EnvoyExtensions.Luas) > 0 { if err := enableFilterOnRoute(route, luaListenerFCFilterName(), &routev3.FilterConfig{Disabled: true}); err != nil { return err } diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 0ec110a96a..f498249003 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -403,7 +403,7 @@ func routeContainsOIDC(irRoute *ir.HTTPRoute) bool { } func (*oidc) patchResources(tCtx *types.ResourceVersionTable, - routes []*ir.HTTPRoute, + _ *ir.HTTPListener, routes []*ir.HTTPRoute, ) error { if err := createOAuthServerClusters(tCtx, routes); err != nil { return err diff --git a/internal/xds/translator/request_buffer.go b/internal/xds/translator/request_buffer.go index ec7b4e321d..6fef1db011 100644 --- a/internal/xds/translator/request_buffer.go +++ b/internal/xds/translator/request_buffer.go @@ -96,7 +96,7 @@ func buildHCMRequestBufferFilter(spec *ir.RequestBuffer) (*hcmv3.HttpFilter, err }, nil } -func (r *requestBuffer) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) error { +func (r *requestBuffer) patchResources(_ *types.ResourceVersionTable, _ *ir.HTTPListener, _ []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/session_persistence.go b/internal/xds/translator/session_persistence.go index 7d202cad59..e2966268d3 100644 --- a/internal/xds/translator/session_persistence.go +++ b/internal/xds/translator/session_persistence.go @@ -229,7 +229,7 @@ func (s *sessionPersistence) patchRoute(route *routev3.Route, irRoute *ir.HTTPRo // patchResources adds all the other needed resources referenced by this // filter to the resource version table. -func (s *sessionPersistence) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) error { +func (s *sessionPersistence) patchResources(_ *types.ResourceVersionTable, _ *ir.HTTPListener, _ []*ir.HTTPRoute) error { return nil } diff --git a/internal/xds/translator/testdata/in/xds-ir/dynamicmodule.yaml b/internal/xds/translator/testdata/in/xds-ir/dynamicmodule.yaml index 7764636556..45473d2fb8 100644 --- a/internal/xds/translator/testdata/in/xds-ir/dynamicmodule.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/dynamicmodule.yaml @@ -122,3 +122,98 @@ http: path: /opt/modules/my_module.so name: envoyextensionpolicy/default/policy-path/dynamic-module/0 terminalFilter: false +# Listener-scoped DynamicModule (attached at Gateway/Listener scope, with a remote source to +# exercise cluster creation) with three routes: +# - httproute-5: no route-scoped policy, inherits the listener-scoped module via VirtualHost. +# - httproute-6: route-scoped policy with a different module, fully replacing the listener one. +# - httproute-7: route-scoped policy that targets the SAME module as the listener (a policy can +# target both a Gateway and one of its HTTPRoutes via separate targetRefs), so the filter name +# collides across scopes and must not be disabled then re-enabled. +- address: 0.0.0.0 + hostnames: + - '*' + name: envoy-gateway/gateway-1/http-listener-scope + envoyExtensions: + dynamicModules: + - doNotClose: false + filterName: listener-filter + loadGlobally: false + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0 + remote: + url: https://listener-modules.example.com/liblistener.so + sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + terminalFilter: false + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10081 + routes: + - destination: + name: httproute/default/httproute-5/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-5/rule/0/backend/0 + hostname: listener-scope.example.com + isHTTP2: false + name: httproute/default/httproute-5/rule/0/match/0/listener_scope_example_com + pathMatch: + distinct: false + name: "" + prefix: /inherit + - destination: + name: httproute/default/httproute-6/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-6/rule/0/backend/0 + envoyExtensions: + dynamicModules: + - doNotClose: false + filterName: route-override-filter + loadGlobally: false + path: /usr/lib/envoy/modules/route_override.so + name: envoyextensionpolicy/default/policy-for-route-6/dynamic-module/0 + terminalFilter: false + hostname: listener-scope.example.com + isHTTP2: false + name: httproute/default/httproute-6/rule/0/match/0/listener_scope_example_com + pathMatch: + distinct: false + name: "" + prefix: /override + - destination: + name: httproute/default/httproute-7/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-7/rule/0/backend/0 + envoyExtensions: + dynamicModules: + - doNotClose: false + filterName: listener-filter + loadGlobally: false + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0 + remote: + url: https://listener-modules.example.com/liblistener.so + sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + terminalFilter: false + hostname: listener-scope.example.com + isHTTP2: false + name: httproute/default/httproute-7/rule/0/match/0/listener_scope_example_com + pathMatch: + distinct: false + name: "" + prefix: /same-name diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml index 915bc8fc6a..166792a530 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml @@ -132,3 +132,99 @@ http: distinct: false name: "" prefix: /bar + # Listener-scoped ExtProc (attached at Gateway/Listener scope) with three routes: + # - httproute-4: no route-scoped policy, inherits the listener-scoped ExtProc via VirtualHost. + # - httproute-5: route-scoped policy with a different ExtProc, fully replacing the listener one. + # - httproute-6: route-scoped policy that targets the SAME ExtProc as the listener (a policy can + # target both a Gateway and one of its HTTPRoutes via separate targetRefs), so the filter name + # collides across scopes and must not be disabled then re-enabled. + - address: 0.0.0.0 + hostnames: + - '*' + name: envoy-gateway/gateway-1/http-listener-scope + envoyExtensions: + extProcs: + - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0 + authority: grpc-backend-listener.envoy-gateway:9000 + destination: + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener + settings: + - protocol: GRPC + weight: 1 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener/backend/0 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10081 + routes: + - destination: + name: httproute/default/httproute-4/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-4/rule/0/backend/0 + hostname: listener-scope.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-4/rule/0/match/0/listener_scope_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: /inherit + - destination: + name: httproute/default/httproute-5/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-5/rule/0/backend/0 + envoyExtensions: + extProcs: + - name: envoyextensionpolicy/default/policy-for-route-5/extproc/0 + authority: grpc-backend-5.default:9500 + destination: + name: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5 + settings: + - protocol: GRPC + weight: 1 + name: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5/backend/0 + hostname: listener-scope.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-5/rule/0/match/0/listener_scope_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: /override + - destination: + name: httproute/default/httproute-6/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-6/rule/0/backend/0 + envoyExtensions: + extProcs: + - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0 + authority: grpc-backend-listener.envoy-gateway:9000 + destination: + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener + settings: + - protocol: GRPC + weight: 1 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener/backend/0 + hostname: listener-scope.envoyproxy.io + isHTTP2: false + name: httproute/default/httproute-6/rule/0/match/0/listener_scope_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: /same-name diff --git a/internal/xds/translator/testdata/in/xds-ir/lua.yaml b/internal/xds/translator/testdata/in/xds-ir/lua.yaml index 8fb2404882..24854f98a0 100644 --- a/internal/xds/translator/testdata/in/xds-ir/lua.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/lua.yaml @@ -275,8 +275,9 @@ http: distinct: false name: "" prefix: / -# Gateway policy with Lua (at listener) + ExtProc (at route), both from the same policy. -# The route's ExtProc carries fromGatewayPolicy:true so the listener Lua must NOT be disabled. +# Gateway policy with Lua and ExtProc, both attached at listener scope from the same policy. +# No route under this listener has its own policy, so both stay listener-scoped and the +# listener Lua must NOT be disabled for httproute-8. - address: 0.0.0.0 hostnames: - '*' @@ -287,6 +288,15 @@ http: request_handle:logInfo('Gateway Lua.') end name: envoyextensionpolicy/default/policy-for-gateway/lua/0 + extProcs: + - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 + authority: grpc-backend.default:8000 + destination: + name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend + settings: + - protocol: GRPC + weight: 1 + name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend/backend/0 path: escapedSlashesAction: UnescapeAndRedirect mergeSlashes: true @@ -309,20 +319,9 @@ http: distinct: false name: "" prefix: /foo - envoyExtensions: - fromGatewayPolicy: true - extProcs: - - name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 - authority: grpc-backend.default:8000 - destination: - name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend - settings: - - protocol: GRPC - weight: 1 - name: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend/backend/0 # Listener Lua with a route that has a fail-open empty policy (EnvoyExtensions non-nil but all -# extension slices empty and no fromGatewayPolicy). The listener Lua must still be disabled -# because the more-specific route policy owns this route regardless of producing no extensions. +# extension slices empty). The listener Lua must still be disabled because the more-specific +# route policy owns this route regardless of producing no extensions. - address: 0.0.0.0 hostnames: - '*' diff --git a/internal/xds/translator/testdata/in/xds-ir/wasm.yaml b/internal/xds/translator/testdata/in/xds-ir/wasm.yaml index de8897fadf..c1083d7948 100644 --- a/internal/xds/translator/testdata/in/xds-ir/wasm.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/wasm.yaml @@ -98,3 +98,99 @@ http: hostKeys: - SOME_KEY - ANOTHER_KEY +# Listener-scoped Wasm (attached at Gateway/Listener scope) with three routes: +# - httproute-3: no route-scoped policy, inherits the listener-scoped Wasm via VirtualHost. +# - httproute-4: route-scoped policy with a different Wasm, fully replacing the listener one. +# - httproute-5: route-scoped policy that targets the SAME Wasm as the listener (a policy can +# target both a Gateway and one of its HTTPRoutes via separate targetRefs), so the filter name +# collides across scopes and must not be disabled then re-enabled. +- address: 0.0.0.0 + hostnames: + - '*' + name: envoy-gateway/gateway-1/http-listener-scope + envoyExtensions: + wasms: + - config: null + failOpen: false + httpWasmCode: + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f.wasm + originalDownloadingURL: https://www.example.com/wasm-filter-listener.wasm + sha256: 8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0 + wasmName: wasm-filter-listener + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10081 + routes: + - destination: + name: httproute/default/httproute-3/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-3/rule/0/backend/0 + hostname: listener-scope.example.com + isHTTP2: false + name: httproute/default/httproute-3/rule/0/match/0/listener_scope_example_com + pathMatch: + distinct: false + name: "" + prefix: /inherit + - destination: + name: httproute/default/httproute-4/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-4/rule/0/backend/0 + envoyExtensions: + wasms: + - config: null + failOpen: false + httpWasmCode: + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/9d2e2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a.wasm + originalDownloadingURL: https://www.example.com/wasm-filter-route-override.wasm + sha256: 9d2e2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a + name: envoyextensionpolicy/default/policy-for-route-4/wasm/0 + wasmName: wasm-filter-route-override + hostname: listener-scope.example.com + isHTTP2: false + name: httproute/default/httproute-4/rule/0/match/0/listener_scope_example_com + pathMatch: + distinct: false + name: "" + prefix: /override + - destination: + name: httproute/default/httproute-5/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + name: httproute/default/httproute-5/rule/0/backend/0 + envoyExtensions: + wasms: + - config: null + failOpen: false + httpWasmCode: + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f.wasm + originalDownloadingURL: https://www.example.com/wasm-filter-listener.wasm + sha256: 8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0 + wasmName: wasm-filter-listener + hostname: listener-scope.example.com + isHTTP2: false + name: httproute/default/httproute-5/rule/0/match/0/listener_scope_example_com + pathMatch: + distinct: false + name: "" + prefix: /same-name diff --git a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.clusters.yaml index d74bab929b..bb37df695a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.clusters.yaml @@ -138,3 +138,120 @@ trustedCa: filename: /etc/ssl/certs/ca-certificates.crt sni: modules.example.com +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-5/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-5/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-6/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-6/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-7/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-7/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + clusterType: + name: envoy.cluster.dns + typedConfig: + '@type': type.googleapis.com/envoy.extensions.clusters.dns.v3.DnsCluster + dnsLookupFamily: V4_PREFERRED + dnsRefreshRate: 30s + respectDnsTtl: true + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + ignoreHealthOnHostRemoval: true + loadAssignment: + clusterName: listener-modules_example_com_443 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: listener-modules.example.com + portValue: 443 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: listener-modules_example_com_443/backend/-1 + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: listener-modules_example_com_443 + perConnectionBufferLimitBytes: 32768 + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + tlsParams: + tlsMaximumProtocolVersion: TLSv1_3 + validationContext: + trustedCa: + filename: /etc/ssl/certs/ca-certificates.crt + sni: listener-modules.example.com diff --git a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.endpoints.yaml index e4cbf3f4ea..1440168674 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.endpoints.yaml @@ -46,3 +46,39 @@ loadBalancingWeight: 1 locality: region: httproute/default/httproute-4/rule/0/backend/0 +- clusterName: httproute/default/httproute-5/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-5/rule/0/backend/0 +- clusterName: httproute/default/httproute-6/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-6/rule/0/backend/0 +- clusterName: httproute/default/httproute-7/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-7/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml index 0b3a43cea0..e49e83edfe 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml @@ -94,3 +94,60 @@ maxConnectionsToAcceptPerSocketEvent: 1 name: envoy-gateway/gateway-1/http perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10081 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - disabled: true + name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-for-route-6/dynamic-module/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + local: + filename: /usr/lib/envoy/modules/route_override.so + filterName: route-override-filter + - disabled: true + name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + remote: + httpUri: + cluster: listener-modules_example_com_443 + timeout: 10s + uri: https://listener-modules.example.com/liblistener.so + sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + filterName: listener-filter + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-listener-scope + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10081 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-listener-scope + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-listener-scope + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.routes.yaml index 237c6abf7e..6cb4ae5844 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.routes.yaml @@ -52,3 +52,46 @@ envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-path/dynamic-module/0: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-listener-scope + virtualHosts: + - domains: + - listener-scope.example.com + name: envoy-gateway/gateway-1/http-listener-scope/listener-scope_example_com + routes: + - match: + pathSeparatedPrefix: /inherit + name: httproute/default/httproute-5/rule/0/match/0/listener_scope_example_com + route: + cluster: httproute/default/httproute-5/rule/0 + upgradeConfigs: + - upgradeType: websocket + - match: + pathSeparatedPrefix: /override + name: httproute/default/httproute-6/rule/0/match/0/listener_scope_example_com + route: + cluster: httproute/default/httproute-6/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-for-route-6/dynamic-module/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + disabled: true + - match: + pathSeparatedPrefix: /same-name + name: httproute/default/httproute-7/rule/0/match/0/listener_scope_example_com + route: + cluster: httproute/default/httproute-7/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + typedPerFilterConfig: + envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml index 890439caa2..0f2d4e1c9f 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml @@ -217,3 +217,132 @@ http2ProtocolOptions: initialConnectionWindowSize: 1048576 initialStreamWindowSize: 65536 +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-4/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-4/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-5/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-5/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-6/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-6/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5 + perConnectionBufferLimitBytes: 32768 + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml index b6f8426798..b1b6197eef 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml @@ -59,3 +59,49 @@ - loadBalancingWeight: 1 locality: region: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3/backend/0 +- clusterName: httproute/default/httproute-4/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-4/rule/0/backend/0 +- clusterName: httproute/default/httproute-5/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-5/rule/0/backend/0 +- clusterName: httproute/default/httproute-6/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-6/rule/0/backend/0 +- clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener/backend/0 +- clusterName: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5 + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml index 47500f8461..b8cbabda8b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml @@ -141,3 +141,66 @@ maxConnectionsToAcceptPerSocketEvent: 1 name: envoy-gateway/gateway-1/http perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10081 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-5/extproc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend-5.default:9500 + clusterName: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5 + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend-listener.envoy-gateway:9000 + clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-listener-scope + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10081 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-listener-scope + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-listener-scope + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml index 8cef38ab6a..6ca0a10f78 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml @@ -47,3 +47,46 @@ envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/extproc/0: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-listener-scope + virtualHosts: + - domains: + - listener-scope.envoyproxy.io + name: envoy-gateway/gateway-1/http-listener-scope/listener-scope_envoyproxy_io + routes: + - match: + pathSeparatedPrefix: /inherit + name: httproute/default/httproute-4/rule/0/match/0/listener_scope_envoyproxy_io + route: + cluster: httproute/default/httproute-4/rule/0 + upgradeConfigs: + - upgradeType: websocket + - match: + pathSeparatedPrefix: /override + name: httproute/default/httproute-5/rule/0/match/0/listener_scope_envoyproxy_io + route: + cluster: httproute/default/httproute-5/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-5/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + disabled: true + - match: + pathSeparatedPrefix: /same-name + name: httproute/default/httproute-6/rule/0/match/0/listener_scope_envoyproxy_io + route: + cluster: httproute/default/httproute-6/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml index 14d1e054b6..4431541261 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml @@ -231,11 +231,10 @@ cluster: httproute/default/httproute-8/rule/0 upgradeConfigs: - upgradeType: websocket - typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-gateway/extproc/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-gateway/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} envoy.filters.http.filter_chain.eep.lua.listener: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml index 0ca9135bd1..62de95acf6 100644 --- a/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.clusters.yaml @@ -44,6 +44,75 @@ name: httproute/default/httproute-2/rule/0 perConnectionBufferLimitBytes: 32768 type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-3/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-3/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-4/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-4/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-5/rule/0 + ignoreHealthOnHostRemoval: true + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: httproute/default/httproute-5/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS - circuitBreakers: thresholds: - maxRetries: 1024 diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.endpoints.yaml index 05442a9a15..a18e45814d 100644 --- a/internal/xds/translator/testdata/out/xds-ir/wasm.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.endpoints.yaml @@ -22,3 +22,39 @@ loadBalancingWeight: 1 locality: region: httproute/default/httproute-2/rule/0/backend/0 +- clusterName: httproute/default/httproute-3/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-3/rule/0/backend/0 +- clusterName: httproute/default/httproute-4/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-4/rule/0/backend/0 +- clusterName: httproute/default/httproute-5/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-5/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml index cb8e4558fc..a5da6fd1bd 100644 --- a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml @@ -135,3 +135,86 @@ maxConnectionsToAcceptPerSocketEvent: 1 name: envoy-gateway/gateway-1/http perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10081 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - disabled: true + name: envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-route-4/wasm/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: "" + name: wasm-filter-route-override + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/9d2e2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 9d2e2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/default/policy-for-route-4/wasm/0 + - disabled: true + name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: "" + name: wasm-filter-listener + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0 + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: envoy-gateway/gateway-1/http-listener-scope + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10081 + useRemoteAddress: true + name: envoy-gateway/gateway-1/http-listener-scope + maxConnectionsToAcceptPerSocketEvent: 1 + name: envoy-gateway/gateway-1/http-listener-scope + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml index 1e07a621d5..39ce7ba57f 100644 --- a/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml @@ -33,3 +33,46 @@ envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} +- ignorePortInHostMatching: true + name: envoy-gateway/gateway-1/http-listener-scope + virtualHosts: + - domains: + - listener-scope.example.com + name: envoy-gateway/gateway-1/http-listener-scope/listener-scope_example_com + routes: + - match: + pathSeparatedPrefix: /inherit + name: httproute/default/httproute-3/rule/0/match/0/listener_scope_example_com + route: + cluster: httproute/default/httproute-3/rule/0 + upgradeConfigs: + - upgradeType: websocket + - match: + pathSeparatedPrefix: /override + name: httproute/default/httproute-4/rule/0/match/0/listener_scope_example_com + route: + cluster: httproute/default/httproute-4/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-route-4/wasm/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + disabled: true + - match: + pathSeparatedPrefix: /same-name + name: httproute/default/httproute-5/rule/0/match/0/listener_scope_example_com + route: + cluster: httproute/default/httproute-5/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + typedPerFilterConfig: + envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 769dd1cd74..c05afb268b 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -519,7 +519,7 @@ func (t *Translator) processHTTPListenerXdsTranslation( // Add all the other needed resources referenced by this filter to the // resource version table. - if err = patchResources(tCtx, httpListener.Routes); err != nil { + if err = patchResources(tCtx, httpListener, httpListener.Routes); err != nil { errs = errors.Join(errs, err) } } diff --git a/internal/xds/translator/utils.go b/internal/xds/translator/utils.go index e2cdc3c88f..7d47e2494f 100644 --- a/internal/xds/translator/utils.go +++ b/internal/xds/translator/utils.go @@ -118,6 +118,32 @@ func enableFilterOnRoute(route *routev3.Route, filterName string, routeCfg proto return nil } +// enableFilterOnVirtualHost enables filterName for the provided virtual host. Unlike +// enableFilterOnRoute this is idempotent: patchVirtualHost may be invoked more than once for the +// same VirtualHost when several IR listeners share one RouteConfiguration (cleartext listeners on +// the same port). +func enableFilterOnVirtualHost(vh *routev3.VirtualHost, filterName string, routeCfg proto.Message) error { + if vh == nil { + return errors.New("xds virtual host is nil") + } + + if _, ok := vh.GetTypedPerFilterConfig()[filterName]; ok { + return nil + } + + routeCfgAny, err := anypb.New(routeCfg) + if err != nil { + return err + } + + if vh.TypedPerFilterConfig == nil { + vh.TypedPerFilterConfig = make(map[string]*anypb.Any) + } + vh.TypedPerFilterConfig[filterName] = routeCfgAny + + return nil +} + // perRouteFilterName generates a unique filter name for the provided filterType and configName. func perRouteFilterName(filterType egv1a1.EnvoyFilter, configName string) string { return fmt.Sprintf("%s/%s", filterType, configName) diff --git a/internal/xds/translator/wasm.go b/internal/xds/translator/wasm.go index 0a2a2557b7..ebc6cc4100 100644 --- a/internal/xds/translator/wasm.go +++ b/internal/xds/translator/wasm.go @@ -58,15 +58,13 @@ func (*wasm) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListe return errors.New("ir listener is nil") } - for _, route := range irListener.Routes { - if !routeContainsWasm(route) { - continue - } - for _, ep := range route.EnvoyExtensions.Wasms { - if hcmContainsFilter(mgr, wasmFilterName(&ep)) { + addFilters := func(wasms []ir.Wasm) { + for i := range wasms { + ep := &wasms[i] + if hcmContainsFilter(mgr, wasmFilterName(ep)) { continue } - filter, err := buildHCMWasmFilter(&ep) + filter, err := buildHCMWasmFilter(ep) if err != nil { errs = errors.Join(errs, err) continue @@ -75,6 +73,18 @@ func (*wasm) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListe } } + // Listener-scoped Wasms are enabled at VirtualHost scope; route-scoped Wasms are enabled + // per route. Both need their (disabled by default) filter present on the HCM. + if listenerContainsWasm(irListener) { + addFilters(irListener.EnvoyExtensions.Wasms) + } + for _, route := range irListener.Routes { + if !routeContainsWasm(route) { + continue + } + addFilters(route.EnvoyExtensions.Wasms) + } + return errs } @@ -183,8 +193,13 @@ func routeContainsWasm(irRoute *ir.HTTPRoute) bool { return irRoute.EnvoyExtensions != nil && len(irRoute.EnvoyExtensions.Wasms) > 0 } +// listenerContainsWasm returns true if Wasms exist at listener scope. +func listenerContainsWasm(irListener *ir.HTTPListener) bool { + return irListener != nil && irListener.EnvoyExtensions != nil && len(irListener.EnvoyExtensions.Wasms) > 0 +} + // patchResources patches the cluster resources for the http wasm code source. -func (*wasm) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) error { +func (*wasm) patchResources(_ *types.ResourceVersionTable, _ *ir.HTTPListener, _ []*ir.HTTPRoute) error { // EG always serves the Wasm module through the built-in HTTP server, which // has been configured in the bootstrap configuration. So we don't need to // create a cluster for the Wasm module. @@ -192,8 +207,15 @@ func (*wasm) patchResources(_ *types.ResourceVersionTable, _ []*ir.HTTPRoute) er } // patchRoute patches the provided route with the wasm config if applicable. -// Note: this method enables the corresponding wasm filter for the provided route. -func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPListener) error { +// +// A nil EnvoyExtensions means no route-scoped policy owns this route: it keeps inheriting the +// listener-scoped Wasms delivered at VirtualHost scope by patchVirtualHost. +// +// A non-nil EnvoyExtensions means a more specific (xRoute or route rule) policy owns this route +// and fully replaces — never merges with — the listener-scoped policy. The extension count is +// intentionally not checked: an empty result (e.g. fail-open invalid Wasm) still represents a +// more specific policy that owns this route and must suppress the lower-scope Wasms. +func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener *ir.HTTPListener) error { if route == nil { return errors.New("xds route is nil") } @@ -204,6 +226,26 @@ func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPL return nil } + own := make(map[string]struct{}, len(irRoute.EnvoyExtensions.Wasms)) + for i := range irRoute.EnvoyExtensions.Wasms { + own[wasmFilterName(&irRoute.EnvoyExtensions.Wasms[i])] = struct{}{} + } + + if listenerContainsWasm(irListener) { + for i := range irListener.EnvoyExtensions.Wasms { + filterName := wasmFilterName(&irListener.EnvoyExtensions.Wasms[i]) + // A single EnvoyExtensionPolicy may target both this listener and this route via + // separate targetRefs, in which case the same filter name appears at both scopes and + // the route re-enables it below instead of disabling it. + if _, ok := own[filterName]; ok { + continue + } + if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{Disabled: true}); err != nil { + return err + } + } + } + for _, ep := range irRoute.EnvoyExtensions.Wasms { filterName := wasmFilterName(&ep) if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{ @@ -215,6 +257,22 @@ func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPL return nil } -func (*wasm) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { +// patchVirtualHost enables the listener-scoped Wasm filters at VirtualHost scope so a listener's +// policy does not bleed into virtual hosts belonging to a different listener that shares the same +// RouteConfiguration. Delivery via VirtualHost TypedPerFilterConfig goes through RDS, so policy +// changes do not trigger listener drains. +func (*wasm) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListener) error { + if !listenerContainsWasm(httpListener) { + return nil + } + + for i := range httpListener.EnvoyExtensions.Wasms { + ep := &httpListener.EnvoyExtensions.Wasms[i] + if err := enableFilterOnVirtualHost(vh, wasmFilterName(ep), &routev3.FilterConfig{ + Config: &anypb.Any{}, + }); err != nil { + return err + } + } return nil } diff --git a/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md b/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md deleted file mode 100644 index b8eb59bbac..0000000000 --- a/release-notes/current/breaking_changes/9131-lua-xds-layout-per-route-filterchain.md +++ /dev/null @@ -1 +0,0 @@ -The xDS layout for Lua EnvoyExtensionPolicies (both Gateway/listener-targeted and HTTPRoute-targeted) has changed. Any EnvoyPatchPolicy rules or extension-server logic that reads or patches the old Lua filter names or per-route config shape will break and must be updated to match the new layout. diff --git a/release-notes/current/breaking_changes/9131-xds-layout-per-route-filterchain.md b/release-notes/current/breaking_changes/9131-xds-layout-per-route-filterchain.md new file mode 100644 index 0000000000..520f375955 --- /dev/null +++ b/release-notes/current/breaking_changes/9131-xds-layout-per-route-filterchain.md @@ -0,0 +1 @@ +The xDS layout for EnvoyExtensionPolicies (both Gateway/listener-targeted and HTTPRoute-targeted) has changed. Any EnvoyPatchPolicy rules or extension-server logic that reads or patches the old extension filter names or per-route config shape will break and must be updated to match the new layout. From 9fb66efa99d3fff07a967a464c263c6b986feac1 Mon Sep 17 00:00:00 2001 From: zirain Date: Sun, 2 Aug 2026 21:20:11 +0800 Subject: [PATCH 14/18] fix Signed-off-by: zirain --- internal/gatewayapi/envoyextensionpolicy.go | 17 +- ...policy-status-conditions-truncated.in.yaml | 376 --- ...olicy-status-conditions-truncated.out.yaml | 2378 ----------------- ...policy-listener-failopen-ownership.in.yaml | 97 + ...olicy-listener-failopen-ownership.out.yaml | 390 +++ ...olicy-status-conditions-truncated.out.yaml | 1 + ...extensionpolicy-status-conditions.out.yaml | 1 + ...y-with-wasm-invalid-configuration.out.yaml | 1 + 8 files changed, 500 insertions(+), 2761 deletions(-) delete mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.in.yaml delete mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.out.yaml create mode 100644 internal/gatewayapi/testdata/envoyextensionpolicy-listener-failopen-ownership.in.yaml create mode 100644 internal/gatewayapi/testdata/envoyextensionpolicy-listener-failopen-ownership.out.yaml diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index 0add78b51c..a89a661db5 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -989,13 +989,16 @@ func (t *Translator) translateEnvoyExtensionPolicyForListeners( // All extensions are attached at listener scope and delivered at VirtualHost // scope by the xDS translator. Routes owned by a more specific policy carry // their own EnvoyExtensions and fully override this one. - if len(extProcs) > 0 || len(wasms) > 0 || len(luas) > 0 || len(dynamicModules) > 0 { - http.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ - ExtProcs: extProcs, - Wasms: wasms, - Luas: luas, - DynamicModules: dynamicModules, - } + // + // Record the ownership sentinel even when every extension slice is empty + // (e.g. all entries failed validation but were fail-open): this listener is + // still owned by this policy, and leaving EnvoyExtensions nil would let a + // lesser-specific Gateway/ListenerSet policy see it as unowned and attach. + http.EnvoyExtensions = &ir.EnvoyExtensionFeatures{ + ExtProcs: extProcs, + Wasms: wasms, + Luas: luas, + DynamicModules: dynamicModules, } } diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.in.yaml deleted file mode 100644 index 6796c3b95c..0000000000 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.in.yaml +++ /dev/null @@ -1,376 +0,0 @@ -envoyExtensionPolicies: -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: EnvoyExtensionPolicy - metadata: - namespace: envoy-gateway - name: target-gateway-with-accepted-truncated-ancestors - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-2 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-3 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-4 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-5 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-6 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-7 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-8 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-9 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-10 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-11 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-12 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-13 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-14 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-15 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-16 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-17 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-18 -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: EnvoyExtensionPolicy - metadata: - namespace: envoy-gateway - name: target-gateway-with-attachment-conflict-truncated-ancestors - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-2 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-3 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-4 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-5 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-6 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-7 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-8 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-9 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-10 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-11 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-12 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-13 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-14 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-15 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-16 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-17 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-18 -gateways: -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-1 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-2 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-3 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-4 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-5 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-6 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-7 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-8 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-9 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-10 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-11 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-12 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-13 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-14 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-15 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-16 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-17 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-18 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.out.yaml deleted file mode 100644 index d198d92cab..0000000000 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.out.yaml +++ /dev/null @@ -1,2378 +0,0 @@ -envoyExtensionPolicies: -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: EnvoyExtensionPolicy - metadata: - name: target-gateway-with-accepted-truncated-ancestors - namespace: envoy-gateway - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-2 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-3 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-4 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-5 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-6 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-7 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-8 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-9 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-10 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-11 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-12 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-13 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-14 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-15 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-16 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-17 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-18 - status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-10 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-11 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-12 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-13 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-14 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-15 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-16 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-17 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-18 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-2 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-3 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-4 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-5 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-6 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-7 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Ancestors have been truncated because the number of policy ancestors - exceeds 16. - reason: Aggregated - status: "True" - type: Aggregated - controllerName: gateway.envoyproxy.io/gatewayclass-controller -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: EnvoyExtensionPolicy - metadata: - name: target-gateway-with-attachment-conflict-truncated-ancestors - namespace: envoy-gateway - spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-2 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-3 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-4 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-5 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-6 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-7 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-8 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-9 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-10 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-11 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-12 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-13 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-14 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-15 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-16 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-17 - - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-18 - status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-1, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-10 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-10, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-11 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-11, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-12 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-12, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-13 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-13, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-14 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-14, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-15 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-15, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-16 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-16, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-17 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-17, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-18 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-18, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-2 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-2, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-3 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-3, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-4 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-4, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-5 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-5, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-6 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-6, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-7 - namespace: envoy-gateway - conditions: - - lastTransitionTime: null - message: Unable to target Gateway gateway-7, another EnvoyExtensionPolicy - has already attached to it - reason: Conflicted - status: "False" - type: Accepted - - lastTransitionTime: null - message: Ancestors have been truncated because the number of policy ancestors - exceeds 16. - reason: Aggregated - status: "True" - type: Aggregated - controllerName: gateway.envoyproxy.io/gatewayclass-controller -gateways: -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-1 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-2 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-3 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-4 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-5 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-6 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-7 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-8 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-9 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-10 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-11 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-12 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-13 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-14 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-15 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-16 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-17 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -- apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - metadata: - name: gateway-18 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -infraIR: - envoy-gateway/gateway-1: - proxy: - listeners: - - name: envoy-gateway/gateway-1/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-1 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-1 - namespace: envoy-gateway-system - envoy-gateway/gateway-2: - proxy: - listeners: - - name: envoy-gateway/gateway-2/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-2 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-2 - namespace: envoy-gateway-system - envoy-gateway/gateway-3: - proxy: - listeners: - - name: envoy-gateway/gateway-3/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-3 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-3 - namespace: envoy-gateway-system - envoy-gateway/gateway-4: - proxy: - listeners: - - name: envoy-gateway/gateway-4/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-4 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-4 - namespace: envoy-gateway-system - envoy-gateway/gateway-5: - proxy: - listeners: - - name: envoy-gateway/gateway-5/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-5 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-5 - namespace: envoy-gateway-system - envoy-gateway/gateway-6: - proxy: - listeners: - - name: envoy-gateway/gateway-6/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-6 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-6 - namespace: envoy-gateway-system - envoy-gateway/gateway-7: - proxy: - listeners: - - name: envoy-gateway/gateway-7/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-7 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-7 - namespace: envoy-gateway-system - envoy-gateway/gateway-8: - proxy: - listeners: - - name: envoy-gateway/gateway-8/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-8 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-8 - namespace: envoy-gateway-system - envoy-gateway/gateway-9: - proxy: - listeners: - - name: envoy-gateway/gateway-9/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-9 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-9 - namespace: envoy-gateway-system - envoy-gateway/gateway-10: - proxy: - listeners: - - name: envoy-gateway/gateway-10/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-10 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-10 - namespace: envoy-gateway-system - envoy-gateway/gateway-11: - proxy: - listeners: - - name: envoy-gateway/gateway-11/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-11 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-11 - namespace: envoy-gateway-system - envoy-gateway/gateway-12: - proxy: - listeners: - - name: envoy-gateway/gateway-12/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-12 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-12 - namespace: envoy-gateway-system - envoy-gateway/gateway-13: - proxy: - listeners: - - name: envoy-gateway/gateway-13/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-13 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-13 - namespace: envoy-gateway-system - envoy-gateway/gateway-14: - proxy: - listeners: - - name: envoy-gateway/gateway-14/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-14 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-14 - namespace: envoy-gateway-system - envoy-gateway/gateway-15: - proxy: - listeners: - - name: envoy-gateway/gateway-15/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-15 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-15 - namespace: envoy-gateway-system - envoy-gateway/gateway-16: - proxy: - listeners: - - name: envoy-gateway/gateway-16/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-16 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-16 - namespace: envoy-gateway-system - envoy-gateway/gateway-17: - proxy: - listeners: - - name: envoy-gateway/gateway-17/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-17 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-17 - namespace: envoy-gateway-system - envoy-gateway/gateway-18: - proxy: - listeners: - - name: envoy-gateway/gateway-18/http - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-18 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-18 - namespace: envoy-gateway-system -xdsIR: - envoy-gateway/gateway-1: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-1-196ae069 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-1 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-1-196ae069 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-1 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-1 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-1/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-2: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-2-4a0e4eb9 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-2 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-2-4a0e4eb9 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-2 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-2 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-2/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-3: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-3-32e857a6 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-3 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-3-32e857a6 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-3 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-3 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-3/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-4: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-4-a293650b - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-4 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-4-a293650b - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-4 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-4 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-4/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-5: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-5-e35ee57f - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-5 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-5-e35ee57f - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-5 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-5 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-5/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-6: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-6-703894b8 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-6 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-6-703894b8 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-6 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-6 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-6/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-7: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-7-8f166bcc - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-7 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-7-8f166bcc - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-7 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-7 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-7/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-8: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-8-18a274e2 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-8 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-8-18a274e2 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-8 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-8 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-8/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-9: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-9-3f4aa2eb - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-9 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-9-3f4aa2eb - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-9 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-9 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-9/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-10: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-10-323a05f0 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-10 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-10-323a05f0 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-10 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-10 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-10/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-11: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-11-7cd86d79 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-11 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-11-7cd86d79 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-11 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-11 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-11/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-12: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-12-b05135f7 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-12 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-12-b05135f7 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-12 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-12 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-12/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-13: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-13-5ef9b255 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-13 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-13-5ef9b255 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-13 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-13 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-13/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-14: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-14-2b849e6e - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-14 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-14-2b849e6e - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-14 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-14 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-14/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-15: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-15-473da5fd - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-15 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-15-473da5fd - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-15 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-15 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-15/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-16: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-16-bc2b5d3e - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-16 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-16-bc2b5d3e - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-16 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-16 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-16/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-17: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-17-686d5dd1 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-17 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-17-686d5dd1 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-17 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-17 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-17/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 - envoy-gateway/gateway-18: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-18-80e55fa6 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-18 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-18-80e55fa6 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-18 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - metadata: - kind: Gateway - name: gateway-18 - namespace: envoy-gateway - sectionName: http - name: envoy-gateway/gateway-18/http - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-listener-failopen-ownership.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-listener-failopen-ownership.in.yaml new file mode 100644 index 0000000000..1f0e53ef93 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-listener-failopen-ownership.in.yaml @@ -0,0 +1,97 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: listener-1 + protocol: HTTP + port: 8081 + allowedRoutes: + namespaces: + from: All + - name: listener-2 + protocol: HTTP + port: 8082 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 # attached to listener-1, which is owned by an empty fail-open listener policy + spec: + hostnames: + - www.foo.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: listener-1 + rules: + - matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 # attached to listener-2, which should still receive the Gateway-wide wasm filter + spec: + hostnames: + - www.bar.com + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: listener-2 + rules: + - matches: + - path: + value: "/bar" + backendRefs: + - name: service-1 + port: 8080 +envoyExtensionPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway-1-listener-1 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: listener-1 + wasm: + - name: wasm-filter-1 + code: + type: HTTP + http: + url: https://www.example.com/non-existent.wasm + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 + failOpen: true +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway-1 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + wasm: + - name: wasm-filter-1 + code: + type: HTTP + http: + url: https://www.example.com/wasm-filter-1.wasm + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-listener-failopen-ownership.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-listener-failopen-ownership.out.yaml new file mode 100644 index 0000000000..373c44c1ca --- /dev/null +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-listener-failopen-ownership.out.yaml @@ -0,0 +1,390 @@ +envoyExtensionPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + name: policy-for-gateway-1-listener-1 + namespace: envoy-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: listener-1 + wasm: + - code: + http: + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 + url: https://www.example.com/non-existent.wasm + type: HTTP + failOpen: true + name: wasm-filter-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: listener-1 + conditions: + - lastTransitionTime: null + message: 'Wasm: module downloaded from https://www.example.com/non-existent.wasm + has checksum 36ed359d2ddef6346c48c9c63ab424db2df51bb19d532e8744bfbbbd6ef0f45a, + which does not match: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4.' + reason: Invalid + status: "False" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + name: policy-for-gateway-1 + namespace: envoy-gateway + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + wasm: + - code: + http: + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 + url: https://www.example.com/wasm-filter-1.wasm + type: HTTP + name: wasm-filter-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + - lastTransitionTime: null + message: 'This policy is being overridden by other envoyExtensionPolicies + for these gateway listeners: [envoy-gateway/gateway-1/listener-1]' + reason: Overridden + status: "True" + type: Overridden + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: listener-1 + port: 8081 + protocol: HTTP + - allowedRoutes: + namespaces: + from: All + name: listener-2 + port: 8082 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: listener-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: listener-2 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + hostnames: + - www.foo.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: listener-1 + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: listener-1 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-2 + namespace: default + spec: + hostnames: + - www.bar.com + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: listener-2 + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /bar + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: listener-2 +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - name: envoy-gateway/gateway-1/listener-1 + ports: + - containerPort: 8081 + name: http-8081 + protocol: HTTP + servicePort: 8081 + - name: envoy-gateway/gateway-1/listener-2 + ports: + - containerPort: 8082 + name: http-8082 + protocol: HTTP + servicePort: 8082 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: envoy-gateway-system +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + globalResources: + envoyClientCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + name: envoy-gateway-system/envoy + privateKey: '[redacted]' + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + protocol: TCP + http: + - address: 0.0.0.0 + envoyExtensions: {} + externalPort: 8081 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: listener-1 + name: envoy-gateway/gateway-1/listener-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8081 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-1/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: www.foo.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo + - address: 0.0.0.0 + envoyExtensions: + wasms: + - config: null + failOpen: false + httpWasmCode: + originalDownloadingURL: https://www.example.com/wasm-filter-1.wasm + servingURL: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm + sha256: 2d89c4c6ab2a1c615c7696ed37ade9e50654ac70384b5d45100eb08e62130ff4 + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/wasm/0 + wasmName: wasm-filter-1 + externalPort: 8082 + hostnames: + - '*' + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: listener-2 + name: envoy-gateway/gateway-1/listener-2 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8082 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-2/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: www.bar.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + pathMatch: + distinct: false + name: "" + prefix: /bar + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions-truncated.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions-truncated.out.yaml index 9090e02d1e..97051b52bf 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions-truncated.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions-truncated.out.yaml @@ -3058,6 +3058,7 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: {} externalPort: 80 hostnames: - '*' diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml index 9508ec8d51..dc064680ac 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml @@ -596,6 +596,7 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: {} externalPort: 80 hostnames: - '*' diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml index f7bfb1b28b..cc013e51da 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-wasm-invalid-configuration.out.yaml @@ -898,6 +898,7 @@ xdsIR: protocol: TCP http: - address: 0.0.0.0 + envoyExtensions: {} externalPort: 80 hostnames: - '*' From c8d0efc71369b0116ce6ac381788272d4683cf0c Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 3 Aug 2026 10:51:30 +0800 Subject: [PATCH 15/18] use shared filter_chain filter Signed-off-by: zirain --- internal/xds/translator/dynamicmodule.go | 184 ++++++++------- internal/xds/translator/extproc.go | 182 ++++++++------- internal/xds/translator/httpfilters.go | 44 ++-- internal/xds/translator/httpfilters_test.go | 18 +- internal/xds/translator/listener.go | 2 - internal/xds/translator/lua.go | 111 ++++----- .../xds-ir/backend-priority.listeners.yaml | 18 +- .../out/xds-ir/backend-priority.routes.yaml | 21 +- .../xds-ir/custom-filter-order.listeners.yaml | 48 +--- .../xds-ir/custom-filter-order.routes.yaml | 59 ++++- .../xds-ir/dns-lookup-family.listeners.yaml | 18 +- .../out/xds-ir/dns-lookup-family.routes.yaml | 21 +- .../out/xds-ir/dynamicmodule.listeners.yaml | 83 +------ .../out/xds-ir/dynamicmodule.routes.yaml | 147 ++++++++++-- .../ext-proc-with-retries.listeners.yaml | 24 +- .../xds-ir/ext-proc-with-retries.routes.yaml | 27 ++- ...-proc-with-traffic-settings.listeners.yaml | 18 +- ...ext-proc-with-traffic-settings.routes.yaml | 21 +- .../out/xds-ir/ext-proc.listeners.yaml | 136 +---------- .../testdata/out/xds-ir/ext-proc.routes.yaml | 196 ++++++++++++++-- .../jsonpatch-with-jsonpath.listeners.yaml | 29 +-- .../jsonpatch-with-jsonpath.routes.yaml | 32 ++- .../testdata/out/xds-ir/lua.listeners.yaml | 56 ++--- .../testdata/out/xds-ir/lua.routes.yaml | 72 ++++-- .../testdata/out/xds-ir/wasm.listeners.yaml | 150 +----------- .../testdata/out/xds-ir/wasm.routes.yaml | 213 ++++++++++++++++-- internal/xds/translator/utils.go | 147 ++++++++++-- internal/xds/translator/wasm.go | 183 ++++++++------- 28 files changed, 1276 insertions(+), 984 deletions(-) diff --git a/internal/xds/translator/dynamicmodule.go b/internal/xds/translator/dynamicmodule.go index b59e16c4df..653d28b3f1 100644 --- a/internal/xds/translator/dynamicmodule.go +++ b/internal/xds/translator/dynamicmodule.go @@ -7,6 +7,9 @@ package translator import ( "errors" + "fmt" + "slices" + "strconv" corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" @@ -30,13 +33,22 @@ type dynamicModule struct{} var _ httpFilter = &dynamicModule{} -// patchHCM builds and appends the dynamic module filters to the HTTP Connection Manager -// if applicable, and they do not already exist. -// Note: this method creates a filter for each route that contains a dynamic module config. -// The filter is disabled by default and enabled on the route level. +// patchHCM adds disabled envoy.filters.http.filter_chain placeholder filters to the HTTP +// Connection Manager: one for per-listener (per-connection) DynamicModule and one for per-route +// DynamicModule. +// +// Both placeholders are added together as soon as either scope has a DynamicModule policy +// anywhere on this listener, even if the other scope currently has none. This keeps the HCM's +// filter set stable across that kind of policy churn too: e.g. adding a per-listener +// DynamicModule policy later to a listener that already has per-route DynamicModule only changes +// route/virtual host TypedPerFilterConfig (an RDS update), never the listener's filter list +// (which would require an LDS update and a connection drain). +// +// DynamicModule has no native per-route override at all, while EG's EnvoyExtensionPolicy API +// allows an ordered list of DynamicModule filters per listener/route. The filter_chain filter +// wraps an ordered, named sub-chain of DynamicModule filters that is supplied separately (per +// virtual host for listener-scoped DynamicModule, per route for route-scoped DynamicModule). func (*dynamicModule) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { - var errs error - if mgr == nil { return errors.New("hcm is nil") } @@ -44,62 +56,40 @@ func (*dynamicModule) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir. return errors.New("ir listener is nil") } - addFilters := func(dms []ir.DynamicModule) { - for i := range dms { - dm := &dms[i] - if hcmContainsFilter(mgr, dynamicModuleFilterName(dm)) { - continue - } - filter, err := buildHCMDynamicModuleFilter(dm) - if err != nil { - errs = errors.Join(errs, err) - continue - } - mgr.HttpFilters = append(mgr.HttpFilters, filter) - } + hasListenerDynamicModule := listenerContainsDynamicModule(irListener) + hasRouteDynamicModule := slices.ContainsFunc(irListener.Routes, routeContainsDynamicModule) + if !hasListenerDynamicModule && !hasRouteDynamicModule { + return nil } - // Listener-scoped DynamicModules are enabled at VirtualHost scope; route-scoped - // DynamicModules are enabled per route. Both need their (disabled by default) filter - // present on the HCM. - if listenerContainsDynamicModule(irListener) { - addFilters(irListener.EnvoyExtensions.DynamicModules) - } - for _, route := range irListener.Routes { - if !routeContainsDynamicModule(route) { + for _, filterName := range []string{eepListenerFCFilterName(), eepFCFilterName()} { + if hcmContainsFilter(mgr, filterName) { continue } - addFilters(route.EnvoyExtensions.DynamicModules) + filter, err := buildHCMFilterChainFilter(filterName) + if err != nil { + return err + } + mgr.HttpFilters = append(mgr.HttpFilters, filter) } - return errs + return nil } -// buildHCMDynamicModuleFilter returns a dynamic module HTTP filter from the provided IR DynamicModule. -func buildHCMDynamicModuleFilter(dm *ir.DynamicModule) (*hcmv3.HttpFilter, error) { - dmProto, err := dynamicModuleConfig(dm) - if err != nil { - return nil, err - } - - dmAny, err := anypb.New(dmProto) - if err != nil { - return nil, err - } - - // All dynamic module filters for all Routes are aggregated on HCM and disabled by default. - // Per-route config is used to enable the relevant filters on appropriate routes. - return &hcmv3.HttpFilter{ - Name: dynamicModuleFilterName(dm), - Disabled: true, - ConfigType: &hcmv3.HttpFilter_TypedConfig{ - TypedConfig: dmAny, - }, - }, nil +// dynamicModuleSubFilterName returns the stable top-level filter name for the per-route +// DynamicModule slot index. The index is the execution slot within the ordered +// EnvoyExtensionPolicy DynamicModule list, so route 0th modules always bind to the same +// listener-level filter. +func dynamicModuleSubFilterName(idx int) string { + return perRouteFilterName(egv1a1.EnvoyFilterDynamicModules, strconv.Itoa(idx)) } -func dynamicModuleFilterName(dm *ir.DynamicModule) string { - return perRouteFilterName(egv1a1.EnvoyFilterDynamicModules, dm.Name) +// dynamicModuleListenerSubFilterName returns the stable HCM-level filter name for a +// listener-level DynamicModule slot. Using the envoy.filters.http.dynamic_modules prefix +// (instead of the raw policy name) ensures sortHTTPFilters assigns it the correct order +// relative to route-level slots. +func dynamicModuleListenerSubFilterName(idx int) string { + return fmt.Sprintf("%s/listener/%d", egv1a1.EnvoyFilterDynamicModules, idx) } func dynamicModuleConfig(dm *ir.DynamicModule) (*dmfilterv3.DynamicModuleFilter, error) { @@ -218,7 +208,7 @@ func (*dynamicModule) patchResources(tCtx *types.ResourceVersionTable, irListene // and fully replaces — never merges with — the listener-scoped policy. The extension count is // intentionally not checked: an empty result (e.g. fail-open invalid Wasm) still represents a // more specific policy that owns this route and must suppress the lower-scope DynamicModules. -func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener *ir.HTTPListener) error { +func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPListener) error { if route == nil { return errors.New("xds route is nil") } @@ -229,34 +219,42 @@ func (*dynamicModule) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, ir return nil } - own := make(map[string]struct{}, len(irRoute.EnvoyExtensions.DynamicModules)) - for i := range irRoute.EnvoyExtensions.DynamicModules { - own[dynamicModuleFilterName(&irRoute.EnvoyExtensions.DynamicModules[i])] = struct{}{} + // A non-nil EnvoyExtensions means a more specific route policy owns this route and fully + // replaces the listener-scoped policy. The extension count is intentionally not checked + // here: an empty result (e.g. fail-open invalid Wasm) still represents a more specific + // policy that owns this route and must suppress the lower-scope DynamicModule. + if err := disableFilterOnRouteOnce(route, eepListenerFCFilterName()); err != nil { + return err } - if listenerContainsDynamicModule(irListener) { - for i := range irListener.EnvoyExtensions.DynamicModules { - filterName := dynamicModuleFilterName(&irListener.EnvoyExtensions.DynamicModules[i]) - // A single EnvoyExtensionPolicy may target both this listener and this route via - // separate targetRefs, in which case the same filter name appears at both scopes and - // the route re-enables it below instead of disabling it. - if _, ok := own[filterName]; ok { - continue - } - if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{Disabled: true}); err != nil { - return err - } + var newFilters []*corev3.TypedExtensionConfig + for idx := range irRoute.EnvoyExtensions.DynamicModules { + cfg, err := dynamicModuleConfig(&irRoute.EnvoyExtensions.DynamicModules[idx]) + if err != nil { + return err } - } - - for _, dm := range irRoute.EnvoyExtensions.DynamicModules { - filterName := dynamicModuleFilterName(&dm) - if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{ - Config: &anypb.Any{}, - }); err != nil { + cfgAny, err := anypb.New(cfg) + if err != nil { return err } + newFilters = append(newFilters, &corev3.TypedExtensionConfig{ + Name: dynamicModuleSubFilterName(idx), + TypedConfig: cfgAny, + }) + } + + if len(newFilters) == 0 { + return nil + } + + merged, err := mergeFilterChainConfigPerRoute(route.GetTypedPerFilterConfig()[eepFCFilterName()], newFilters) + if err != nil { + return err } + if route.TypedPerFilterConfig == nil { + route.TypedPerFilterConfig = make(map[string]*anypb.Any) + } + route.TypedPerFilterConfig[eepFCFilterName()] = merged return nil } @@ -269,13 +267,39 @@ func (*dynamicModule) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir return nil } - for i := range httpListener.EnvoyExtensions.DynamicModules { - dm := &httpListener.EnvoyExtensions.DynamicModules[i] - if err := enableFilterOnVirtualHost(vh, dynamicModuleFilterName(dm), &routev3.FilterConfig{ - Config: &anypb.Any{}, - }); err != nil { + filterName := eepListenerFCFilterName() + existing := vh.GetTypedPerFilterConfig()[filterName] + alreadyDelivered, err := filterChainAlreadyHasType(existing, egv1a1.EnvoyFilterDynamicModules) + if err != nil { + return err + } + if alreadyDelivered { + return nil + } + + var newFilters []*corev3.TypedExtensionConfig + for idx := range httpListener.EnvoyExtensions.DynamicModules { + cfg, err := dynamicModuleConfig(&httpListener.EnvoyExtensions.DynamicModules[idx]) + if err != nil { return err } + cfgAny, err := anypb.New(cfg) + if err != nil { + return err + } + newFilters = append(newFilters, &corev3.TypedExtensionConfig{ + Name: dynamicModuleListenerSubFilterName(idx), + TypedConfig: cfgAny, + }) + } + + merged, err := mergeFilterChainConfigPerRoute(existing, newFilters) + if err != nil { + return err + } + if vh.TypedPerFilterConfig == nil { + vh.TypedPerFilterConfig = make(map[string]*anypb.Any) } + vh.TypedPerFilterConfig[filterName] = merged return nil } diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go index bd4d0d0b0d..6b37c5c88f 100644 --- a/internal/xds/translator/extproc.go +++ b/internal/xds/translator/extproc.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "slices" + "strconv" corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" @@ -31,77 +32,61 @@ type extProc struct{} var _ httpFilter = &extProc{} -// patchHCM builds and appends the ext_proc Filters to the HTTP Connection Manager -// if applicable, and it does not already exist. -// Note: this method creates an ext_proc filter for each route that contains an ExtAuthz config. -// The filter is disabled by default. It is enabled on the route level. +// patchHCM adds disabled envoy.filters.http.filter_chain placeholder filters to the HTTP +// Connection Manager: one for per-listener (per-connection) ExtProc and one for per-route +// ExtProc. +// +// Both placeholders are added together as soon as either scope has an ExtProc policy anywhere on +// this listener, even if the other scope currently has none. This keeps the HCM's filter set +// stable across that kind of policy churn too: e.g. adding a per-listener ExtProc policy later to +// a listener that already has per-route ExtProc only changes route/virtual host +// TypedPerFilterConfig (an RDS update), never the listener's filter list (which would require +// an LDS update and a connection drain). +// +// Envoy's ExtProcPerRoute API can only override one processor for one filter instance, while EG's +// EnvoyExtensionPolicy API allows an ordered list of ExtProc filters per listener/route. The +// filter_chain filter wraps an ordered, named sub-chain of ExtProc filters that is supplied +// separately (per virtual host for listener-scoped ExtProc, per route for route-scoped ExtProc). func (*extProc) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { - var errs error - if mgr == nil { return errors.New("hcm is nil") } - if irListener == nil { return errors.New("ir listener is nil") } - addFilters := func(extProcs []ir.ExtProc) { - for i := range extProcs { - ep := &extProcs[i] - if hcmContainsFilter(mgr, extProcFilterName(ep)) { - continue - } - - filter, err := buildHCMExtProcFilter(ep) - if err != nil { - errs = errors.Join(errs, err) - continue - } - - mgr.HttpFilters = append(mgr.HttpFilters, filter) - } + hasListenerExtProc := listenerContainsExtProc(irListener) + hasRouteExtProc := slices.ContainsFunc(irListener.Routes, routeContainsExtProc) + if !hasListenerExtProc && !hasRouteExtProc { + return nil } - // Listener-scoped ExtProcs are enabled at VirtualHost scope; route-scoped ExtProcs are - // enabled per route. Both need their (disabled by default) filter present on the HCM. - if listenerContainsExtProc(irListener) { - addFilters(irListener.EnvoyExtensions.ExtProcs) - } - for _, route := range irListener.Routes { - if !routeContainsExtProc(route) { + for _, filterName := range []string{eepListenerFCFilterName(), eepFCFilterName()} { + if hcmContainsFilter(mgr, filterName) { continue } - addFilters(route.EnvoyExtensions.ExtProcs) + filter, err := buildHCMFilterChainFilter(filterName) + if err != nil { + return err + } + mgr.HttpFilters = append(mgr.HttpFilters, filter) } - return errs + return nil } -// buildHCMExtProcFilter returns an ext_proc HTTP filter from the provided IR HTTPRoute. -func buildHCMExtProcFilter(extProc *ir.ExtProc) (*hcmv3.HttpFilter, error) { - extAuthProto, err := extProcConfig(extProc) - if err != nil { - return nil, err - } - extAuthAny, err := anypb.New(extAuthProto) - if err != nil { - return nil, err - } - - // All extproc filters for all Routes are aggregated on HCM and disabled by default - // Per-route config is used to enable the relevant filters on appropriate routes - return &hcmv3.HttpFilter{ - Name: extProcFilterName(extProc), - Disabled: true, - ConfigType: &hcmv3.HttpFilter_TypedConfig{ - TypedConfig: extAuthAny, - }, - }, nil +// extProcSubFilterName returns the stable top-level filter name for the per-route ExtProc slot +// index. The index is the execution slot within the ordered EnvoyExtensionPolicy ExtProc list, so +// route 0th processors always bind to the same listener-level filter. +func extProcSubFilterName(idx int) string { + return perRouteFilterName(egv1a1.EnvoyFilterExtProc, strconv.Itoa(idx)) } -func extProcFilterName(extProc *ir.ExtProc) string { - return perRouteFilterName(egv1a1.EnvoyFilterExtProc, extProc.Name) +// extProcListenerSubFilterName returns the stable HCM-level filter name for a listener-level +// ExtProc slot. Using the envoy.filters.http.ext_proc prefix (instead of the raw policy name) +// ensures sortHTTPFilters assigns it the correct order relative to route-level slots. +func extProcListenerSubFilterName(idx int) string { + return fmt.Sprintf("%s/listener/%d", egv1a1.EnvoyFilterExtProc, idx) } func extProcConfig(extProc *ir.ExtProc) (*extprocv3.ExternalProcessor, error) { @@ -230,7 +215,7 @@ func (*extProc) patchResources(tCtx *types.ResourceVersionTable, // and fully replaces — never merges with — the listener-scoped policy. The extension count is // intentionally not checked: an empty result (e.g. fail-open invalid Wasm) still represents a // more specific policy that owns this route and must suppress the lower-scope ExtProcs. -func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener *ir.HTTPListener) error { +func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPListener) error { if route == nil { return errors.New("xds route is nil") } @@ -241,35 +226,42 @@ func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListen return nil } - own := make(map[string]struct{}, len(irRoute.EnvoyExtensions.ExtProcs)) - for i := range irRoute.EnvoyExtensions.ExtProcs { - own[extProcFilterName(&irRoute.EnvoyExtensions.ExtProcs[i])] = struct{}{} + // A non-nil EnvoyExtensions means a more specific route policy owns this route and fully + // replaces the listener-scoped policy. The extension count is intentionally not checked + // here: an empty result (e.g. fail-open invalid Wasm) still represents a more specific + // policy that owns this route and must suppress the lower-scope ExtProc. + if err := disableFilterOnRouteOnce(route, eepListenerFCFilterName()); err != nil { + return err } - if listenerContainsExtProc(irListener) { - for i := range irListener.EnvoyExtensions.ExtProcs { - filterName := extProcFilterName(&irListener.EnvoyExtensions.ExtProcs[i]) - // A single EnvoyExtensionPolicy may target both this listener and this route via - // separate targetRefs, in which case the same filter name appears at both scopes and - // the route re-enables it below instead of disabling it. - if _, ok := own[filterName]; ok { - continue - } - if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{Disabled: true}); err != nil { - return err - } + var newFilters []*corev3.TypedExtensionConfig + for idx := range irRoute.EnvoyExtensions.ExtProcs { + cfg, err := extProcConfig(&irRoute.EnvoyExtensions.ExtProcs[idx]) + if err != nil { + return err } - } - - for i := range irRoute.EnvoyExtensions.ExtProcs { - ep := &irRoute.EnvoyExtensions.ExtProcs[i] - filterName := extProcFilterName(ep) - if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{ - Config: &anypb.Any{}, - }); err != nil { + cfgAny, err := anypb.New(cfg) + if err != nil { return err } + newFilters = append(newFilters, &corev3.TypedExtensionConfig{ + Name: extProcSubFilterName(idx), + TypedConfig: cfgAny, + }) + } + + if len(newFilters) == 0 { + return nil + } + + merged, err := mergeFilterChainConfigPerRoute(route.GetTypedPerFilterConfig()[eepFCFilterName()], newFilters) + if err != nil { + return err + } + if route.TypedPerFilterConfig == nil { + route.TypedPerFilterConfig = make(map[string]*anypb.Any) } + route.TypedPerFilterConfig[eepFCFilterName()] = merged return nil } @@ -331,13 +323,39 @@ func (*extProc) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPL return nil } - for i := range httpListener.EnvoyExtensions.ExtProcs { - ep := &httpListener.EnvoyExtensions.ExtProcs[i] - if err := enableFilterOnVirtualHost(vh, extProcFilterName(ep), &routev3.FilterConfig{ - Config: &anypb.Any{}, - }); err != nil { + filterName := eepListenerFCFilterName() + existing := vh.GetTypedPerFilterConfig()[filterName] + alreadyDelivered, err := filterChainAlreadyHasType(existing, egv1a1.EnvoyFilterExtProc) + if err != nil { + return err + } + if alreadyDelivered { + return nil + } + + var newFilters []*corev3.TypedExtensionConfig + for idx := range httpListener.EnvoyExtensions.ExtProcs { + cfg, err := extProcConfig(&httpListener.EnvoyExtensions.ExtProcs[idx]) + if err != nil { return err } + cfgAny, err := anypb.New(cfg) + if err != nil { + return err + } + newFilters = append(newFilters, &corev3.TypedExtensionConfig{ + Name: extProcListenerSubFilterName(idx), + TypedConfig: cfgAny, + }) + } + + merged, err := mergeFilterChainConfigPerRoute(existing, newFilters) + if err != nil { + return err + } + if vh.TypedPerFilterConfig == nil { + vh.TypedPerFilterConfig = make(map[string]*anypb.Any) } + vh.TypedPerFilterConfig[filterName] = merged return nil } diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index 2fbee4eb55..05fc5cdb98 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -7,9 +7,7 @@ package translator import ( "container/list" - "fmt" "sort" - "strconv" "strings" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" @@ -128,19 +126,12 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter { order = 10 case isFilterType(filter, egv1a1.EnvoyFilterBuffer): order = 11 - case isFilterType(filter, egv1a1.EnvoyFilterLua): - if strings.Contains(filter.Name, "listener") { - // Listener-level Lua runs before route-level Lua. - order = 12 - } else { - order = 62 - } - case isFilterType(filter, egv1a1.EnvoyFilterExtProc): - order = 100 + mustGetFilterIndex(filter.Name) - case isFilterType(filter, egv1a1.EnvoyFilterWasm): - order = 200 + mustGetFilterIndex(filter.Name) - case isFilterType(filter, egv1a1.EnvoyFilterDynamicModules): - order = 250 + mustGetFilterIndex(filter.Name) + case filter.Name == eepListenerFCFilterName(): + // Lua, ExtProc, Wasm, and DynamicModule all share this one placeholder for their + // listener-scoped instances, and it runs before the shared route-scoped placeholder. + order = 12 + case filter.Name == eepFCFilterName(): + order = 62 case isFilterType(filter, egv1a1.EnvoyFilterGeoIP): order = 300 case isFilterType(filter, egv1a1.EnvoyFilterRBAC): @@ -367,25 +358,18 @@ func isFilterType(filter *hcmv3.HttpFilter, filterType egv1a1.EnvoyFilter) bool if strings.HasPrefix(filter.Name, string(filterType)) { return true } - // Lua is delivered via envoy.filters.http.filter_chain placeholder filters - // (luaFCFilterName/luaListenerFCFilterName) rather than under the envoy.filters.http.lua - // prefix, so FilterOrder entries that reference EnvoyFilterLua need to match those names too. - if filterType == egv1a1.EnvoyFilterLua { - return filter.Name == luaFCFilterName() || filter.Name == luaListenerFCFilterName() + // Lua, ExtProc, Wasm, and DynamicModules are all delivered via the same two shared + // envoy.filters.http.filter_chain placeholder filters rather than under their own + // filter-type prefix, so FilterOrder entries that reference any of these types need to + // match those placeholder names too. Because the placeholder is shared, moving one of + // these types in a custom FilterOrder moves all of them together. + switch filterType { + case egv1a1.EnvoyFilterLua, egv1a1.EnvoyFilterExtProc, egv1a1.EnvoyFilterWasm, egv1a1.EnvoyFilterDynamicModules: + return filter.Name == eepFCFilterName() || filter.Name == eepListenerFCFilterName() } return false } -// mustGetFilterIndex returns the index of the filter in its filter type. -func mustGetFilterIndex(filterName string) int { - a := strings.Split(filterName, "/") - index, err := strconv.Atoi(a[len(a)-1]) - if err != nil { - panic(fmt.Errorf("cannot get filter index from %s :%w", filterName, err)) - } - return index -} - // patchResources adds all the other needed resources referenced by this // filter to the resource version table. // for example: diff --git a/internal/xds/translator/httpfilters_test.go b/internal/xds/translator/httpfilters_test.go index b663ca9c95..a85c21204e 100644 --- a/internal/xds/translator/httpfilters_test.go +++ b/internal/xds/translator/httpfilters_test.go @@ -428,25 +428,23 @@ func Test_sortHTTPFilters(t *testing.T) { }, }, { - name: "custom filter order-lua-filter-chain-placeholder", + name: "custom filter order-eep-filter-chain-placeholder", filters: []*hcmv3.HttpFilter{ httpFilterForTest(egv1a1.EnvoyFilterRouter), - httpFilterForTest(egv1a1.EnvoyFilterExtProc + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), - httpFilterForTest(egv1a1.EnvoyFilter(luaFCFilterName())), - httpFilterForTest(egv1a1.EnvoyFilter(luaListenerFCFilterName())), - httpFilterForTest(egv1a1.EnvoyFilterWasm + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), + httpFilterForTest(egv1a1.EnvoyFilterOAuth2 + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(egv1a1.EnvoyFilter(eepFCFilterName())), + httpFilterForTest(egv1a1.EnvoyFilter(eepListenerFCFilterName())), }, filterOrder: []egv1a1.FilterPosition{ { Name: egv1a1.EnvoyFilterLua, - After: new(egv1a1.EnvoyFilterWasm), + After: new(egv1a1.EnvoyFilterOAuth2), }, }, want: []*hcmv3.HttpFilter{ - httpFilterForTest(egv1a1.EnvoyFilterExtProc + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), - httpFilterForTest(egv1a1.EnvoyFilterWasm + "/envoyextensionpolicy/default/policy-for-http-route-1/0"), - httpFilterForTest(egv1a1.EnvoyFilter(luaListenerFCFilterName())), - httpFilterForTest(egv1a1.EnvoyFilter(luaFCFilterName())), + httpFilterForTest(egv1a1.EnvoyFilterOAuth2 + "/securitypolicy/default/policy-for-http-route-1"), + httpFilterForTest(egv1a1.EnvoyFilter(eepListenerFCFilterName())), + httpFilterForTest(egv1a1.EnvoyFilter(eepFCFilterName())), httpFilterForTest(egv1a1.EnvoyFilterRouter), }, }, diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index 41e86b74db..be3e2eb136 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -1364,5 +1364,3 @@ func buildRequestIDExtension(requestID *ir.RequestIDExtensionAction) *hcmv3.Requ TypedConfig: requestIDConfig, } } - -const FilterChainFilterNamePrefixForEEP = "envoy.filters.http.filter_chain.eep." diff --git a/internal/xds/translator/lua.go b/internal/xds/translator/lua.go index 38f688213a..f73f7b4afa 100644 --- a/internal/xds/translator/lua.go +++ b/internal/xds/translator/lua.go @@ -13,7 +13,6 @@ import ( corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" - filterchainv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/filter_chain/v3" luafilterv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/lua/v3" hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" "google.golang.org/protobuf/encoding/protojson" @@ -34,7 +33,11 @@ type lua struct{} var _ httpFilter = &lua{} // patchHCM adds disabled envoy.filters.http.filter_chain placeholder filters to the HTTP -// Connection Manager: one for per-listener (per-connection) Lua and one for per-route Lua. +// Connection Manager: one shared placeholder for per-listener (per-connection) EnvoyExtensionPolicy +// extensions and one shared placeholder for per-route extensions. Lua, ExtProc, Wasm, and +// DynamicModule all deliver their instances through these same two placeholders instead of each +// type getting its own, so the HCM's filter list never grows or reorders as extensions of any +// type are added, removed, or renamed. // // Both placeholders are added together as soon as either scope has a Lua policy anywhere on // this listener, even if the other scope currently has none. This keeps the HCM's filter set @@ -61,7 +64,7 @@ func (*lua) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListen return nil } - for _, filterName := range []string{luaListenerFCFilterName(), luaFCFilterName()} { + for _, filterName := range []string{eepListenerFCFilterName(), eepFCFilterName()} { if hcmContainsFilter(mgr, filterName) { continue } @@ -75,42 +78,6 @@ func (*lua) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListen return nil } -// luaFCFilterName returns the stable HCM-level filter name for the per-route Lua -// filter_chain placeholder. -func luaFCFilterName() string { - return FilterChainFilterNamePrefixForEEP + "lua" -} - -// luaListenerFCFilterName returns the stable HCM-level filter name for the per-listener -// (per-connection) Lua filter_chain placeholder. -func luaListenerFCFilterName() string { - return FilterChainFilterNamePrefixForEEP + "lua.listener" -} - -func buildHCMFilterChainFilter(filterName string) (*hcmv3.HttpFilter, error) { - var ( - fcProto *filterchainv3.FilterChainConfig - fcAny *anypb.Any - err error - ) - fcProto = &filterchainv3.FilterChainConfig{} - - if err = fcProto.ValidateAll(); err != nil { - return nil, err - } - if fcAny, err = anypb.New(fcProto); err != nil { - return nil, err - } - - return &hcmv3.HttpFilter{ - Name: filterName, - Disabled: true, - ConfigType: &hcmv3.HttpFilter_TypedConfig{ - TypedConfig: fcAny, - }, - }, nil -} - // luaFilterName returns the stable top-level filter name for the per-route Lua slot index. // The index is the execution slot within the ordered EnvoyExtensionPolicy Lua // list, so route 0th scripts always bind to the same listener-level filter. @@ -142,7 +109,7 @@ func (*lua) patchResources(_ *types.ResourceVersionTable, _ *ir.HTTPListener, _ // Routes with no Lua entries fall back to the listener-level Lua inherited from the virtual host. // Only routes with their own Lua entries disable the inherited listener-level Lua and install // their own scripts in its place. -func (*lua) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener *ir.HTTPListener) error { +func (*lua) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPListener) error { if route == nil { return errors.New("xds route is nil") } @@ -157,18 +124,11 @@ func (*lua) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener * // replaces the listener-scoped policy. The extension count is intentionally not checked // here: an empty result (e.g. fail-open invalid Wasm) still represents a more specific // policy that owns this route and must suppress the lower-scope Lua. - if irListener != nil && irListener.EnvoyExtensions != nil && len(irListener.EnvoyExtensions.Luas) > 0 { - if err := enableFilterOnRoute(route, luaListenerFCFilterName(), &routev3.FilterConfig{Disabled: true}); err != nil { - return err - } + if err := disableFilterOnRouteOnce(route, eepListenerFCFilterName()); err != nil { + return err } - if route.TypedPerFilterConfig == nil { - route.TypedPerFilterConfig = make(map[string]*anypb.Any) - } - filterChainConfigPerRoute := &filterchainv3.FilterChainConfigPerRoute{ - FilterChain: &filterchainv3.FilterChain{}, - } + var newFilters []*corev3.TypedExtensionConfig for idx, ep := range irRoute.EnvoyExtensions.Luas { filterName := luaFilterName(idx) luaOnFCFilter := &luafilterv3.Lua{ @@ -191,29 +151,33 @@ func (*lua) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener * if err != nil { return err } + if route.TypedPerFilterConfig == nil { + route.TypedPerFilterConfig = make(map[string]*anypb.Any) + } route.TypedPerFilterConfig[filterName] = luaPerRouteAny } luaOnFCFilterAny, err := anypb.New(luaOnFCFilter) if err != nil { return err } - filterChainConfigPerRoute.FilterChain.Filters = append(filterChainConfigPerRoute.FilterChain.Filters, - &corev3.TypedExtensionConfig{ - Name: filterName, - TypedConfig: luaOnFCFilterAny, - }, - ) + newFilters = append(newFilters, &corev3.TypedExtensionConfig{ + Name: filterName, + TypedConfig: luaOnFCFilterAny, + }) } - if len(filterChainConfigPerRoute.FilterChain.Filters) == 0 { + if len(newFilters) == 0 { return nil } - fcAny, err := anypb.New(filterChainConfigPerRoute) + + merged, err := mergeFilterChainConfigPerRoute(route.GetTypedPerFilterConfig()[eepFCFilterName()], newFilters) if err != nil { return err } - - route.TypedPerFilterConfig[luaFCFilterName()] = fcAny + if route.TypedPerFilterConfig == nil { + route.TypedPerFilterConfig = make(map[string]*anypb.Any) + } + route.TypedPerFilterConfig[eepFCFilterName()] = merged return nil } @@ -226,8 +190,13 @@ func (*lua) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListe return nil } - filterName := luaListenerFCFilterName() - if vh.TypedPerFilterConfig != nil && vh.TypedPerFilterConfig[filterName] != nil { + filterName := eepListenerFCFilterName() + existing := vh.GetTypedPerFilterConfig()[filterName] + alreadyDelivered, err := filterChainAlreadyHasType(existing, egv1a1.EnvoyFilterLua) + if err != nil { + return err + } + if alreadyDelivered { // Already delivered for this VirtualHost, e.g. because patchVirtualHost was called // again for a different IR listener sharing the same RouteConfiguration. return nil @@ -237,9 +206,7 @@ func (*lua) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListe vh.TypedPerFilterConfig = map[string]*anypb.Any{} } - filterChainConfigPerRoute := &filterchainv3.FilterChainConfigPerRoute{ - FilterChain: &filterchainv3.FilterChain{}, - } + var newFilters []*corev3.TypedExtensionConfig for i, ep := range httpListener.EnvoyExtensions.Luas { subFilterName := luaListenerFilterName(i) luaOnFCFilter := &luafilterv3.Lua{ @@ -268,18 +235,16 @@ func (*lua) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPListe if err != nil { return err } - filterChainConfigPerRoute.FilterChain.Filters = append(filterChainConfigPerRoute.FilterChain.Filters, - &corev3.TypedExtensionConfig{ - Name: subFilterName, - TypedConfig: luaOnFCFilterAny, - }, - ) + newFilters = append(newFilters, &corev3.TypedExtensionConfig{ + Name: subFilterName, + TypedConfig: luaOnFCFilterAny, + }) } - fcAny, err := anypb.New(filterChainConfigPerRoute) + merged, err := mergeFilterChainConfigPerRoute(existing, newFilters) if err != nil { return err } - vh.TypedPerFilterConfig[filterName] = fcAny + vh.TypedPerFilterConfig[filterName] = merged return nil } diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml index 7f609a90d1..041f6a8e9e 100644 --- a/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml @@ -15,19 +15,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend.envoy-gateway:8000 - clusterName: envoyextensionpolicy/default/policy-for-http-route/0 - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.route + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml index e5e50ccde2..3bcb015933 100644 --- a/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml @@ -28,9 +28,26 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.envoy-gateway:8000 + clusterName: envoyextensionpolicy/default/policy-for-http-route/0 + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP - domains: - www.bar.com metadata: diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml index 3cdc7e287f..151840d5da 100644 --- a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.listeners.yaml @@ -24,53 +24,13 @@ typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"parameter1":{"key1":"value1","key2":"value2"},"parameter2":"value3"}' - name: wasm-filter-1 - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + name: envoy.filters.http.filter_chain.eep.route typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"parameter1":"value1","parameter2":"value2"}' - name: wasm-filter-2 - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.jwt_authn typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication diff --git a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.routes.yaml index bae1ee1b81..7a190cca3c 100644 --- a/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/custom-filter-order.routes.yaml @@ -24,12 +24,59 @@ regex: https://.*\.test\.com:8080 - exact: https://www.test.org:8080 forwardNotMatchingPreflights: false + envoy.filters.http.filter_chain.eep.listener: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.wasm/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":{"key1":"value1","key2":"value2"},"parameter2":"value3"}' + name: wasm-filter-1 + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/0 + - name: envoy.filters.http.wasm/1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":"value1","parameter2":"value2"}' + name: wasm-filter-2 + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: a1efca12ea51069abb123bf9c77889fcc2a31cc5483fc14d115e44fdf07c7980 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/1 envoy.filters.http.jwt_authn: '@type': type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteConfig requirementName: example1-or-example2_73a070ef6c8ee8ea - envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/1: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.listeners.yaml index 584a9f8d68..57e79cd2ef 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.listeners.yaml @@ -139,19 +139,13 @@ withRequestBody: maxRequestBytes: 8192 - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-httproute/extproc/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: backend-fqdn2.default:9090 - clusterName: envoyextensionpolicy/default/policy-for-httproute/extproc/0 - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.route + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.grpc_web typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb diff --git a/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.routes.yaml index 22a2d4c21c..874f787fa4 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.routes.yaml @@ -31,9 +31,26 @@ envoy.filters.http.ext_authz/securitypolicy/envoy-gateway/policy-for-gateway-1: '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute checkSettings: {} - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-httproute/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: backend-fqdn2.default:9090 + clusterName: envoyextensionpolicy/default/policy-for-httproute/extproc/0 + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP - domains: - '*' metadata: diff --git a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml index e49e83edfe..d87b32b5e0 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml @@ -15,66 +15,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-for-http-route/dynamic-module/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter - dynamicModuleConfig: - doNotClose: true - loadGlobally: true - module: - local: - filename: /usr/lib/envoy/modules/ai_gateway.so - filterConfig: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"maxTokensPerMinute":10000}' - filterName: token-ratelimit + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-path/dynamic-module/0 + name: envoy.filters.http.filter_chain.eep.route typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter - dynamicModuleConfig: - module: - local: - filename: /opt/modules/my_module.so - filterName: path-filter - - disabled: true - name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-terminal/dynamic-module/0 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter - dynamicModuleConfig: - module: - local: - filename: /usr/lib/envoy/modules/my_handler.so - filterName: handler - terminalFilter: true - - disabled: true - name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway/dynamic-module/0 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter - dynamicModuleConfig: - module: - local: - filename: /usr/lib/envoy/modules/my_auth.so - filterConfig: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"authEndpoint":"https://auth.example.com"}' - filterName: auth-check - - disabled: true - name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway/dynamic-module/1 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter - dynamicModuleConfig: - module: - remote: - httpUri: - cluster: modules_example_com_443 - timeout: 10s - uri: https://modules.example.com/libremote_auth.so - sha256: abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 - filterConfig: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"authEndpoint":"https://remote-auth.example.com"}' - filterName: remote-auth-check + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -111,27 +58,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-for-route-6/dynamic-module/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter - dynamicModuleConfig: - module: - local: - filename: /usr/lib/envoy/modules/route_override.so - filterName: route-override-filter + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0 + name: envoy.filters.http.filter_chain.eep.route typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter - dynamicModuleConfig: - module: - remote: - httpUri: - cluster: listener-modules_example_com_443 - timeout: 10s - uri: https://listener-modules.example.com/liblistener.so - sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef - filterName: listener-filter + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.routes.yaml index 6cb4ae5844..9924217d1a 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.routes.yaml @@ -13,9 +13,26 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-for-http-route/dynamic-module/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.dynamic_modules/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + doNotClose: true + loadGlobally: true + module: + local: + filename: /usr/lib/envoy/modules/ai_gateway.so + filterConfig: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"maxTokensPerMinute":10000}' + filterName: token-ratelimit - match: pathSeparatedPrefix: /bar name: httproute/default/httproute-2/rule/0/match/0/www_example_com @@ -24,12 +41,39 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway/dynamic-module/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway/dynamic-module/1: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.dynamic_modules/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + local: + filename: /usr/lib/envoy/modules/my_auth.so + filterConfig: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"authEndpoint":"https://auth.example.com"}' + filterName: auth-check + - name: envoy.filters.http.dynamic_modules/1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + remote: + httpUri: + cluster: modules_example_com_443 + timeout: 10s + uri: https://modules.example.com/libremote_auth.so + sha256: abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 + filterConfig: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"authEndpoint":"https://remote-auth.example.com"}' + filterName: remote-auth-check - match: pathSeparatedPrefix: /terminal name: httproute/default/httproute-3/rule/0/match/0/www_example_com @@ -38,9 +82,22 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-terminal/dynamic-module/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.dynamic_modules/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + local: + filename: /usr/lib/envoy/modules/my_handler.so + filterName: handler + terminalFilter: true - match: pathSeparatedPrefix: /path-loaded name: httproute/default/httproute-4/rule/0/match/0/www_example_com @@ -49,9 +106,21 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-path/dynamic-module/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.dynamic_modules/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + local: + filename: /opt/modules/my_module.so + filterName: path-filter - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-listener-scope virtualHosts: @@ -74,12 +143,21 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.dynamic_modules/envoyextensionpolicy/default/policy-for-route-6/dynamic-module/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.dynamic_modules/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + local: + filename: /usr/lib/envoy/modules/route_override.so + filterName: route-override-filter - match: pathSeparatedPrefix: /same-name name: httproute/default/httproute-7/rule/0/match/0/listener_scope_example_com @@ -88,10 +166,39 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.dynamic_modules/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + remote: + httpUri: + cluster: listener-modules_example_com_443 + timeout: 10s + uri: https://listener-modules.example.com/liblistener.so + sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + filterName: listener-filter typedPerFilterConfig: - envoy.filters.http.dynamic_modules/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/dynamic-module/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + envoy.filters.http.filter_chain.eep.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.dynamic_modules/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_modules.v3.DynamicModuleFilter + dynamicModuleConfig: + module: + remote: + httpUri: + cluster: listener-modules_example_com_443 + timeout: 10s + uri: https://listener-modules.example.com/liblistener.so + sha256: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + filterName: listener-filter diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-retries.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-retries.listeners.yaml index ce5ee3269c..041f6a8e9e 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-retries.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-retries.listeners.yaml @@ -15,25 +15,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend.envoy-gateway:8000 - clusterName: envoyextensionpolicy/default/policy-for-http-route/0 - retryPolicy: - numRetries: 2 - retryBackOff: - baseInterval: 0.200s - maxInterval: 3s - retryOn: 5xx,deadline-exceeded,internal,unavailable - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.route + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-retries.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-retries.routes.yaml index e5e50ccde2..50073ae41d 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-retries.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-retries.routes.yaml @@ -28,9 +28,32 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.envoy-gateway:8000 + clusterName: envoyextensionpolicy/default/policy-for-http-route/0 + retryPolicy: + numRetries: 2 + retryBackOff: + baseInterval: 0.200s + maxInterval: 3s + retryOn: 5xx,deadline-exceeded,internal,unavailable + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP - domains: - www.bar.com metadata: diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml index 7f609a90d1..041f6a8e9e 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml @@ -15,19 +15,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend.envoy-gateway:8000 - clusterName: envoyextensionpolicy/default/policy-for-http-route/0 - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.route + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml index e5e50ccde2..3bcb015933 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml @@ -28,9 +28,26 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.envoy-gateway:8000 + clusterName: envoyextensionpolicy/default/policy-for-http-route/0 + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP - domains: - www.bar.com metadata: diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml index b8cbabda8b..d87b32b5e0 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml @@ -15,113 +15,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-1/extproc/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - failureModeAllow: true - grpcService: - envoyGrpc: - authority: grpc-backend-2.default:8000 - clusterName: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 - timeout: 10s - messageTimeout: 5s - processingMode: - requestBodyMode: BUFFERED_PARTIAL - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SEND - responseTrailerMode: SKIP + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-2/extproc/0 + name: envoy.filters.http.filter_chain.eep.route typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - allowModeOverride: true - failureModeAllow: true - grpcService: - envoyGrpc: - authority: grpc-backend-4.default:4000 - clusterName: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 - timeout: 10s - messageTimeout: 5s - metadataOptions: - forwardingNamespaces: - untyped: - - envoy.filters.http.ext_authz - receivingNamespaces: - untyped: - - envoy.filters.http.my_custom - processingMode: - requestBodyMode: BUFFERED - requestHeaderMode: SEND - requestTrailerMode: SKIP - responseBodyMode: STREAMED - responseHeaderMode: SKIP - responseTrailerMode: SKIP - requestAttributes: - - xds.route_metadata - - connection.requested_server_name - responseAttributes: - - request.path - - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend.envoy-gateway:9000 - clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend - timeout: 10s - messageTimeout: 15s - metadataOptions: - forwardingNamespaces: - untyped: - - envoy.filters.http.ext_proc - receivingNamespaces: - untyped: - - envoy.filters.http.prc_ext - observabilityMode: true - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP - requestAttributes: - - xds.route_metadata - - connection.requested_server_name - responseAttributes: - - request.path - statusOnError: - code: ServiceUnavailable - - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/extproc/0 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend-3.envoy-gateway:3000 - clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3 - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP - - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-route-3/extproc/0 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend-3.envoy-gateway:3000 - clusterName: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3 - timeout: 10s - processingMode: - requestBodyMode: FULL_DUPLEX_STREAMED - requestHeaderMode: SKIP - requestTrailerMode: SEND - responseBodyMode: FULL_DUPLEX_STREAMED - responseHeaderMode: SKIP - responseTrailerMode: SEND + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -158,33 +58,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-5/extproc/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend-5.default:9500 - clusterName: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5 - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0 + name: envoy.filters.http.filter_chain.eep.route typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend-listener.envoy-gateway:9000 - clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml index 6ca0a10f78..89dc137e53 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml @@ -13,12 +13,59 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-1/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-2/extproc/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + allowModeOverride: true + failureModeAllow: true + grpcService: + envoyGrpc: + authority: grpc-backend-4.default:4000 + clusterName: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 + timeout: 10s + messageTimeout: 5s + metadataOptions: + forwardingNamespaces: + untyped: + - envoy.filters.http.ext_authz + receivingNamespaces: + untyped: + - envoy.filters.http.my_custom + processingMode: + requestBodyMode: BUFFERED + requestHeaderMode: SEND + requestTrailerMode: SKIP + responseBodyMode: STREAMED + responseHeaderMode: SKIP + responseTrailerMode: SKIP + requestAttributes: + - xds.route_metadata + - connection.requested_server_name + responseAttributes: + - request.path + - name: envoy.filters.http.ext_proc/1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + failureModeAllow: true + grpcService: + envoyGrpc: + authority: grpc-backend-2.default:8000 + clusterName: envoyextensionpolicy/default/policy-for-route-1/0/grpc-backend-2 + timeout: 10s + messageTimeout: 5s + processingMode: + requestBodyMode: BUFFERED_PARTIAL + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SEND + responseTrailerMode: SKIP - match: pathSeparatedPrefix: /bar name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io @@ -27,9 +74,28 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-route-3/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend-3.envoy-gateway:3000 + clusterName: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3 + timeout: 10s + processingMode: + requestBodyMode: FULL_DUPLEX_STREAMED + requestHeaderMode: SKIP + requestTrailerMode: SEND + responseBodyMode: FULL_DUPLEX_STREAMED + responseHeaderMode: SKIP + responseTrailerMode: SEND - domains: - "" name: envoy-gateway/gateway-1/http/ @@ -41,12 +107,55 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/extproc/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend-3.envoy-gateway:3000 + clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-2/0/grpc-backend-3 + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP + - name: envoy.filters.http.ext_proc/1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.envoy-gateway:9000 + clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend + timeout: 10s + messageTimeout: 15s + metadataOptions: + forwardingNamespaces: + untyped: + - envoy.filters.http.ext_proc + receivingNamespaces: + untyped: + - envoy.filters.http.prc_ext + observabilityMode: true + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP + requestAttributes: + - xds.route_metadata + - connection.requested_server_name + responseAttributes: + - request.path + statusOnError: + code: ServiceUnavailable - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-listener-scope virtualHosts: @@ -69,12 +178,26 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-route-5/extproc/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend-5.default:9500 + clusterName: envoyextensionpolicy/default/policy-for-route-5/0/grpc-backend-5 + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP - match: pathSeparatedPrefix: /same-name name: httproute/default/httproute-6/rule/0/match/0/listener_scope_envoyproxy_io @@ -83,10 +206,41 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend-listener.envoy-gateway:9000 + clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/extproc/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + envoy.filters.http.filter_chain.eep.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend-listener.envoy-gateway:9000 + clusterName: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/0/grpc-backend-listener + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml index 56d7ceff94..584d1a7470 100644 --- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml @@ -81,30 +81,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-http-route/wasm/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"parameter1":{"key1":"value1"},"parameter2":{"key2":{"key3":"value3"}}}' - failOpen: true - name: wasm-filter-4 - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway:18002/fe571e7b1ef5dc626ceb2c2c86782a134a92989a2643485238951696ae4334c3.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/default/policy-for-http-route/wasm/0 + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig + - disabled: true + name: envoy.filters.http.filter_chain.eep.route + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml index e874e015b2..d8ea76c06e 100644 --- a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml @@ -52,9 +52,37 @@ another-filter-per-filter-config: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} - envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-http-route/wasm/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.wasm/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":{"key1":"value1"},"parameter2":{"key2":{"key3":"value3"}}}' + failOpen: true + name: wasm-filter-4 + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway:18002/fe571e7b1ef5dc626ceb2c2c86782a134a92989a2643485238951696ae4334c3.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/default/policy-for-http-route/wasm/0 - match: prefix: / name: httproute/default/httproute-1/rule/1/match/0/www_example_com diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml index 9a5d0bff46..64a9ccb3b5 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml @@ -15,11 +15,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router @@ -58,11 +58,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router @@ -101,11 +101,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router @@ -144,27 +144,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend.default:8000 - clusterName: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -201,11 +187,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router @@ -244,27 +230,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - - disabled: true - name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-gateway/extproc/0 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - grpcService: - envoyGrpc: - authority: grpc-backend.default:8000 - clusterName: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend - timeout: 10s - processingMode: - requestHeaderMode: SKIP - requestTrailerMode: SKIP - responseHeaderMode: SKIP - responseTrailerMode: SKIP - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -301,11 +273,11 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.filter_chain.eep.lua.listener + name: envoy.filters.http.filter_chain.eep.listener typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.filter_chain.eep.lua + name: envoy.filters.http.filter_chain.eep.route typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml index 4431541261..88e2f3baf3 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.routes.yaml @@ -13,7 +13,10 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua: + envoy.filters.http.filter_chain.eep.listener: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + disabled: true + envoy.filters.http.filter_chain.eep.route: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -36,7 +39,10 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua: + envoy.filters.http.filter_chain.eep.listener: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + disabled: true + envoy.filters.http.filter_chain.eep.route: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -67,7 +73,10 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua: + envoy.filters.http.filter_chain.eep.listener: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + disabled: true + envoy.filters.http.filter_chain.eep.route: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -77,16 +86,13 @@ defaultSourceCode: inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Goodbye.') end - envoy.filters.http.filter_chain.eep.lua.listener: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - disabled: true envoy.filters.http.lua/0: '@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute filterContext: mode: strict token_header: x-api-key typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -116,7 +122,7 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -146,12 +152,26 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.ext_proc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.default:8000 + clusterName: envoyextensionpolicy/default/policy-for-http-route/0/grpc-backend + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP - match: pathSeparatedPrefix: /bar name: httproute/default/httproute-5/rule/0/match/0/www_example_com @@ -160,7 +180,7 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -185,7 +205,7 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -207,7 +227,7 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -232,10 +252,7 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-gateway/extproc/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: @@ -245,6 +262,19 @@ defaultSourceCode: inlineString: function envoy_on_request(request_handle) request_handle:logInfo('Gateway Lua.') end + - name: envoy.filters.http.ext_proc/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.default:8000 + clusterName: envoyextensionpolicy/default/policy-for-gateway/0/grpc-backend + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-8 virtualHosts: @@ -260,11 +290,11 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true typedPerFilterConfig: - envoy.filters.http.filter_chain.eep.lua.listener: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute filterChain: filters: diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml index a5da6fd1bd..d87b32b5e0 100644 --- a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml @@ -15,107 +15,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-http-route/wasm/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"parameter1":{"key1":"value1"},"parameter2":{"key2":{"key3":"value3"}}}' - failOpen: true - name: wasm-filter-4 - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway:18002/fe571e7b1ef5dc626ceb2c2c86782a134a92989a2643485238951696ae4334c3.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/default/policy-for-http-route/wasm/0 + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 + name: envoy.filters.http.filter_chain.eep.route typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"parameter1":{"key1":"value1","key2":"value2"},"parameter2":"value3"}' - name: wasm-filter-1 - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 - - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: '{"parameter1":"value1","parameter2":"value2"}' - name: wasm-filter-2 - rootId: my-root-id - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46 - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 - - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: "" - name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee - environmentVariables: - hostEnvKeys: - - SOME_KEY - - ANOTHER_KEY - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router @@ -152,53 +58,13 @@ maxConcurrentStreams: 100 httpFilters: - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-route-4/wasm/0 + name: envoy.filters.http.filter_chain.eep.listener typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: "" - name: wasm-filter-route-override - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/9d2e2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: 9d2e2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/default/policy-for-route-4/wasm/0 + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - disabled: true - name: envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0 + name: envoy.filters.http.filter_chain.eep.route typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm - config: - configuration: - '@type': type.googleapis.com/google.protobuf.StringValue - value: "" - name: wasm-filter-listener - vmConfig: - code: - remote: - httpUri: - cluster: wasm_cluster - timeout: 10s - uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f.wasm - retryPolicy: - numRetries: 10 - retryBackOff: - baseInterval: 1s - maxInterval: 30s - sha256: 8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f - runtime: envoy.wasm.runtime.v8 - vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0 + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfig - name: envoy.filters.http.router typedConfig: '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml index 39ce7ba57f..e756a97c8f 100644 --- a/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.routes.yaml @@ -13,9 +13,37 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-http-route/wasm/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.wasm/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":{"key1":"value1"},"parameter2":{"key2":{"key3":"value3"}}}' + failOpen: true + name: wasm-filter-4 + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway:18002/fe571e7b1ef5dc626ceb2c2c86782a134a92989a2643485238951696ae4334c3.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: a1f0b78b8c1320690327800e3a5de10e7dbba7b6c752e702193a395a52c727b6 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/default/policy-for-http-route/wasm/0 - match: pathSeparatedPrefix: /bar name: httproute/default/httproute-2/rule/0/match/0/www_example_com @@ -24,15 +52,87 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.wasm/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":{"key1":"value1","key2":"value2"},"parameter2":"value3"}' + name: wasm-filter-1 + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/5c90b9a82642ce00a7753923fabead306b9d9a54a7c0bd2463a1af3efcfb110b.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 746df05c8f3a0b07a46c0967cfbc5cbe5b9d48d0f79b6177eeedf8be6c8b34b5 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/0 + - name: envoy.filters.http.wasm/1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: '{"parameter1":"value1","parameter2":"value2"}' + name: wasm-filter-2 + rootId: my-root-id + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/7abf116e5cd5a20389604a5ba0f3bd04fdf76f92181fe67506b42c2ee596d3fd.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 314100af781b98a8ca175d5bf90a8bf76576e20a2f397a88223404edc6ebfd46 + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/1 + - name: envoy.filters.http.wasm/2 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: "" + name: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/42d30b4a4cc631415e6e48c02d244700da327201eb273f752cacf745715b31d9.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 2a19e4f337e5223d7287e7fccd933fb01905deaff804292e5257f8c681b82bee + environmentVariables: + hostEnvKeys: + - SOME_KEY + - ANOTHER_KEY + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway/wasm/2 - ignorePortInHostMatching: true name: envoy-gateway/gateway-1/http-listener-scope virtualHosts: @@ -55,12 +155,36 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.wasm/envoyextensionpolicy/default/policy-for-route-4/wasm/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} - envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.wasm/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: "" + name: wasm-filter-route-override + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/9d2e2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 9d2e2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/default/policy-for-route-4/wasm/0 - match: pathSeparatedPrefix: /same-name name: httproute/default/httproute-5/rule/0/match/0/listener_scope_example_com @@ -69,10 +193,61 @@ upgradeConfigs: - upgradeType: websocket typedPerFilterConfig: - envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0: + envoy.filters.http.filter_chain.eep.listener: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + disabled: true + envoy.filters.http.filter_chain.eep.route: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.wasm/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: "" + name: wasm-filter-listener + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0 typedPerFilterConfig: - envoy.filters.http.wasm/envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} + envoy.filters.http.filter_chain.eep.listener: + '@type': type.googleapis.com/envoy.extensions.filters.http.filter_chain.v3.FilterChainConfigPerRoute + filterChain: + filters: + - name: envoy.filters.http.wasm/listener/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + config: + configuration: + '@type': type.googleapis.com/google.protobuf.StringValue + value: "" + name: wasm-filter-listener + vmConfig: + code: + remote: + httpUri: + cluster: wasm_cluster + timeout: 10s + uri: https://envoy-gateway.envoy-gateway-system.svc.cluster.local:18002/8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f.wasm + retryPolicy: + numRetries: 10 + retryBackOff: + baseInterval: 1s + maxInterval: 30s + sha256: 8c1f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f + runtime: envoy.wasm.runtime.v8 + vmId: envoyextensionpolicy/envoy-gateway/policy-for-gateway-listener/wasm/0 diff --git a/internal/xds/translator/utils.go b/internal/xds/translator/utils.go index 7d47e2494f..1d5c192557 100644 --- a/internal/xds/translator/utils.go +++ b/internal/xds/translator/utils.go @@ -10,12 +10,14 @@ import ( "fmt" "net/netip" "net/url" + "sort" "strconv" "strings" "time" corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + filterchainv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/filter_chain/v3" hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" @@ -118,35 +120,140 @@ func enableFilterOnRoute(route *routev3.Route, filterName string, routeCfg proto return nil } -// enableFilterOnVirtualHost enables filterName for the provided virtual host. Unlike -// enableFilterOnRoute this is idempotent: patchVirtualHost may be invoked more than once for the -// same VirtualHost when several IR listeners share one RouteConfiguration (cleartext listeners on -// the same port). -func enableFilterOnVirtualHost(vh *routev3.VirtualHost, filterName string, routeCfg proto.Message) error { - if vh == nil { - return errors.New("xds virtual host is nil") - } +// perRouteFilterName generates a unique filter name for the provided filterType and configName. +func perRouteFilterName(filterType egv1a1.EnvoyFilter, configName string) string { + return fmt.Sprintf("%s/%s", filterType, configName) +} - if _, ok := vh.GetTypedPerFilterConfig()[filterName]; ok { - return nil +// buildHCMFilterChainFilter returns a disabled envoy.filters.http.filter_chain placeholder +// filter with the given stable name. Shared by extension types (Lua, ExtProc, Wasm, +// DynamicModule) whose EnvoyExtensionPolicy API allows an ordered list of instances per +// listener/route but whose native Envoy filter can only be overridden with a single instance +// per route. The placeholder's name never changes as instances are added/removed, so the HCM's +// filter list stays stable (no LDS update / connection drain); the actual ordered list of +// instances is delivered separately via FilterChainConfigPerRoute in TypedPerFilterConfig. +func buildHCMFilterChainFilter(filterName string) (*hcmv3.HttpFilter, error) { + var ( + fcProto *filterchainv3.FilterChainConfig + fcAny *anypb.Any + err error + ) + fcProto = &filterchainv3.FilterChainConfig{} + + if err = fcProto.ValidateAll(); err != nil { + return nil, err + } + if fcAny, err = anypb.New(fcProto); err != nil { + return nil, err } - routeCfgAny, err := anypb.New(routeCfg) - if err != nil { - return err + return &hcmv3.HttpFilter{ + Name: filterName, + Disabled: true, + ConfigType: &hcmv3.HttpFilter_TypedConfig{ + TypedConfig: fcAny, + }, + }, nil +} + +// filterChainFilterNamePrefixForEEP is the stable HCM-level filter name shared by every +// EnvoyExtensionPolicy extension type (Lua, ExtProc, Wasm, DynamicModule) that is delivered via +// an envoy.filters.http.filter_chain placeholder. All extension types share the same two +// placeholders (this name, and this name + ".listener") rather than each getting their own, so +// adding/removing an instance of any extension type never changes the HCM's filter list. +const filterChainFilterNamePrefixForEEP = "envoy.filters.http.filter_chain.eep" + +// eepFCFilterName returns the stable HCM-level filter name for the shared, per-route +// EnvoyExtensionPolicy filter_chain placeholder. Every extension type (Lua, ExtProc, Wasm, +// DynamicModule) delivers its route-scoped instances through this single placeholder rather than +// each type getting its own, so adding/removing an instance of any type never changes the HCM's +// filter list. +func eepFCFilterName() string { + return filterChainFilterNamePrefixForEEP + ".route" +} + +// eepListenerFCFilterName returns the stable HCM-level filter name for the shared, per-listener +// (per-connection) EnvoyExtensionPolicy filter_chain placeholder. See eepFCFilterName. +func eepListenerFCFilterName() string { + return filterChainFilterNamePrefixForEEP + ".listener" +} + +// eepSubFilterPriority orders sub-filters within a shared filter_chain placeholder's inner +// FilterChain across extension types: Lua runs before ExtProc, which runs before Wasm, which +// runs before DynamicModule. Instances of the same type keep the relative order they were +// appended in (stable sort), which is already the ordered EnvoyExtensionPolicy list order. +func eepSubFilterPriority(name string) int { + switch { + case strings.HasPrefix(name, string(egv1a1.EnvoyFilterLua)): + return 0 + case strings.HasPrefix(name, string(egv1a1.EnvoyFilterExtProc)): + return 1 + case strings.HasPrefix(name, string(egv1a1.EnvoyFilterWasm)): + return 2 + case strings.HasPrefix(name, string(egv1a1.EnvoyFilterDynamicModules)): + return 3 + default: + return 99 } +} - if vh.TypedPerFilterConfig == nil { - vh.TypedPerFilterConfig = make(map[string]*anypb.Any) +// mergeFilterChainConfigPerRoute merges newFilters into the FilterChainConfigPerRoute already +// stored at existing (nil if none yet), re-sorting the combined inner FilterChain so that +// multiple extension types sharing the same filter_chain placeholder still run in a stable, +// predictable cross-type order instead of whatever order patchRoute/patchVirtualHost happened to +// be called in for this route/virtual host. +func mergeFilterChainConfigPerRoute(existing *anypb.Any, newFilters []*corev3.TypedExtensionConfig) (*anypb.Any, error) { + fc := &filterchainv3.FilterChainConfigPerRoute{FilterChain: &filterchainv3.FilterChain{}} + if existing != nil { + if err := existing.UnmarshalTo(fc); err != nil { + return nil, err + } + if fc.FilterChain == nil { + fc.FilterChain = &filterchainv3.FilterChain{} + } } - vh.TypedPerFilterConfig[filterName] = routeCfgAny - return nil + fc.FilterChain.Filters = append(fc.FilterChain.Filters, newFilters...) + sort.SliceStable(fc.FilterChain.Filters, func(i, j int) bool { + return eepSubFilterPriority(fc.FilterChain.Filters[i].Name) < eepSubFilterPriority(fc.FilterChain.Filters[j].Name) + }) + + return anypb.New(fc) } -// perRouteFilterName generates a unique filter name for the provided filterType and configName. -func perRouteFilterName(filterType egv1a1.EnvoyFilter, configName string) string { - return fmt.Sprintf("%s/%s", filterType, configName) +// disableFilterOnRouteOnce disables filterName on the route unless some TypedPerFilterConfig is +// already set under that name. Several extension types can all want to disable the same shared +// filter_chain placeholder for a route that fully overrides listener-scoped extensions, so unlike +// enableFilterOnRoute this must tolerate being called more than once for the same route/filter. +func disableFilterOnRouteOnce(route *routev3.Route, filterName string) error { + if _, ok := route.GetTypedPerFilterConfig()[filterName]; ok { + return nil + } + return enableFilterOnRoute(route, filterName, &routev3.FilterConfig{Disabled: true}) +} + +// filterChainAlreadyHasType reports whether the FilterChainConfigPerRoute stored at existing (if +// any) already contains a sub-filter of the given type. Used by patchVirtualHost to stay +// idempotent per extension type: unlike the old per-type placeholder, the shared filter_chain key +// may already carry a different type's contribution, so "the key is set" no longer implies "this +// type already delivered its filters here". +func filterChainAlreadyHasType(existing *anypb.Any, filterType egv1a1.EnvoyFilter) (bool, error) { + if existing == nil { + return false, nil + } + fc := &filterchainv3.FilterChainConfigPerRoute{} + if err := existing.UnmarshalTo(fc); err != nil { + return false, err + } + if fc.FilterChain == nil { + return false, nil + } + for _, f := range fc.FilterChain.Filters { + if strings.HasPrefix(f.Name, string(filterType)) { + return true, nil + } + } + return false, nil } func hcmContainsFilter(mgr *hcmv3.HttpConnectionManager, filterName string) bool { diff --git a/internal/xds/translator/wasm.go b/internal/xds/translator/wasm.go index ebc6cc4100..51997a747d 100644 --- a/internal/xds/translator/wasm.go +++ b/internal/xds/translator/wasm.go @@ -7,6 +7,9 @@ package translator import ( "errors" + "fmt" + "slices" + "strconv" "time" corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" @@ -44,13 +47,21 @@ type wasm struct{} var _ httpFilter = &wasm{} -// patchHCM builds and appends the wasm Filters to the HTTP Connection Manager -// if applicable, and it does not already exist. -// Note: this method creates a wasm filter for each route that contains an wasm config. -// The filter is disabled by default. It is enabled on the route level. +// patchHCM adds disabled envoy.filters.http.filter_chain placeholder filters to the HTTP +// Connection Manager: one for per-listener (per-connection) Wasm and one for per-route Wasm. +// +// Both placeholders are added together as soon as either scope has a Wasm policy anywhere on +// this listener, even if the other scope currently has none. This keeps the HCM's filter set +// stable across that kind of policy churn too: e.g. adding a per-listener Wasm policy later to +// a listener that already has per-route Wasm only changes route/virtual host +// TypedPerFilterConfig (an RDS update), never the listener's filter list (which would require +// an LDS update and a connection drain). +// +// Wasm has no native per-route override at all, while EG's EnvoyExtensionPolicy API allows an +// ordered list of Wasm filters per listener/route. The filter_chain filter wraps an ordered, +// named sub-chain of Wasm filters that is supplied separately (per virtual host for +// listener-scoped Wasm, per route for route-scoped Wasm). func (*wasm) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { - var errs error - if mgr == nil { return errors.New("hcm is nil") } @@ -58,64 +69,38 @@ func (*wasm) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListe return errors.New("ir listener is nil") } - addFilters := func(wasms []ir.Wasm) { - for i := range wasms { - ep := &wasms[i] - if hcmContainsFilter(mgr, wasmFilterName(ep)) { - continue - } - filter, err := buildHCMWasmFilter(ep) - if err != nil { - errs = errors.Join(errs, err) - continue - } - mgr.HttpFilters = append(mgr.HttpFilters, filter) - } + hasListenerWasm := listenerContainsWasm(irListener) + hasRouteWasm := slices.ContainsFunc(irListener.Routes, routeContainsWasm) + if !hasListenerWasm && !hasRouteWasm { + return nil } - // Listener-scoped Wasms are enabled at VirtualHost scope; route-scoped Wasms are enabled - // per route. Both need their (disabled by default) filter present on the HCM. - if listenerContainsWasm(irListener) { - addFilters(irListener.EnvoyExtensions.Wasms) - } - for _, route := range irListener.Routes { - if !routeContainsWasm(route) { + for _, filterName := range []string{eepListenerFCFilterName(), eepFCFilterName()} { + if hcmContainsFilter(mgr, filterName) { continue } - addFilters(route.EnvoyExtensions.Wasms) + filter, err := buildHCMFilterChainFilter(filterName) + if err != nil { + return err + } + mgr.HttpFilters = append(mgr.HttpFilters, filter) } - return errs + return nil } -// buildHCMWasmFilter returns a wasm HTTP filter from the provided IR HTTPRoute. -func buildHCMWasmFilter(wasm *ir.Wasm) (*hcmv3.HttpFilter, error) { - var ( - wasmProto *wasmfilterv3.Wasm - wasmAny *anypb.Any - err error - ) - - if wasmProto, err = wasmConfig(wasm); err != nil { - return nil, err - } - if wasmAny, err = anypb.New(wasmProto); err != nil { - return nil, err - } - - // All wasm filters for all Routes are aggregated on HCM and disabled by default - // Per-route config is used to enable the relevant filters on appropriate routes - return &hcmv3.HttpFilter{ - Name: wasmFilterName(wasm), - Disabled: true, - ConfigType: &hcmv3.HttpFilter_TypedConfig{ - TypedConfig: wasmAny, - }, - }, nil +// wasmSubFilterName returns the stable top-level filter name for the per-route Wasm slot index. +// The index is the execution slot within the ordered EnvoyExtensionPolicy Wasm list, so route +// 0th modules always bind to the same listener-level filter. +func wasmSubFilterName(idx int) string { + return perRouteFilterName(egv1a1.EnvoyFilterWasm, strconv.Itoa(idx)) } -func wasmFilterName(wasm *ir.Wasm) string { - return perRouteFilterName(egv1a1.EnvoyFilterWasm, wasm.Name) +// wasmListenerSubFilterName returns the stable HCM-level filter name for a listener-level Wasm +// slot. Using the envoy.filters.http.wasm prefix (instead of the raw policy name) ensures +// sortHTTPFilters assigns it the correct order relative to route-level slots. +func wasmListenerSubFilterName(idx int) string { + return fmt.Sprintf("%s/listener/%d", egv1a1.EnvoyFilterWasm, idx) } func wasmConfig(wasm *ir.Wasm) (*wasmfilterv3.Wasm, error) { @@ -215,7 +200,7 @@ func (*wasm) patchResources(_ *types.ResourceVersionTable, _ *ir.HTTPListener, _ // and fully replaces — never merges with — the listener-scoped policy. The extension count is // intentionally not checked: an empty result (e.g. fail-open invalid Wasm) still represents a // more specific policy that owns this route and must suppress the lower-scope Wasms. -func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener *ir.HTTPListener) error { +func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPListener) error { if route == nil { return errors.New("xds route is nil") } @@ -226,34 +211,42 @@ func (*wasm) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, irListener return nil } - own := make(map[string]struct{}, len(irRoute.EnvoyExtensions.Wasms)) - for i := range irRoute.EnvoyExtensions.Wasms { - own[wasmFilterName(&irRoute.EnvoyExtensions.Wasms[i])] = struct{}{} + // A non-nil EnvoyExtensions means a more specific route policy owns this route and fully + // replaces the listener-scoped policy. The extension count is intentionally not checked + // here: an empty result (e.g. fail-open invalid Wasm) still represents a more specific + // policy that owns this route and must suppress the lower-scope Wasm. + if err := disableFilterOnRouteOnce(route, eepListenerFCFilterName()); err != nil { + return err } - if listenerContainsWasm(irListener) { - for i := range irListener.EnvoyExtensions.Wasms { - filterName := wasmFilterName(&irListener.EnvoyExtensions.Wasms[i]) - // A single EnvoyExtensionPolicy may target both this listener and this route via - // separate targetRefs, in which case the same filter name appears at both scopes and - // the route re-enables it below instead of disabling it. - if _, ok := own[filterName]; ok { - continue - } - if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{Disabled: true}); err != nil { - return err - } + var newFilters []*corev3.TypedExtensionConfig + for idx := range irRoute.EnvoyExtensions.Wasms { + cfg, err := wasmConfig(&irRoute.EnvoyExtensions.Wasms[idx]) + if err != nil { + return err } - } - - for _, ep := range irRoute.EnvoyExtensions.Wasms { - filterName := wasmFilterName(&ep) - if err := enableFilterOnRoute(route, filterName, &routev3.FilterConfig{ - Config: &anypb.Any{}, - }); err != nil { + cfgAny, err := anypb.New(cfg) + if err != nil { return err } + newFilters = append(newFilters, &corev3.TypedExtensionConfig{ + Name: wasmSubFilterName(idx), + TypedConfig: cfgAny, + }) + } + + if len(newFilters) == 0 { + return nil + } + + merged, err := mergeFilterChainConfigPerRoute(route.GetTypedPerFilterConfig()[eepFCFilterName()], newFilters) + if err != nil { + return err + } + if route.TypedPerFilterConfig == nil { + route.TypedPerFilterConfig = make(map[string]*anypb.Any) } + route.TypedPerFilterConfig[eepFCFilterName()] = merged return nil } @@ -266,13 +259,39 @@ func (*wasm) patchVirtualHost(vh *routev3.VirtualHost, httpListener *ir.HTTPList return nil } - for i := range httpListener.EnvoyExtensions.Wasms { - ep := &httpListener.EnvoyExtensions.Wasms[i] - if err := enableFilterOnVirtualHost(vh, wasmFilterName(ep), &routev3.FilterConfig{ - Config: &anypb.Any{}, - }); err != nil { + filterName := eepListenerFCFilterName() + existing := vh.GetTypedPerFilterConfig()[filterName] + alreadyDelivered, err := filterChainAlreadyHasType(existing, egv1a1.EnvoyFilterWasm) + if err != nil { + return err + } + if alreadyDelivered { + return nil + } + + var newFilters []*corev3.TypedExtensionConfig + for idx := range httpListener.EnvoyExtensions.Wasms { + cfg, err := wasmConfig(&httpListener.EnvoyExtensions.Wasms[idx]) + if err != nil { return err } + cfgAny, err := anypb.New(cfg) + if err != nil { + return err + } + newFilters = append(newFilters, &corev3.TypedExtensionConfig{ + Name: wasmListenerSubFilterName(idx), + TypedConfig: cfgAny, + }) + } + + merged, err := mergeFilterChainConfigPerRoute(existing, newFilters) + if err != nil { + return err + } + if vh.TypedPerFilterConfig == nil { + vh.TypedPerFilterConfig = make(map[string]*anypb.Any) } + vh.TypedPerFilterConfig[filterName] = merged return nil } From e353b7aef5a3ec407a8769d4c99e8d909663fb3b Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 3 Aug 2026 16:36:34 +0800 Subject: [PATCH 16/18] fix Signed-off-by: zirain --- internal/xds/translator/csrf.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/xds/translator/csrf.go b/internal/xds/translator/csrf.go index 6e21ea4073..be610c788e 100644 --- a/internal/xds/translator/csrf.go +++ b/internal/xds/translator/csrf.go @@ -138,7 +138,11 @@ func (*csrf) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute, _ *ir.HTTPL return nil } -func (*csrf) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error { +func (*csrf) patchResources(*types.ResourceVersionTable, *ir.HTTPListener, []*ir.HTTPRoute) error { + return nil +} + +func (*csrf) patchVirtualHost(_ *routev3.VirtualHost, _ *ir.HTTPListener) error { return nil } From dda91b01adcb9687df74b3af55ca3f60c2671cba Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 3 Aug 2026 18:24:13 +0800 Subject: [PATCH 17/18] fix gen Signed-off-by: zirain --- .../testdata/out/xds-ir/dynamicmodule.listeners.yaml | 1 + .../translator/testdata/out/xds-ir/ext-proc.listeners.yaml | 1 + .../xds/translator/testdata/out/xds-ir/lua.listeners.yaml | 6 ++++++ .../xds/translator/testdata/out/xds-ir/wasm.listeners.yaml | 1 + 4 files changed, 9 insertions(+) diff --git a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml index bc1dd72698..e960ad6855 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dynamicmodule.listeners.yaml @@ -76,6 +76,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-listener-scope serverHeaderTransformation: PASS_THROUGH diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml index bc1dd72698..e960ad6855 100644 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml @@ -76,6 +76,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-listener-scope serverHeaderTransformation: PASS_THROUGH diff --git a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml index ea2f351a9f..fd4b91045b 100644 --- a/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/lua.listeners.yaml @@ -76,6 +76,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-2 serverHeaderTransformation: PASS_THROUGH @@ -119,6 +120,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-3 serverHeaderTransformation: PASS_THROUGH @@ -162,6 +164,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-4 serverHeaderTransformation: PASS_THROUGH @@ -205,6 +208,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-5 serverHeaderTransformation: PASS_THROUGH @@ -248,6 +252,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-7 serverHeaderTransformation: PASS_THROUGH @@ -291,6 +296,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-8 serverHeaderTransformation: PASS_THROUGH diff --git a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml index bc1dd72698..e960ad6855 100644 --- a/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/wasm.listeners.yaml @@ -76,6 +76,7 @@ rds: configSource: ads: {} + initialFetchTimeout: 0s resourceApiVersion: V3 routeConfigName: envoy-gateway/gateway-1/http-listener-scope serverHeaderTransformation: PASS_THROUGH From 098ac560d1072b9045cee49ea62b36c70817215c Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 4 Aug 2026 20:45:22 +0800 Subject: [PATCH 18/18] chore: fix wasm stats test Signed-off-by: zirain --- test/e2e/tests/wasm_http.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/e2e/tests/wasm_http.go b/test/e2e/tests/wasm_http.go index 095588d874..03d769ff17 100644 --- a/test/e2e/tests/wasm_http.go +++ b/test/e2e/tests/wasm_http.go @@ -80,10 +80,11 @@ var HTTPWasmTest = suite.ConformanceTest{ // filters"), so each of the 2 wasm-configured routes above gets its own dedicated Wasm // filter/VM even though both reference the same underlying .wasm module. The // process-wide "wasm.wasm_vm_count" gauge should therefore read exactly 3* worker thread. + tlog.Logf(t, "concurrency: %d", runtime.NumCPU()) t.Run("wasm vm count is per-route", func(t *testing.T) { promQL := `sum(envoy_wasm_wasm_vm_count{app_kubernetes_io_component="proxy", app_kubernetes_io_managed_by="envoy-gateway", app_kubernetes_io_name="envoy", gateway_envoyproxy_io_owning_gateway_name="same-namespace"})` - // 3 is the count of routes - expectedCount := model.SampleValue(3 * runtime.NumCPU()) + // 2 is the count of routes with WASM + expectedCount := model.SampleValue(2 * (runtime.NumCPU() + 2)) tlog.Logf(t, "expected to got %v", expectedCount) if err := wait.PollUntilContextTimeout(context.TODO(), time.Second, time.Minute, true, func(_ context.Context) (done bool, err error) {