diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml index ae0cd811ca..cdf6c1f2f4 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-headers.out.yaml @@ -66,9 +66,9 @@ httpRoutes: controllerName: gateway.envoyproxy.io/gatewayclass-controller conditions: - type: Accepted - status: "True" - reason: Accepted - message: Route is accepted + status: "False" + reason: UnsupportedValue + message: RequestHeaderModifier Filter cannot set a header with an empty name xdsIR: envoy-gateway-gateway-1: http: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml index 29a0545904..2aec958edf 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml @@ -66,9 +66,9 @@ httpRoutes: controllerName: gateway.envoyproxy.io/gatewayclass-controller conditions: - type: Accepted - status: "True" - reason: Accepted - message: Route is accepted + status: "False" + reason: UnsupportedValue + message: "RequestHeaderModifier Filter cannot set headers with a '/' or ':' character in them. Header: 'example:1'" xdsIR: envoy-gateway-gateway-1: http: diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml index 3892e0bc6c..399ca60131 100644 --- a/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-header-filter-no-valid-headers.out.yaml @@ -61,9 +61,9 @@ httpRoutes: controllerName: gateway.envoyproxy.io/gatewayclass-controller conditions: - type: Accepted - status: "True" - reason: Accepted - message: Route is accepted + status: "False" + reason: UnsupportedValue + message: "RequestHeaderModifier Filter did not provide valid configuration to add/set/remove any headers" xdsIR: envoy-gateway-gateway-1: http: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.in.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.in.yaml index 32d8717c5f..e40076f5b5 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.in.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.in.yaml @@ -35,8 +35,9 @@ httpRoutes: - name: service-1 port: 8080 filters: - - type: UnsupportedType - requestRedirect: - scheme: https - statusCode: 301 + - type: ExtensionRef + extensionRef: + group: unsupported.group.io + kind: UnsupportedKind + name: unsupported diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml index 3127021f04..0217bbf571 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-filter-type.out.yaml @@ -47,10 +47,11 @@ httpRoutes: - name: service-1 port: 8080 filters: - - type: UnsupportedType - requestRedirect: - scheme: https - statusCode: 301 + - type: ExtensionRef + extensionRef: + group: unsupported.group.io + kind: UnsupportedKind + name: unsupported status: parents: - parentRef: @@ -60,9 +61,9 @@ httpRoutes: controllerName: gateway.envoyproxy.io/gatewayclass-controller conditions: - type: Accepted - status: "True" - reason: Accepted - message: Route is accepted + status: "False" + reason: UnsupportedValue + message: "Unknown custom filter type: ExtensionRef" xdsIR: envoy-gateway-gateway-1: http: @@ -81,7 +82,7 @@ xdsIR: # I believe the correct way to handle an invalid filter should be to allow the HTTPRoute to function # normally but leave out the filter config and set the status, but this behaviour can be changed. directResponse: - body: "Unknown custom filter type: UnsupportedType" + body: "Unknown custom filter type: ExtensionRef" statusCode: 500 infraIR: envoy-gateway-gateway-1: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml index 630f9fb75e..c211bfb8e6 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-scheme.out.yaml @@ -60,9 +60,9 @@ httpRoutes: controllerName: gateway.envoyproxy.io/gatewayclass-controller conditions: - type: Accepted - status: "True" - reason: Accepted - message: Route is accepted + status: "False" + reason: UnsupportedValue + message: "Scheme: unknown is unsupported, only 'https' and 'http' are supported" xdsIR: envoy-gateway-gateway-1: http: diff --git a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml index dbb2df4af0..007254e44a 100644 --- a/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml +++ b/internal/gatewayapi/testdata/httproute-with-redirect-filter-invalid-status.out.yaml @@ -60,9 +60,9 @@ httpRoutes: controllerName: gateway.envoyproxy.io/gatewayclass-controller conditions: - type: Accepted - status: "True" - reason: Accepted - message: Route is accepted + status: "False" + reason: UnsupportedValue + message: "Status code 666 is invalid, only 302 and 301 are supported" xdsIR: envoy-gateway-gateway-1: http: diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.in.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.in.yaml new file mode 100644 index 0000000000..17a0293da6 --- /dev/null +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.in.yaml @@ -0,0 +1,41 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + 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: "/" + backendRefs: + - name: service-1 + port: 8080 + filters: + - type: URLRewrite + urlRewrite: + hostname: urlrewrite.envoyproxy.io + diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml new file mode 100644 index 0000000000..8ff359b486 --- /dev/null +++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-filter-invalid-filter-type.out.yaml @@ -0,0 +1,100 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + hostname: "*.envoyproxy.io" + allowedRoutes: + namespaces: + from: All + status: + listeners: + - name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + attachedRoutes: 1 + conditions: + - type: Ready + status: "True" + reason: Ready + message: Listener is ready +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1beta1 + 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: "/" + backendRefs: + - name: service-1 + port: 8080 + filters: + - type: URLRewrite + urlRewrite: + hostname: urlrewrite.envoyproxy.io + status: + parents: + - parentRef: + namespace: envoy-gateway + name: gateway-1 + sectionName: http + controllerName: gateway.envoyproxy.io/gatewayclass-controller + conditions: + - type: Accepted + status: "False" + reason: UnsupportedValue + message: "Unsupported filter type: URLRewrite" +xdsIR: + envoy-gateway-gateway-1: + http: + - name: envoy-gateway-gateway-1-http + address: 0.0.0.0 + port: 10080 + hostnames: + - "*.envoyproxy.io" + routes: + - name: default-httproute-1-rule-0-match-0-gateway.envoyproxy.io + pathMatch: + prefix: "/" + headerMatches: + - name: ":authority" + exact: gateway.envoyproxy.io + # I believe the correct way to handle an invalid filter should be to allow the HTTPRoute to function + # normally but leave out the filter config and set the status, but this behaviour can be changed. + directResponse: + body: "Unsupported filter type: URLRewrite" + statusCode: 500 +infraIR: + envoy-gateway-gateway-1: + proxy: + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + name: envoy-gateway-gateway-1 + image: envoyproxy/envoy:v1.23-latest + listeners: + - address: "" + ports: + - name: http + protocol: "HTTP" + containerPort: 10080 + servicePort: 80 diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 0d4db0be7e..3a08be0745 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -1025,7 +1025,7 @@ func (t *Translator) ProcessHTTPRoutes(httpRoutes []*v1beta1.HTTPRoute, gateways "RequestHeaderModifier Filter did not provide valid configuration to add/set/remove any headers", ) } - default: + case v1beta1.HTTPRouteFilterExtensionRef: // "If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. // Instead, requests that would have been processed by that filter MUST receive a HTTP error response." errMsg := fmt.Sprintf("Unknown custom filter type: %s", filter.Type) @@ -1039,6 +1039,19 @@ func (t *Translator) ProcessHTTPRoutes(httpRoutes []*v1beta1.HTTPRoute, gateways Body: &errMsg, StatusCode: 500, } + default: + // Unsupported filters. + errMsg := fmt.Sprintf("Unsupported filter type: %s", filter.Type) + parentRef.SetCondition(httpRoute, + v1beta1.RouteConditionAccepted, + metav1.ConditionFalse, + v1beta1.RouteReasonUnsupportedValue, + errMsg, + ) + directResponse = &ir.DirectResponse{ + Body: &errMsg, + StatusCode: 500, + } } } @@ -1181,7 +1194,11 @@ func (t *Translator) ProcessHTTPRoutes(httpRoutes []*v1beta1.HTTPRoute, gateways v1beta1.RouteReasonNoMatchingListenerHostname, "There were no hostname intersections between the HTTPRoute and this parent ref's Listener(s).", ) - } else { + } + + // If no negative conditions have been set, the route is considered "Accepted=True". + if parentRef.httpRoute != nil && + len(parentRef.httpRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 { parentRef.SetCondition(httpRoute, v1beta1.RouteConditionAccepted, metav1.ConditionTrue, @@ -1361,7 +1378,11 @@ func (t *Translator) ProcessTLSRoutes(tlsRoutes []*v1alpha2.TLSRoute, gateways [ v1beta1.RouteReasonNoMatchingListenerHostname, "There were no hostname intersections between the HTTPRoute and this parent ref's Listener(s).", ) - } else { + } + + // If no negative conditions have been set, the route is considered "Accepted=True". + if parentRef.tlsRoute != nil && + len(parentRef.tlsRoute.Status.Parents[parentRef.routeParentStatusIdx].Conditions) == 0 { parentRef.SetCondition(tlsRoute, v1beta1.RouteConditionAccepted, metav1.ConditionTrue,