...

Source file src/sigs.k8s.io/gateway-api/conformance/tests/httproute-redirect-port-and-scheme.go

Documentation: sigs.k8s.io/gateway-api/conformance/tests

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package tests
    18  
    19  import (
    20  	"testing"
    21  
    22  	"k8s.io/apimachinery/pkg/types"
    23  
    24  	"sigs.k8s.io/gateway-api/conformance/utils/http"
    25  	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
    26  	"sigs.k8s.io/gateway-api/conformance/utils/roundtripper"
    27  	"sigs.k8s.io/gateway-api/conformance/utils/suite"
    28  	"sigs.k8s.io/gateway-api/conformance/utils/tls"
    29  )
    30  
    31  func init() {
    32  	ConformanceTests = append(ConformanceTests, HTTPRouteRedirectPortAndScheme)
    33  }
    34  
    35  var HTTPRouteRedirectPortAndScheme = suite.ConformanceTest{
    36  	ShortName:   "HTTPRouteRedirectPortAndScheme",
    37  	Description: "An HTTPRoute with port and scheme redirect filter",
    38  	Manifests:   []string{"tests/httproute-redirect-port-and-scheme.yaml"},
    39  	Features: []suite.SupportedFeature{
    40  		suite.SupportGateway,
    41  		suite.SupportHTTPRoute,
    42  		suite.SupportHTTPRoutePortRedirect,
    43  		suite.SupportGatewayPort8080,
    44  	},
    45  	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
    46  		ns := "gateway-conformance-infra"
    47  
    48  		gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
    49  		routeNN := types.NamespacedName{Name: "http-route-for-listener-on-port-80", Namespace: ns}
    50  		gwAddr80 := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
    51  		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
    52  
    53  		gwNN = types.NamespacedName{Name: "same-namespace-with-http-listener-on-8080", Namespace: ns}
    54  		routeNN = types.NamespacedName{Name: "http-route-for-listener-on-port-8080", Namespace: ns}
    55  		gwAddr8080 := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
    56  		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
    57  
    58  		gwNN = types.NamespacedName{Name: "same-namespace-with-https-listener", Namespace: ns}
    59  		routeNN = types.NamespacedName{Name: "http-route-for-listener-on-port-443", Namespace: ns}
    60  		gwAddr443 := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
    61  		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
    62  
    63  		certNN := types.NamespacedName{Name: "tls-validity-checks-certificate", Namespace: ns}
    64  		cPem, keyPem, err := GetTLSSecret(suite.Client, certNN)
    65  		if err != nil {
    66  			t.Fatalf("unexpected error finding TLS secret: %v", err)
    67  		}
    68  
    69  		// NOTE: In all the test cases, a missing value of expected Port within
    70  		//   RedirectRequest implies that it is still valid and acceptable for a
    71  		//   port to be specified in the redirect if it corresponds to the scheme
    72  		//   (80 and 443).
    73  
    74  		////////////////////////////////////////////////////////////////////////////
    75  		// Test cases that use http-route-for-listener-on-port-80
    76  		////////////////////////////////////////////////////////////////////////////
    77  
    78  		testCases := []http.ExpectedResponse{
    79  			{
    80  				Request: http.Request{
    81  					Path:             "/scheme-nil-and-port-nil",
    82  					UnfollowRedirect: true,
    83  				},
    84  				Response: http.Response{StatusCode: 302},
    85  				RedirectRequest: &roundtripper.RedirectRequest{
    86  					Scheme: "http",
    87  					Host:   "example.org",
    88  				},
    89  				Namespace: ns,
    90  			},
    91  			{
    92  				Request: http.Request{
    93  					Path:             "/scheme-nil-and-port-80",
    94  					UnfollowRedirect: true,
    95  				},
    96  				Response: http.Response{StatusCode: 302},
    97  				RedirectRequest: &roundtripper.RedirectRequest{
    98  					Scheme: "http",
    99  					Host:   "example.org",
   100  				},
   101  				Namespace: ns,
   102  			},
   103  			{
   104  				Request: http.Request{
   105  					Path:             "/scheme-nil-and-port-8080",
   106  					UnfollowRedirect: true,
   107  				},
   108  				Response: http.Response{StatusCode: 302},
   109  				RedirectRequest: &roundtripper.RedirectRequest{
   110  					Scheme: "http",
   111  					Port:   "8080",
   112  					Host:   "example.org",
   113  				},
   114  				Namespace: ns,
   115  			},
   116  			{
   117  				Request: http.Request{
   118  					Path:             "/scheme-https-and-port-nil",
   119  					UnfollowRedirect: true,
   120  				},
   121  				Response: http.Response{StatusCode: 302},
   122  				RedirectRequest: &roundtripper.RedirectRequest{
   123  					Scheme: "https",
   124  					Host:   "example.org",
   125  				},
   126  				Namespace: ns,
   127  			},
   128  			{
   129  				Request: http.Request{
   130  					Path:             "/scheme-https-and-port-443",
   131  					UnfollowRedirect: true,
   132  				},
   133  				Response: http.Response{StatusCode: 302},
   134  				RedirectRequest: &roundtripper.RedirectRequest{
   135  					Scheme: "https",
   136  					Host:   "example.org",
   137  				},
   138  				Namespace: ns,
   139  			},
   140  			{
   141  				Request: http.Request{
   142  					Path:             "/scheme-https-and-port-8443",
   143  					UnfollowRedirect: true,
   144  				},
   145  				Response: http.Response{StatusCode: 302},
   146  				RedirectRequest: &roundtripper.RedirectRequest{
   147  					Scheme: "https",
   148  					Port:   "8443",
   149  					Host:   "example.org",
   150  				},
   151  				Namespace: ns,
   152  			},
   153  		}
   154  
   155  		for i := range testCases {
   156  			tc := testCases[i]
   157  			t.Run("http-listener-on-80/"+tc.GetTestCaseName(i), func(t *testing.T) {
   158  				t.Parallel()
   159  				http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr80, tc)
   160  			})
   161  		}
   162  
   163  		////////////////////////////////////////////////////////////////////////////
   164  		// Test cases that use same-namespace-with-http-listener-on-8080
   165  		////////////////////////////////////////////////////////////////////////////
   166  
   167  		testCases = []http.ExpectedResponse{
   168  			{
   169  				Request: http.Request{
   170  					Path:             "/scheme-nil-and-port-nil",
   171  					UnfollowRedirect: true,
   172  				},
   173  				Response: http.Response{StatusCode: 302},
   174  				RedirectRequest: &roundtripper.RedirectRequest{
   175  					Scheme: "http",
   176  					Port:   "8080",
   177  					Host:   "example.org",
   178  				},
   179  				Namespace: ns,
   180  			},
   181  			{
   182  				Request: http.Request{
   183  					Path:             "/scheme-nil-and-port-80",
   184  					UnfollowRedirect: true,
   185  				},
   186  				Response: http.Response{StatusCode: 302},
   187  				RedirectRequest: &roundtripper.RedirectRequest{
   188  					Scheme: "http",
   189  					Host:   "example.org",
   190  				},
   191  				Namespace: ns,
   192  			},
   193  			{
   194  				Request: http.Request{
   195  					Path:             "/scheme-https-and-port-nil",
   196  					UnfollowRedirect: true,
   197  				},
   198  				Response: http.Response{StatusCode: 302},
   199  				RedirectRequest: &roundtripper.RedirectRequest{
   200  					Scheme: "https",
   201  					Host:   "example.org",
   202  				},
   203  				Namespace: ns,
   204  			},
   205  		}
   206  
   207  		for i := range testCases {
   208  			tc := testCases[i]
   209  			t.Run("http-listener-on-8080/"+tc.GetTestCaseName(i), func(t *testing.T) {
   210  				t.Parallel()
   211  				http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr8080, tc)
   212  			})
   213  		}
   214  
   215  		////////////////////////////////////////////////////////////////////////////
   216  		// Test cases that use http-route-for-listener-on-port-443
   217  		////////////////////////////////////////////////////////////////////////////
   218  
   219  		testCases = []http.ExpectedResponse{
   220  			{
   221  				Request: http.Request{
   222  					Host:             "example.org",
   223  					Path:             "/scheme-nil-and-port-nil",
   224  					UnfollowRedirect: true,
   225  				},
   226  				Response: http.Response{StatusCode: 302},
   227  				RedirectRequest: &roundtripper.RedirectRequest{
   228  					Scheme: "https",
   229  					Host:   "example.org",
   230  				},
   231  				Namespace: ns,
   232  			},
   233  			{
   234  				Request: http.Request{
   235  					Host:             "example.org",
   236  					Path:             "/scheme-nil-and-port-443",
   237  					UnfollowRedirect: true,
   238  				},
   239  				Response: http.Response{StatusCode: 302},
   240  				RedirectRequest: &roundtripper.RedirectRequest{
   241  					Scheme: "https",
   242  					Host:   "example.org",
   243  				},
   244  				Namespace: ns,
   245  			},
   246  			{
   247  				Request: http.Request{
   248  					Host:             "example.org",
   249  					Path:             "/scheme-nil-and-port-8443",
   250  					UnfollowRedirect: true,
   251  				},
   252  				Response: http.Response{StatusCode: 302},
   253  				RedirectRequest: &roundtripper.RedirectRequest{
   254  					Scheme: "https",
   255  					Port:   "8443",
   256  					Host:   "example.org",
   257  				},
   258  				Namespace: ns,
   259  			},
   260  			{
   261  				Request: http.Request{
   262  					Host:             "example.org",
   263  					Path:             "/scheme-http-and-port-nil",
   264  					UnfollowRedirect: true,
   265  				},
   266  				Response: http.Response{StatusCode: 302},
   267  				RedirectRequest: &roundtripper.RedirectRequest{
   268  					Scheme: "http",
   269  					Host:   "example.org",
   270  				},
   271  				Namespace: ns,
   272  			},
   273  			{
   274  				Request: http.Request{
   275  					Host:             "example.org",
   276  					Path:             "/scheme-http-and-port-80",
   277  					UnfollowRedirect: true,
   278  				},
   279  				Response: http.Response{StatusCode: 302},
   280  				RedirectRequest: &roundtripper.RedirectRequest{
   281  					Scheme: "http",
   282  					Host:   "example.org",
   283  				},
   284  				Namespace: ns,
   285  			},
   286  			{
   287  				Request: http.Request{
   288  					Host:             "example.org",
   289  					Path:             "/scheme-http-and-port-8080",
   290  					UnfollowRedirect: true,
   291  				},
   292  				Response: http.Response{StatusCode: 302},
   293  				RedirectRequest: &roundtripper.RedirectRequest{
   294  					Scheme: "http",
   295  					Port:   "8080",
   296  					Host:   "example.org",
   297  				},
   298  				Namespace: ns,
   299  			},
   300  		}
   301  
   302  		for i := range testCases {
   303  			tc := testCases[i]
   304  			t.Run("https-listener-on-443/"+tc.GetTestCaseName(i), func(t *testing.T) {
   305  				t.Parallel()
   306  				tls.MakeTLSRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr443, cPem, keyPem, "example.org", tc)
   307  			})
   308  		}
   309  	},
   310  }
   311  

View as plain text