From e932a6c4c5fc84ac42d980d4cb922f396190395a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Ma=C5=82ek?= Date: Tue, 15 Nov 2022 14:40:35 +0100 Subject: [PATCH] feat: add RouteReasonNoMatchingParent --- apis/v1beta1/shared_types.go | 6 ++ ...id-parentref-not-matching-listener-port.go | 62 +++++++++++++++++++ ...-parentref-not-matching-listener-port.yaml | 15 +++++ conformance/utils/suite/suite.go | 3 + 4 files changed, 86 insertions(+) create mode 100644 conformance/tests/httproute-invalid-parentref-not-matching-listener-port.go create mode 100644 conformance/tests/httproute-invalid-parentref-not-matching-listener-port.yaml diff --git a/apis/v1beta1/shared_types.go b/apis/v1beta1/shared_types.go index bcb2944821..daf0edd057 100644 --- a/apis/v1beta1/shared_types.go +++ b/apis/v1beta1/shared_types.go @@ -225,6 +225,12 @@ const ( // compatible Listeners whose Hostname matches the route RouteReasonNoMatchingListenerHostname RouteConditionReason = "NoMatchingListenerHostname" + // This reason is used with the "Accepted" condition when there are + // no matching Parents. In the case of Gateways, this can occur when + // a Route ParentRef specifies a Port and/or SectionName that does not + // match any Listeners in the Gateway. + RouteReasonNoMatchingParent RouteConditionReason = "NoMatchingParent" + // This reason is used with the "Accepted" condition when a value for an Enum // is not recognized. RouteReasonUnsupportedValue RouteConditionReason = "UnsupportedValue" diff --git a/conformance/tests/httproute-invalid-parentref-not-matching-listener-port.go b/conformance/tests/httproute-invalid-parentref-not-matching-listener-port.go new file mode 100644 index 0000000000..3ade80809a --- /dev/null +++ b/conformance/tests/httproute-invalid-parentref-not-matching-listener-port.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tests + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + "sigs.k8s.io/gateway-api/apis/v1beta1" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, HTTPRouteInvalidParentRefNotMatchingListenerPort) +} + +var HTTPRouteInvalidParentRefNotMatchingListenerPort = suite.ConformanceTest{ + ShortName: "HTTPRouteInvalidParentRefNotMatchingListenerPort", + Description: "A single HTTPRoute in the gateway-conformance-infra namespace should set the Accepted status to False with reason NoMatchingParent when attempting to bind to a Gateway that does not have a matching ListenerPort.", + Features: []suite.SupportedFeature{suite.SupportRouteDestinationPortMatching}, + Manifests: []string{"tests/httproute-invalid-backendref-not-matching-listener-port.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + routeNN := types.NamespacedName{Name: "httproute-listener-not-matching-route-port", Namespace: "gateway-conformance-infra"} + gwNN := types.NamespacedName{Name: "gateway-listener-not-matching-route-port", Namespace: "gateway-conformance-infra"} + + // The Route must have an Accepted Condition with a NoMatchingParent Reason. + t.Run("HTTPRoute with no matching port in ParentRef has an Accepted Condition with status False and Reason NoMatchingParent", func(t *testing.T) { + resolvedRefsCond := metav1.Condition{ + Type: string(v1beta1.RouteConditionAccepted), + Status: metav1.ConditionFalse, + Reason: string(v1beta1.RouteReasonNoMatchingParent), + } + + kubernetes.HTTPRouteMustHaveCondition(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN, resolvedRefsCond) + }) + + t.Run("Route should not have Parents accepted in status", func(t *testing.T) { + kubernetes.HTTPRouteMustHaveNoAcceptedParents(t, suite.Client, suite.TimeoutConfig, routeNN) + }) + + t.Run("Gateway should have 0 Routes attached", func(t *testing.T) { + kubernetes.GatewayMustHaveZeroRoutes(t, suite.Client, suite.TimeoutConfig, gwNN) + }) + }, +} diff --git a/conformance/tests/httproute-invalid-parentref-not-matching-listener-port.yaml b/conformance/tests/httproute-invalid-parentref-not-matching-listener-port.yaml new file mode 100644 index 0000000000..b89206e139 --- /dev/null +++ b/conformance/tests/httproute-invalid-parentref-not-matching-listener-port.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: httproute-listener-not-matching-route-port + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + namespace: gateway-conformance-infra + # mismatched port here (81 is not an available gateway listener) triggers NoMatchingParent reason + port: 81 + rules: + - backendRefs: + - name: infra-backend-v1 + kind: Service diff --git a/conformance/utils/suite/suite.go b/conformance/utils/suite/suite.go index 1b1cdf3d08..42afe128d2 100644 --- a/conformance/utils/suite/suite.go +++ b/conformance/utils/suite/suite.go @@ -48,6 +48,9 @@ const ( // This option indicates support for HTTPRoute response header modification (extended conformance). SupportHTTPResponseHeaderModification SupportedFeature = "HTTPResponseHeaderModification" + + // This option indicates support for Destination Port matching (extended conformance). + SupportRouteDestinationPortMatching SupportedFeature = "RouteDestinationPortMatching" ) // StandardCoreFeatures are the features that are required to be conformant with