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/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= 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/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/listener.go b/internal/gatewayapi/listener.go index 7141d36ac7..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 @@ -408,10 +409,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 { @@ -427,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{ @@ -583,11 +591,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, @@ -830,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/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/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/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/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/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/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/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-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-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-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 eb2f5e64ec..e97a04d42e 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-without-format.out.yaml @@ -182,12 +182,15 @@ xdsIR: protocol: GRPC name: envoy-gateway-system/test type: TCP + json: + - path: /dev/stdout openTelemetry: - authority: otel-collector.monitoring.svc.cluster.local 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/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/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..31f27d30c1 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend-uds.out.yaml @@ -0,0 +1,271 @@ +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 + 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: + name: tracing + settings: + - addressType: IP + endpoints: + - host: "" + path: /var/run/envoy-uds/dsd.socket + port: 0 + 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/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/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/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 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..360a4d936d --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-invalid-no-section-name-listener.out.yaml @@ -0,0 +1,175 @@ +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 + 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 + 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: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 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/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/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 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 +} 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/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 8ee2266901..336f781d29 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -7,6 +7,7 @@ package kubernetes import ( "context" + "errors" "fmt" "time" @@ -179,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. @@ -214,13 +225,20 @@ 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 + failToProcessGCParamsRef := false 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 { + 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( managedGC.DeepCopy(), @@ -228,85 +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 + 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, resourceMappings, gwcResource); err != nil { + 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, resourceMappings); err != nil { + 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, resourceMappings); err != nil { + 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, resourceMappings); err != nil { + 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, resourceMappings); err != nil { + 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, resourceMappings); err != nil { + 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, resourceMappings); err != nil { + 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, resourceMappings) + 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 resourceMappings.allAssociatedNamespaces { + 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 @@ -325,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 } } } @@ -363,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) { @@ -377,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. @@ -417,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), @@ -429,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 { @@ -443,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 { @@ -461,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 { @@ -509,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) @@ -528,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 { @@ -544,6 +656,7 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour } } } + return nil } // processSecurityPolicyObjectRefs adds the referenced resources in SecurityPolicies @@ -552,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 @@ -573,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) @@ -591,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) @@ -609,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) @@ -669,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 { @@ -681,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) @@ -690,6 +823,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicyObjectRefs( } } } + return nil } // processBackendRef adds the referenced BackendRef to the resourceMap for later processBackendRefs. @@ -746,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() @@ -773,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. @@ -789,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 { @@ -840,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 @@ -855,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. @@ -874,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) @@ -882,6 +1013,7 @@ func (r *gatewayAPIReconciler) processCtpConfigMapRefs( } } } + return nil } // processConfigMapRef adds the referenced ConfigMap to the resourceTree if it's valid. @@ -898,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 { @@ -948,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 { @@ -964,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) @@ -978,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 @@ -1063,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 { @@ -1086,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) @@ -1136,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 @@ -1193,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 @@ -1216,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 @@ -1241,11 +1383,7 @@ 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 + return r.processSecurityPolicyObjectRefs(ctx, resourceTree, resourceMap) } // processBackendTLSPolicies adds BackendTLSPolicies and their referenced resources to the resourceTree @@ -1269,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 @@ -1987,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) } } } @@ -2006,15 +2141,12 @@ 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) } // 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 { @@ -2112,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 @@ -2151,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. @@ -2165,6 +2301,7 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicyRefs( } } } + return nil } // processEnvoyExtensionPolicies adds EnvoyExtensionPolicies and their referenced resources to the resourceTree @@ -2182,15 +2319,14 @@ 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) } } // 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 @@ -2233,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 @@ -2271,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) @@ -2288,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) @@ -2303,4 +2447,5 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicyObjectRefs( } } } + return nil } 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/controller_test.go b/internal/provider/kubernetes/controller_test.go index 86eba77554..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" @@ -281,7 +284,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", @@ -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) + }) + } +} 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/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/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/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/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/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/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/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, 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) } diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 32b53627d1..ece60fcf16 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: | @@ -20,6 +21,12 @@ 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. + 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: | 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: