From 71ae6cac7821782f22b73e847c9cdd56d8e84183 Mon Sep 17 00:00:00 2001 From: bitliu Date: Fri, 1 Aug 2025 14:38:18 +0800 Subject: [PATCH] fix: populate status for custom backendRef not found Signed-off-by: bitliu --- internal/gatewayapi/route.go | 12 ++ ...custom-backend-invalid-apiversion.out.yaml | 32 +--- ...oute-with-custom-backend-not-found.in.yaml | 46 +++++ ...ute-with-custom-backend-not-found.out.yaml | 180 ++++++++++++++++++ 4 files changed, 247 insertions(+), 23 deletions(-) create mode 100644 internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.in.yaml create mode 100644 internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.out.yaml diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index a60564028e..412dea76c3 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -1488,6 +1488,18 @@ func (t *Translator) processDestination(name string, backendRefContext BackendRe if t.isCustomBackendResource(backendRef.Group, KindDerefOr(backendRef.Kind, resource.KindService)) { // Add the custom backend resource to ExtensionRefFilters so it can be processed by the extension system unstructuredRef = t.processBackendExtensions(backendRef.BackendObjectReference, backendNamespace, resources) + + // Check if the custom backend resource was found + if unstructuredRef == nil { + return nil, nil, status.NewRouteStatusError( + fmt.Errorf("custom backend %s %s/%s not found", + KindDerefOr(backendRef.Kind, resource.KindService), + backendNamespace, + backendRef.Name), + gwapiv1.RouteReasonBackendNotFound, + ).WithType(gwapiv1.RouteConditionResolvedRefs) + } + return &ir.DestinationSetting{ Name: name, Weight: &weight, diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-invalid-apiversion.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-invalid-apiversion.out.yaml index bf91cc836b..1083567720 100644 --- a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-invalid-apiversion.out.yaml +++ b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-invalid-apiversion.out.yaml @@ -80,9 +80,11 @@ httpRoutes: status: "True" type: Accepted - lastTransitionTime: null - message: Resolved all the Object references for the Route - reason: ResolvedRefs - status: "True" + message: |- + Failed to process route rule 0 backendRef 0: custom backend S3Backend default/s3-backend not found. + Failed to process route rule 1 backendRef 0: custom backend LambdaBackend default/lambda-backend not found. + reason: BackendNotFound + status: "False" type: ResolvedRefs controllerName: gateway.envoyproxy.io/gatewayclass-controller parentRef: @@ -145,16 +147,8 @@ xdsIR: mergeSlashes: true port: 10080 routes: - - destination: - metadata: - kind: HTTPRoute - name: httproute-1 - namespace: default - name: httproute/default/httproute-1/rule/1 - settings: - - isCustomBackend: true - name: httproute/default/httproute-1/rule/1/backend/0 - weight: 1 + - directResponse: + statusCode: 500 hostname: gateway.envoyproxy.io isHTTP2: false metadata: @@ -166,16 +160,8 @@ xdsIR: distinct: false name: "" prefix: /lambda - - destination: - metadata: - kind: HTTPRoute - name: httproute-1 - namespace: default - name: httproute/default/httproute-1/rule/0 - settings: - - isCustomBackend: true - name: httproute/default/httproute-1/rule/0/backend/0 - weight: 1 + - directResponse: + statusCode: 500 hostname: gateway.envoyproxy.io isHTTP2: false metadata: diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.in.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.in.yaml new file mode 100644 index 0000000000..bd1054f0e7 --- /dev/null +++ b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.in.yaml @@ -0,0 +1,46 @@ +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 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/s3" + backendRefs: + - group: storage.example.io + kind: S3Backend + name: s3-backend + port: 443 + - matches: + - path: + value: "/lambda" + backendRefs: + - group: compute.example.io + kind: LambdaBackend + name: lambda-backend + port: 443 diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.out.yaml new file mode 100644 index 0000000000..1083567720 --- /dev/null +++ b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.out.yaml @@ -0,0 +1,180 @@ +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: '*.envoyproxy.io' + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - group: storage.example.io + kind: S3Backend + name: s3-backend + port: 443 + matches: + - path: + value: /s3 + - backendRefs: + - group: compute.example.io + kind: LambdaBackend + name: lambda-backend + port: 443 + matches: + - path: + value: /lambda + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: |- + Failed to process route rule 0 backendRef 0: custom backend S3Backend default/s3-backend not found. + Failed to process route rule 1 backendRef 0: custom backend LambdaBackend default/lambda-backend not found. + reason: BackendNotFound + status: "False" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: "" +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + globalResources: + proxyServiceCluster: + name: envoy-gateway/gateway-1 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + name: envoy-envoy-gateway-gateway-1-196ae069 + sectionName: "8080" + name: envoy-gateway/gateway-1 + protocol: TCP + http: + - address: 0.0.0.0 + externalPort: 80 + hostnames: + - '*.envoyproxy.io' + 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 + routes: + - directResponse: + statusCode: 500 + hostname: gateway.envoyproxy.io + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/1/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: /lambda + - directResponse: + statusCode: 500 + hostname: gateway.envoyproxy.io + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: /s3 + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003