From a88271b35d334b0fd8741fa4441e6b5f25062d95 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Wed, 30 Apr 2025 22:43:49 +0000 Subject: [PATCH] add redirect-port and redirect scheme mesh tests --- .../tests/mesh/httproute-redirect-port.go | 113 +++++++++++++++++ .../tests/mesh/httproute-redirect-port.yaml | 48 ++++++++ .../tests/mesh/httproute-redirect-scheme.go | 116 ++++++++++++++++++ .../tests/mesh/httproute-redirect-scheme.yaml | 49 ++++++++ .../tests/mesh/httproute-rewrite-path.go | 2 +- pkg/features/mesh.go | 17 +++ 6 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 conformance/tests/mesh/httproute-redirect-port.go create mode 100644 conformance/tests/mesh/httproute-redirect-port.yaml create mode 100644 conformance/tests/mesh/httproute-redirect-scheme.go create mode 100644 conformance/tests/mesh/httproute-redirect-scheme.yaml diff --git a/conformance/tests/mesh/httproute-redirect-port.go b/conformance/tests/mesh/httproute-redirect-port.go new file mode 100644 index 0000000000..cae14c230e --- /dev/null +++ b/conformance/tests/mesh/httproute-redirect-port.go @@ -0,0 +1,113 @@ +/* +Copyright 2025 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 meshtests + +import ( + "testing" + + "sigs.k8s.io/gateway-api/conformance/utils/echo" + "sigs.k8s.io/gateway-api/conformance/utils/http" + "sigs.k8s.io/gateway-api/conformance/utils/roundtripper" + "sigs.k8s.io/gateway-api/conformance/utils/suite" + "sigs.k8s.io/gateway-api/pkg/features" +) + +func init() { + MeshConformanceTests = append(MeshConformanceTests, MeshHTTPRouteRedirectPort) +} + +var MeshHTTPRouteRedirectPort = suite.ConformanceTest{ + ShortName: "MeshHTTPRouteRedirectPort", + Description: "An HTTPRoute with a port redirect filter", + Manifests: []string{"tests/mesh/httproute-redirect-port.yaml"}, + Features: []features.FeatureName{ + features.SupportMesh, + features.SupportHTTPRoute, + features.SupportMeshHTTPRouteRedirectPort, + }, + Test: func(t *testing.T, s *suite.ConformanceTestSuite) { + ns := "gateway-conformance-mesh" + client := echo.ConnectToApp(t, s, echo.MeshAppEchoV1) + + testCases := []http.ExpectedResponse{ + { + Request: http.Request{ + Host: "echo", + Path: "/port", + UnfollowRedirect: true, + }, + Response: http.Response{ + StatusCode: 302, + }, + RedirectRequest: &roundtripper.RedirectRequest{ + Port: "8083", + }, + Namespace: ns, + }, { + Request: http.Request{ + Host: "echo", + Path: "/port-and-host", + UnfollowRedirect: true, + }, + Response: http.Response{ + StatusCode: 302, + }, + RedirectRequest: &roundtripper.RedirectRequest{ + Host: "example.org", + Port: "8083", + }, + Namespace: ns, + }, { + Request: http.Request{ + Host: "echo", + Path: "/port-and-status", + UnfollowRedirect: true, + }, + Response: http.Response{ + StatusCode: 301, + }, + RedirectRequest: &roundtripper.RedirectRequest{ + Port: "8083", + }, + Namespace: ns, + }, { + Request: http.Request{ + Host: "echo", + Path: "/port-and-host-and-status", + UnfollowRedirect: true, + }, + Response: http.Response{ + StatusCode: 302, + }, + RedirectRequest: &roundtripper.RedirectRequest{ + Port: "8083", + Host: "example.org", + }, + Namespace: ns, + }, + } + for i := range testCases { + // Declare tc here to avoid loop variable + // reuse issues across parallel tests. + tc := testCases[i] + t.Run(tc.GetTestCaseName(i), func(t *testing.T) { + t.Parallel() + client.MakeRequestAndExpectEventuallyConsistentResponse(t, tc, s.TimeoutConfig) + }) + } + }, +} diff --git a/conformance/tests/mesh/httproute-redirect-port.yaml b/conformance/tests/mesh/httproute-redirect-port.yaml new file mode 100644 index 0000000000..522d67327e --- /dev/null +++ b/conformance/tests/mesh/httproute-redirect-port.yaml @@ -0,0 +1,48 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: mesh-redirect-port + namespace: gateway-conformance-mesh +spec: + parentRefs: + - group: "" + kind: Service + name: echo + port: 80 + rules: + - matches: + - path: + type: PathPrefix + value: /port + filters: + - type: RequestRedirect + requestRedirect: + port: 8083 + - matches: + - path: + type: PathPrefix + value: /port-and-host + filters: + - type: RequestRedirect + requestRedirect: + hostname: example.org + port: 8083 + - matches: + - path: + type: PathPrefix + value: /port-and-status + filters: + - type: RequestRedirect + requestRedirect: + port: 8083 + statusCode: 301 + - matches: + - path: + type: PathPrefix + value: /port-and-host-and-status + filters: + - type: RequestRedirect + requestRedirect: + port: 8083 + hostname: example.org + statusCode: 302 diff --git a/conformance/tests/mesh/httproute-redirect-scheme.go b/conformance/tests/mesh/httproute-redirect-scheme.go new file mode 100644 index 0000000000..e241730914 --- /dev/null +++ b/conformance/tests/mesh/httproute-redirect-scheme.go @@ -0,0 +1,116 @@ +/* +Copyright 2025 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 meshtests + +import ( + "testing" + + "sigs.k8s.io/gateway-api/conformance/utils/echo" + "sigs.k8s.io/gateway-api/conformance/utils/http" + "sigs.k8s.io/gateway-api/conformance/utils/roundtripper" + "sigs.k8s.io/gateway-api/conformance/utils/suite" + "sigs.k8s.io/gateway-api/pkg/features" +) + +func init() { + MeshConformanceTests = append(MeshConformanceTests, MeshHTTPRouteSchemeRedirect) +} + +var MeshHTTPRouteSchemeRedirect = suite.ConformanceTest{ + ShortName: "MeshHTTPRouteSchemeRedirect", + Description: "An HTTPRoute with a scheme redirect filter", + Manifests: []string{"tests/mesh/httproute-redirect-scheme.yaml"}, + Features: []features.FeatureName{ + features.SupportMesh, + features.SupportHTTPRoute, + features.SupportMeshHTTPRouteSchemeRedirect, + }, + Test: func(t *testing.T, s *suite.ConformanceTestSuite) { + ns := "gateway-conformance-mesh" + client := echo.ConnectToApp(t, s, echo.MeshAppEchoV1) + + testCases := []http.ExpectedResponse{ + { + Request: http.Request{ + Host: "echo", + Path: "/scheme", + UnfollowRedirect: true, + }, + Response: http.Response{ + StatusCode: 302, + }, + RedirectRequest: &roundtripper.RedirectRequest{ + Scheme: "https", + }, + Namespace: ns, + }, + { + Request: http.Request{ + Host: "echo", + Path: "/scheme-and-host", + UnfollowRedirect: true, + }, + Response: http.Response{ + StatusCode: 302, + }, + RedirectRequest: &roundtripper.RedirectRequest{ + Host: "example.org", + Scheme: "https", + }, + Namespace: ns, + }, + { + Request: http.Request{ + Host: "echo", + Path: "/scheme-and-status", + UnfollowRedirect: true, + }, + Response: http.Response{ + StatusCode: 301, + }, + RedirectRequest: &roundtripper.RedirectRequest{ + Scheme: "https", + }, + Namespace: ns, + }, + { + Request: http.Request{ + Host: "echo", + Path: "/scheme-and-host-and-status", + UnfollowRedirect: true, + }, + Response: http.Response{ + StatusCode: 302, + }, + RedirectRequest: &roundtripper.RedirectRequest{ + Scheme: "https", + Host: "example.org", + }, + Namespace: ns, + }, + } + for i := range testCases { + // Declare tc here to avoid loop variable + // reuse issues across parallel tests. + tc := testCases[i] + t.Run(tc.GetTestCaseName(i), func(t *testing.T) { + t.Parallel() + client.MakeRequestAndExpectEventuallyConsistentResponse(t, tc, s.TimeoutConfig) + }) + } + }, +} diff --git a/conformance/tests/mesh/httproute-redirect-scheme.yaml b/conformance/tests/mesh/httproute-redirect-scheme.yaml new file mode 100644 index 0000000000..b5f4628cd9 --- /dev/null +++ b/conformance/tests/mesh/httproute-redirect-scheme.yaml @@ -0,0 +1,49 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: mesh-redirect-scheme + namespace: gateway-conformance-mesh +spec: + parentRefs: + - group: "" + kind: Service + name: echo + port: 80 + rules: + - matches: + - path: + type: PathPrefix + value: /scheme + filters: + - type: RequestRedirect + requestRedirect: + scheme: "https" + - matches: + - path: + type: PathPrefix + value: /scheme-and-host + filters: + - type: RequestRedirect + requestRedirect: + hostname: example.org + scheme: "https" + - matches: + - path: + type: PathPrefix + value: /scheme-and-status + filters: + - type: RequestRedirect + requestRedirect: + scheme: "https" + statusCode: 301 + - matches: + - path: + type: PathPrefix + value: /scheme-and-host-and-status + filters: + - type: RequestRedirect + requestRedirect: + scheme: "https" + statusCode: 302 + hostname: example.org + diff --git a/conformance/tests/mesh/httproute-rewrite-path.go b/conformance/tests/mesh/httproute-rewrite-path.go index 79416a96c8..22f8ae66a3 100644 --- a/conformance/tests/mesh/httproute-rewrite-path.go +++ b/conformance/tests/mesh/httproute-rewrite-path.go @@ -34,8 +34,8 @@ var MeshHTTPRouteRewritePath = suite.ConformanceTest{ Description: "An HTTPRoute with path rewrite filter", Features: []features.FeatureName{ features.SupportMesh, - features.SupportMeshHTTPRouteRewritePath, features.SupportHTTPRoute, + features.SupportMeshHTTPRouteRewritePath, }, Manifests: []string{"tests/mesh/httproute-rewrite-path.yaml"}, Test: func(t *testing.T, s *suite.ConformanceTestSuite) { diff --git a/pkg/features/mesh.go b/pkg/features/mesh.go index 711681c58c..18c29e4cbd 100644 --- a/pkg/features/mesh.go +++ b/pkg/features/mesh.go @@ -50,6 +50,10 @@ const ( SupportMeshConsumerRoute FeatureName = "MeshConsumerRoute" // This option indicates mesh support for HTTPRoute path rewrite (extended conformance) SupportMeshHTTPRouteRewritePath FeatureName = "MeshHTTPRouteRewritePath" + // This option indicates mesh support for HTTPRoute scheme redirect (extended conformance) + SupportMeshHTTPRouteSchemeRedirect FeatureName = "MeshHTTPRouteSchemeRedirect" + // This option indicates mesh support for HTTPRoute port redirect (extended conformance) + SupportMeshHTTPRouteRedirectPort FeatureName = "MeshHTTPRouteRedirectPort" ) var ( @@ -69,6 +73,18 @@ var ( Name: SupportMeshHTTPRouteRewritePath, Channel: FeatureChannelStandard, } + + // MeshHTTPRouteSchemeRedirect contains metadata for the MeshHTTPRouteSchemeRedirect feature. + MeshHTTPRouteSchemeRedirect = Feature{ + Name: SupportMeshHTTPRouteRewritePath, + Channel: FeatureChannelStandard, + } + + // MeshHTTPRouteRedirectPort contains metadata for the MeshHTTPRouteRedirectPort feature. + MeshHTTPRouteRedirectPort = Feature{ + Name: SupportMeshHTTPRouteRedirectPort, + Channel: FeatureChannelStandard, + } ) // MeshExtendedFeatures includes all the supported features for the service mesh at @@ -77,4 +93,5 @@ var MeshExtendedFeatures = sets.New( MeshClusterIPMatchingFeature, MeshConsumerRouteFeature, MeshHTTPRouteRewritePath, + MeshHTTPRouteSchemeRedirect, )