From 620b1b38d150b860ac862009b3e7ba82f97e95c4 Mon Sep 17 00:00:00 2001 From: Guy Daich Date: Fri, 20 Jun 2025 10:40:31 -0500 Subject: [PATCH 01/16] fix(translator): ext-proc full duplex streamed trailers and validation (#6323) * fix ext proc validation and trailer management for full duplex streamed mode Signed-off-by: Guy Daich Signed-off-by: shawnh2 --- api/v1alpha1/ext_proc_types.go | 4 +- ....envoyproxy.io_envoyextensionpolicies.yaml | 6 + ....envoyproxy.io_envoyextensionpolicies.yaml | 6 + internal/xds/translator/extproc.go | 64 +++--- .../testdata/in/xds-ir/ext-proc.yaml | 22 ++ .../out/xds-ir/ext-proc.clusters.yaml | 41 ++++ .../out/xds-ir/ext-proc.endpoints.yaml | 17 ++ .../out/xds-ir/ext-proc.listeners.yaml | 16 ++ .../testdata/out/xds-ir/ext-proc.routes.yaml | 14 ++ release-notes/current.yaml | 3 + site/content/en/latest/api/extension_types.md | 2 +- .../envoyextensionpolicy_test.go | 203 ++++++++++++++++++ test/helm/gateway-crds-helm/all.out.yaml | 6 + .../envoy-gateway-crds.out.yaml | 6 + 14 files changed, 383 insertions(+), 27 deletions(-) diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go index 95893d3c61..9e821f68ce 100644 --- a/api/v1alpha1/ext_proc_types.go +++ b/api/v1alpha1/ext_proc_types.go @@ -17,7 +17,8 @@ const ( StreamedExtProcBodyProcessingMode ExtProcBodyProcessingMode = "Streamed" // BufferedExtProcBodyProcessingMode will buffer the message body in memory and send the entire body at once. If the body exceeds the configured buffer limit, then the downstream system will receive an error. BufferedExtProcBodyProcessingMode ExtProcBodyProcessingMode = "Buffered" - // FullDuplexStreamedExtBodyProcessingMode will send the body in pieces, to be read in a stream. Full details here: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto.html#enum-extensions-filters-http-ext-proc-v3-processingmode-bodysendmode + // FullDuplexStreamedExtBodyProcessingMode will send the body in pieces, to be read in a stream. When enabled, trailers are also sent, and failOpen must be false. + // Full details here: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto.html#enum-extensions-filters-http-ext-proc-v3-processingmode-bodysendmode FullDuplexStreamedExtBodyProcessingMode ExtProcBodyProcessingMode = "FullDuplexStreamed" // BufferedPartialExtBodyHeaderProcessingMode will buffer the message body in memory and send the entire body in one chunk. If the body exceeds the configured buffer limit, then the body contents up to the buffer limit will be sent. BufferedPartialExtBodyHeaderProcessingMode ExtProcBodyProcessingMode = "BufferedPartial" @@ -67,6 +68,7 @@ type ExtProcProcessingMode struct { // +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)" // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true" // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true" +// +kubebuilder:validation:XValidation:message="If FullDuplexStreamed body processing mode is used, FailOpen must be false.",rule="!(has(self.failOpen) && self.failOpen == true && ((has(self.processingMode.request.body) && self.processingMode.request.body == 'FullDuplexStreamed') || (has(self.processingMode.response.body) && self.processingMode.response.body == 'FullDuplexStreamed')))" type ExtProc struct { BackendCluster `json:",inline"` diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index 7e8fa5d33c..02e5a482db 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -1042,6 +1042,12 @@ spec: group. rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group == "" || f.group == ''gateway.envoyproxy.io'')) : true' + - message: If FullDuplexStreamed body processing mode is used, FailOpen + must be false. + rule: '!(has(self.failOpen) && self.failOpen == true && ((has(self.processingMode.request.body) + && self.processingMode.request.body == ''FullDuplexStreamed'') + || (has(self.processingMode.response.body) && self.processingMode.response.body + == ''FullDuplexStreamed'')))' maxItems: 16 type: array lua: diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index d49a6046d2..723c677bf1 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -1041,6 +1041,12 @@ spec: group. rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group == "" || f.group == ''gateway.envoyproxy.io'')) : true' + - message: If FullDuplexStreamed body processing mode is used, FailOpen + must be false. + rule: '!(has(self.failOpen) && self.failOpen == true && ((has(self.processingMode.request.body) + && self.processingMode.request.body == ''FullDuplexStreamed'') + || (has(self.processingMode.response.body) && self.processingMode.response.body + == ''FullDuplexStreamed'')))' maxItems: 16 type: array lua: diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go index b9452b6731..5ec36fc9bd 100644 --- a/internal/xds/translator/extproc.go +++ b/internal/xds/translator/extproc.go @@ -99,16 +99,10 @@ func extProcConfig(extProc ir.ExtProc) *extprocv3.ExternalProcessor { Seconds: defaultExtServiceRequestTimeout, }, }, - ProcessingMode: &extprocv3.ProcessingMode{ - RequestHeaderMode: extprocv3.ProcessingMode_SKIP, - ResponseHeaderMode: extprocv3.ProcessingMode_SKIP, - RequestBodyMode: extprocv3.ProcessingMode_NONE, - ResponseBodyMode: extprocv3.ProcessingMode_NONE, - RequestTrailerMode: extprocv3.ProcessingMode_SKIP, - ResponseTrailerMode: extprocv3.ProcessingMode_SKIP, - }, } + config.ProcessingMode = buildProcessingMode(extProc) + if extProc.FailOpen != nil { config.FailureModeAllow = *extProc.FailOpen } @@ -117,22 +111,6 @@ func extProcConfig(extProc ir.ExtProc) *extprocv3.ExternalProcessor { config.MessageTimeout = durationpb.New(extProc.MessageTimeout.Duration) } - if extProc.RequestBodyProcessingMode != nil { - config.ProcessingMode.RequestBodyMode = buildExtProcBodyProcessingMode(extProc.RequestBodyProcessingMode) - } - - if extProc.RequestHeaderProcessing { - config.ProcessingMode.RequestHeaderMode = extprocv3.ProcessingMode_SEND - } - - if extProc.ResponseBodyProcessingMode != nil { - config.ProcessingMode.ResponseBodyMode = buildExtProcBodyProcessingMode(extProc.ResponseBodyProcessingMode) - } - - if extProc.ResponseHeaderProcessing { - config.ProcessingMode.ResponseHeaderMode = extprocv3.ProcessingMode_SEND - } - if extProc.RequestAttributes != nil { var attrs []string attrs = append(attrs, extProc.RequestAttributes...) @@ -232,7 +210,43 @@ func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { return nil } -func buildExtProcBodyProcessingMode(mode *ir.ExtProcBodyProcessingMode) extprocv3.ProcessingMode_BodySendMode { +func buildProcessingMode(extProc ir.ExtProc) *extprocv3.ProcessingMode { + processingMode := &extprocv3.ProcessingMode{ + RequestHeaderMode: extprocv3.ProcessingMode_SKIP, + ResponseHeaderMode: extprocv3.ProcessingMode_SKIP, + RequestBodyMode: extprocv3.ProcessingMode_NONE, + ResponseBodyMode: extprocv3.ProcessingMode_NONE, + RequestTrailerMode: extprocv3.ProcessingMode_SKIP, + ResponseTrailerMode: extprocv3.ProcessingMode_SKIP, + } + + if extProc.RequestBodyProcessingMode != nil { + processingMode.RequestBodyMode = translateExtProcBodyProcessingMode(extProc.RequestBodyProcessingMode) + // + if processingMode.RequestBodyMode == extprocv3.ProcessingMode_FULL_DUPLEX_STREAMED { + processingMode.RequestTrailerMode = extprocv3.ProcessingMode_SEND + } + } + + if extProc.RequestHeaderProcessing { + processingMode.RequestHeaderMode = extprocv3.ProcessingMode_SEND + } + + if extProc.ResponseBodyProcessingMode != nil { + processingMode.ResponseBodyMode = translateExtProcBodyProcessingMode(extProc.ResponseBodyProcessingMode) + if processingMode.ResponseBodyMode == extprocv3.ProcessingMode_FULL_DUPLEX_STREAMED { + processingMode.ResponseTrailerMode = extprocv3.ProcessingMode_SEND + } + } + + if extProc.ResponseHeaderProcessing { + processingMode.ResponseHeaderMode = extprocv3.ProcessingMode_SEND + } + + return processingMode +} + +func translateExtProcBodyProcessingMode(mode *ir.ExtProcBodyProcessingMode) extprocv3.ProcessingMode_BodySendMode { lookup := map[ir.ExtProcBodyProcessingMode]extprocv3.ProcessingMode_BodySendMode{ ir.ExtProcBodyBuffered: extprocv3.ProcessingMode_BUFFERED, ir.ExtProcBodyBufferedPartial: extprocv3.ProcessingMode_BUFFERED_PARTIAL, 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 6f39befb84..bc4b11ed09 100644 --- a/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/ext-proc.yaml @@ -102,6 +102,28 @@ http: - protocol: GRPC weight: 1 name: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend/backend/0 + - 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 + envoyExtensions: + extProcs: + - name: envoyextensionpolicy/envoy-gateway/policy-for-route-3/extproc/0 + authority: grpc-backend-3.envoy-gateway:3000 + requestBodyProcessingMode: FullDuplexStreamed + responseBodyProcessingMode: FullDuplexStreamed + destination: + name: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3 + settings: + - protocol: GRPC + weight: 1 + name: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3/backend/0 hostname: gateway.envoyproxy.io isHTTP2: false name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io 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 14ff9d61df..6e72ef5092 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.clusters.yaml @@ -32,6 +32,23 @@ name: httproute/default/httproute-2/rule/0 perConnectionBufferLimitBytes: 32768 type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-3/rule/0 + ignoreHealthOnHostRemoval: true + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-3/rule/0 + perConnectionBufferLimitBytes: 32768 + type: EDS - circuitBreakers: thresholds: - maxRetries: 1024 @@ -128,3 +145,27 @@ http2ProtocolOptions: initialConnectionWindowSize: 1048576 initialStreamWindowSize: 65536 +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3 + ignoreHealthOnHostRemoval: true + lbPolicy: LEAST_REQUEST + name: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3 + 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 4ec680ce7f..b6f8426798 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.endpoints.yaml @@ -22,6 +22,18 @@ 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: envoyextensionpolicy/default/policy-for-route-2/0/grpc-backend-4 endpoints: - loadBalancingWeight: 1 @@ -42,3 +54,8 @@ - loadBalancingWeight: 1 locality: region: envoyextensionpolicy/envoy-gateway/policy-for-gateway-1/0/grpc-backend/backend/0 +- clusterName: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3 + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/envoy-gateway/policy-for-route-3/0/grpc-backend-3/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 16f3139344..7b5e8bbb77 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.listeners.yaml @@ -103,6 +103,22 @@ - connection.requested_server_name responseAttributes: - request.path + - 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 - 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 c17e6456d1..8cef38ab6a 100755 --- a/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc.routes.yaml @@ -22,6 +22,20 @@ - match: pathSeparatedPrefix: /bar name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io + route: + cluster: httproute/default/httproute-3/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/envoy-gateway/policy-for-route-3/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - domains: + - "" + name: envoy-gateway/gateway-1/http/ + routes: + - match: + prefix: / route: cluster: httproute/default/httproute-2/rule/0 upgradeConfigs: diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 32b53627d1..b804fc66c0 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -20,6 +20,9 @@ bug fixes: | Fixed issue where WASM cache init failure caused routes with WASM-less EnvoyExtensionPolicies to have 500 direct responses. Fixed issue which UDP listeners were not created in the Envoy proxy config when Gateway was created. Keep ALPN configuration for listeners with overlapping certificates when ALPN is explicitly set in ClientTrafficPolicy. + Fixed issue where EnvoyExtensionPolicy ExtProc body processing mode is set to FullDuplexStreamed, but trailers were not sent. + Fixed validation issue where EnvoyExtensionPolicy ExtProc failOpen is true, and body processing mode FullDuplexStreamed is not rejected. + # Enhancements that improve performance. performance improvements: | diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 8e7da32400..1615f4cc1c 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1680,7 +1680,7 @@ _Appears in:_ | ----- | ----------- | | `Streamed` | StreamedExtProcBodyProcessingMode will stream the body to the server in pieces as they arrive at the proxy.
| | `Buffered` | BufferedExtProcBodyProcessingMode will buffer the message body in memory and send the entire body at once. If the body exceeds the configured buffer limit, then the downstream system will receive an error.
| -| `FullDuplexStreamed` | FullDuplexStreamedExtBodyProcessingMode will send the body in pieces, to be read in a stream. Full details here: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto.html#enum-extensions-filters-http-ext-proc-v3-processingmode-bodysendmode
| +| `FullDuplexStreamed` | FullDuplexStreamedExtBodyProcessingMode will send the body in pieces, to be read in a stream. When enabled, trailers are also sent, and failOpen must be false.
Full details here: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto.html#enum-extensions-filters-http-ext-proc-v3-processingmode-bodysendmode
| | `BufferedPartial` | BufferedPartialExtBodyHeaderProcessingMode will buffer the message body in memory and send the entire body in one chunk. If the body exceeds the configured buffer limit, then the body contents up to the buffer limit will be sent.
| diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go index c8f3fe776a..195d45dd05 100644 --- a/test/cel-validation/envoyextensionpolicy_test.go +++ b/test/cel-validation/envoyextensionpolicy_test.go @@ -414,6 +414,209 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { "spec.extProc[0].processingMode.request.body: Unsupported value: \"not-a-body-mode\": supported values: \"Streamed\", \"Buffered\", \"BufferedPartial\"", }, }, + { + desc: "valid ExtProc without FullDuplexStreamed body and failOpen true", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + }, + ProcessingMode: &egv1a1.ExtProcProcessingMode{ + Request: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("Buffered")), + }, + Response: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("Buffered")), + }, + }, + FailOpen: ptr.To(true), + }, + }, + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "valid ExtProc with FullDuplexStreamed body and failOpen false", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + }, + ProcessingMode: &egv1a1.ExtProcProcessingMode{ + Request: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("FullDuplexStreamed")), + }, + Response: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("FullDuplexStreamed")), + }, + }, + FailOpen: ptr.To(false), + }, + }, + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "valid ExtProc with FullDuplexStreamed body and failOpen nil", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + }, + ProcessingMode: &egv1a1.ExtProcProcessingMode{ + Request: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("FullDuplexStreamed")), + }, + Response: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("FullDuplexStreamed")), + }, + }, + }, + }, + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "invalid ExtProc with FullDuplexStreamed request body and failOpen", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + }, + ProcessingMode: &egv1a1.ExtProcProcessingMode{ + Request: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("FullDuplexStreamed")), + }, + Response: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("Buffered")), + }, + }, + FailOpen: ptr.To(true), + }, + }, + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + } + }, + wantErrors: []string{ + "spec.extProc[0]: Invalid value: \"object\": If FullDuplexStreamed body processing mode is used, FailOpen must be false.", + }, + }, + { + desc: "invalid ExtProc with FullDuplexStreamed response body and failOpen", + mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { + sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ + ExtProc: []egv1a1.ExtProc{ + { + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, + }, + }, + }, + ProcessingMode: &egv1a1.ExtProcProcessingMode{ + Request: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("Buffered")), + }, + Response: &egv1a1.ProcessingModeOptions{ + Body: ptr.To(egv1a1.ExtProcBodyProcessingMode("FullDuplexStreamed")), + }, + }, + FailOpen: ptr.To(true), + }, + }, + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + } + }, + wantErrors: []string{ + "spec.extProc[0]: Invalid value: \"object\": If FullDuplexStreamed body processing mode is used, FailOpen must be false.", + }, + }, { desc: "Valid Lua filter (inline)", mutate: func(sp *egv1a1.EnvoyExtensionPolicy) { diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index a18c940126..2fb2cadc78 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -22045,6 +22045,12 @@ spec: group. rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group == "" || f.group == ''gateway.envoyproxy.io'')) : true' + - message: If FullDuplexStreamed body processing mode is used, FailOpen + must be false. + rule: '!(has(self.failOpen) && self.failOpen == true && ((has(self.processingMode.request.body) + && self.processingMode.request.body == ''FullDuplexStreamed'') + || (has(self.processingMode.response.body) && self.processingMode.response.body + == ''FullDuplexStreamed'')))' maxItems: 16 type: array lua: diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index 65b9f354fb..de14372e95 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -4733,6 +4733,12 @@ spec: group. rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group == "" || f.group == ''gateway.envoyproxy.io'')) : true' + - message: If FullDuplexStreamed body processing mode is used, FailOpen + must be false. + rule: '!(has(self.failOpen) && self.failOpen == true && ((has(self.processingMode.request.body) + && self.processingMode.request.body == ''FullDuplexStreamed'') + || (has(self.processingMode.response.body) && self.processingMode.response.body + == ''FullDuplexStreamed'')))' maxItems: 16 type: array lua: From 299e7b56340001a447210d069259759cbe0cfb3c Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 23 Jun 2025 16:30:24 -0400 Subject: [PATCH 02/16] feat: disable automountServiceAccountToken for proxy and ratelimit (#6364) Signed-off-by: Jeff Davis --- .../infrastructure/kubernetes/proxy/resource_provider.go | 3 +++ .../proxy/testdata/daemonsets/component-level.yaml | 1 + .../kubernetes/proxy/testdata/daemonsets/custom.yaml | 1 + .../kubernetes/proxy/testdata/daemonsets/default-env.yaml | 1 + .../kubernetes/proxy/testdata/daemonsets/default.yaml | 1 + .../proxy/testdata/daemonsets/disable-prometheus.yaml | 1 + .../kubernetes/proxy/testdata/daemonsets/extension-env.yaml | 1 + .../proxy/testdata/daemonsets/gateway-namespace-mode.yaml | 1 + .../testdata/daemonsets/override-labels-and-annotations.yaml | 1 + .../proxy/testdata/daemonsets/patch-daemonset.yaml | 1 + .../proxy/testdata/daemonsets/shutdown-manager.yaml | 1 + .../kubernetes/proxy/testdata/daemonsets/volumes.yaml | 1 + .../proxy/testdata/daemonsets/with-annotations.yaml | 1 + .../proxy/testdata/daemonsets/with-concurrency.yaml | 1 + .../proxy/testdata/daemonsets/with-extra-args.yaml | 1 + .../proxy/testdata/daemonsets/with-image-pull-secrets.yaml | 1 + .../kubernetes/proxy/testdata/daemonsets/with-name.yaml | 1 + .../proxy/testdata/daemonsets/with-node-selector.yaml | 1 + .../daemonsets/with-topology-spread-constraints.yaml | 1 + .../kubernetes/proxy/testdata/deployments/bootstrap.yaml | 1 + .../proxy/testdata/deployments/component-level.yaml | 1 + .../kubernetes/proxy/testdata/deployments/custom.yaml | 1 + .../testdata/deployments/custom_with_initcontainers.yaml | 1 + .../kubernetes/proxy/testdata/deployments/default-env.yaml | 1 + .../kubernetes/proxy/testdata/deployments/default.yaml | 1 + .../proxy/testdata/deployments/disable-prometheus.yaml | 1 + .../kubernetes/proxy/testdata/deployments/dual-stack.yaml | 1 + .../kubernetes/proxy/testdata/deployments/extension-env.yaml | 1 + .../proxy/testdata/deployments/gateway-namespace-mode.yaml | 1 + .../kubernetes/proxy/testdata/deployments/ipv6.yaml | 1 + .../deployments/override-labels-and-annotations.yaml | 1 + .../proxy/testdata/deployments/patch-deployment.yaml | 1 + .../proxy/testdata/deployments/shutdown-manager.yaml | 1 + .../kubernetes/proxy/testdata/deployments/volumes.yaml | 1 + .../proxy/testdata/deployments/with-annotations.yaml | 1 + .../proxy/testdata/deployments/with-concurrency.yaml | 1 + .../proxy/testdata/deployments/with-empty-memory-limits.yaml | 1 + .../proxy/testdata/deployments/with-extra-args.yaml | 1 + .../proxy/testdata/deployments/with-image-pull-secrets.yaml | 1 + .../kubernetes/proxy/testdata/deployments/with-name.yaml | 1 + .../proxy/testdata/deployments/with-node-selector.yaml | 1 + .../deployments/with-topology-spread-constraints.yaml | 1 + .../proxy/testdata/gateway-namespace-mode/deployment.yaml | 2 ++ .../testdata/gateway-namespace-mode/serviceaccount.yaml | 2 ++ .../kubernetes/proxy/testdata/serviceaccount/default.yaml | 1 + .../testdata/serviceaccount/gateway-namespace-mode.yaml | 1 + .../proxy/testdata/serviceaccount/with-annotations.yaml | 1 + .../infrastructure/kubernetes/proxy_serviceaccount_test.go | 5 +++++ .../infrastructure/kubernetes/ratelimit/resource_provider.go | 1 + .../ratelimit/testdata/envoy-ratelimit-serviceaccount.yaml | 1 + .../kubernetes/ratelimit_serviceaccount_test.go | 3 +++ release-notes/current.yaml | 1 + 52 files changed, 62 insertions(+) diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go index b83b9002b7..5a82864907 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go @@ -139,6 +139,7 @@ func (r *ResourceRender) ServiceAccount() (*corev1.ServiceAccount, error) { Kind: "ServiceAccount", APIVersion: "v1", }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: r.Namespace(), Name: r.Name(), @@ -370,6 +371,7 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { Annotations: podAnnotations, }, Spec: corev1.PodSpec{ + AutomountServiceAccountToken: ptr.To(false), Containers: containers, InitContainers: deploymentConfig.InitContainers, ServiceAccountName: r.Name(), @@ -596,6 +598,7 @@ func (r *ResourceRender) getPodSpec( proxyConfig *egv1a1.EnvoyProxy, ) corev1.PodSpec { return corev1.PodSpec{ + AutomountServiceAccountToken: ptr.To(false), Containers: containers, InitContainers: initContainers, ServiceAccountName: ExpectedResourceHashedName(r.infra.Name), diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml index 6e500f7b39..718ba0863e 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml index a90cada680..4c4c728856 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml @@ -33,6 +33,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml index d74ed2faf1..7e66e79853 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml index 8f08280887..a464db4f73 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml index be43f0d003..3d339c89de 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml @@ -28,6 +28,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml index 1f4853b41a..3b4c424a8c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml index ae8b78e904..32cfbcf2eb 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml @@ -37,6 +37,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: gateway-1 gateway.envoyproxy.io/owning-gateway-namespace: ns1 spec: + automountServiceAccountToken: false containers: - args: - --service-cluster ns1/gateway-1 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml index 1aa26a1c6d..055a5f6e24 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml @@ -41,6 +41,7 @@ spec: label1: value1-override label2: value2 spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml index 2d38eaba84..83db2f7ada 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml index 716cb61c94..1cfc1b3e35 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml index 2009045573..aea69f3f7a 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml index 2e8a3f85ff..d3d60cccdd 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml @@ -37,6 +37,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml index faae3da331..86fe15d198 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml index 708bc655bb..45f166c78b 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml index 07a2eac965..507c7062cf 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml index f078b2f83b..da78a5b93c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml index 0c061fc053..c0255f0113 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml index 85739bdb6b..073fcc4a06 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml index 53d6c883cc..27e558cfc9 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml index 4e530e1ab8..9abe3a8a44 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml index eb0cb4a055..ac022e4a3f 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml @@ -38,6 +38,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml index aa3d4ef914..17027ec146 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml @@ -38,6 +38,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml index deb7fc0d3d..643dd23d23 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml @@ -37,6 +37,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml index 7b010c5f15..8a17a5c203 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml index ce2417f6d9..189b531ae6 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml @@ -32,6 +32,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml index 72775a58c8..e5491087ad 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml index cd36c6cf44..3fab05d693 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml @@ -37,6 +37,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml index 2c84b757e9..1f918d39f7 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml @@ -41,6 +41,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: gateway-1 gateway.envoyproxy.io/owning-gateway-namespace: ns1 spec: + automountServiceAccountToken: false containers: - args: - --service-cluster ns1/gateway-1 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml index 0cf8f99a5f..798d2184ba 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml index 003093b283..42893f45fd 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml @@ -45,6 +45,7 @@ spec: label1: value1-override label2: value2 spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml index 438ca1f446..be0dc6d8b5 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml index 51cff26904..383e7e08ea 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml index 26951afe48..9671d045a8 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml @@ -37,6 +37,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml index f8068f45cc..81365d0b73 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml @@ -41,6 +41,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml index b4eb9d5d1b..9a9051362e 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml index e2273aca97..08e6739127 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml index f4f8f7030d..e642037054 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml index ec1f1157f2..9ab1f6bd1c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml index b8ac9b251e..5937dce236 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml index 30dcd66b26..cdbbd8835e 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml index 08028a30c5..b1f818d689 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml @@ -36,6 +36,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: default gateway.envoyproxy.io/owning-gateway-namespace: default spec: + automountServiceAccountToken: false containers: - args: - --service-cluster default diff --git a/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml index 37d149d9cb..ce0c5c2caa 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml @@ -41,6 +41,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: gateway-1 gateway.envoyproxy.io/owning-gateway-namespace: namespace-1 spec: + automountServiceAccountToken: false containers: - args: - --service-cluster namespace-1/gateway-1 @@ -496,6 +497,7 @@ spec: gateway.envoyproxy.io/owning-gateway-name: gateway-2 gateway.envoyproxy.io/owning-gateway-namespace: namespace-2 spec: + automountServiceAccountToken: false containers: - args: - --service-cluster namespace-2/gateway-2 diff --git a/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/serviceaccount.yaml b/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/serviceaccount.yaml index 13d5c8e03e..947f8e916f 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/serviceaccount.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/serviceaccount.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: creationTimestamp: null @@ -17,6 +18,7 @@ metadata: uid: test-owner-reference-uid-for-gateway --- apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: creationTimestamp: null diff --git a/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/default.yaml index 04760e0b91..4cbfff7e48 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/default.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/default.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: creationTimestamp: null diff --git a/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/gateway-namespace-mode.yaml b/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/gateway-namespace-mode.yaml index 484e1f7068..d540cb6dad 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/gateway-namespace-mode.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/gateway-namespace-mode.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: creationTimestamp: null diff --git a/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/with-annotations.yaml index f4076de4e1..6a65d87705 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/with-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/serviceaccount/with-annotations.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: annotations: diff --git a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go index 62c1b4963c..86805fad51 100644 --- a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go +++ b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go @@ -56,6 +56,7 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) { Kind: "ServiceAccount", APIVersion: "v1", }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: "test", Name: "envoy-test-9f86d081", @@ -105,6 +106,7 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) { Kind: "ServiceAccount", APIVersion: "v1", }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: "test", Name: "envoy-test-9f86d081", @@ -137,6 +139,7 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) { Kind: "ServiceAccount", APIVersion: "v1", }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: "test", Name: "very-long-name-that-will-be-hashed-and-cut-off-because-its-too-long", @@ -154,6 +157,7 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) { Kind: "ServiceAccount", APIVersion: "v1", }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: "test", Name: "envoy-very-long-name-that-will-be-hashed-and-cut-off-b-5bacc75e", @@ -192,6 +196,7 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) { Kind: "ServiceAccount", APIVersion: "v1", }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: "ns1", Name: "envoy-ns1-gateway-1-02ae0474", diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go index 9013127e0f..199955cbda 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go @@ -174,6 +174,7 @@ func (r *ResourceRender) ServiceAccount() (*corev1.ServiceAccount, error) { Kind: ResourceKindServiceAccount, APIVersion: apiVersion, }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: r.Namespace(), Name: InfraName, diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/envoy-ratelimit-serviceaccount.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/envoy-ratelimit-serviceaccount.yaml index 05b389768d..c11aaac1e3 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/envoy-ratelimit-serviceaccount.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/envoy-ratelimit-serviceaccount.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +automountServiceAccountToken: false kind: ServiceAccount metadata: name: envoy-ratelimit diff --git a/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go b/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go index ecf366eeff..62c854db91 100644 --- a/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go +++ b/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go @@ -17,6 +17,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" @@ -50,6 +51,7 @@ func TestCreateOrUpdateRateLimitServiceAccount(t *testing.T) { Kind: "ServiceAccount", APIVersion: "v1", }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: "envoy-gateway-system", Name: ratelimit.InfraName, @@ -72,6 +74,7 @@ func TestCreateOrUpdateRateLimitServiceAccount(t *testing.T) { Kind: "ServiceAccount", APIVersion: "v1", }, + AutomountServiceAccountToken: ptr.To(false), ObjectMeta: metav1.ObjectMeta{ Namespace: "envoy-gateway-system", Name: ratelimit.InfraName, diff --git a/release-notes/current.yaml b/release-notes/current.yaml index b804fc66c0..72987e8903 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -5,6 +5,7 @@ breaking changes: | # Updates addressing vulnerabilities, security flaws, or compliance requirements. security updates: | + Disable automountServiceAccountToken for proxy and ratelimit deployments and serviceAccounts # New features or capabilities added in this release. new features: | From a4df600235c99ca996a58170dd3e511e946b4c46 Mon Sep 17 00:00:00 2001 From: zirain Date: Sat, 21 Jun 2025 13:15:41 +0800 Subject: [PATCH 03/16] bugfix: make EnvoyPatchPolicy able to replace telemetry cluster (#6367) Signed-off-by: zirain Signed-off-by: shawnh2 --- internal/xds/translator/translator.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 439288409e..b6273eb855 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -117,15 +117,16 @@ func (t *Translator) Translate(xdsIR *ir.Xds) (*types.ResourceVersionTable, erro errs = errors.Join(errs, err) } - if err := processJSONPatches(tCtx, xdsIR.EnvoyPatchPolicies); err != nil { + if err := processClusterForAccessLog(tCtx, xdsIR.AccessLog, xdsIR.Metrics); err != nil { errs = errors.Join(errs, err) } - if err := processClusterForAccessLog(tCtx, xdsIR.AccessLog, xdsIR.Metrics); err != nil { + if err := processClusterForTracing(tCtx, xdsIR.Tracing, xdsIR.Metrics); err != nil { errs = errors.Join(errs, err) } - if err := processClusterForTracing(tCtx, xdsIR.Tracing, xdsIR.Metrics); err != nil { + // All XDS resources is ready, let's do the patch. + if err := processJSONPatches(tCtx, xdsIR.EnvoyPatchPolicies); err != nil { errs = errors.Join(errs, err) } From 4021137a32654ca817410b614c1e05b8dd64df46 Mon Sep 17 00:00:00 2001 From: Kota Kimura <86363983+kkk777-7@users.noreply.github.com> Date: Tue, 24 Jun 2025 07:00:55 +0900 Subject: [PATCH 04/16] feat: add validation of section name for Gateway listener (#6343) * add validation of section name Signed-off-by: kkk777-7 * update error status reason Signed-off-by: kkk777-7 * refactor: define as function of validate section name for gateway listener Signed-off-by: kkk777-7 Signed-off-by: shawnh2 --- internal/gatewayapi/clienttrafficpolicy.go | 23 +-- internal/gatewayapi/securitypolicy.go | 11 ++ ...nttrafficpolicy-status-conditions.out.yaml | 4 +- ...y-invalid-no-section-name-listener.in.yaml | 51 +++++ ...-invalid-no-section-name-listener.out.yaml | 187 ++++++++++++++++++ internal/gatewayapi/validate.go | 27 +++ 6 files changed, 285 insertions(+), 18 deletions(-) create mode 100644 internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.in.yaml create mode 100644 internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 843109838f..b520f65924 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -303,22 +303,13 @@ func resolveCTPolicyTargetRef( } // If sectionName is set, make sure its valid - sectionName := targetRef.SectionName - if sectionName != nil { - found := false - for _, l := range gateway.listeners { - if l.Name == *sectionName { - found = true - break - } - } - if !found { - message := fmt.Sprintf("No section name %s found for %s", *sectionName, key.String()) - - return gateway.GatewayContext, &status.PolicyResolveError{ - Reason: gwapiv1a2.PolicyReasonInvalid, - Message: message, - } + if targetRef.SectionName != nil { + if err := validateGatewayListenerSectionName( + *targetRef.SectionName, + key, + gateway.listeners, + ); err != nil { + return gateway.GatewayContext, err } } diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index e2dd18b2b1..f3709b6d70 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -305,6 +305,17 @@ func resolveSecurityPolicyGatewayTargetRef( return nil, nil } + // If sectionName is set, make sure its valid + if target.SectionName != nil { + if err := validateGatewayListenerSectionName( + *target.SectionName, + key, + gateway.listeners, + ); err != nil { + return gateway.GatewayContext, err + } + } + // Check if another policy targeting the same Gateway exists if gateway.attached { message := fmt.Sprintf("Unable to target Gateway %s, another SecurityPolicy has already attached to it", diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml index 6e61e34bee..4be05811b7 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml @@ -103,8 +103,8 @@ clientTrafficPolicies: sectionName: foo-bar conditions: - lastTransitionTime: null - message: No section name foo-bar found for envoy-gateway/gateway-3 - reason: Invalid + message: No section name foo-bar found for Gateway envoy-gateway/gateway-3 + reason: TargetNotFound status: "False" type: Accepted controllerName: gateway.envoyproxy.io/gatewayclass-controller diff --git a/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.in.yaml b/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.in.yaml new file mode 100644 index 0000000000..b96956b8a3 --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.in.yaml @@ -0,0 +1,51 @@ +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: 80 + hostname: listener-1.gateway-1.envoyproxy.io + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - listener-1.gateway-1.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: listener-1 + rules: + - matches: + - path: + value: "/foo" + backendRefs: + - name: service-1 + port: 8080 +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: envoy-gateway + name: policy-for-gateway-1 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: not-found-section-name + cors: + allowHeaders: + - "x-gateway-1" diff --git a/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml b/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml new file mode 100644 index 0000000000..3f896cfafc --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml @@ -0,0 +1,187 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + hostname: listener-1.gateway-1.envoyproxy.io + name: listener-1 + 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: listener-1 + 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: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - listener-1.gateway-1.envoyproxy.io + 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 +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/listener-1 + 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 +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + creationTimestamp: null + name: policy-for-gateway-1 + namespace: envoy-gateway + spec: + cors: + allowHeaders: + - x-gateway-1 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: not-found-section-name + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: not-found-section-name + conditions: + - lastTransitionTime: null + message: No section name not-found-section-name found for Gateway envoy-gateway/gateway-1 + reason: TargetNotFound + status: "False" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - listener-1.gateway-1.envoyproxy.io + isHTTP2: false + 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: 10080 + 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: + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-1/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: listener-1.gateway-1.envoyproxy.io + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/listener-1_gateway-1_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: /foo + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/validate.go b/internal/gatewayapi/validate.go index d97ee80713..d2b72b4bfb 100644 --- a/internal/gatewayapi/validate.go +++ b/internal/gatewayapi/validate.go @@ -14,6 +14,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -1037,3 +1038,29 @@ func (t *Translator) validateExtServiceBackendReference( } return nil } + +// validateGatewayListenerSectionName check: +// if the section name exists in the target Gateway listeners. +func validateGatewayListenerSectionName( + sectionName gwapiv1.SectionName, + targetKey types.NamespacedName, + listeners []*ListenerContext, +) *status.PolicyResolveError { + found := false + for _, l := range listeners { + if l.Name == sectionName { + found = true + break + } + } + if !found { + message := fmt.Sprintf("No section name %s found for Gateway %s", + string(sectionName), targetKey.String()) + + return &status.PolicyResolveError{ + Reason: gwapiv1a2.PolicyReasonTargetNotFound, + Message: message, + } + } + return nil +} From 7ed3804d6858e5efe0af01506fff71ef5cf9065a Mon Sep 17 00:00:00 2001 From: Rudrakh Panigrahi Date: Tue, 24 Jun 2025 07:37:17 +0530 Subject: [PATCH 05/16] fix: add configMap indexers for EEP reconciler (#6369) Signed-off-by: Rudrakh Panigrahi --- internal/provider/kubernetes/controller.go | 1 + .../provider/kubernetes/controller_offline.go | 1 + internal/provider/kubernetes/indexers.go | 29 +++++ internal/provider/kubernetes/predicates.go | 14 +++ .../provider/kubernetes/predicates_test.go | 109 ++++++++++++++++++ internal/provider/kubernetes/test/utils.go | 12 ++ release-notes/current.yaml | 1 + 7 files changed, 167 insertions(+) diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 8ee2266901..f656d5ccf2 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -2182,6 +2182,7 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicies( // It will be recomputed by the gateway-api layer envoyExtensionPolicy.Status = gwapiv1a2.PolicyStatus{} if !resourceMap.allAssociatedEnvoyExtensionPolicies.Has(utils.NamespacedName(&envoyExtensionPolicy).String()) { + r.log.Info("processing EnvoyExtensionPolicy", "namespace", policy.Namespace, "name", policy.Name) resourceMap.allAssociatedEnvoyExtensionPolicies.Insert(utils.NamespacedName(&envoyExtensionPolicy).String()) resourceTree.EnvoyExtensionPolicies = append(resourceTree.EnvoyExtensionPolicies, &envoyExtensionPolicy) } diff --git a/internal/provider/kubernetes/controller_offline.go b/internal/provider/kubernetes/controller_offline.go index 74f64d1a01..9a55f8a318 100644 --- a/internal/provider/kubernetes/controller_offline.go +++ b/internal/provider/kubernetes/controller_offline.go @@ -139,6 +139,7 @@ func newOfflineGatewayAPIClient() client.Client { WithIndex(&egv1a1.SecurityPolicy{}, configMapSecurityPolicyIndex, configMapSecurityPolicyIndexFunc). WithIndex(&egv1a1.EnvoyExtensionPolicy{}, backendEnvoyExtensionPolicyIndex, backendEnvoyExtensionPolicyIndexFunc). WithIndex(&egv1a1.EnvoyExtensionPolicy{}, secretEnvoyExtensionPolicyIndex, secretEnvoyExtensionPolicyIndexFunc). + WithIndex(&egv1a1.EnvoyExtensionPolicy{}, configMapEepIndex, configMapEepIndexFunc). WithIndex(&gwapiv1a3.BackendTLSPolicy{}, configMapBtlsIndex, configMapBtlsIndexFunc). WithIndex(&gwapiv1a3.BackendTLSPolicy{}, secretBtlsIndex, secretBtlsIndexFunc). WithIndex(&egv1a1.HTTPRouteFilter{}, configMapHTTPRouteFilterIndex, configMapRouteFilterIndexFunc). diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go index 17fcb85968..188117da0e 100644 --- a/internal/provider/kubernetes/indexers.go +++ b/internal/provider/kubernetes/indexers.go @@ -52,6 +52,7 @@ const ( secretEnvoyExtensionPolicyIndex = "secretEnvoyExtensionPolicyIndex" httpRouteFilterHTTPRouteIndex = "httpRouteFilterHTTPRouteIndex" configMapBtpIndex = "configMapBtpIndex" + configMapEepIndex = "configMapEepIndex" configMapHTTPRouteFilterIndex = "configMapHTTPRouteFilterIndex" secretHTTPRouteFilterIndex = "secretHTTPRouteFilterIndex" ) @@ -809,6 +810,28 @@ func configMapBtpIndexFunc(rawObj client.Object) []string { return configMapReferences } +func configMapEepIndexFunc(rawObj client.Object) []string { + eep := rawObj.(*egv1a1.EnvoyExtensionPolicy) + var configMapReferences []string + if eep.Spec.Lua == nil { + return configMapReferences + } + + for _, p := range eep.Spec.Lua { + if p.ValueRef != nil { + if string(p.ValueRef.Kind) == resource.KindConfigMap { + configMapReferences = append(configMapReferences, + types.NamespacedName{ + Namespace: eep.Namespace, + Name: string(p.ValueRef.Name), + }.String(), + ) + } + } + } + return configMapReferences +} + // addRouteFilterIndexers adds indexing on HTTPRouteFilter, for ConfigMap objects that are // referenced in HTTPRouteFilter objects. This helps in querying for HTTPRouteFilters that are // affected by a particular ConfigMap CRUD. @@ -928,6 +951,12 @@ func addEnvoyExtensionPolicyIndexers(ctx context.Context, mgr manager.Manager) e return err } + if err = mgr.GetFieldIndexer().IndexField( + ctx, &egv1a1.EnvoyExtensionPolicy{}, configMapEepIndex, + configMapEepIndexFunc); err != nil { + return err + } + return nil } diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go index 1ec83ee0fa..235750ceb3 100644 --- a/internal/provider/kubernetes/predicates.go +++ b/internal/provider/kubernetes/predicates.go @@ -764,6 +764,20 @@ func (r *gatewayAPIReconciler) validateConfigMapForReconcile(obj client.Object) } } + if r.eepCRDExists { + eepList := &egv1a1.EnvoyExtensionPolicyList{} + if err := r.client.List(context.Background(), eepList, &client.ListOptions{ + FieldSelector: fields.OneTermEqualSelector(configMapEepIndex, utils.NamespacedName(configMap).String()), + }); err != nil { + r.log.Error(err, "unable to find associated EnvoyExtensionPolicy") + return false + } + + if len(eepList.Items) > 0 { + return true + } + } + if r.hrfCRDExists { routeFilterList := &egv1a1.HTTPRouteFilterList{} if err := r.client.List(context.Background(), routeFilterList, &client.ListOptions{ diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go index 0ccb4999c2..ec34defd07 100644 --- a/internal/provider/kubernetes/predicates_test.go +++ b/internal/provider/kubernetes/predicates_test.go @@ -175,6 +175,115 @@ func TestValidateGatewayForReconcile(t *testing.T) { } } +// TestValidateConfigMapForReconcile tests the validateConfigMapForReconcile +// predicate function. +func TestValidateConfigMapForReconcile(t *testing.T) { + testCases := []struct { + name string + configs []client.Object + configMap client.Object + expect bool + }{ + { + name: "references EnvoyExtensionPolicy Lua config map", + configs: []client.Object{ + test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil), + test.GetGateway(types.NamespacedName{Name: "scheduled-status-test"}, "test-gc", 8080), + &egv1a1.EnvoyExtensionPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "lua-cm", + Namespace: "test", + }, + Spec: egv1a1.EnvoyExtensionPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRefs: []gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Kind: "Gateway", + Name: "scheduled-status-test", + }, + }, + }, + }, + Lua: []egv1a1.Lua{ + { + Type: egv1a1.LuaValueTypeValueRef, + ValueRef: &gwapiv1.LocalObjectReference{ + Kind: gwapiv1a2.Kind("ConfigMap"), + Name: gwapiv1a2.ObjectName("lua"), + Group: gwapiv1a2.Group("v1"), + }, + }, + }, + }, + }, + }, + configMap: test.GetConfigMap(types.NamespacedName{Name: "lua", Namespace: "test"}, make(map[string]string), make(map[string]string)), + expect: true, + }, + { + name: "does not reference EnvoyExtensionPolicy Lua config map", + configs: []client.Object{ + test.GetGatewayClass("test-gc", egv1a1.GatewayControllerName, nil), + test.GetGateway(types.NamespacedName{Name: "scheduled-status-test"}, "test-gc", 8080), + &egv1a1.EnvoyExtensionPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "lua-cm", + Namespace: "test", + }, + Spec: egv1a1.EnvoyExtensionPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRefs: []gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + { + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Kind: "Gateway", + Name: "scheduled-status-test", + }, + }, + }, + }, + Lua: []egv1a1.Lua{ + { + Type: egv1a1.LuaValueTypeValueRef, + ValueRef: &gwapiv1.LocalObjectReference{ + Kind: gwapiv1a2.Kind("ConfigMap"), + Name: gwapiv1a2.ObjectName("lua"), + Group: gwapiv1a2.Group("v1"), + }, + }, + }, + }, + }, + }, + configMap: test.GetConfigMap(types.NamespacedName{Name: "not-lua", Namespace: "test"}, make(map[string]string), make(map[string]string)), + expect: false, + }, + } + + // Create the reconciler. + logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo) + + r := gatewayAPIReconciler{ + classController: egv1a1.GatewayControllerName, + log: logger, + spCRDExists: true, + epCRDExists: true, + eepCRDExists: true, + } + + for _, tc := range testCases { + r.client = fakeclient.NewClientBuilder(). + WithScheme(envoygateway.GetScheme()). + WithObjects(tc.configs...). + WithIndex(&egv1a1.EnvoyExtensionPolicy{}, configMapEepIndex, configMapEepIndexFunc). + Build() + t.Run(tc.name, func(t *testing.T) { + res := r.validateConfigMapForReconcile(tc.configMap) + require.Equal(t, tc.expect, res) + }) + } +} + // TestValidateSecretForReconcile tests the validateSecretForReconcile // predicate function. func TestValidateSecretForReconcile(t *testing.T) { diff --git a/internal/provider/kubernetes/test/utils.go b/internal/provider/kubernetes/test/utils.go index a6b2ef3256..3eac5782a8 100644 --- a/internal/provider/kubernetes/test/utils.go +++ b/internal/provider/kubernetes/test/utils.go @@ -364,6 +364,18 @@ func GetService(nsName types.NamespacedName, labels map[string]string, ports map return service } +// GetConfigMap returns a sample ConfigMap with labels and data +func GetConfigMap(nsName types.NamespacedName, labels, data map[string]string) *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: nsName.Name, + Namespace: nsName.Namespace, + Labels: labels, + }, + Data: data, + } +} + // GetEndpointSlice returns a sample EndpointSlice. func GetEndpointSlice(nsName types.NamespacedName, svcName string, isServiceImport bool) *discoveryv1.EndpointSlice { var labels map[string]string diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 72987e8903..0bbdd1aa18 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -23,6 +23,7 @@ bug fixes: | Keep ALPN configuration for listeners with overlapping certificates when ALPN is explicitly set in ClientTrafficPolicy. Fixed issue where EnvoyExtensionPolicy ExtProc body processing mode is set to FullDuplexStreamed, but trailers were not sent. Fixed validation issue where EnvoyExtensionPolicy ExtProc failOpen is true, and body processing mode FullDuplexStreamed is not rejected. + Add ConfigMap indexers for EnvoyExtensionPolicies to reconcile Lua changes # Enhancements that improve performance. From f3f5c515484235db7eedd239613ecebc6a469c82 Mon Sep 17 00:00:00 2001 From: zirain Date: Thu, 26 Jun 2025 09:25:11 +0800 Subject: [PATCH 06/16] fix: use buildEndpointType for access and tracing (#6370) Signed-off-by: zirain --- .../envoyproxy-tracing-backend-uds.in.yaml | 119 ++++++++ .../envoyproxy-tracing-backend-uds.out.yaml | 282 ++++++++++++++++++ internal/xds/translator/accesslog.go | 4 +- .../testdata/in/xds-ir/accesslog-cel.yaml | 3 +- .../in/xds-ir/accesslog-endpoint-stats.yaml | 1 + .../in/xds-ir/accesslog-formatters.yaml | 1 + .../in/xds-ir/accesslog-multi-cel.yaml | 1 + .../testdata/in/xds-ir/accesslog-types.yaml | 3 + .../in/xds-ir/accesslog-with-format.yaml | 1 + .../testdata/in/xds-ir/accesslog.yaml | 1 + .../testdata/in/xds-ir/dns-lookup-family.yaml | 13 +- .../in/xds-ir/tracing-datadog-uds.yaml | 50 ++++ .../testdata/in/xds-ir/tracing-datadog.yaml | 1 + .../in/xds-ir/tracing-endpoint-stats.yaml | 1 + .../testdata/in/xds-ir/tracing-zipkin.yaml | 1 + .../testdata/in/xds-ir/tracing.yaml | 1 + .../xds-ir/dns-lookup-family.clusters.yaml | 19 +- .../xds-ir/tracing-datadog-uds.clusters.yaml | 34 +++ .../xds-ir/tracing-datadog-uds.endpoints.yaml | 23 ++ .../xds-ir/tracing-datadog-uds.listeners.yaml | 60 ++++ .../xds-ir/tracing-datadog-uds.routes.yaml | 14 + internal/xds/translator/tracing.go | 3 +- 22 files changed, 626 insertions(+), 10 deletions(-) create mode 100644 internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.in.yaml create mode 100644 internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/tracing-datadog-uds.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.routes.yaml diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.in.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.in.yaml new file mode 100644 index 0000000000..f6ed2988fb --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.in.yaml @@ -0,0 +1,119 @@ +envoyProxyForGatewayClass: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + telemetry: + tracing: + samplingRate: 100 + provider: + backendSettings: + http2: + initialStreamWindowSize: 128Ki + initialConnectionWindowSize: 2Mi + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + type: ConsistentHash + consistentHash: + type: Header + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + circuitBreaker: + maxConnections: 2048 + timeout: + tcp: + connectTimeout: 15s + connection: + bufferLimit: 20Mi + backendRefs: + - group: gateway.envoyproxy.io + kind: Backend + name: datadog-svc + namespace: envoy-gateway-system + port: 8126 + type: OpenTelemetry + provider: + type: Kubernetes + kubernetes: + envoyService: + type: LoadBalancer + envoyDeployment: + replicas: 2 + container: + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_name + image: "envoyproxy/envoy:distroless-dev" + resources: + requests: + cpu: 100m + memory: 512Mi + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + pod: + annotations: + key1: val1 + key2: val2 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: "router" + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + fsGroupChangePolicy: "OnRootMismatch" + volumes: + - name: certs + secret: + secretName: envoy-cert +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + 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 +backends: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: Backend + metadata: + name: datadog-svc + namespace: envoy-gateway-system + spec: + endpoints: + - unix: + path: /var/run/envoy-uds/dsd.socket + type: Endpoints diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml new file mode 100644 index 0000000000..b797b32849 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml @@ -0,0 +1,282 @@ +backends: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: Backend + metadata: + creationTimestamp: null + name: datadog-svc + namespace: envoy-gateway-system + spec: + endpoints: + - unix: + path: /var/run/envoy-uds/dsd.socket + type: Endpoints + status: + conditions: + - lastTransitionTime: null + message: The Backend was accepted + reason: Accepted + status: "True" + type: Accepted +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + 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 +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: test + namespace: envoy-gateway-system + spec: + logging: {} + provider: + kubernetes: + envoyDeployment: + container: + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_name + image: envoyproxy/envoy:distroless-dev + resources: + requests: + cpu: 100m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + runAsUser: 2000 + pod: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + annotations: + key1: val1 + key2: val2 + securityContext: + fsGroup: 2000 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 3000 + runAsUser: 1000 + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: router + volumes: + - name: certs + secret: + secretName: envoy-cert + replicas: 2 + envoyService: + type: LoadBalancer + type: Kubernetes + telemetry: + tracing: + provider: + backendRefs: + - group: gateway.envoyproxy.io + kind: Backend + name: datadog-svc + namespace: envoy-gateway-system + port: 8126 + backendSettings: + circuitBreaker: + maxConnections: 2048 + connection: + bufferLimit: 20Mi + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 2Mi + initialStreamWindowSize: 128Ki + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + consistentHash: + header: + name: X-some-header + type: Header + type: ConsistentHash + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + type: OpenTelemetry + samplingRate: 100 + status: {} + listeners: + - address: null + 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 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + 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 + tracing: + destination: + metadata: + kind: EnvoyProxy + name: test + namespace: envoy-gateway-system + name: tracing + settings: + - addressType: IP + endpoints: + - host: "" + path: /var/run/envoy-uds/dsd.socket + port: 0 + metadata: + kind: Backend + name: datadog-svc + namespace: envoy-gateway-system + name: tracing/backend/-1 + protocol: TCP + provider: + backendRefs: + - group: gateway.envoyproxy.io + kind: Backend + name: datadog-svc + namespace: envoy-gateway-system + port: 8126 + backendSettings: + circuitBreaker: + maxConnections: 2048 + connection: + bufferLimit: 20Mi + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 2Mi + initialStreamWindowSize: 128Ki + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + consistentHash: + header: + name: X-some-header + type: Header + type: ConsistentHash + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + type: OpenTelemetry + samplingRate: 100 + serviceName: gateway-1.envoy-gateway + traffic: + backendConnection: + bufferLimit: 20971520 + circuitBreaker: + maxConnections: 2048 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 131072 + initialStreamWindowSize: 2097152 + maxConcurrentStreams: 200 + resetStreamOnError: true + loadBalancer: + consistentHash: + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s diff --git a/internal/xds/translator/accesslog.go b/internal/xds/translator/accesslog.go index 9c584445f7..d657d13412 100644 --- a/internal/xds/translator/accesslog.go +++ b/internal/xds/translator/accesslog.go @@ -520,7 +520,7 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL name: als.Destination.Name, settings: als.Destination.Settings, tSocket: nil, - endpointType: EndpointTypeStatic, + endpointType: buildEndpointType(als.Destination.Settings), loadBalancer: traffic.LoadBalancer, proxyProtocol: traffic.ProxyProtocol, circuitBreaker: traffic.CircuitBreaker, @@ -547,7 +547,7 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL name: otel.Destination.Name, settings: otel.Destination.Settings, tSocket: nil, - endpointType: EndpointTypeDNS, + endpointType: buildEndpointType(otel.Destination.Settings), metrics: metrics, loadBalancer: traffic.LoadBalancer, proxyProtocol: traffic.ProxyProtocol, diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-cel.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-cel.yaml index aa6681dddc..5a22eccfd8 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-cel.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-cel.yaml @@ -29,7 +29,8 @@ accesslog: destination: name: "accesslog-0" settings: - - endpoints: + - addressType: FQDN + endpoints: - host: "otel-collector.default.svc.cluster.local" port: 4317 protocol: "GRPC" diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml index c9c4bc6085..17760201da 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-endpoint-stats.yaml @@ -28,6 +28,7 @@ accesslog: - endpoints: - host: "otel-collector.default.svc.cluster.local" port: 4317 + addressType: FQDN protocol: "GRPC" name: "accesslog-0/backend/0" http: diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml index 3deb3b589e..4f9893c566 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-formatters.yaml @@ -36,6 +36,7 @@ accesslog: - endpoints: - host: "otel-collector.default.svc.cluster.local" port: 4317 + addressType: FQDN protocol: "GRPC" name: "accesslog-0/backend/0" http: diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-multi-cel.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-multi-cel.yaml index d1257878d0..989390b135 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-multi-cel.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-multi-cel.yaml @@ -36,6 +36,7 @@ accesslog: - endpoints: - host: "otel-collector.default.svc.cluster.local" port: 4317 + addressType: FQDN protocol: "GRPC" name: "accesslog-0/backend/0" http: diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-types.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-types.yaml index e995f5a50c..93e038e10a 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-types.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-types.yaml @@ -112,6 +112,7 @@ accessLog: - host: otel-collector.monitoring.svc.cluster.local port: 4317 protocol: GRPC + addressType: FQDN weight: 1 name: accesslog_otel_0_3/backend/0 logType: Route @@ -127,6 +128,7 @@ accessLog: - host: otel-collector.monitoring.svc.cluster.local port: 4317 protocol: GRPC + addressType: FQDN weight: 1 name: accesslog_otel_1_3/backend/0 logType: Listener @@ -142,6 +144,7 @@ accessLog: - host: otel-collector.monitoring.svc.cluster.local port: 4317 protocol: GRPC + addressType: FQDN weight: 1 name: accesslog_otel_2_3/backend/0 resources: diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-with-format.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-with-format.yaml index 5a7fba2ea5..915517dc73 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-with-format.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-with-format.yaml @@ -45,6 +45,7 @@ accesslog: - endpoints: - host: "otel-collector.default.svc.cluster.local" port: 4317 + addressType: FQDN protocol: "GRPC" http: - name: "first-listener" diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml index 7c8bcb91db..7b27237294 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog.yaml @@ -52,6 +52,7 @@ accesslog: - host: "otel-collector.default.svc.cluster.local" port: 4317 protocol: "GRPC" + addressType: FQDN name: "accesslog-0/backend/0" http: - name: "first-listener" diff --git a/internal/xds/translator/testdata/in/xds-ir/dns-lookup-family.yaml b/internal/xds/translator/testdata/in/xds-ir/dns-lookup-family.yaml index 82e8491aaa..9fcd42b86e 100644 --- a/internal/xds/translator/testdata/in/xds-ir/dns-lookup-family.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/dns-lookup-family.yaml @@ -1,9 +1,14 @@ accessLog: openTelemetry: - destination: - name: accesslog_otel_0_1 + name: "accesslog_otel_0_1" settings: - - protocol: TCP + - endpoints: + - host: "otel-collector.default.svc.cluster.local" + port: 4317 + protocol: "GRPC" + addressType: FQDN + name: "accesslog-0/backend/0" resources: k8s.cluster.name: cluster-1 text: | @@ -19,7 +24,7 @@ accessLog: http: - address: 0.0.0.0 hostnames: - - '*' + - "*" isHTTP2: true metadata: kind: Gateway @@ -101,7 +106,7 @@ http: port: 8080 protocol: GRPC weight: 1 - hostname: '*' + hostname: "*" isHTTP2: true metadata: kind: GRPCRoute diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-datadog-uds.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-datadog-uds.yaml new file mode 100644 index 0000000000..694c99fd27 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/tracing-datadog-uds.yaml @@ -0,0 +1,50 @@ +name: "tracing" +tracing: + serviceName: "fake-name.fake-ns" + samplingRate: 90 + customTags: + "literal1": + type: Literal + literal: + value: "value1" + "env1": + type: Environment + environment: + name: "env1" + defaultValue: "-" + "req1": + type: RequestHeader + requestHeader: + name: "X-Request-Id" + defaultValue: "-" + authority: "datadog-agent.default.svc.cluster.local" + destination: + name: "tracing-0" + settings: + - addressType: IP + endpoints: + - host: "" + path: /var/run/envoy-uds/dsd.socket + port: 0 + name: "tracing-0/backend/0" + provider: + type: Datadog +http: + - name: "first-listener" + address: "::" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "direct-route" + hostname: "*" + destination: + name: "direct-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + name: "direct-route-dest/backend/0" diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-datadog.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-datadog.yaml index 809ccb6b77..c7c42d9bae 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing-datadog.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing-datadog.yaml @@ -24,6 +24,7 @@ tracing: - endpoints: - host: "datadog-agent.default.svc.cluster.local" port: 8126 + addressType: FQDN name: "tracing-0/backend/0" provider: type: Datadog diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml index 4c8145aefd..1a147187d2 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing-endpoint-stats.yaml @@ -27,6 +27,7 @@ tracing: - host: "otel-collector.default.svc.cluster.local" port: 4317 protocol: "GRPC" + addressType: FQDN name: "tracing-0/backend/0" provider: host: otel-collector.monitoring.svc.cluster.local diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing-zipkin.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing-zipkin.yaml index 5fbee5baf2..2db97e2646 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing-zipkin.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing-zipkin.yaml @@ -25,6 +25,7 @@ tracing: - host: "zipkin.default.svc.cluster.local" port: 9411 protocol: "TCP" + addressType: FQDN name: "tracing-0/backend/0" provider: host: zipkin.default.svc.cluster.local diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml index 33d4b01ee3..c0196ca747 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml @@ -25,6 +25,7 @@ tracing: - host: "otel-collector.default.svc.cluster.local" port: 4317 protocol: "GRPC" + addressType: FQDN name: "tracing-0/backend/0" traffic: backendConnection: diff --git a/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.clusters.yaml index d7473a42f5..30b831b0eb 100644 --- a/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.clusters.yaml @@ -122,9 +122,24 @@ loadAssignment: clusterName: accesslog_otel_0_1 endpoints: - - loadBalancingWeight: 1 - locality: {} + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: otel-collector.default.svc.cluster.local + portValue: 4317 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: accesslog-0/backend/0 name: accesslog_otel_0_1 perConnectionBufferLimitBytes: 32768 respectDnsTtl: true type: STRICT_DNS + 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/tracing-datadog-uds.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.clusters.yaml new file mode 100644 index 0000000000..46b6091ff5 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.clusters.yaml @@ -0,0 +1,34 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: direct-route-dest + ignoreHealthOnHostRemoval: true + lbPolicy: LEAST_REQUEST + name: direct-route-dest + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: tracing-0 + ignoreHealthOnHostRemoval: true + lbPolicy: LEAST_REQUEST + name: tracing-0 + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.endpoints.yaml new file mode 100644 index 0000000000..d4d338eb9d --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.endpoints.yaml @@ -0,0 +1,23 @@ +- clusterName: direct-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: direct-route-dest/backend/0 +- clusterName: tracing-0 + endpoints: + - lbEndpoints: + - endpoint: + address: + pipe: + path: /var/run/envoy-uds/dsd.socket + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: tracing-0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.listeners.yaml new file mode 100644 index 0000000000..32f1b0230f --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.listeners.yaml @@ -0,0 +1,60 @@ +- address: + socketAddress: + address: '::' + portValue: 10080 + 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.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: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10080 + tracing: + clientSampling: + value: 100 + customTags: + - environment: + defaultValue: '-' + name: env1 + tag: env1 + - literal: + value: value1 + tag: literal1 + - requestHeader: + defaultValue: '-' + name: X-Request-Id + tag: req1 + overallSampling: + value: 100 + provider: + name: envoy.tracers.datadog + typedConfig: + '@type': type.googleapis.com/envoy.config.trace.v3.DatadogConfig + collectorCluster: tracing-0 + serviceName: fake-name.fake-ns + randomSampling: + value: 90 + spawnUpstreamSpan: true + useRemoteAddress: true + name: first-listener + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.routes.yaml new file mode 100644 index 0000000000..ea343799ac --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tracing-datadog-uds.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + prefix: / + name: direct-route + route: + cluster: direct-route-dest + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go index fb8de98677..7950f2074c 100644 --- a/internal/xds/translator/tracing.go +++ b/internal/xds/translator/tracing.go @@ -128,11 +128,12 @@ func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Trac if traffic == nil { traffic = &ir.TrafficFeatures{} } + return addXdsCluster(tCtx, &xdsClusterArgs{ name: tracing.Destination.Name, settings: tracing.Destination.Settings, tSocket: nil, - endpointType: EndpointTypeDNS, + endpointType: buildEndpointType(tracing.Destination.Settings), metrics: metrics, loadBalancer: traffic.LoadBalancer, proxyProtocol: traffic.ProxyProtocol, From 30ad36b4c8e55ce59817cd4a678b06be2d1d9ea6 Mon Sep 17 00:00:00 2001 From: shawnh2 Date: Wed, 2 Jul 2025 22:29:43 +0800 Subject: [PATCH 07/16] fix: default accesslog not working (#6441) * fix default accesslog Signed-off-by: zirain * release notes Signed-off-by: zirain --------- Signed-off-by: zirain Signed-off-by: shawnh2 --- internal/gatewayapi/listener.go | 5 ----- .../envoyproxy-accesslog-file-json-no-format.out.yaml | 4 +++- .../testdata/envoyproxy-accesslog-without-format.out.yaml | 2 ++ release-notes/current.yaml | 1 + 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index 7141d36ac7..cd0083a6c3 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -583,11 +583,6 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources * } irAccessLog.Text = append(irAccessLog.Text, al) case egv1a1.ProxyAccessLogFormatTypeJSON: - if len(format.JSON) == 0 { - // TODO: use a default JSON format if not specified? - continue - } - al := &ir.JSONAccessLog{ JSON: format.JSON, Path: sink.File.Path, diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json-no-format.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json-no-format.out.yaml index fea122c1c2..e658fa476e 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json-no-format.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-file-json-no-format.out.yaml @@ -125,7 +125,9 @@ infraIR: namespace: envoy-gateway-system xdsIR: envoy-gateway/gateway-1: - accessLog: {} + accessLog: + json: + - path: /dev/stdout http: - address: 0.0.0.0 hostnames: diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml index eb2f5e64ec..86183eb0b3 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml @@ -182,6 +182,8 @@ xdsIR: protocol: GRPC name: envoy-gateway-system/test type: TCP + json: + - path: /dev/stdout openTelemetry: - authority: otel-collector.monitoring.svc.cluster.local destination: diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 0bbdd1aa18..0ea5220e82 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -24,6 +24,7 @@ bug fixes: | Fixed issue where EnvoyExtensionPolicy ExtProc body processing mode is set to FullDuplexStreamed, but trailers were not sent. Fixed validation issue where EnvoyExtensionPolicy ExtProc failOpen is true, and body processing mode FullDuplexStreamed is not rejected. Add ConfigMap indexers for EnvoyExtensionPolicies to reconcile Lua changes + Fixed issue that default accesslog format not working. # Enhancements that improve performance. From ab908b595e4c4aa3088cb0f5cf0b0b57eb994618 Mon Sep 17 00:00:00 2001 From: zirain Date: Wed, 2 Jul 2025 10:16:54 +0800 Subject: [PATCH 08/16] chore: fix cve (#6446) * fix cve Signed-off-by: zirain * lint Signed-off-by: zirain --------- Signed-off-by: zirain --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e40b2a63ce..36401d3aea 100644 --- a/go.mod +++ b/go.mod @@ -236,7 +236,7 @@ require ( github.com/go-toolsmith/astp v1.1.0 // indirect github.com/go-toolsmith/strparse v1.1.0 // indirect github.com/go-toolsmith/typep v1.1.0 // indirect - github.com/go-viper/mapstructure/v2 v2.2.1 // indirect + github.com/go-viper/mapstructure/v2 v2.3.0 // indirect github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect github.com/gobuffalo/flect v1.0.3 // indirect github.com/gobwas/glob v0.2.3 // indirect diff --git a/go.sum b/go.sum index f125296c18..0e8a048e2a 100644 --- a/go.sum +++ b/go.sum @@ -551,8 +551,8 @@ github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQi github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= -github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= -github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= +github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-xmlfmt/xmlfmt v1.1.3 h1:t8Ey3Uy7jDSEisW2K3somuMKIpzktkWptA0iFCnRUWY= github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= From 0a3eb9cdf3b4adcf5bd4a09fd90a08d1d9569581 Mon Sep 17 00:00:00 2001 From: Sudipto Baral Date: Tue, 1 Jul 2025 23:30:12 -0400 Subject: [PATCH 09/16] fix: Do not set backendRequestTimeout when Retries are set (#6421) * fix: Do not set backendRequestTimeout when Retries are set Signed-off-by: sudipto baral * fix: update comment Signed-off-by: sudipto baral --------- Signed-off-by: sudipto baral --- internal/gatewayapi/route.go | 7 ++++--- internal/gatewayapi/testdata/httproute-retry.out.yaml | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index b98e81a465..3a38774519 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -316,9 +316,10 @@ func processRouteTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) { irRoute.Timeout = ptr.To(metav1.Duration{Duration: d}) } - // Also set the IR Route Timeout to the backend request timeout - // until we introduce retries, then set it to per try timeout - if rule.Timeouts.BackendRequest != nil { + // Only set the IR Route Timeout to the backend request timeout + // when retries are not configured. When retries are configured, + // the backend request timeout should set for per-retry timeout. + if rule.Timeouts.BackendRequest != nil && rule.Retry == nil { d, err := time.ParseDuration(string(*rule.Timeouts.BackendRequest)) if err != nil { d, _ = time.ParseDuration(HTTPRequestTimeout) diff --git a/internal/gatewayapi/testdata/httproute-retry.out.yaml b/internal/gatewayapi/testdata/httproute-retry.out.yaml index 2d9e06df3a..70eafe617b 100644 --- a/internal/gatewayapi/testdata/httproute-retry.out.yaml +++ b/internal/gatewayapi/testdata/httproute-retry.out.yaml @@ -308,7 +308,6 @@ xdsIR: retryOn: httpStatusCodes: - 500 - timeout: 3s traffic: retry: numRetries: 5 From e11817dd10647eeb4427707a792a63334693298b Mon Sep 17 00:00:00 2001 From: zirain Date: Wed, 2 Jul 2025 11:33:30 +0800 Subject: [PATCH 10/16] gatewayapi: don't append gwcResource if there's invalid GatewayClass (#6379) * gatewayapi: don't process gloabal resources when acceptedGateways is 0 Signed-off-by: zirain * update Signed-off-by: zirain * fix test Signed-off-by: zirain * don't skip gateways Signed-off-by: zirain --------- Signed-off-by: zirain Signed-off-by: shawnh2 --- internal/gatewayapi/runner/runner.go | 2 +- internal/provider/kubernetes/controller.go | 38 +++++++++++-------- .../provider/kubernetes/controller_test.go | 2 +- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go index 1a8e3b00e3..3ff25ba175 100644 --- a/internal/gatewayapi/runner/runner.go +++ b/internal/gatewayapi/runner/runner.go @@ -177,7 +177,7 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re result, err := t.Translate(resources) if err != nil { // Currently all errors that Translate returns should just be logged - r.Logger.Error(err, "errors detected during translation") + r.Logger.Error(err, "errors detected during translation", "gateway-class", resources.GatewayClass.Name) } // Publish the IRs. diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index f656d5ccf2..550d1f5f5c 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -7,6 +7,7 @@ package kubernetes import ( "context" + "errors" "fmt" "time" @@ -214,13 +215,14 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques // Initialize resource types. gwcResource := resource.NewResources() gwcResource.GatewayClass = managedGC - gwcResources = append(gwcResources, gwcResource) - resourceMappings := newResourceMapping() + + gwcResourceMapping := newResourceMapping() // Process the parametersRef of the accepted GatewayClass. // This should run before processGateways and processBackendRefs if managedGC.Spec.ParametersRef != nil && managedGC.DeletionTimestamp == nil { - if err := r.processGatewayClassParamsRef(ctx, managedGC, resourceMappings, gwcResource); err != nil { + if err := r.processGatewayClassParamsRef(ctx, managedGC, gwcResourceMapping, gwcResource); err != nil { + r.log.Error(err, fmt.Sprintf("failed processGatewayClassParamsRef for gatewayClass %s, skipping it", managedGC.Name)) msg := fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err) gc := status.SetGatewayClassAccepted( managedGC.DeepCopy(), @@ -231,23 +233,31 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques continue } } + // it's safe here to append gwcResource to gwcResources + gwcResources = append(gwcResources, gwcResource) + // process global resources + // add the OIDC HMAC Secret to the resourceTree + r.processOIDCHMACSecret(ctx, gwcResource, gwcResourceMapping) + // add the Envoy TLS Secret to the resourceTree + r.processEnvoyTLSSecret(ctx, gwcResource, gwcResourceMapping) // Add all Gateways, their associated Routes, and referenced resources to the resourceTree - if err = r.processGateways(ctx, managedGC, resourceMappings, gwcResource); err != nil { + if err = r.processGateways(ctx, managedGC, gwcResourceMapping, gwcResource); err != nil { r.log.Error(err, fmt.Sprintf("failed processGateways for gatewayClass %s, skipping it", managedGC.Name)) continue } if r.eppCRDExists { // Add all EnvoyPatchPolicies to the resourceTree - if err = r.processEnvoyPatchPolicies(ctx, gwcResource, resourceMappings); err != nil { + if err = r.processEnvoyPatchPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { r.log.Error(err, fmt.Sprintf("failed processEnvoyPatchPolicies for gatewayClass %s, skipping it", managedGC.Name)) continue } } + if r.ctpCRDExists { // Add all ClientTrafficPolicies and their referenced resources to the resourceTree - if err = r.processClientTrafficPolicies(ctx, gwcResource, resourceMappings); err != nil { + if err = r.processClientTrafficPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { r.log.Error(err, fmt.Sprintf("failed processClientTrafficPolicies for gatewayClass %s, skipping it", managedGC.Name)) continue } @@ -255,7 +265,7 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques if r.btpCRDExists { // Add all BackendTrafficPolicies to the resourceTree - if err = r.processBackendTrafficPolicies(ctx, gwcResource, resourceMappings); err != nil { + if err = r.processBackendTrafficPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { r.log.Error(err, fmt.Sprintf("failed processBackendTrafficPolicies for gatewayClass %s, skipping it", managedGC.Name)) continue } @@ -263,7 +273,7 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques if r.spCRDExists { // Add all SecurityPolicies and their referenced resources to the resourceTree - if err = r.processSecurityPolicies(ctx, gwcResource, resourceMappings); err != nil { + if err = r.processSecurityPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { r.log.Error(err, fmt.Sprintf("failed processSecurityPolicies for gatewayClass %s, skipping it", managedGC.Name)) continue } @@ -271,7 +281,7 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques if r.bTLSPolicyCRDExists { // Add all BackendTLSPolies to the resourceTree - if err = r.processBackendTLSPolicies(ctx, gwcResource, resourceMappings); err != nil { + if err = r.processBackendTLSPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { r.log.Error(err, fmt.Sprintf("failed processBackendTLSPolicies for gatewayClass %s, skipping it", managedGC.Name)) continue } @@ -279,7 +289,7 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques if r.eepCRDExists { // Add all EnvoyExtensionPolicies and their referenced resources to the resourceTree - if err = r.processEnvoyExtensionPolicies(ctx, gwcResource, resourceMappings); err != nil { + if err = r.processEnvoyExtensionPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { r.log.Error(err, fmt.Sprintf("failed processEnvoyExtensionPolicies for gatewayClass %s, skipping it", managedGC.Name)) continue } @@ -300,11 +310,11 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques // Add the referenced services, ServiceImports, and EndpointSlices in // the collected BackendRefs to the resourceTree. // BackendRefs are referred by various Route objects and the ExtAuth in SecurityPolicies. - r.processBackendRefs(ctx, gwcResource, resourceMappings) + r.processBackendRefs(ctx, gwcResource, gwcResourceMapping) // For this particular Gateway, and all associated objects, check whether the // namespace exists. Add to the resourceTree. - for ns := range resourceMappings.allAssociatedNamespaces { + for ns := range gwcResourceMapping.allAssociatedNamespaces { namespace, err := r.getNamespace(ctx, ns) if err != nil { r.log.Error(err, "unable to find the namespace") @@ -1243,8 +1253,6 @@ func (r *gatewayAPIReconciler) processSecurityPolicies( // Add the referenced Resources in SecurityPolicies to the resourceTree r.processSecurityPolicyObjectRefs(ctx, resourceTree, resourceMap) - // Add the OIDC HMAC Secret to the resourceTree - r.processOIDCHMACSecret(ctx, resourceTree, resourceMap) return nil } @@ -2014,7 +2022,7 @@ func (r *gatewayAPIReconciler) processGatewayClassParamsRef(ctx context.Context, // Check for incompatible configuration: both MergeGateways and GatewayNamespaceMode enabled if r.gatewayNamespaceMode && ep.Spec.MergeGateways != nil && *ep.Spec.MergeGateways { - return fmt.Errorf("using Merged Gateways with Gateway Namespace Mode is not supported.") + return errors.New("using Merged Gateways with Gateway Namespace Mode is not supported") } if err := r.processEnvoyProxy(ep, resourceMap); err != nil { diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go index 86eba77554..f01716ed63 100644 --- a/internal/provider/kubernetes/controller_test.go +++ b/internal/provider/kubernetes/controller_test.go @@ -281,7 +281,7 @@ func TestProcessGatewayClassParamsRef(t *testing.T) { }, gatewayNamespaceMode: true, expected: false, - expectedError: "using Merged Gateways with Gateway Namespace Mode is not supported.", + expectedError: "using Merged Gateways with Gateway Namespace Mode is not supported", }, { name: "valid merged gateways enabled configuration", From ff2c6387d75bb24ff4416305a9ab8f90b2b0743b Mon Sep 17 00:00:00 2001 From: shawnh2 Date: Wed, 2 Jul 2025 22:49:06 +0800 Subject: [PATCH 11/16] fix testdata Signed-off-by: shawnh2 --- .../testdata/envoyproxy-tracing-backend-uds.out.yaml | 11 ----------- ...ypolicy-invalid-no-section-name-listener.out.yaml | 12 ------------ 2 files changed, 23 deletions(-) diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml index b797b32849..31f27d30c1 100644 --- a/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml @@ -169,9 +169,6 @@ infraIR: 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: @@ -201,10 +198,6 @@ xdsIR: port: 19003 tracing: destination: - metadata: - kind: EnvoyProxy - name: test - namespace: envoy-gateway-system name: tracing settings: - addressType: IP @@ -212,10 +205,6 @@ xdsIR: - host: "" path: /var/run/envoy-uds/dsd.socket port: 0 - metadata: - kind: Backend - name: datadog-svc - namespace: envoy-gateway-system name: tracing/backend/-1 protocol: TCP provider: diff --git a/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml b/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml index 3f896cfafc..360a4d936d 100644 --- a/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml @@ -94,9 +94,6 @@ infraIR: 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 securityPolicies: @@ -122,7 +119,6 @@ securityPolicies: kind: Gateway name: gateway-1 namespace: envoy-gateway - sectionName: not-found-section-name conditions: - lastTransitionTime: null message: No section name not-found-section-name found for Gateway envoy-gateway/gateway-1 @@ -152,20 +148,12 @@ xdsIR: port: 10080 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: - name: service-1 - namespace: default - sectionName: "8080" name: httproute/default/httproute-1/rule/0/backend/0 protocol: HTTP weight: 1 From 3614e78fbb5a20dc35300daf0aa96af589d6b6ee Mon Sep 17 00:00:00 2001 From: shawnh2 Date: Wed, 2 Jul 2025 22:53:05 +0800 Subject: [PATCH 12/16] fix k8s provider controller Signed-off-by: shawnh2 --- internal/provider/kubernetes/controller.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 550d1f5f5c..ed40f0f56b 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -238,8 +238,6 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques // process global resources // add the OIDC HMAC Secret to the resourceTree r.processOIDCHMACSecret(ctx, gwcResource, gwcResourceMapping) - // add the Envoy TLS Secret to the resourceTree - r.processEnvoyTLSSecret(ctx, gwcResource, gwcResourceMapping) // Add all Gateways, their associated Routes, and referenced resources to the resourceTree if err = r.processGateways(ctx, managedGC, gwcResourceMapping, gwcResource); err != nil { From 58b90a9414b5a9854d32db5c4bb13c2700a4be5e Mon Sep 17 00:00:00 2001 From: Patryk Rostkowski <48490105+patrostkowski@users.noreply.github.com> Date: Thu, 3 Jul 2025 19:20:29 +0200 Subject: [PATCH 13/16] fix: retry reconcile on transient errors during reconcile (#6299) * fix: add isTransientError helper to classify retryable errors Introduces isTransientError to detect transient Kubernetes errors and enable proper reconciliation retries. Signed-off-by: Patryk Rostkowski handle errors from processing BackendRefs Signed-off-by: Huabing (Robin) Zhao handle errors from processing ConfigMap Signed-off-by: Huabing (Robin) Zhao * skip invalid GatewayClass Signed-off-by: Huabing (Robin) Zhao * address comment Signed-off-by: Huabing (Robin) Zhao * handle all transient errors Signed-off-by: Huabing (Robin) Zhao * don't skip failed GCs Signed-off-by: Huabing (Robin) Zhao --------- Signed-off-by: Patryk Rostkowski Signed-off-by: Huabing (Robin) Zhao Co-authored-by: Huabing (Robin) Zhao (cherry picked from commit 71ce56fa06778d668d9c8b0524571ad766c4e79f) Signed-off-by: Huabing (Robin) Zhao --- internal/provider/kubernetes/controller.go | 292 +++++++++++++----- .../provider/kubernetes/controller_test.go | 32 ++ 2 files changed, 247 insertions(+), 77 deletions(-) diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index ed40f0f56b..336f781d29 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -180,6 +180,16 @@ func byNamespaceSelectorEnabled(eg *egv1a1.EnvoyGateway) bool { } } +func isTransientError(err error) bool { + return kerrors.IsServerTimeout(err) || + kerrors.IsTimeout(err) || + kerrors.IsTooManyRequests(err) || + kerrors.IsServiceUnavailable(err) || + kerrors.IsStoreReadError(err) || + kerrors.IsInternalError(err) || + kerrors.IsUnexpectedServerError(err) +} + // Reconcile handles reconciling all resources in a single call. Any resource event should enqueue the // same reconcile.Request containing the gateway controller name. This allows multiple resource updates to // be handled by a single call to Reconcile. The reconcile.Request DOES NOT map to a specific resource. @@ -220,8 +230,14 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques // Process the parametersRef of the accepted GatewayClass. // This should run before processGateways and processBackendRefs + failToProcessGCParamsRef := false if managedGC.Spec.ParametersRef != nil && managedGC.DeletionTimestamp == nil { if err := r.processGatewayClassParamsRef(ctx, managedGC, gwcResourceMapping, gwcResource); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing GatewayClass parametersRef", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } + r.log.Error(err, fmt.Sprintf("failed processGatewayClassParamsRef for gatewayClass %s, skipping it", managedGC.Name)) msg := fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err) gc := status.SetGatewayClassAccepted( @@ -230,91 +246,163 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques string(gwapiv1.GatewayClassReasonInvalidParameters), msg) r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status) - continue + failToProcessGCParamsRef = true + } + } + + // process envoy gateway secret refs + if err := r.processEnvoyProxySecretRef(ctx, gwcResource); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing TLS SecretRef for EnvoyProxy", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err } + + r.log.Error(err, fmt.Sprintf("failed process TLS SecretRef for EnvoyProxy for gatewayClass %s, skipping it", managedGC.Name)) + gc := status.SetGatewayClassAccepted( + managedGC.DeepCopy(), + false, + string(gwapiv1.GatewayClassReasonAccepted), + fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err)) + r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status) + failToProcessGCParamsRef = true + } + + if !failToProcessGCParamsRef { + // GatewayClass is valid so far, mark it as accepted. + gc := status.SetGatewayClassAccepted( + managedGC.DeepCopy(), + true, + string(gwapiv1.GatewayClassReasonAccepted), + status.MsgValidGatewayClass) + r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status) } + // it's safe here to append gwcResource to gwcResources gwcResources = append(gwcResources, gwcResource) // process global resources // add the OIDC HMAC Secret to the resourceTree - r.processOIDCHMACSecret(ctx, gwcResource, gwcResourceMapping) + if err = r.processOIDCHMACSecret(ctx, gwcResource, gwcResourceMapping); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing OIDC HMAC Secret", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } + r.log.Error(err, fmt.Sprintf("failed processOIDCHMACSecret for gatewayClass %s, skipping it", managedGC.Name)) + } // Add all Gateways, their associated Routes, and referenced resources to the resourceTree if err = r.processGateways(ctx, managedGC, gwcResourceMapping, gwcResource); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing gateways", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processGateways for gatewayClass %s, skipping it", managedGC.Name)) - continue } if r.eppCRDExists { // Add all EnvoyPatchPolicies to the resourceTree if err = r.processEnvoyPatchPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing EnvoyPatchPolicies", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processEnvoyPatchPolicies for gatewayClass %s, skipping it", managedGC.Name)) - continue } } if r.ctpCRDExists { // Add all ClientTrafficPolicies and their referenced resources to the resourceTree if err = r.processClientTrafficPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing ClientTrafficPolicies", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processClientTrafficPolicies for gatewayClass %s, skipping it", managedGC.Name)) - continue } } if r.btpCRDExists { // Add all BackendTrafficPolicies to the resourceTree if err = r.processBackendTrafficPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing BackendTrafficPolicies", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processBackendTrafficPolicies for gatewayClass %s, skipping it", managedGC.Name)) - continue } } if r.spCRDExists { // Add all SecurityPolicies and their referenced resources to the resourceTree if err = r.processSecurityPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing SecurityPolicies", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processSecurityPolicies for gatewayClass %s, skipping it", managedGC.Name)) - continue } } if r.bTLSPolicyCRDExists { // Add all BackendTLSPolies to the resourceTree if err = r.processBackendTLSPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing BackendTLSPolicies", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processBackendTLSPolicies for gatewayClass %s, skipping it", managedGC.Name)) - continue } } if r.eepCRDExists { // Add all EnvoyExtensionPolicies and their referenced resources to the resourceTree if err = r.processEnvoyExtensionPolicies(ctx, gwcResource, gwcResourceMapping); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing EnvoyExtensionPolicies", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processEnvoyExtensionPolicies for gatewayClass %s, skipping it", managedGC.Name)) - continue } } if err = r.processExtensionServerPolicies(ctx, gwcResource); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing ExtensionServerPolicies", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processExtensionServerPolicies for gatewayClass %s, skipping it", managedGC.Name)) - continue } if r.backendCRDExists { if err = r.processBackends(ctx, gwcResource); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing Backends", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed processBackends for gatewayClass %s, skipping it", managedGC.Name)) - continue } } // Add the referenced services, ServiceImports, and EndpointSlices in // the collected BackendRefs to the resourceTree. // BackendRefs are referred by various Route objects and the ExtAuth in SecurityPolicies. - r.processBackendRefs(ctx, gwcResource, gwcResourceMapping) + if err = r.processBackendRefs(ctx, gwcResource, gwcResourceMapping); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error processing BackendRefs", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } + + r.log.Error(err, fmt.Sprintf("failed processBackendRefs for gatewayClass %s, skipping it", managedGC.Name)) + } // For this particular Gateway, and all associated objects, check whether the // namespace exists. Add to the resourceTree. for ns := range gwcResourceMapping.allAssociatedNamespaces { namespace, err := r.getNamespace(ctx, ns) if err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error getting namespace", "namespace", ns, "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, "unable to find the namespace") if kerrors.IsNotFound(err) { continue @@ -333,30 +421,27 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques } } - // process envoy gateway secret refs - r.processEnvoyProxySecretRef(ctx, gwcResource) - gc := status.SetGatewayClassAccepted( - managedGC.DeepCopy(), - true, - string(gwapiv1.GatewayClassReasonAccepted), - status.MsgValidGatewayClass) - r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status) - if len(gwcResource.Gateways) == 0 { r.log.Info("No gateways found for accepted gatewayClass") // If needed, remove the finalizer from the accepted GatewayClass. if err := r.removeFinalizer(ctx, managedGC); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error removing finalizer from gatewayClass", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed to remove finalizer from gatewayClass %s", managedGC.Name)) - continue } } else { // finalize the accepted GatewayClass. if err := r.addFinalizer(ctx, managedGC); err != nil { + if isTransientError(err) { + r.log.Error(err, "transient error adding finalizer to gatewayClass", "gatewayClass", managedGC.Name) + return reconcile.Result{}, err + } r.log.Error(err, fmt.Sprintf("failed adding finalizer to gatewayClass %s", managedGC.Name)) - continue } } } @@ -371,9 +456,9 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques return reconcile.Result{}, nil } -func (r *gatewayAPIReconciler) processEnvoyProxySecretRef(ctx context.Context, gwcResource *resource.Resources) { +func (r *gatewayAPIReconciler) processEnvoyProxySecretRef(ctx context.Context, gwcResource *resource.Resources) error { if gwcResource.EnvoyProxyForGatewayClass == nil || gwcResource.EnvoyProxyForGatewayClass.Spec.BackendTLS == nil || gwcResource.EnvoyProxyForGatewayClass.Spec.BackendTLS.ClientCertificateRef == nil { - return + return nil } certRef := gwcResource.EnvoyProxyForGatewayClass.Spec.BackendTLS.ClientCertificateRef if refsSecret(certRef) { @@ -385,11 +470,10 @@ func (r *gatewayAPIReconciler) processEnvoyProxySecretRef(ctx context.Context, g gwcResource.EnvoyProxyForGatewayClass.Namespace, resource.KindEnvoyProxy, *certRef); err != nil { - r.log.Error(err, - "failed to process TLS SecretRef for EnvoyProxy", - "gateway", "issue", "secretRef", certRef) + return err } } + return nil } // managedGatewayClasses returns a list of GatewayClass objects that are managed by the Envoy Gateway Controller. @@ -425,7 +509,11 @@ func (r *gatewayAPIReconciler) managedGatewayClasses(ctx context.Context) ([]*gw // - EndpointSlices // - Backends // - CACertificateRefs in the Backends -func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResource *resource.Resources, resourceMappings *resourceMappings) { +func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResource *resource.Resources, resourceMappings *resourceMappings) error { + // Only transient errors are returned from this function to allow Reconcile to retry. + // All other errors are just logged and ignored - these errors result in missing referenced backend resources + // in the resource tree, which is acceptable as the Gateway API translation layer will handle them. + // The Gateway API translation layer will surface these errors in the status of the resources referencing them. for backendRef := range resourceMappings.allAssociatedBackendRefs { backendRefKind := gatewayapi.KindDerefOr(backendRef.Kind, resource.KindService) r.log.Info("processing Backend", "kind", backendRefKind, "namespace", string(*backendRef.Namespace), @@ -437,6 +525,9 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour service := new(corev1.Service) err := r.client.Get(ctx, types.NamespacedName{Namespace: string(*backendRef.Namespace), Name: string(backendRef.Name)}, service) if err != nil { + if isTransientError(err) { + return err + } r.log.Error(err, "failed to get Service", "namespace", string(*backendRef.Namespace), "name", string(backendRef.Name)) } else { @@ -451,6 +542,9 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour serviceImport := new(mcsapiv1a1.ServiceImport) err := r.client.Get(ctx, types.NamespacedName{Namespace: string(*backendRef.Namespace), Name: string(backendRef.Name)}, serviceImport) if err != nil { + if isTransientError(err) { + return err + } r.log.Error(err, "failed to get ServiceImport", "namespace", string(*backendRef.Namespace), "name", string(backendRef.Name)) } else { @@ -469,6 +563,9 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour backend := new(egv1a1.Backend) err := r.client.Get(ctx, types.NamespacedName{Namespace: string(*backendRef.Namespace), Name: string(backendRef.Name)}, backend) if err != nil { + if isTransientError(err) { + return err + } r.log.Error(err, "failed to get Backend", "namespace", string(*backendRef.Namespace), "name", string(backendRef.Name)) } else { @@ -517,6 +614,10 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour caRefNew) } if err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process CACertificateRef for Backend", "backend", backend, "caCertificateRef", caCertRef.Name) @@ -536,6 +637,9 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour client.InNamespace(*backendRef.Namespace), } if err := r.client.List(ctx, endpointSliceList, opts...); err != nil { + if isTransientError(err) { + return err + } r.log.Error(err, "failed to get EndpointSlices", "namespace", string(*backendRef.Namespace), backendRefKind, string(backendRef.Name)) } else { @@ -552,6 +656,7 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour } } } + return nil } // processSecurityPolicyObjectRefs adds the referenced resources in SecurityPolicies @@ -560,7 +665,7 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour // - BackendRefs for ExAuth func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings, -) { +) error { // we don't return errors from this method, because we want to continue reconciling // the rest of the SecurityPolicies despite that one reference is invalid. This // allows Envoy Gateway to continue serving traffic even if some SecurityPolicies @@ -581,6 +686,10 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( policy.Namespace, policy.Name, oidc.ClientSecret); err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process OIDC SecretRef for SecurityPolicy", "policy", policy, "secretRef", oidc.ClientSecret) @@ -599,6 +708,10 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( policy.Namespace, policy.Name, credRef); err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process APIKeyAuth SecretRef for SecurityPolicy", "policy", policy, "secretRef", apiKeyAuth.CredentialRefs) @@ -617,6 +730,10 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( policy.Namespace, policy.Name, basicAuth.Users); err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process BasicAuth SecretRef for SecurityPolicy", "policy", policy, "secretRef", basicAuth.Users) @@ -677,6 +794,10 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( Kind: &provider.LocalJWKS.ValueRef.Kind, Name: provider.LocalJWKS.ValueRef.Name, }); err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process LocalJWKS ConfigMap", "policy", policy, "localJWKS", provider.LocalJWKS) } } else if provider.RemoteJWKS != nil { @@ -689,6 +810,10 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( policy.Namespace, policy.Name, br.BackendObjectReference); err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process RemoteJWKS BackendRef for SecurityPolicy", "policy", policy, "backendRef", br.BackendObjectReference) @@ -698,6 +823,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( } } } + return nil } // processBackendRef adds the referenced BackendRef to the resourceMap for later processBackendRefs. @@ -754,25 +880,16 @@ func (r *gatewayAPIReconciler) processBackendRef( // processOIDCHMACSecret adds the OIDC HMAC Secret to the resourceTree. // The OIDC HMAC Secret is created by the CertGen job and is used by SecurityPolicy // to configure OAuth2 filters. -func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings) { +func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings) error { var ( secret corev1.Secret err error ) - err = r.client.Get(ctx, + if err = r.client.Get(ctx, types.NamespacedName{Namespace: r.namespace, Name: oidcHMACSecretName}, - &secret, - ) - // We don't return an error here, because we want to continue reconciling - // despite that the OIDC HMAC secret can't be found. - // If the OIDC HMAC Secret is missing, the SecurityPolicy with OIDC will be - // marked as invalid in its status when translating to IR. - if err != nil { - r.log.Error(err, - "failed to process OIDC HMAC Secret", - "namespace", r.namespace, "name", oidcHMACSecretName) - return + &secret); err != nil { + return err } key := utils.NamespacedName(&secret).String() @@ -781,6 +898,7 @@ func (r *gatewayAPIReconciler) processOIDCHMACSecret(ctx context.Context, resour resourceTree.Secrets = append(resourceTree.Secrets, &secret) r.log.Info("processing OIDC HMAC Secret", "namespace", r.namespace, "name", oidcHMACSecretName) } + return nil } // processSecretRef adds the referenced Secret to the resourceTree if it's valid. @@ -797,12 +915,10 @@ func (r *gatewayAPIReconciler) processSecretRef( ) error { secret := new(corev1.Secret) secretNS := gatewayapi.NamespaceDerefOr(secretRef.Namespace, ownerNS) - err := r.client.Get(ctx, + if err := r.client.Get(ctx, types.NamespacedName{Namespace: secretNS, Name: string(secretRef.Name)}, - secret, - ) - if err != nil && kerrors.IsNotFound(err) { - return fmt.Errorf("unable to find the Secret: %s/%s", secretNS, string(secretRef.Name)) + secret); err != nil { + return err } if secretNS != ownerNS { @@ -848,7 +964,7 @@ func (r *gatewayAPIReconciler) processSecretRef( // to the resourceTree func (r *gatewayAPIReconciler) processCtpConfigMapRefs( ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings, -) { +) error { for _, policy := range resourceTree.ClientTrafficPolicies { tls := policy.Spec.TLS @@ -863,6 +979,10 @@ func (r *gatewayAPIReconciler) processCtpConfigMapRefs( policy.Namespace, policy.Name, caCertRef); err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } // we don't return an error here, because we want to continue // reconciling the rest of the ClientTrafficPolicies despite that this // reference is invalid. @@ -882,6 +1002,9 @@ func (r *gatewayAPIReconciler) processCtpConfigMapRefs( policy.Namespace, policy.Name, caCertRef); err != nil { + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process CACertificateRef for ClientTrafficPolicy", "policy", policy, "caCertificateRef", caCertRef.Name) @@ -890,6 +1013,7 @@ func (r *gatewayAPIReconciler) processCtpConfigMapRefs( } } } + return nil } // processConfigMapRef adds the referenced ConfigMap to the resourceTree if it's valid. @@ -906,12 +1030,10 @@ func (r *gatewayAPIReconciler) processConfigMapRef( ) error { configMap := new(corev1.ConfigMap) configMapNS := gatewayapi.NamespaceDerefOr(configMapRef.Namespace, ownerNS) - err := r.client.Get(ctx, + if err := r.client.Get(ctx, types.NamespacedName{Namespace: configMapNS, Name: string(configMapRef.Name)}, - configMap, - ) - if err != nil && kerrors.IsNotFound(err) { - return fmt.Errorf("unable to find the ConfigMap: %s/%s", configMapNS, string(configMapRef.Name)) + configMap); err != nil { + return err } if configMapNS != ownerNS { @@ -956,7 +1078,7 @@ func (r *gatewayAPIReconciler) processConfigMapRef( // to the resourceTree func (r *gatewayAPIReconciler) processBtpConfigMapRefs( ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings, -) { +) error { for _, policy := range resourceTree.BackendTrafficPolicies { for _, ro := range policy.Spec.ResponseOverride { if ro.Response.Body != nil && ro.Response.Body.ValueRef != nil && string(ro.Response.Body.ValueRef.Kind) == resource.KindConfigMap { @@ -972,6 +1094,10 @@ func (r *gatewayAPIReconciler) processBtpConfigMapRefs( // when translating to IR because the referenced configmap can't be // found. if err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process ResponseOverride ValueRef for BackendTrafficPolicy", "policy", policy, "ValueRef", ro.Response.Body.ValueRef.Name) @@ -986,13 +1112,13 @@ func (r *gatewayAPIReconciler) processBtpConfigMapRefs( } } } + return nil } func (r *gatewayAPIReconciler) getNamespace(ctx context.Context, name string) (*corev1.Namespace, error) { nsKey := types.NamespacedName{Name: name} ns := new(corev1.Namespace) if err := r.client.Get(ctx, nsKey, ns); err != nil { - r.log.Error(err, "unable to get Namespace") return nil, err } return ns, nil @@ -1071,6 +1197,10 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g gtw := gtw //nolint:copyloopvar if r.namespaceLabel != nil { if ok, err := r.checkObjectNamespaceLabels(>w); err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } r.log.Error(err, "failed to check namespace labels for gateway %s in namespace %s: %w", gtw.GetName(), gtw.GetNamespace()) continue } else if !ok { @@ -1094,6 +1224,9 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g gtw.Namespace, gtw.Name, certRef); err != nil { + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process TLS SecretRef for gateway", "gateway", gtw, "secretRef", certRef) @@ -1144,6 +1277,10 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g gtw.Status = gwapiv1.GatewayStatus{} if err := r.processGatewayParamsRef(ctx, >w, resourceMap, resourceTree); err != nil { + // If the error is transient, we return it to allow Reconcile to retry. + if isTransientError(err) { + return err + } // Update the Gateway status to not accepted if there is an error processing the parametersRef. // These not-accepted gateways will not be processed by the gateway-api layer, but their status will be // updated in the gateway-api layer along with other gateways. This is to avoid the potential race condition @@ -1201,9 +1338,7 @@ func (r *gatewayAPIReconciler) processClientTrafficPolicies( } } - r.processCtpConfigMapRefs(ctx, resourceTree, resourceMap) - - return nil + return r.processCtpConfigMapRefs(ctx, resourceTree, resourceMap) } // processBackendTrafficPolicies adds BackendTrafficPolicies to the resourceTree @@ -1224,8 +1359,7 @@ func (r *gatewayAPIReconciler) processBackendTrafficPolicies(ctx context.Context resourceTree.BackendTrafficPolicies = append(resourceTree.BackendTrafficPolicies, &backendTrafficPolicy) } } - r.processBtpConfigMapRefs(ctx, resourceTree, resourceMap) - return nil + return r.processBtpConfigMapRefs(ctx, resourceTree, resourceMap) } // processSecurityPolicies adds SecurityPolicies and their referenced resources to the resourceTree @@ -1249,9 +1383,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicies( } // Add the referenced Resources in SecurityPolicies to the resourceTree - r.processSecurityPolicyObjectRefs(ctx, resourceTree, resourceMap) - - return nil + return r.processSecurityPolicyObjectRefs(ctx, resourceTree, resourceMap) } // processBackendTLSPolicies adds BackendTLSPolicies and their referenced resources to the resourceTree @@ -1275,8 +1407,7 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicies( } // Add the referenced Secrets and ConfigMaps in BackendTLSPolicies to the resourceTree. - r.processBackendTLSPolicyRefs(ctx, resourceTree, resourceMap) - return nil + return r.processBackendTLSPolicyRefs(ctx, resourceTree, resourceMap) } // processBackends adds Backends to the resourceTree @@ -1993,9 +2124,7 @@ func (r *gatewayAPIReconciler) processGatewayParamsRef(ctx context.Context, gtw gtw.Namespace, gtw.Name, *certRef); err != nil { - r.log.Error(err, - "failed to process TLS SecretRef for gateway", - "gateway", utils.NamespacedName(gtw).String(), "secretRef", certRef) + return fmt.Errorf("failed to process TLS SecretRef for gateway %s/%s: %w", gtw.Namespace, gtw.Name, err) } } } @@ -2012,9 +2141,6 @@ func (r *gatewayAPIReconciler) processGatewayClassParamsRef(ctx context.Context, ep := new(egv1a1.EnvoyProxy) if err := r.client.Get(ctx, types.NamespacedName{Namespace: string(*gc.Spec.ParametersRef.Namespace), Name: gc.Spec.ParametersRef.Name}, ep); err != nil { - if kerrors.IsNotFound(err) { - return fmt.Errorf("envoyproxy referenced by gatewayclass is not found: %w", err) - } return fmt.Errorf("failed to find envoyproxy %s/%s: %w", r.namespace, gc.Spec.ParametersRef.Name, err) } @@ -2118,7 +2244,7 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicyRefs( ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings, -) { +) error { for _, policy := range resourceTree.BackendTLSPolicies { tls := policy.Spec.Validation @@ -2157,6 +2283,10 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicyRefs( caRefNew) } if err != nil { + // if the error is transient, we return it to retry later + if isTransientError(err) { + return err + } // we don't return an error here, because we want to continue // reconciling the rest of the ClientTrafficPolicies despite that this // reference is invalid. @@ -2171,6 +2301,7 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicyRefs( } } } + return nil } // processEnvoyExtensionPolicies adds EnvoyExtensionPolicies and their referenced resources to the resourceTree @@ -2195,9 +2326,7 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicies( } // Add the referenced Resources in EnvoyExtensionPolicies to the resourceTree - r.processEnvoyExtensionPolicyObjectRefs(ctx, resourceTree, resourceMap) - - return nil + return r.processEnvoyExtensionPolicyObjectRefs(ctx, resourceTree, resourceMap) } // processExtensionServerPolicies adds directly attached policies intended for the extension server @@ -2240,7 +2369,7 @@ func (r *gatewayAPIReconciler) processExtensionServerPolicies( // - ValueRefs for Luas func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs( ctx context.Context, resourceTree *resource.Resources, resourceMap *resourceMappings, -) { +) error { // we don't return errors from this method, because we want to continue reconciling // the rest of the EnvoyExtensionPolicies despite that one reference is invalid. This // allows Envoy Gateway to continue serving traffic even if some EnvoyExtensionPolicies @@ -2278,6 +2407,10 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs( policy.Namespace, policy.Name, *wasm.Code.Image.PullSecretRef); err != nil { + // If the error is transient, we return it to retry later + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process Wasm Image PullSecretRef for EnvoyExtensionPolicy", "policy", policy, "secretRef", wasm.Code.Image.PullSecretRef) @@ -2295,6 +2428,10 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs( configMap, ) if err != nil { + // If the error is transient, we return it to retry later + if isTransientError(err) { + return err + } r.log.Error(err, "failed to process Lua ValueRef for EnvoyExtensionPolicy", "policy", policy, "ValueRef", lua.ValueRef.Name) @@ -2310,4 +2447,5 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs( } } } + return nil } diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go index f01716ed63..a8b33af98a 100644 --- a/internal/provider/kubernetes/controller_test.go +++ b/internal/provider/kubernetes/controller_test.go @@ -7,11 +7,14 @@ package kubernetes import ( "context" + "fmt" "os" "testing" "github.com/stretchr/testify/require" + kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" @@ -1022,3 +1025,32 @@ func setupReferenceGrantReconciler(objs []client.Object) *gatewayAPIReconciler { Build() return r } + +func TestIsTransientError(t *testing.T) { + serverTimeoutErr := kerrors.NewServerTimeout( + schema.GroupResource{Group: "core", Resource: "pods"}, "list", 10) + timeoutErr := kerrors.NewTimeoutError("request timeout", 1) + wrappedTooManyRequestsErr := fmt.Errorf("wrapping: %w", kerrors.NewTooManyRequests("too many requests", 1)) + serviceUnavailableErr := kerrors.NewServiceUnavailable("service unavailable") + badRequestErr := kerrors.NewBadRequest("bad request") + + testCases := []struct { + name string + err error + expected bool + }{ + {"ServerTimeout", serverTimeoutErr, true}, + {"Timeout", timeoutErr, true}, + {"TooManyRequests", wrappedTooManyRequestsErr, true}, + {"ServiceUnavailable", serviceUnavailableErr, true}, + {"BadRequest", badRequestErr, false}, + {"NilError", nil, false}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual := isTransientError(tc.err) + require.Equal(t, tc.expected, actual) + }) + } +} From bcc8384eae19dbce2846b14c02743c20aade2d1b Mon Sep 17 00:00:00 2001 From: Rudrakh Panigrahi Date: Thu, 19 Jun 2025 02:29:48 +0530 Subject: [PATCH 14/16] fix: fix bug in hostname overlap detection (#6332) fix bug in hostname overlap detection Signed-off-by: Rudrakh Panigrahi (cherry picked from commit e78e2684d7b57526344f5f420be3dac78cbb2c15) Signed-off-by: Huabing (Robin) Zhao --- internal/gatewayapi/listener.go | 13 ++++++++++--- internal/gatewayapi/listener_test.go | 6 ++++++ release-notes/current.yaml | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index cd0083a6c3..16bd9c0c4a 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -408,10 +408,17 @@ func isOverlappingHostname(hostname1, hostname2 *gwapiv1.Hostname) bool { if hostname1 == nil || hostname2 == nil { return true } + domain1 := strings.Replace(string(*hostname1), "*.", "", 1) + domain2 := strings.Replace(string(*hostname2), "*.", "", 1) + return isSubdomain(domain1, domain2) || isSubdomain(domain2, domain1) +} - h1 := strings.Replace(string(*hostname1), "*.", "", 1) - h2 := strings.Replace(string(*hostname2), "*.", "", 1) - return strings.HasSuffix(h1, h2) || strings.HasSuffix(h2, h1) +// isSubdomain checks if subDomain is a sub-domain of domain +func isSubdomain(subDomain, domain string) bool { + if subDomain == domain { + return true + } + return strings.HasSuffix(subDomain, fmt.Sprintf(".%s", domain)) } func buildListenerMetadata(listener *ListenerContext, gateway *GatewayContext) *ir.ResourceMetadata { diff --git a/internal/gatewayapi/listener_test.go b/internal/gatewayapi/listener_test.go index 9c16fa6500..293ded7f1b 100644 --- a/internal/gatewayapi/listener_test.go +++ b/internal/gatewayapi/listener_test.go @@ -174,6 +174,12 @@ func TestIsOverlappingHostname(t *testing.T) { hostname2: ptr.To(gwapiv1.Hostname("*.test.com")), want: false, }, + { + name: "different sub domains of same domain", + hostname1: ptr.To(gwapiv1.Hostname("api.foo.dev")), + hostname2: ptr.To(gwapiv1.Hostname("testing-api.foo.dev")), + want: false, + }, } for _, tt := range tests { diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 0ea5220e82..985f724141 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -25,7 +25,7 @@ bug fixes: | Fixed validation issue where EnvoyExtensionPolicy ExtProc failOpen is true, and body processing mode FullDuplexStreamed is not rejected. Add ConfigMap indexers for EnvoyExtensionPolicies to reconcile Lua changes Fixed issue that default accesslog format not working. - + Fixed bug in certificate SANs overlap detection in listeners. # Enhancements that improve performance. performance improvements: | From f7e6478bddcc1a627b95cb692dd452b3fd35d9f8 Mon Sep 17 00:00:00 2001 From: zirain Date: Fri, 4 Jul 2025 01:18:33 +0800 Subject: [PATCH 15/16] fix telemetry with host port not working (#6460) Signed-off-by: zirain (cherry picked from commit c0a2ce710758974e1bcb5524f1086b50176307e2) Signed-off-by: Huabing (Robin) Zhao --- internal/gatewayapi/listener.go | 26 ++++++++++++------- .../envoyproxy-accesslog-cel.out.yaml | 3 ++- .../envoyproxy-accesslog-types.out.yaml | 9 ++++--- ...envoyproxy-accesslog-with-traffic.out.yaml | 3 ++- ...voyproxy-accesslog-without-format.out.yaml | 3 ++- .../testdata/envoyproxy-accesslog.out.yaml | 3 ++- ...with-infrastructure-parametersref.out.yaml | 3 ++- ...astructure-parametersref-fallback.out.yaml | 3 ++- .../tracing-merged-multiple-routes.out.yaml | 3 ++- .../testdata/tracing-multiple-routes.out.yaml | 6 +++-- .../tracing-sampling-fraction.out.yaml | 3 ++- 11 files changed, 43 insertions(+), 22 deletions(-) diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index 16bd9c0c4a..1c3da9aa37 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "math" + "net" "strings" "github.com/google/cel-go/cel" @@ -24,7 +25,7 @@ import ( "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/utils" "github.com/envoyproxy/gateway/internal/utils/naming" - "github.com/envoyproxy/gateway/internal/utils/net" + netutils "github.com/envoyproxy/gateway/internal/utils/net" "github.com/envoyproxy/gateway/internal/xds/bootstrap" ) @@ -105,10 +106,10 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR resource continue } - address := net.IPv4ListenerAddress + address := netutils.IPv4ListenerAddress ipFamily := getEnvoyIPFamily(gateway.envoyProxy) if ipFamily != nil && (*ipFamily == egv1a1.IPv6 || *ipFamily == egv1a1.DualStack) { - address = net.IPv6ListenerAddress + address = netutils.IPv6ListenerAddress } // Add the listener to the Xds IR @@ -434,14 +435,14 @@ func buildListenerMetadata(listener *ListenerContext, gateway *GatewayContext) * func (t *Translator) processProxyReadyListener(xdsIR *ir.Xds, envoyProxy *egv1a1.EnvoyProxy) { var ( ipFamily = egv1a1.IPv4 - address = net.IPv4ListenerAddress + address = netutils.IPv4ListenerAddress ) if envoyProxy != nil && envoyProxy.Spec.IPFamily != nil { ipFamily = *envoyProxy.Spec.IPFamily } if ipFamily == egv1a1.IPv6 || ipFamily == egv1a1.DualStack { - address = net.IPv6ListenerAddress + address = netutils.IPv6ListenerAddress } xdsIR.ReadyListener = &ir.ReadyListener{ @@ -832,12 +833,19 @@ func (t *Translator) processBackendRefs(name string, backendCluster egv1a1.Backe } func destinationSettingFromHostAndPort(name, host string, port uint32) []*ir.DestinationSetting { + // check if host is an IP address or a hostname + addressType := ir.FQDN + if net.ParseIP(host) != nil { + addressType = ir.IP + } + return []*ir.DestinationSetting{ { - Name: name, - Weight: ptr.To[uint32](1), - Protocol: ir.GRPC, - Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(host, port, false, nil)}, + Name: name, + Weight: ptr.To[uint32](1), + Protocol: ir.GRPC, + AddressType: ptr.To(addressType), + Endpoints: []*ir.DestinationEndpoint{ir.NewDestEndpoint(host, port, false, nil)}, }, } } diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-cel.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-cel.out.yaml index 5860d22d37..abd4bf1283 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-cel.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-cel.out.yaml @@ -163,7 +163,8 @@ xdsIR: destination: name: accesslog_otel_0_1 settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: accesslog_otel_0_1/backend/-1 diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-types.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-types.out.yaml index ee39fdc588..92f21c3131 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-types.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-types.out.yaml @@ -384,7 +384,8 @@ xdsIR: destination: name: accesslog_otel_2_3 settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: accesslog_otel_2_3/backend/-1 @@ -399,7 +400,8 @@ xdsIR: destination: name: accesslog_otel_3_3 settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: accesslog_otel_3_3/backend/-1 @@ -414,7 +416,8 @@ xdsIR: destination: name: accesslog_otel_4_3 settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: accesslog_otel_4_3/backend/-1 diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml index 6a4fc3fe26..313df92f55 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml @@ -274,7 +274,8 @@ xdsIR: destination: name: accesslog_otel_0_3 settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: accesslog_otel_0_3/backend/-1 diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml index 86183eb0b3..e97a04d42e 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml @@ -189,7 +189,8 @@ xdsIR: destination: name: accesslog_otel_0_3 settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: accesslog_otel_0_3/backend/-1 diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml index e249d572af..6120ff55cc 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog.out.yaml @@ -195,7 +195,8 @@ xdsIR: destination: name: accesslog_otel_0_3 settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: accesslog_otel_0_3/backend/-1 diff --git a/internal/gatewayapi/testdata/gateway-with-infrastructure-parametersref.out.yaml b/internal/gatewayapi/testdata/gateway-with-infrastructure-parametersref.out.yaml index 7baf8b12da..fd47572505 100644 --- a/internal/gatewayapi/testdata/gateway-with-infrastructure-parametersref.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-infrastructure-parametersref.out.yaml @@ -170,7 +170,8 @@ xdsIR: destination: name: tracing settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: tracing/backend/-1 diff --git a/internal/gatewayapi/testdata/gateway-with-invalid-infrastructure-parametersref-fallback.out.yaml b/internal/gatewayapi/testdata/gateway-with-invalid-infrastructure-parametersref-fallback.out.yaml index 65d151a0d4..dc57b692e9 100644 --- a/internal/gatewayapi/testdata/gateway-with-invalid-infrastructure-parametersref-fallback.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-invalid-infrastructure-parametersref-fallback.out.yaml @@ -170,7 +170,8 @@ xdsIR: destination: name: tracing settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: tracing/backend/-1 diff --git a/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml index afbe442fed..1cd07e0e0f 100644 --- a/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml +++ b/internal/gatewayapi/testdata/tracing-merged-multiple-routes.out.yaml @@ -327,7 +327,8 @@ xdsIR: destination: name: tracing settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: tracing/backend/-1 diff --git a/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml b/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml index be6b15a8ec..3247acec3b 100644 --- a/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml +++ b/internal/gatewayapi/testdata/tracing-multiple-routes.out.yaml @@ -303,7 +303,8 @@ xdsIR: destination: name: tracing settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: tracing/backend/-1 @@ -380,7 +381,8 @@ xdsIR: destination: name: tracing settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: tracing/backend/-1 diff --git a/internal/gatewayapi/testdata/tracing-sampling-fraction.out.yaml b/internal/gatewayapi/testdata/tracing-sampling-fraction.out.yaml index dfa0855b1e..935696fc89 100644 --- a/internal/gatewayapi/testdata/tracing-sampling-fraction.out.yaml +++ b/internal/gatewayapi/testdata/tracing-sampling-fraction.out.yaml @@ -329,7 +329,8 @@ xdsIR: destination: name: tracing settings: - - endpoints: + - addressType: FQDN + endpoints: - host: otel-collector.monitoring.svc.cluster.local port: 4317 name: tracing/backend/-1 From 17b2b009fd5f53e98fc79a5ad8acee5d454ecaf8 Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 17 Jun 2025 07:06:36 +0800 Subject: [PATCH 16/16] bugfix: BackendTlsPolicy should not reference across namespace (#6309) * bugfix: BackendTlsPolicy should not reference across namespace Signed-off-by: zirain (cherry picked from commit 9925189efe6107e7badc5bfb0e3940de42df6f1a) Signed-off-by: Huabing (Robin) Zhao --- internal/gatewayapi/backendtlspolicy.go | 46 ++++++++++--------- .../backendtlspolicy-ca-only-secret.in.yaml | 2 +- ...with-extproc-with-backendtlspolicy.in.yaml | 2 +- ...ith-extproc-with-backendtlspolicy.out.yaml | 43 +++++++++++------ ...-extproc-with-multiple-backendrefs.in.yaml | 2 +- ...with-extproc-with-traffic-features.in.yaml | 2 +- .../envoyproxy-priority-backend.in.yaml | 2 +- .../httproute-dynamic-resolver.in.yaml | 2 +- ...with-extauth-with-backendtlspolicy.in.yaml | 26 +++++++++++ release-notes/current.yaml | 1 + 10 files changed, 85 insertions(+), 43 deletions(-) diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go index dc5c86b0f1..0a69bc989f 100644 --- a/internal/gatewayapi/backendtlspolicy.go +++ b/internal/gatewayapi/backendtlspolicy.go @@ -78,7 +78,7 @@ func (t *Translator) processBackendTLSConfig( return tlsBundle, nil } - caCert, err := getCaCertsFromCARefs(backend.Spec.TLS.CACertificateRefs, resources) + caCert, err := getCaCertsFromCARefs(backend.Namespace, backend.Spec.TLS.CACertificateRefs, resources) if err != nil { return nil, err } @@ -234,7 +234,7 @@ func getBackendTLSBundle(backendTLSPolicy *gwapiv1a3.BackendTLSPolicy, resources return tlsBundle, nil } - caCert, err := getCaCertsFromCARefs(backendTLSPolicy.Spec.Validation.CACertificateRefs, resources) + caCert, err := getCaCertsFromCARefs(backendTLSPolicy.Namespace, backendTLSPolicy.Spec.Validation.CACertificateRefs, resources) if err != nil { return nil, err } @@ -245,43 +245,45 @@ func getBackendTLSBundle(backendTLSPolicy *gwapiv1a3.BackendTLSPolicy, resources return tlsBundle, nil } -func getCaCertsFromCARefs(caCertificates []gwapiv1.LocalObjectReference, resources *resource.Resources) ([]byte, error) { +func getCaCertsFromCARefs(namespace string, caCertificates []gwapiv1.LocalObjectReference, resources *resource.Resources) ([]byte, error) { ca := "" for _, caRef := range caCertificates { kind := string(caRef.Kind) switch kind { case resource.KindConfigMap: - for _, cmap := range resources.ConfigMaps { - if cmap.Name == string(caRef.Name) { - if crt, dataOk := cmap.Data["ca.crt"]; dataOk { - if ca != "" { - ca += "\n" - } - ca += crt - } else { - return nil, fmt.Errorf("no ca found in configmap %s", cmap.Name) + cm := resources.GetConfigMap(namespace, string(caRef.Name)) + if cm != nil { + if crt, dataOk := cm.Data[caCertKey]; dataOk { + if ca != "" { + ca += "\n" } + ca += crt + } else { + return nil, fmt.Errorf("no ca found in configmap %s", cm.Name) } + } else { + return nil, fmt.Errorf("configmap %s not found in namespace %s", caRef.Name, namespace) } case resource.KindSecret: - for _, secret := range resources.Secrets { - if secret.Name == string(caRef.Name) { - if crt, dataOk := secret.Data["ca.crt"]; dataOk { - if ca != "" { - ca += "\n" - } - ca += string(crt) - } else { - return nil, fmt.Errorf("no ca found in secret %s", secret.Name) + secret := resources.GetSecret(namespace, string(caRef.Name)) + if secret != nil { + if crt, dataOk := secret.Data[caCertKey]; dataOk { + if ca != "" { + ca += "\n" } + ca += string(crt) + } else { + return nil, fmt.Errorf("no ca found in secret %s", secret.Name) } + } else { + return nil, fmt.Errorf("secret %s not found in namespace %s", caRef.Name, namespace) } } } if ca == "" { - return nil, fmt.Errorf("no ca found in referred configmaps") + return nil, fmt.Errorf("no ca found in referred ConfigMap or Secret") } return []byte(ca), nil } diff --git a/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.in.yaml index fd4caad15e..b7a7e20a21 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.in.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-ca-only-secret.in.yaml @@ -94,7 +94,7 @@ secrets: kind: Secret metadata: name: ca-secret - namespace: policies + namespace: backends data: ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K backendTLSPolicies: diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml index c1ab243b13..c1aeda28d8 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.in.yaml @@ -127,7 +127,7 @@ configMaps: kind: ConfigMap metadata: name: ca-cmap - namespace: default + namespace: envoy-gateway data: ca.crt: | -----BEGIN CERTIFICATE----- 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 a5523f6cde..f0adb6c2c4 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-backendtlspolicy.out.yaml @@ -58,9 +58,9 @@ backendTLSPolicies: namespace: default conditions: - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" + message: Configmap ca-cmap not found in namespace default. + reason: Invalid + status: "False" type: Accepted controllerName: gateway.envoyproxy.io/gatewayclass-controller envoyExtensionPolicies: @@ -92,9 +92,9 @@ envoyExtensionPolicies: sectionName: http conditions: - lastTransitionTime: null - message: Policy has been accepted. - reason: Accepted - status: "True" + message: 'ExtProc: configmap ca-cmap not found in namespace default.' + reason: Invalid + status: "False" type: Accepted controllerName: gateway.envoyproxy.io/gatewayclass-controller - apiVersion: gateway.envoyproxy.io/v1alpha1 @@ -317,27 +317,40 @@ xdsIR: name: httproute/default/httproute-1/rule/0/backend/0 protocol: HTTP weight: 1 + directResponse: + statusCode: 500 envoyExtensions: extProcs: - - authority: grpc-backend-2.default:9000 + - allowModeOverride: true + authority: grpc-backend.envoy-gateway:8000 destination: - name: envoyextensionpolicy/default/policy-for-http-route/extproc/0 + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0 settings: - addressType: IP - endpoints: - - host: 8.8.8.8 - port: 9000 - name: envoyextensionpolicy/default/policy-for-http-route/extproc/0/backend/0 + name: envoyextensionpolicy/default/policy-for-gateway/extproc/0/backend/0 protocol: GRPC tls: alpnProtocols: null caCertificate: certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K - name: policy-btls-grpc-2/default-ca - sni: grpc-backend-2 + name: policy-btls-grpc/envoy-gateway-ca + sni: grpc-backend weight: 1 - name: envoyextensionpolicy/default/policy-for-http-route/extproc/0 + 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 hostname: www.foo.com isHTTP2: false diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml index 89be7cac75..b99388294f 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-multiple-backendrefs.in.yaml @@ -129,7 +129,7 @@ configMaps: kind: ConfigMap metadata: name: ca-cmap - namespace: default + namespace: envoy-gateway data: ca.crt: | -----BEGIN CERTIFICATE----- diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml index 30af5a4dbd..614a841e6b 100644 --- a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml @@ -129,7 +129,7 @@ configMaps: kind: ConfigMap metadata: name: ca-cmap - namespace: default + namespace: envoy-gateway data: ca.crt: | -----BEGIN CERTIFICATE----- diff --git a/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml index 42e46b8990..fb48d771c2 100644 --- a/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml @@ -129,7 +129,7 @@ configMaps: kind: ConfigMap metadata: name: ca-cmap - namespace: default + namespace: envoy-gateway data: ca.crt: | -----BEGIN CERTIFICATE----- diff --git a/internal/gatewayapi/testdata/httproute-dynamic-resolver.in.yaml b/internal/gatewayapi/testdata/httproute-dynamic-resolver.in.yaml index 03f9e16bf9..1837a9d282 100644 --- a/internal/gatewayapi/testdata/httproute-dynamic-resolver.in.yaml +++ b/internal/gatewayapi/testdata/httproute-dynamic-resolver.in.yaml @@ -75,7 +75,7 @@ configMaps: kind: ConfigMap metadata: name: ca-cmap - namespace: backends + namespace: default data: ca.crt: | -----BEGIN CERTIFICATE----- diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml index abd7ed641b..a019d9118e 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-with-backendtlspolicy.in.yaml @@ -123,6 +123,32 @@ referenceGrants: - group: "" kind: Service configMaps: + - apiVersion: v1 + kind: ConfigMap + metadata: + name: ca-cmap + namespace: envoy-gateway + data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL + BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw + MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G + A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc + 1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM + yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b + kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU + Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq + ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR + bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48 + 6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/ + BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz + 2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J + i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE + A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg + d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1 + 3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q== + -----END CERTIFICATE----- - apiVersion: v1 kind: ConfigMap metadata: diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 985f724141..ece60fcf16 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -26,6 +26,7 @@ bug fixes: | Add ConfigMap indexers for EnvoyExtensionPolicies to reconcile Lua changes Fixed issue that default accesslog format not working. Fixed bug in certificate SANs overlap detection in listeners. + Fixed issue that BackendTLSPolicy should not reference ConfigMap or Secret across namespace. # Enhancements that improve performance. performance improvements: |