From e9d26ee418e14e410e3010d2c4771554b7c62a6a Mon Sep 17 00:00:00 2001 From: Steve Kriss Date: Fri, 30 Jul 2021 14:41:51 -0600 Subject: [PATCH] internal/dag: improve TLSRoute selection test coverage Adds test coverage for the matching of TLSRoutes with Gateways. Updates #3440. Signed-off-by: Steve Kriss --- internal/dag/builder_test.go | 631 +++++++++++++++++++++++++---------- 1 file changed, 455 insertions(+), 176 deletions(-) diff --git a/internal/dag/builder_test.go b/internal/dag/builder_test.go index fb969339b04..4e33bbfb03d 100644 --- a/internal/dag/builder_test.go +++ b/internal/dag/builder_test.go @@ -305,6 +305,81 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, } + gatewayTLSRouteSameNamespace := &gatewayapi_v1alpha1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "contour", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.GatewaySpec{ + GatewayClassName: validClass.Name, + Listeners: []gatewayapi_v1alpha1.Listener{{ + Port: 80, + Protocol: gatewayapi_v1alpha1.TLSProtocolType, + TLS: &gatewayapi_v1alpha1.GatewayTLSConfig{ + Mode: tlsModeTypePtr(gatewayapi_v1alpha1.TLSModePassthrough), + }, + Routes: gatewayapi_v1alpha1.RouteBindingSelector{ + Kind: KindTLSRoute, + Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ + From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectSame), + }, + }, + }}, + }, + } + + gatewayTLSRouteNamespaceSelector := &gatewayapi_v1alpha1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "contour", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.GatewaySpec{ + GatewayClassName: validClass.Name, + Listeners: []gatewayapi_v1alpha1.Listener{{ + Port: 80, + Protocol: gatewayapi_v1alpha1.TLSProtocolType, + TLS: &gatewayapi_v1alpha1.GatewayTLSConfig{ + Mode: tlsModeTypePtr(gatewayapi_v1alpha1.TLSModePassthrough), + }, + Routes: gatewayapi_v1alpha1.RouteBindingSelector{ + Kind: KindTLSRoute, + Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ + From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectSelector), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"matching-label-key": "matching-label-value"}, + }, + }, + }, + }}, + }, + } + + gatewayTLSRouteWithRouteSelector := &gatewayapi_v1alpha1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "contour", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.GatewaySpec{ + GatewayClassName: validClass.Name, + Listeners: []gatewayapi_v1alpha1.Listener{{ + Port: 80, + Protocol: gatewayapi_v1alpha1.TLSProtocolType, + TLS: &gatewayapi_v1alpha1.GatewayTLSConfig{ + Mode: tlsModeTypePtr(gatewayapi_v1alpha1.TLSModePassthrough), + }, + Routes: gatewayapi_v1alpha1.RouteBindingSelector{ + Kind: KindTLSRoute, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"matching-label-key": "matching-label-value"}, + }, + Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ + From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectAll), + }, + }, + }}, + }, + } + gatewayTLSRouteModePassthrough := &gatewayapi_v1alpha1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Name: "contour", @@ -1091,19 +1166,11 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, want: listeners(), }, - "TLSRoute with TLS.Mode=Passthrough is valid": { + // BEGIN TLSRoute<->Gateway selection test cases + "TLSRoute: Gateway selects TLSRoutes in all namespaces": { gatewayclass: validClass, - gateway: gatewayTLSRouteModePassthrough, + gateway: gatewayTLSRouteNoSelector, objs: []interface{}{ - &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "custom", - Labels: map[string]string{ - "app": "contour", - "type": "controller", - }, - }, - }, kuardServiceCustomNs, &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ @@ -1142,40 +1209,15 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, ), }, - "TLSRoute with TLS.Mode=Passthrough is invalid if certificateRef is specified": { + "TLSRoute: Gateway selects TLSRoutes in same namespace, and route is in the same namespace": { gatewayclass: validClass, - gateway: &gatewayapi_v1alpha1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Name: "contour", - Namespace: "projectcontour", - }, - Spec: gatewayapi_v1alpha1.GatewaySpec{ - Listeners: []gatewayapi_v1alpha1.Listener{{ - Port: 80, - Protocol: gatewayapi_v1alpha1.TLSProtocolType, - TLS: &gatewayapi_v1alpha1.GatewayTLSConfig{ - Mode: tlsModeTypePtr(gatewayapi_v1alpha1.TLSModePassthrough), - CertificateRef: &gatewayapi_v1alpha1.LocalObjectReference{ - Group: "core", - Kind: "Secret", - Name: sec1.Name, - }, - }, - Routes: gatewayapi_v1alpha1.RouteBindingSelector{ - Kind: KindTLSRoute, - Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ - From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectAll), - }, - }, - }}, - }, - }, + gateway: gatewayTLSRouteSameNamespace, objs: []interface{}{ kuardService, &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ Name: "basic", - Namespace: "projectcontour", + Namespace: gatewayTLSRouteSameNamespace.Namespace, }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ @@ -1192,26 +1234,32 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, }, }, - want: listeners(), + want: listeners( + &Listener{ + Port: 443, + VirtualHosts: virtualhosts( + &SecureVirtualHost{ + VirtualHost: VirtualHost{ + Name: "test.projectcontour.io", + ListenerName: "ingress_https", + }, + TCPProxy: &TCPProxy{ + Clusters: clustersWeight(service(kuardService)), + }, + }, + ), + }, + ), }, - "TLSRoute with TLS.Mode=Terminate is invalid when TLS certificate reference is not defined": { + "TLSRoute: Gateway selects TLSRoutes in same namespace, and route is not in the same namespace": { gatewayclass: validClass, - gateway: gatewayTLSRouteModeTerminate, + gateway: gatewayTLSRouteSameNamespace, objs: []interface{}{ - &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "custom", - Labels: map[string]string{ - "app": "contour", - "type": "controller", - }, - }, - }, kuardServiceCustomNs, &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ Name: "basic", - Namespace: "custom", + Namespace: kuardServiceCustomNs.Namespace, }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ @@ -1230,32 +1278,21 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, want: listeners(), }, - "TLSRoute with TLS not defined is invalid": { + "TLSRoute: Gateway selects TLSRoutes in namespaces matching selector, and route is in a matching namespace": { gatewayclass: validClass, - gateway: &gatewayapi_v1alpha1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Name: "contour", - Namespace: "projectcontour", - }, - Spec: gatewayapi_v1alpha1.GatewaySpec{ - Listeners: []gatewayapi_v1alpha1.Listener{{ - Port: 80, - Protocol: gatewayapi_v1alpha1.TLSProtocolType, - Routes: gatewayapi_v1alpha1.RouteBindingSelector{ - Kind: KindTLSRoute, - Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ - From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectAll), - }, - }, - }}, - }, - }, + gateway: gatewayTLSRouteNamespaceSelector, objs: []interface{}{ - kuardService, + kuardServiceCustomNs, + &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: kuardServiceCustomNs.Namespace, + Labels: map[string]string{"matching-label-key": "matching-label-value"}, + }, + }, &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ Name: "basic", - Namespace: "projectcontour", + Namespace: kuardServiceCustomNs.Namespace, }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ @@ -1272,78 +1309,38 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, }, }, - want: listeners(), - }, - "TLSRoute with invalid listener protocol of HTTP": { - gatewayclass: validClass, - gateway: &gatewayapi_v1alpha1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Name: "contour", - Namespace: "projectcontour", - }, - Spec: gatewayapi_v1alpha1.GatewaySpec{ - Listeners: []gatewayapi_v1alpha1.Listener{{ - Port: 80, - Protocol: gatewayapi_v1alpha1.HTTPProtocolType, - TLS: &gatewayapi_v1alpha1.GatewayTLSConfig{ - Mode: tlsModeTypePtr(gatewayapi_v1alpha1.TLSModePassthrough), - CertificateRef: &gatewayapi_v1alpha1.LocalObjectReference{ - Group: "core", - Kind: "Secret", - Name: sec1.Name, + want: listeners( + &Listener{ + Port: 443, + VirtualHosts: virtualhosts( + &SecureVirtualHost{ + VirtualHost: VirtualHost{ + Name: "test.projectcontour.io", + ListenerName: "ingress_https", }, - }, - Routes: gatewayapi_v1alpha1.RouteBindingSelector{ - Kind: KindTLSRoute, - Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ - From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectAll), + TCPProxy: &TCPProxy{ + Clusters: clustersWeight(service(kuardServiceCustomNs)), }, }, - }}, - }, - }, - objs: []interface{}{ - kuardService, - &gatewayapi_v1alpha1.TLSRoute{ - ObjectMeta: metav1.ObjectMeta{ - Name: "basic", - Namespace: "projectcontour", - }, - Spec: gatewayapi_v1alpha1.TLSRouteSpec{ - Gateways: &gatewayapi_v1alpha1.RouteGateways{ - Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), - }, - Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ - Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ - SNIs: []gatewayapi_v1alpha1.Hostname{ - "test.projectcontour.io", - }, - }}, - ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), - }}, - }, + ), }, - }, - want: listeners(), + ), }, - "TLSRoute with invalid listener kind": { + "TLSRoute: Gateway selects TLSRoutes in namespaces matching selector, and route is in a non-matching namespace": { gatewayclass: validClass, - gateway: gatewayNoSelector, + gateway: gatewayTLSRouteNamespaceSelector, objs: []interface{}{ + kuardServiceCustomNs, &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ - Name: "custom", - Labels: map[string]string{ - "app": "contour", - "type": "controller", - }, + Name: kuardServiceCustomNs.Namespace, + Labels: map[string]string{"matching-label-key": "this-label-value-does-not-match"}, }, }, - kuardServiceCustomNs, &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ Name: "basic", - Namespace: "custom", + Namespace: kuardServiceCustomNs.Namespace, }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ @@ -1362,26 +1359,17 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, want: listeners(), }, - // TLSRoute is in a different namespace than the Gateway, - // but will be allowed since "All" is set. - "TLSRoute: RouteGateways with GatewayAllowType: All": { + + "TLSRoute: Gateway selects TLSRoutes matching selector, and route matches": { gatewayclass: validClass, - gateway: gatewayTLSRouteNoSelector, + gateway: gatewayTLSRouteWithRouteSelector, objs: []interface{}{ - &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "custom", - Labels: map[string]string{ - "app": "contour", - "type": "controller", - }, - }, - }, kuardServiceCustomNs, &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ Name: "basic", - Namespace: "custom", + Namespace: kuardServiceCustomNs.Namespace, + Labels: map[string]string{"matching-label-key": "matching-label-value"}, }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ @@ -1415,30 +1403,47 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, ), }, - // TLSRoute is in a different namespace than the Gateway, - // and is rejected since "SameNamespace" is set. - "TLSRoute doesn't match with RouteGateways.GatewayAllowType: SameNamespace": { + "TLSRoute: Gateway selects TLSRoutes matching selector, and route does not match": { gatewayclass: validClass, - gateway: gatewayNoSelector, + gateway: gatewayTLSRouteWithRouteSelector, objs: []interface{}{ - &v1.Namespace{ + kuardServiceCustomNs, + &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ - Name: "custom", - Labels: map[string]string{ - "app": "contour", - "type": "controller", + Name: "basic", + Namespace: kuardServiceCustomNs.Namespace, + Labels: map[string]string{"matching-label-key": "this-label-value-does-not-match"}, + }, + Spec: gatewayapi_v1alpha1.TLSRouteSpec{ + Gateways: &gatewayapi_v1alpha1.RouteGateways{ + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), }, + Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ + Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ + SNIs: []gatewayapi_v1alpha1.Hostname{ + "test.projectcontour.io", + }, + }}, + ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), + }}, }, }, + }, + want: listeners(), + }, + "TLSRoute: Gateway selects non-TLSRoutes": { + gatewayclass: validClass, + gateway: gatewayNoSelector, // selects HTTPRoutes, not TLSRoutes + objs: []interface{}{ kuardServiceCustomNs, &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ Name: "basic", - Namespace: "custom", + Namespace: kuardServiceCustomNs.Namespace, }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ - Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowSameNamespace), + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), }, Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ @@ -1453,9 +1458,7 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, want: listeners(), }, - // TLSRoute is in the same namespace of the Gateway, - // and is allowed since "SameNamespace" is set. - "TLSRoute matches with RouteGateways.GatewayAllowType: SameNamespace": { + "TLSRoute: TLSRoute allows Gateways in same namespace, and gateway is in the same namespace": { gatewayclass: validClass, gateway: gatewayTLSRouteNoSelector, objs: []interface{}{ @@ -1463,7 +1466,7 @@ func TestDAGInsertGatewayAPI(t *testing.T) { &gatewayapi_v1alpha1.TLSRoute{ ObjectMeta: metav1.ObjectMeta{ Name: "basic", - Namespace: "projectcontour", + Namespace: kuardService.Namespace, }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ @@ -1497,11 +1500,113 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, ), }, - // TLSRoute references same Gateway is configured with - // in the FromList. - "TLSRoute matches with RouteGateways.GatewayAllowType: FromList": { + "TLSRoute: TLSRoute allows Gateways in same namespace, and gateway is not in the same namespace": { + gatewayclass: validClass, + gateway: gatewayTLSRouteNoSelector, + objs: []interface{}{ + kuardServiceCustomNs, + &gatewayapi_v1alpha1.TLSRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic", + Namespace: kuardServiceCustomNs.Namespace, + }, + Spec: gatewayapi_v1alpha1.TLSRouteSpec{ + Gateways: &gatewayapi_v1alpha1.RouteGateways{ + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowSameNamespace), + }, + Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ + Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ + SNIs: []gatewayapi_v1alpha1.Hostname{ + "test.projectcontour.io", + }, + }}, + ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), + }}, + }, + }, + }, + want: listeners(), + }, + "TLSRoute: TLSRoute allows Gateways from list, and gateway is in the list": { gatewayclass: validClass, gateway: gatewayTLSRouteNoSelector, + objs: []interface{}{ + kuardService, + &gatewayapi_v1alpha1.TLSRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic", + Namespace: kuardService.Namespace, + }, + Spec: gatewayapi_v1alpha1.TLSRouteSpec{ + Gateways: &gatewayapi_v1alpha1.RouteGateways{ + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowFromList), + GatewayRefs: []gatewayapi_v1alpha1.GatewayReference{ + {Namespace: gatewayTLSRouteNoSelector.Namespace, Name: gatewayTLSRouteNoSelector.Name}, + }, + }, + Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ + Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ + SNIs: []gatewayapi_v1alpha1.Hostname{ + "test.projectcontour.io", + }, + }}, + ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), + }}, + }, + }, + }, + want: listeners( + &Listener{ + Port: 443, + VirtualHosts: virtualhosts( + &SecureVirtualHost{ + VirtualHost: VirtualHost{ + Name: "test.projectcontour.io", + ListenerName: "ingress_https", + }, + TCPProxy: &TCPProxy{ + Clusters: clustersWeight(service(kuardService)), + }, + }, + ), + }, + ), + }, + "TLSRoute: TLSRoute allows Gateways from list, and gateway is not in the list": { + gatewayclass: validClass, + gateway: gatewayTLSRouteNoSelector, + objs: []interface{}{ + kuardService, + &gatewayapi_v1alpha1.TLSRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic", + Namespace: kuardService.Namespace, + }, + Spec: gatewayapi_v1alpha1.TLSRouteSpec{ + Gateways: &gatewayapi_v1alpha1.RouteGateways{ + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowFromList), + GatewayRefs: []gatewayapi_v1alpha1.GatewayReference{ + {Namespace: "some-other-namespace", Name: "some-other-gateway-name"}, + }, + }, + Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ + Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ + SNIs: []gatewayapi_v1alpha1.Hostname{ + "test.projectcontour.io", + }, + }}, + ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), + }}, + }, + }, + }, + want: listeners(), + }, + // END TLSRoute<->Gateway selection test cases + + "TLSRoute with TLS.Mode=Passthrough is valid": { + gatewayclass: validClass, + gateway: gatewayTLSRouteModePassthrough, objs: []interface{}{ &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ @@ -1520,11 +1625,7 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ - Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowFromList), - GatewayRefs: []gatewayapi_v1alpha1.GatewayReference{{ - Name: "contour", - Namespace: "projectcontour", - }}, + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), }, Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ @@ -1554,11 +1655,61 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, ), }, - // TLSRoute references different Gateway is configured with - // in the FromList. - "TLSRoute doesn't match with RouteGateways.GatewayAllowType: FromList": { + "TLSRoute with TLS.Mode=Passthrough is invalid if certificateRef is specified": { gatewayclass: validClass, - gateway: gatewayNoSelector, + gateway: &gatewayapi_v1alpha1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "contour", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.GatewaySpec{ + Listeners: []gatewayapi_v1alpha1.Listener{{ + Port: 80, + Protocol: gatewayapi_v1alpha1.TLSProtocolType, + TLS: &gatewayapi_v1alpha1.GatewayTLSConfig{ + Mode: tlsModeTypePtr(gatewayapi_v1alpha1.TLSModePassthrough), + CertificateRef: &gatewayapi_v1alpha1.LocalObjectReference{ + Group: "core", + Kind: "Secret", + Name: sec1.Name, + }, + }, + Routes: gatewayapi_v1alpha1.RouteBindingSelector{ + Kind: KindTLSRoute, + Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ + From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectAll), + }, + }, + }}, + }, + }, + objs: []interface{}{ + kuardService, + &gatewayapi_v1alpha1.TLSRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.TLSRouteSpec{ + Gateways: &gatewayapi_v1alpha1.RouteGateways{ + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), + }, + Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ + Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ + SNIs: []gatewayapi_v1alpha1.Hostname{ + "test.projectcontour.io", + }, + }}, + ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), + }}, + }, + }, + }, + want: listeners(), + }, + "TLSRoute with TLS.Mode=Terminate is invalid when TLS certificate reference is not defined": { + gatewayclass: validClass, + gateway: gatewayTLSRouteModeTerminate, objs: []interface{}{ &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ @@ -1577,11 +1728,139 @@ func TestDAGInsertGatewayAPI(t *testing.T) { }, Spec: gatewayapi_v1alpha1.TLSRouteSpec{ Gateways: &gatewayapi_v1alpha1.RouteGateways{ - Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowFromList), - GatewayRefs: []gatewayapi_v1alpha1.GatewayReference{{ - Name: "wrong", - Namespace: "reference", + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), + }, + Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ + Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ + SNIs: []gatewayapi_v1alpha1.Hostname{ + "test.projectcontour.io", + }, + }}, + ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), + }}, + }, + }, + }, + want: listeners(), + }, + "TLSRoute with TLS not defined is invalid": { + gatewayclass: validClass, + gateway: &gatewayapi_v1alpha1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "contour", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.GatewaySpec{ + Listeners: []gatewayapi_v1alpha1.Listener{{ + Port: 80, + Protocol: gatewayapi_v1alpha1.TLSProtocolType, + Routes: gatewayapi_v1alpha1.RouteBindingSelector{ + Kind: KindTLSRoute, + Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ + From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectAll), + }, + }, + }}, + }, + }, + objs: []interface{}{ + kuardService, + &gatewayapi_v1alpha1.TLSRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.TLSRouteSpec{ + Gateways: &gatewayapi_v1alpha1.RouteGateways{ + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), + }, + Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ + Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ + SNIs: []gatewayapi_v1alpha1.Hostname{ + "test.projectcontour.io", + }, }}, + ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), + }}, + }, + }, + }, + want: listeners(), + }, + "TLSRoute with invalid listener protocol of HTTP": { + gatewayclass: validClass, + gateway: &gatewayapi_v1alpha1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "contour", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.GatewaySpec{ + Listeners: []gatewayapi_v1alpha1.Listener{{ + Port: 80, + Protocol: gatewayapi_v1alpha1.HTTPProtocolType, + TLS: &gatewayapi_v1alpha1.GatewayTLSConfig{ + Mode: tlsModeTypePtr(gatewayapi_v1alpha1.TLSModePassthrough), + CertificateRef: &gatewayapi_v1alpha1.LocalObjectReference{ + Group: "core", + Kind: "Secret", + Name: sec1.Name, + }, + }, + Routes: gatewayapi_v1alpha1.RouteBindingSelector{ + Kind: KindTLSRoute, + Namespaces: &gatewayapi_v1alpha1.RouteNamespaces{ + From: routeSelectTypePtr(gatewayapi_v1alpha1.RouteSelectAll), + }, + }, + }}, + }, + }, + objs: []interface{}{ + kuardService, + &gatewayapi_v1alpha1.TLSRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic", + Namespace: "projectcontour", + }, + Spec: gatewayapi_v1alpha1.TLSRouteSpec{ + Gateways: &gatewayapi_v1alpha1.RouteGateways{ + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), + }, + Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ + Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{ + SNIs: []gatewayapi_v1alpha1.Hostname{ + "test.projectcontour.io", + }, + }}, + ForwardTo: tcpRouteForwardTo("kuard", 8080, nil), + }}, + }, + }, + }, + want: listeners(), + }, + "TLSRoute with invalid listener kind": { + gatewayclass: validClass, + gateway: gatewayNoSelector, + objs: []interface{}{ + &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "custom", + Labels: map[string]string{ + "app": "contour", + "type": "controller", + }, + }, + }, + kuardServiceCustomNs, + &gatewayapi_v1alpha1.TLSRoute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "basic", + Namespace: "custom", + }, + Spec: gatewayapi_v1alpha1.TLSRouteSpec{ + Gateways: &gatewayapi_v1alpha1.RouteGateways{ + Allow: gatewayAllowTypePtr(gatewayapi_v1alpha1.GatewayAllowAll), }, Rules: []gatewayapi_v1alpha1.TLSRouteRule{{ Matches: []gatewayapi_v1alpha1.TLSRouteMatch{{