From 57ec43221e9dfbe9c0c7e0cda2e40c0acb477c45 Mon Sep 17 00:00:00 2001 From: zirain Date: Wed, 17 Dec 2025 11:13:00 +0800 Subject: [PATCH 1/9] fix: do not trigger IR deletion when EnvoyProxy is invalid Signed-off-by: zirain --- .../translate/out/invalid-envoyproxy.all.yaml | 55 ++++++++ internal/gatewayapi/runner/runner.go | 8 ++ ...voyproxy-accesslog-with-bad-sinks.out.yaml | 24 ++++ .../envoyproxy-for-gatewayclass.in.yaml | 82 +++++++++++ .../envoyproxy-for-gatewayclass.out.yaml | 130 ++++++++++++++++++ internal/gatewayapi/translator.go | 46 +++++-- 6 files changed, 337 insertions(+), 8 deletions(-) create mode 100644 internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.in.yaml create mode 100644 internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml diff --git a/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml b/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml index 0b837379b8..59d6d1bda9 100644 --- a/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/invalid-envoyproxy.all.yaml @@ -41,3 +41,58 @@ gatewayClass: reason: InvalidParameters status: "False" type: Accepted +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: eg + namespace: default + spec: + gatewayClassName: eg + listeners: + - allowedRoutes: + namespaces: + from: Same + name: tcp + port: 1234 + protocol: TCP + - allowedRoutes: + namespaces: + from: Same + name: udp + port: 1234 + protocol: UDP + - allowedRoutes: + namespaces: + from: Same + hostname: foo.com + name: tls-passthrough + port: 8443 + protocol: TLS + tls: + mode: Passthrough + - allowedRoutes: + kinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespaces: + from: Same + name: http + port: 80 + protocol: HTTP + - allowedRoutes: + kinds: + - group: gateway.networking.k8s.io + kind: GRPCRoute + namespaces: + from: Same + name: grpc + port: 8080 + protocol: HTTP + status: + conditions: + - lastTransitionTime: null + message: 'Invalid parametersRef:: dynamic_resources cannot be modified' + reason: InvalidParameters + status: "False" + type: Accepted diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go index 77dcf79481..3f55fe5f2e 100644 --- a/internal/gatewayapi/runner/runner.go +++ b/internal/gatewayapi/runner/runner.go @@ -242,6 +242,14 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re } } + // For https://github.com/envoyproxy/gateway/issues/7735, if a gateway/gatewayclass + // referenced an invalid EnvoyProxy, it's part of failed gateways, we shouldn't delete + // the IR. + for _, gtw := range result.Gateways { + irKey := t.IRKey(types.NamespacedName{Namespace: gtw.Namespace, Name: gtw.Name}) + delete(keysToDelete.IR, irKey) + } + for key, val := range result.XdsIR { logV := traceLogger.V(1).WithValues(string(message.XDSIRMessageName), key) if logV.Enabled() { diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml index 33bd24785c..8febab01e3 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml @@ -19,5 +19,29 @@ gatewayClass: reason: InvalidParameters status: "False" type: Accepted +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http + port: 80 + protocol: HTTP + status: + conditions: + - lastTransitionTime: null + message: 'Invalid parametersRef:: [unable to configure access log when using + File sink type but "file" field being empty, unable to configure access log + when using OpenTelemetry sink type but "openTelemetry" field being empty]' + reason: InvalidParameters + status: "False" + type: Accepted infraIR: {} xdsIR: {} diff --git a/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.in.yaml b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.in.yaml new file mode 100644 index 0000000000..e96817a1e9 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.in.yaml @@ -0,0 +1,82 @@ +gatewayClass: + apiVersion: gateway.networking.k8s.io/v1 + kind: GatewayClass + metadata: + name: envoy-gateway-class + spec: + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: invalid + namespace: envoy-gateway-system +envoyProxyForGatewayClass: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway + name: invalid + spec: + telemetry: + accessLog: + settings: + - format: + type: Text + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + sinks: + - type: File + - type: ALS + - type: OpenTelemetry +envoyProxiesForGateways: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway + name: valid + spec: + telemetry: + accessLog: + settings: + - format: + type: Text + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + sinks: + - type: File + file: + path: /dev/stdout +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: ep-from-gtw + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + infrastructure: + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: valid + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: ep-from-gc + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same diff --git a/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml new file mode 100644 index 0000000000..091eb2fe39 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml @@ -0,0 +1,130 @@ +gatewayClass: + apiVersion: gateway.networking.k8s.io/v1 + kind: GatewayClass + metadata: + name: envoy-gateway-class + spec: + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: invalid + namespace: envoy-gateway-system + status: + conditions: + - lastTransitionTime: null + message: 'Invalid parametersRef: [unable to configure access log when using + File sink type but "file" field being empty, unable to configure access log + when using OpenTelemetry sink type but "openTelemetry" field being empty]' + reason: InvalidParameters + status: "False" + type: Accepted +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: ep-from-gtw + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + infrastructure: + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: valid + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http + port: 80 + protocol: HTTP + status: {} +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: ep-from-gc + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http + port: 80 + protocol: HTTP + status: + conditions: + - lastTransitionTime: null + message: 'Invalid parametersRef:: [unable to configure access log when using + File sink type but "file" field being empty, unable to configure access log + when using OpenTelemetry sink type but "openTelemetry" field being empty]' + reason: InvalidParameters + status: "False" + type: Accepted +infraIR: + envoy-gateway/ep-from-gtw: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + name: valid + namespace: envoy-gateway + spec: + logging: {} + telemetry: + accessLog: + settings: + - format: + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + type: Text + sinks: + - file: + path: /dev/stdout + type: File + status: {} + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: ep-from-gtw + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/ep-from-gtw + namespace: envoy-gateway-system +xdsIR: + envoy-gateway/ep-from-gtw: + accessLog: + text: + - format: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + path: /dev/stdout + globalResources: + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-ep-from-gtw-90cb3c57 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/ep-from-gtw + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-ep-from-gtw-90cb3c57 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/ep-from-gtw + protocol: TCP + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 6f547ed6c8..b79ebef629 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -369,18 +369,56 @@ func (t *Translator) GetRelevantGateways(resources *resource.Resources) ( envoyproxyMap := make(map[types.NamespacedName]*egv1a1.EnvoyProxy, len(resources.EnvoyProxiesForGateways)+1) envoyproxyValidationErrorMap := make(map[types.NamespacedName]error, len(resources.EnvoyProxiesForGateways)) + for _, ep := range resources.EnvoyProxiesForGateways { + key := utils.NamespacedName(ep) + envoyproxyMap[key] = ep + if err := validateEnvoyProxy(ep); err != nil { + envoyproxyValidationErrorMap[key] = err + } + } + // if EnvoyProxy not found, provider layer set GC status to not accepted. // if EnvoyProxy found but invalid, set GC status to not accepted, // otherwise set GC status to accepted. if ep := resources.EnvoyProxyForGatewayClass; ep != nil { err := validateEnvoyProxy(ep) if err != nil { + envoyproxyValidationErrorMap[utils.NamespacedName(ep)] = err t.Logger.Error(err, "Skipping GatewayClass because EnvoyProxy is invalid", "gatewayclass", t.GatewayClassName, "envoyproxy", ep.Name, "namespace", ep.Namespace) status.SetGatewayClassAccepted(resources.GatewayClass, false, string(gwapiv1.GatewayClassReasonInvalidParameters), fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err)) + + for _, gateway := range resources.Gateways { + if gateway == nil { + // Should not happen + panic("received nil gateway") + } + + logKeysAndValues := []any{ + "namespace", gateway.Namespace, "name", gateway.Name, + } + + gtwCtx := &GatewayContext{ + Gateway: gateway, + } + gtwCtx.attachEnvoyProxy(resources, envoyproxyMap) + gwEnvoyProxy := gtwCtx.envoyProxy + key := utils.NamespacedName(gwEnvoyProxy) + if err, exits := envoyproxyValidationErrorMap[key]; exits { + failedGateways = append(failedGateways, gtwCtx) + t.Logger.Info("Invalid parametersRef", logKeysAndValues...) + status.UpdateGatewayStatusNotAccepted(gtwCtx.Gateway, gwapiv1.GatewayReasonInvalidParameters, + fmt.Sprintf("%s: %v", "Invalid parametersRef:", err.Error())) + continue + } + + // Gateway use a valid EnvoyProxy from spec.infrastructure.parametersRef + acceptedGateways = append(acceptedGateways, gtwCtx) + } + return acceptedGateways, failedGateways } @@ -398,14 +436,6 @@ func (t *Translator) GetRelevantGateways(resources *resource.Resources) ( // we didn't append to envoyproxyValidatioErrorMap because it's valid. } - for _, ep := range resources.EnvoyProxiesForGateways { - key := utils.NamespacedName(ep) - envoyproxyMap[key] = ep - if err := validateEnvoyProxy(ep); err != nil { - envoyproxyValidationErrorMap[key] = err - } - } - for _, gateway := range resources.Gateways { if gateway == nil { // Should not happen From c839278c4bbedb6d51f6b49c35755a620e0dc678 Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 20 Jan 2026 13:59:16 +0800 Subject: [PATCH 2/9] add Invalid to ir.Infra Signed-off-by: zirain --- internal/gatewayapi/runner/runner.go | 8 -- ...voyproxy-accesslog-with-bad-sinks.out.yaml | 17 +++- .../envoyproxy-for-gatewayclass.out.yaml | 13 ++++ ...-gateway-accesslog-with-bad-sinks.out.yaml | 17 +++- internal/gatewayapi/translator.go | 77 +++++++++++-------- internal/infrastructure/runner/runner.go | 6 ++ internal/ir/infra.go | 3 + 7 files changed, 98 insertions(+), 43 deletions(-) diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go index 3f55fe5f2e..77dcf79481 100644 --- a/internal/gatewayapi/runner/runner.go +++ b/internal/gatewayapi/runner/runner.go @@ -242,14 +242,6 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re } } - // For https://github.com/envoyproxy/gateway/issues/7735, if a gateway/gatewayclass - // referenced an invalid EnvoyProxy, it's part of failed gateways, we shouldn't delete - // the IR. - for _, gtw := range result.Gateways { - irKey := t.IRKey(types.NamespacedName{Namespace: gtw.Namespace, Name: gtw.Name}) - delete(keysToDelete.IR, irKey) - } - for key, val := range result.XdsIR { logV := traceLogger.V(1).WithValues(string(message.XDSIRMessageName), key) if logV.Enabled() { diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml index 8febab01e3..5cae024b64 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml @@ -43,5 +43,18 @@ gateways: reason: InvalidParameters status: "False" type: Accepted -infraIR: {} -xdsIR: {} +infraIR: + envoy-gateway/gateway-1: + invalid: true + proxy: + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: envoy-gateway-system +xdsIR: + envoy-gateway/gateway-1: {} diff --git a/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml index 091eb2fe39..82157282c3 100644 --- a/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml @@ -64,6 +64,18 @@ gateways: status: "False" type: Accepted infraIR: + envoy-gateway/ep-from-gc: + invalid: true + proxy: + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: ep-from-gc + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/ep-from-gc + namespace: envoy-gateway-system envoy-gateway/ep-from-gtw: proxy: config: @@ -96,6 +108,7 @@ infraIR: name: envoy-gateway/ep-from-gtw namespace: envoy-gateway-system xdsIR: + envoy-gateway/ep-from-gc: {} envoy-gateway/ep-from-gtw: accessLog: text: diff --git a/internal/gatewayapi/testdata/envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml b/internal/gatewayapi/testdata/envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml index 5da07c49ab..f4703c0a2a 100644 --- a/internal/gatewayapi/testdata/envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml @@ -27,5 +27,18 @@ gateways: reason: InvalidParameters status: "False" type: Accepted -infraIR: {} -xdsIR: {} +infraIR: + envoy-gateway/gateway-1: + invalid: true + proxy: + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: envoy-gateway-system +xdsIR: + envoy-gateway/gateway-1: {} diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index b79ebef629..41d3bffd7a 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -251,7 +251,7 @@ func (t *Translator) Translate(resources *resource.Resources) (*TranslateResult, // Gateways are already sorted by the provider layer // Build IR maps. - xdsIR, infraIR := t.InitIRs(acceptedGateways) + xdsIR, infraIR := t.InitIRs(acceptedGateways, failedGateways) // Process XListenerSets and attach them to the relevant Gateways t.ProcessXListenerSets(resources.XListenerSets, acceptedGateways) @@ -493,40 +493,21 @@ func validateEnvoyProxy(ep *egv1a1.EnvoyProxy) error { } // InitIRs checks if mergeGateways is enabled in EnvoyProxy config and initializes XdsIR and InfraIR maps with adequate keys. -func (t *Translator) InitIRs(gateways []*GatewayContext) (map[string]*ir.Xds, map[string]*ir.Infra) { +func (t *Translator) InitIRs(acceptedGateways, failedGateways []*GatewayContext) (map[string]*ir.Xds, map[string]*ir.Infra) { xdsIR := make(resource.XdsIRMap) infraIR := make(resource.InfraIRMap) - for _, gateway := range gateways { - gwXdsIR := &ir.Xds{} - gwInfraIR := ir.NewInfra() - labels := infrastructureLabels(gateway.Gateway) - annotations := infrastructureAnnotations(gateway.Gateway) - gwInfraIR.Proxy.GetProxyMetadata().Annotations = annotations - - irKey := t.IRKey(types.NamespacedName{Namespace: gateway.Namespace, Name: gateway.Name}) - if t.MergeGateways { - maps.Copy(labels, GatewayClassOwnerLabel(string(t.GatewayClassName))) - gwInfraIR.Proxy.GetProxyMetadata().Labels = labels - } else { - maps.Copy(labels, GatewayOwnerLabels(gateway.Namespace, gateway.Name)) - gwInfraIR.Proxy.GetProxyMetadata().Labels = labels - } + for _, gateway := range acceptedGateways { + irKey, gwXdsIR, gwInfraIR := t.buildIR(gateway) + // save the IR references in the map before the translation starts + xdsIR[irKey] = gwXdsIR + infraIR[irKey] = gwInfraIR + } - gwInfraIR.Proxy.Name = irKey - gwInfraIR.Proxy.Namespace = t.ControllerNamespace - gwInfraIR.Proxy.GetProxyMetadata().OwnerReference = &ir.ResourceMetadata{ - Kind: resource.KindGatewayClass, - Name: string(t.GatewayClassName), - } - if t.GatewayNamespaceMode { - gwInfraIR.Proxy.Name = gateway.Name - gwInfraIR.Proxy.Namespace = gateway.Namespace - gwInfraIR.Proxy.GetProxyMetadata().OwnerReference = &ir.ResourceMetadata{ - Kind: resource.KindGateway, - Name: gateway.Name, - } - } + for _, gtw := range failedGateways { + irKey, gwXdsIR, gwInfraIR := t.buildIR(gtw) + // marked as invalid + gwInfraIR.Invalid = ptr.To(true) // save the IR references in the map before the translation starts xdsIR[irKey] = gwXdsIR infraIR[irKey] = gwInfraIR @@ -535,6 +516,40 @@ func (t *Translator) InitIRs(gateways []*GatewayContext) (map[string]*ir.Xds, ma return xdsIR, infraIR } +func (t *Translator) buildIR(gateway *GatewayContext) (string, *ir.Xds, *ir.Infra) { + gwXdsIR := &ir.Xds{} + gwInfraIR := ir.NewInfra() + labels := infrastructureLabels(gateway.Gateway) + annotations := infrastructureAnnotations(gateway.Gateway) + gwInfraIR.Proxy.GetProxyMetadata().Annotations = annotations + + irKey := t.IRKey(types.NamespacedName{Namespace: gateway.Namespace, Name: gateway.Name}) + if t.MergeGateways { + maps.Copy(labels, GatewayClassOwnerLabel(string(t.GatewayClassName))) + gwInfraIR.Proxy.GetProxyMetadata().Labels = labels + } else { + maps.Copy(labels, GatewayOwnerLabels(gateway.Namespace, gateway.Name)) + gwInfraIR.Proxy.GetProxyMetadata().Labels = labels + } + + gwInfraIR.Proxy.Name = irKey + gwInfraIR.Proxy.Namespace = t.ControllerNamespace + gwInfraIR.Proxy.GetProxyMetadata().OwnerReference = &ir.ResourceMetadata{ + Kind: resource.KindGatewayClass, + Name: string(t.GatewayClassName), + } + if t.GatewayNamespaceMode { + gwInfraIR.Proxy.Name = gateway.Name + gwInfraIR.Proxy.Namespace = gateway.Namespace + gwInfraIR.Proxy.GetProxyMetadata().OwnerReference = &ir.ResourceMetadata{ + Kind: resource.KindGateway, + Name: gateway.Name, + } + } + + return irKey, gwXdsIR, gwInfraIR +} + // IsEnvoyServiceRouting returns true if EnvoyProxy.Spec.RoutingType == ServiceRoutingType // or, alternatively, if Translator.EndpointRoutingDisabled has been explicitly set to true; // otherwise, it returns false. diff --git a/internal/infrastructure/runner/runner.go b/internal/infrastructure/runner/runner.go index fa557b682b..52c6e8bccb 100644 --- a/internal/infrastructure/runner/runner.go +++ b/internal/infrastructure/runner/runner.go @@ -124,6 +124,12 @@ func (r *Runner) updateProxyInfraFromSubscription(ctx context.Context, sub <-cha return } + // Skip creating or updating infra if the Infra IR is invalid. + if ptr.Deref(val.Invalid, false) { + r.Logger.Info("Infra IR was update, but it is invalid. Skipping infra provision.") + return + } + if err := r.mgr.CreateOrUpdateProxyInfra(ctx, val); err != nil { r.Logger.Error(err, "failed to create new infra") errChan <- err diff --git a/internal/ir/infra.go b/internal/ir/infra.go index f546617a8a..dd06336092 100644 --- a/internal/ir/infra.go +++ b/internal/ir/infra.go @@ -25,6 +25,9 @@ const ( // Infra defines managed infrastructure. // +k8s:deepcopy-gen=true type Infra struct { + // Invalid indicates whether the IR is invalid. + // This is an optional bool so that we won't update all existing files. + Invalid *bool `json:"invalid,omitempty" yaml:"invalid,omitempty"` // Proxy defines managed proxy infrastructure. Proxy *ProxyInfra `json:"proxy" yaml:"proxy"` } From 92c9522523c364d7ece94644ce1d0f0f52e3809b Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 20 Jan 2026 14:13:00 +0800 Subject: [PATCH 3/9] fix gen Signed-off-by: zirain --- internal/ir/zz_generated.deepcopy.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 1adea00e18..6148a3c702 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2364,6 +2364,11 @@ func (in *HealthCheckSettings) DeepCopy() *HealthCheckSettings { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Infra) DeepCopyInto(out *Infra) { *out = *in + if in.Invalid != nil { + in, out := &in.Invalid, &out.Invalid + *out = new(bool) + **out = **in + } if in.Proxy != nil { in, out := &in.Proxy, &out.Proxy *out = new(ProxyInfra) From 48a3d9ce2c523db3bfd7a1a084c4e3ae2f5cc6ea Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 20 Jan 2026 16:49:21 +0800 Subject: [PATCH 4/9] add e2e Signed-off-by: zirain --- internal/infrastructure/runner/runner.go | 10 +- .../testdata/envoyproxy-invalid-update.yaml | 20 ++++ test/e2e/testdata/envoyproxy-invalid.yaml | 50 ++++++++++ test/e2e/tests/envoyproxy_invalid.go | 93 +++++++++++++++++++ 4 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 test/e2e/testdata/envoyproxy-invalid-update.yaml create mode 100644 test/e2e/testdata/envoyproxy-invalid.yaml create mode 100644 test/e2e/tests/envoyproxy_invalid.go diff --git a/internal/infrastructure/runner/runner.go b/internal/infrastructure/runner/runner.go index 52c6e8bccb..59da0bccde 100644 --- a/internal/infrastructure/runner/runner.go +++ b/internal/infrastructure/runner/runner.go @@ -119,17 +119,17 @@ func (r *Runner) updateProxyInfraFromSubscription(ctx context.Context, sub <-cha } } else { // Manage the proxy infra. - if len(val.Proxy.Listeners) == 0 { - r.Logger.Info("Infra IR was updated, but no listeners were found. Skipping infra creation.") - return - } - // Skip creating or updating infra if the Infra IR is invalid. if ptr.Deref(val.Invalid, false) { r.Logger.Info("Infra IR was update, but it is invalid. Skipping infra provision.") return } + if len(val.Proxy.Listeners) == 0 { + r.Logger.Info("Infra IR was updated, but no listeners were found. Skipping infra creation.") + return + } + if err := r.mgr.CreateOrUpdateProxyInfra(ctx, val); err != nil { r.Logger.Error(err, "failed to create new infra") errChan <- err diff --git a/test/e2e/testdata/envoyproxy-invalid-update.yaml b/test/e2e/testdata/envoyproxy-invalid-update.yaml new file mode 100644 index 0000000000..3120169568 --- /dev/null +++ b/test/e2e/testdata/envoyproxy-invalid-update.yaml @@ -0,0 +1,20 @@ +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyProxy +metadata: + name: eg-invalid + namespace: gateway-conformance-infra +spec: + ipFamily: IPv4 + bootstrap: + type: "Merge" + value: | + stats_config: + stats_tags: + - tag_name: route_kind + regex: '^cluster\.((\w+)/)" + provider: + type: Kubernetes + kubernetes: + envoyHpa: + minReplicas: 1 + maxReplicas: 2 diff --git a/test/e2e/testdata/envoyproxy-invalid.yaml b/test/e2e/testdata/envoyproxy-invalid.yaml new file mode 100644 index 0000000000..e97c1c3943 --- /dev/null +++ b/test/e2e/testdata/envoyproxy-invalid.yaml @@ -0,0 +1,50 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: eg-invalid + namespace: gateway-conformance-infra +spec: + gatewayClassName: "{GATEWAY_CLASS_NAME}" + listeners: + - name: http + port: 80 + protocol: HTTP + allowedRoutes: + namespaces: + from: All + infrastructure: + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: eg-invalid +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyProxy +metadata: + name: eg-invalid + namespace: gateway-conformance-infra +spec: + ipFamily: IPv4 + provider: + type: Kubernetes + kubernetes: + envoyHpa: + minReplicas: 1 + maxReplicas: 2 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: eg-invalid + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: eg-invalid + rules: + - backendRefs: + - name: infra-backend-v1 + port: 8080 + matches: + - path: + type: PathPrefix + value: /invalid diff --git a/test/e2e/tests/envoyproxy_invalid.go b/test/e2e/tests/envoyproxy_invalid.go new file mode 100644 index 0000000000..b2e958adbc --- /dev/null +++ b/test/e2e/tests/envoyproxy_invalid.go @@ -0,0 +1,93 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +//go:build e2e + +package tests + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + "sigs.k8s.io/gateway-api/conformance/utils/http" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, EnvoyProxyInvalidUpdateTest) +} + +var EnvoyProxyInvalidUpdateTest = suite.ConformanceTest{ + ShortName: "EnvoyProxyInvalidUpdate", + Description: "Update EnvoyProxy with invalid value, infra should skip provision", + Manifests: []string{"testdata/envoyproxy-invalid.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "eg-invalid", Namespace: ns} + gwNN := types.NamespacedName{Name: "eg-invalid", Namespace: ns} + gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gwapiv1.HTTPRoute{}, false, routeNN) + okResp := http.ExpectedResponse{ + Request: http.Request{ + Path: "/invalid", + }, + Response: http.Response{ + StatusCodes: []int{200}, + }, + Namespace: ns, + } + + // Send a request to a valid path and expect a successful response + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, okResp) + + // get the pod name for specific Gateway + expectedNs := GetGatewayResourceNamespace() + podName, err := getPodNameForGateway(t, suite, expectedNs, gwNN) + require.NoError(t, err) + + // Update EnvoyProx with invalid bootstrap + suite.Applier.MustApplyWithCleanup(t, suite.Client, suite.TimeoutConfig, "testdata/envoyproxy-invalid-update.yaml", true) + + // Make sure that the Gateway contains InvalidParameters + kubernetes.GatewayMustHaveCondition(t, suite.Client, suite.TimeoutConfig, gwNN, metav1.Condition{ + Type: string(gwapiv1.GatewayConditionAccepted), + Status: metav1.ConditionFalse, + Reason: string(gwapiv1.GatewayReasonInvalidParameters), + }) + + podShouldBeSame, err := getPodNameForGateway(t, suite, expectedNs, gwNN) + require.NoError(t, err) + require.Equal(t, podName, podShouldBeSame) + }, +} + +func getPodNameForGateway(t *testing.T, suite *suite.ConformanceTestSuite, expectedNs string, gtw types.NamespacedName) (string, error) { + pods := &corev1.PodList{} + err := suite.Client.List(t.Context(), pods, &client.ListOptions{ + Namespace: expectedNs, + LabelSelector: labels.SelectorFromSet(map[string]string{ + "app.kubernetes.io/managed-by": "envoy-gateway", + "app.kubernetes.io/name": "envoy", + "gateway.envoyproxy.io/owning-gateway-name": gtw.Name, + "gateway.envoyproxy.io/owning-gateway-namespace": gtw.Namespace, + }), + }) + if err != nil { + return "", err + } + + if len(pods.Items) != 1 { + return "", fmt.Errorf("get unexpected count of pods: %d", len(pods.Items)) + } + + return pods.Items[0].Name, err +} From 740ec808cfea7129f72261862aedf27599a77599 Mon Sep 17 00:00:00 2001 From: zirain Date: Fri, 30 Jan 2026 12:35:08 +0800 Subject: [PATCH 5/9] remove invalid Signed-off-by: zirain --- .../testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml | 1 - .../testdata/envoyproxy-for-gatewayclass.out.yaml | 1 - .../envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml | 1 - internal/gatewayapi/translator.go | 2 -- internal/infrastructure/runner/runner.go | 7 +------ internal/ir/infra.go | 3 --- internal/ir/zz_generated.deepcopy.go | 5 ----- 7 files changed, 1 insertion(+), 19 deletions(-) diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml index 5cae024b64..525659b83f 100644 --- a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-bad-sinks.out.yaml @@ -45,7 +45,6 @@ gateways: type: Accepted infraIR: envoy-gateway/gateway-1: - invalid: true proxy: metadata: labels: diff --git a/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml index 82157282c3..e6115b165f 100644 --- a/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml @@ -65,7 +65,6 @@ gateways: type: Accepted infraIR: envoy-gateway/ep-from-gc: - invalid: true proxy: metadata: labels: diff --git a/internal/gatewayapi/testdata/envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml b/internal/gatewayapi/testdata/envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml index f4703c0a2a..7b78a40a65 100644 --- a/internal/gatewayapi/testdata/envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-gateway-accesslog-with-bad-sinks.out.yaml @@ -29,7 +29,6 @@ gateways: type: Accepted infraIR: envoy-gateway/gateway-1: - invalid: true proxy: metadata: labels: diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 41d3bffd7a..327597727b 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -506,8 +506,6 @@ func (t *Translator) InitIRs(acceptedGateways, failedGateways []*GatewayContext) for _, gtw := range failedGateways { irKey, gwXdsIR, gwInfraIR := t.buildIR(gtw) - // marked as invalid - gwInfraIR.Invalid = ptr.To(true) // save the IR references in the map before the translation starts xdsIR[irKey] = gwXdsIR infraIR[irKey] = gwInfraIR diff --git a/internal/infrastructure/runner/runner.go b/internal/infrastructure/runner/runner.go index 59da0bccde..2472d37f5e 100644 --- a/internal/infrastructure/runner/runner.go +++ b/internal/infrastructure/runner/runner.go @@ -119,12 +119,7 @@ func (r *Runner) updateProxyInfraFromSubscription(ctx context.Context, sub <-cha } } else { // Manage the proxy infra. - // Skip creating or updating infra if the Infra IR is invalid. - if ptr.Deref(val.Invalid, false) { - r.Logger.Info("Infra IR was update, but it is invalid. Skipping infra provision.") - return - } - + // Skip creating or updating infra if the Infra IR without any listener. if len(val.Proxy.Listeners) == 0 { r.Logger.Info("Infra IR was updated, but no listeners were found. Skipping infra creation.") return diff --git a/internal/ir/infra.go b/internal/ir/infra.go index dd06336092..f546617a8a 100644 --- a/internal/ir/infra.go +++ b/internal/ir/infra.go @@ -25,9 +25,6 @@ const ( // Infra defines managed infrastructure. // +k8s:deepcopy-gen=true type Infra struct { - // Invalid indicates whether the IR is invalid. - // This is an optional bool so that we won't update all existing files. - Invalid *bool `json:"invalid,omitempty" yaml:"invalid,omitempty"` // Proxy defines managed proxy infrastructure. Proxy *ProxyInfra `json:"proxy" yaml:"proxy"` } diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 6148a3c702..1adea00e18 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2364,11 +2364,6 @@ func (in *HealthCheckSettings) DeepCopy() *HealthCheckSettings { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Infra) DeepCopyInto(out *Infra) { *out = *in - if in.Invalid != nil { - in, out := &in.Invalid, &out.Invalid - *out = new(bool) - **out = **in - } if in.Proxy != nil { in, out := &in.Proxy, &out.Proxy *out = new(ProxyInfra) From 051d32db08262d4ca8a822a36813c1b70bbad572 Mon Sep 17 00:00:00 2001 From: zirain Date: Mon, 2 Feb 2026 19:46:55 +0800 Subject: [PATCH 6/9] add comments Signed-off-by: zirain --- internal/gatewayapi/translator.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 327597727b..0e6fd7f32d 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -504,6 +504,8 @@ func (t *Translator) InitIRs(acceptedGateways, failedGateways []*GatewayContext) infraIR[irKey] = gwInfraIR } + // we need to build IRs for failed gateways to avoid delete event to Infra IR, + // which will cause the deletion of infra resources managed by the failed gateways. for _, gtw := range failedGateways { irKey, gwXdsIR, gwInfraIR := t.buildIR(gtw) // save the IR references in the map before the translation starts From c74d004bc3c47845c514a0a42805347921687133 Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 3 Feb 2026 08:26:31 +0800 Subject: [PATCH 7/9] update Signed-off-by: zirain --- internal/infrastructure/runner/runner.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/infrastructure/runner/runner.go b/internal/infrastructure/runner/runner.go index 2472d37f5e..5587847a79 100644 --- a/internal/infrastructure/runner/runner.go +++ b/internal/infrastructure/runner/runner.go @@ -120,6 +120,8 @@ func (r *Runner) updateProxyInfraFromSubscription(ctx context.Context, sub <-cha } else { // Manage the proxy infra. // Skip creating or updating infra if the Infra IR without any listener. + // e.g.https://github.com/envoyproxy/gateway/issues/3044 --- Invalid Listener + // https://github.com/envoyproxy/gateway/issues/7735 --- Invalid EnvoyProxy if len(val.Proxy.Listeners) == 0 { r.Logger.Info("Infra IR was updated, but no listeners were found. Skipping infra creation.") return From fb98dea85591e19fc71b7b352c168330720b9c4b Mon Sep 17 00:00:00 2001 From: zirain Date: Tue, 3 Feb 2026 13:08:44 +0800 Subject: [PATCH 8/9] merge loop Signed-off-by: zirain --- .../envoyproxy-for-gatewayclass.out.yaml | 50 ++++++++++++++- internal/gatewayapi/translator.go | 61 +++++-------------- 2 files changed, 65 insertions(+), 46 deletions(-) diff --git a/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml index e6115b165f..66857d519f 100644 --- a/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-for-gatewayclass.out.yaml @@ -39,7 +39,31 @@ gateways: name: http port: 80 protocol: HTTP - status: {} + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: @@ -97,6 +121,14 @@ infraIR: path: /dev/stdout type: File status: {} + listeners: + - address: null + name: envoy-gateway/ep-from-gtw/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 metadata: labels: gateway.envoyproxy.io/owning-gateway-name: ep-from-gtw @@ -135,6 +167,22 @@ xdsIR: sectionName: "8080" name: envoy-gateway/ep-from-gtw protocol: TCP + http: + - address: 0.0.0.0 + externalPort: 80 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: ep-from-gtw + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/ep-from-gtw/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 readyListener: address: 0.0.0.0 ipFamily: IPv4 diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 0e6fd7f32d..2199f47995 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -390,50 +390,20 @@ func (t *Translator) GetRelevantGateways(resources *resource.Resources) ( status.SetGatewayClassAccepted(resources.GatewayClass, false, string(gwapiv1.GatewayClassReasonInvalidParameters), fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err)) - - for _, gateway := range resources.Gateways { - if gateway == nil { - // Should not happen - panic("received nil gateway") - } - - logKeysAndValues := []any{ - "namespace", gateway.Namespace, "name", gateway.Name, - } - - gtwCtx := &GatewayContext{ - Gateway: gateway, - } - gtwCtx.attachEnvoyProxy(resources, envoyproxyMap) - gwEnvoyProxy := gtwCtx.envoyProxy - key := utils.NamespacedName(gwEnvoyProxy) - if err, exits := envoyproxyValidationErrorMap[key]; exits { - failedGateways = append(failedGateways, gtwCtx) - t.Logger.Info("Invalid parametersRef", logKeysAndValues...) - status.UpdateGatewayStatusNotAccepted(gtwCtx.Gateway, gwapiv1.GatewayReasonInvalidParameters, - fmt.Sprintf("%s: %v", "Invalid parametersRef:", err.Error())) - continue - } - - // Gateway use a valid EnvoyProxy from spec.infrastructure.parametersRef - acceptedGateways = append(acceptedGateways, gtwCtx) + } else { + // TODO: remove this nil check after we update all the testdata. + if resources.GatewayClass != nil { + status.SetGatewayClassAccepted( + resources.GatewayClass, + true, + string(gwapiv1.GatewayClassReasonAccepted), + status.MsgValidGatewayClass) } - return acceptedGateways, failedGateways - } - - // TODO: remove this nil check after we update all the testdata. - if resources.GatewayClass != nil { - status.SetGatewayClassAccepted( - resources.GatewayClass, - true, - string(gwapiv1.GatewayClassReasonAccepted), - status.MsgValidGatewayClass) + key := utils.NamespacedName(ep) + envoyproxyMap[key] = ep + // we didn't append to envoyproxyValidatioErrorMap because it's valid. } - - key := utils.NamespacedName(ep) - envoyproxyMap[key] = ep - // we didn't append to envoyproxyValidatioErrorMap because it's valid. } for _, gateway := range resources.Gateways { @@ -445,16 +415,17 @@ func (t *Translator) GetRelevantGateways(resources *resource.Resources) ( logKeysAndValues := []any{ "namespace", gateway.Namespace, "name", gateway.Name, } - if gateway.Spec.GatewayClassName != t.GatewayClassName { - t.Logger.Info("Skipping Gateway because GatewayClassName doesn't match", logKeysAndValues...) - continue - } gCtx := &GatewayContext{ Gateway: gateway, } gCtx.attachEnvoyProxy(resources, envoyproxyMap) + if gateway.Spec.GatewayClassName != t.GatewayClassName { + t.Logger.Info("Skipping Gateway because GatewayClassName doesn't match", logKeysAndValues...) + continue + } + // Gateways that are not accepted by the controller because they reference an invalid EnvoyProxy. if status.GatewayNotAccepted(gCtx.Gateway) { failedGateways = append(failedGateways, gCtx) From 422b0d62533ff071e0c32f7e7c7703a1eceed54b Mon Sep 17 00:00:00 2001 From: zirain Date: Wed, 4 Feb 2026 13:39:57 +0800 Subject: [PATCH 9/9] move back Signed-off-by: zirain --- internal/gatewayapi/translator.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 2199f47995..08b72d9f1f 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -415,17 +415,16 @@ func (t *Translator) GetRelevantGateways(resources *resource.Resources) ( logKeysAndValues := []any{ "namespace", gateway.Namespace, "name", gateway.Name, } + if gateway.Spec.GatewayClassName != t.GatewayClassName { + t.Logger.Info("Skipping Gateway because GatewayClassName doesn't match", logKeysAndValues...) + continue + } gCtx := &GatewayContext{ Gateway: gateway, } gCtx.attachEnvoyProxy(resources, envoyproxyMap) - if gateway.Spec.GatewayClassName != t.GatewayClassName { - t.Logger.Info("Skipping Gateway because GatewayClassName doesn't match", logKeysAndValues...) - continue - } - // Gateways that are not accepted by the controller because they reference an invalid EnvoyProxy. if status.GatewayNotAccepted(gCtx.Gateway) { failedGateways = append(failedGateways, gCtx)