Skip to content

Commit

Permalink
feat: implement Backend API for TLSRoute (#4493)
Browse files Browse the repository at this point in the history
add tests for tlsroute with Backend

Signed-off-by: Huabing Zhao <zhaohuabing@gmail.com>
  • Loading branch information
zhaohuabing authored Oct 22, 2024
1 parent 1e6899d commit 544bd9c
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 16 deletions.
13 changes: 8 additions & 5 deletions internal/gatewayapi/testdata/tlsroute-with-backend.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,9 @@ tlsRoutes:
status: "True"
type: Accepted
- lastTransitionTime: null
message: Resource default/backend-ip of type Backend is not supported for
TLSRoute routes
reason: UnsupportedValue
status: "False"
message: Resolved all the Object references for the Route
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
Expand All @@ -122,7 +121,11 @@ xdsIR:
- destination:
name: tlsroute/default/tlsroute-1/rule/-1
settings:
- weight: 1
- addressType: IP
endpoints:
- host: 1.1.1.1
port: 3001
weight: 1
name: tlsroute/default/tlsroute-1
tls:
inspector:
Expand Down
2 changes: 1 addition & 1 deletion internal/gatewayapi/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func (t *Translator) validateBackendRefBackend(backendRef *gwapiv1a2.BackendRef,
return false
}

if kind != resource.KindHTTPRoute {
if kind != resource.KindHTTPRoute && kind != resource.KindTLSRoute {
status.SetRouteStatusCondition(routeStatus,
parentRef.routeParentStatusIdx,
route.GetGeneration(),
Expand Down
20 changes: 10 additions & 10 deletions internal/provider/kubernetes/predicates.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,40 +353,40 @@ func (r *gatewayAPIReconciler) isRouteReferencingBackend(nsName *types.Namespace
httpRouteList := &gwapiv1.HTTPRouteList{}
if err := r.client.List(ctx, httpRouteList, &client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(backendHTTPRouteIndex, nsName.String()),
}); err != nil {
r.log.Error(err, "unable to find associated HTTPRoutes")
}); err != nil && !kerrors.IsNotFound(err) {
r.log.Error(err, "failed to find associated HTTPRoutes")
return false
}

grpcRouteList := &gwapiv1.GRPCRouteList{}
if err := r.client.List(ctx, grpcRouteList, &client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(backendGRPCRouteIndex, nsName.String()),
}); err != nil {
r.log.Error(err, "unable to find associated GRPCRoutes")
}); err != nil && !kerrors.IsNotFound(err) {
r.log.Error(err, "failed to find associated GRPCRoutes")
return false
}

tlsRouteList := &gwapiv1a2.TLSRouteList{}
if err := r.client.List(ctx, tlsRouteList, &client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(backendTLSRouteIndex, nsName.String()),
}); err != nil {
r.log.Error(err, "unable to find associated TLSRoutes")
}); err != nil && !kerrors.IsNotFound(err) {
r.log.Error(err, "failed to find associated TLSRoutes")
return false
}

tcpRouteList := &gwapiv1a2.TCPRouteList{}
if err := r.client.List(ctx, tcpRouteList, &client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(backendTCPRouteIndex, nsName.String()),
}); err != nil {
r.log.Error(err, "unable to find associated TCPRoutes")
}); err != nil && !kerrors.IsNotFound(err) {
r.log.Error(err, "failed to find associated TCPRoutes")
return false
}

udpRouteList := &gwapiv1a2.UDPRouteList{}
if err := r.client.List(ctx, udpRouteList, &client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(backendUDPRouteIndex, nsName.String()),
}); err != nil {
r.log.Error(err, "unable to find associated UDPRoutes")
}); err != nil && !kerrors.IsNotFound(err) {
r.log.Error(err, "failed to find associated UDPRoutes")
return false
}

Expand Down
8 changes: 8 additions & 0 deletions test/e2e/base/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ spec:
allowedRoutes:
namespaces:
from: Same
- name: tls
protocol: TLS
port: 443
tls:
mode: Passthrough
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
Expand Down
27 changes: 27 additions & 0 deletions test/e2e/testdata/tlsroute-to-backend-fqdn.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: tlsroute-to-backend-fqdn
namespace: gateway-conformance-infra
spec:
parentRefs:
- name: same-namespace
sectionName: tls
hostnames:
- "example.com"
rules:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
name: backend-fqdn
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
name: backend-fqdn
namespace: gateway-conformance-infra
spec:
endpoints:
- fqdn:
hostname: tls-backend-2.gateway-conformance-infra.svc.cluster.local
port: 443
41 changes: 41 additions & 0 deletions test/e2e/testdata/tlsroute-to-backend-ip.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: tlsroute-to-backend-ip
namespace: gateway-conformance-infra
spec:
parentRefs:
- name: same-namespace
sectionName: tls
hostnames:
- "example.com"
rules:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
name: backend-ip
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
name: backend-ip
namespace: gateway-conformance-infra
spec:
endpoints:
- ip:
address: 10.96.96.96
port: 443
---
apiVersion: v1
kind: Service
metadata:
name: tls-backend-2-clusterip
namespace: gateway-conformance-infra
spec:
selector:
app: tls-backend-2
clusterIP: 10.96.96.96
ports:
- protocol: TCP
port: 443
targetPort: 8443
File renamed without changes.
89 changes: 89 additions & 0 deletions test/e2e/tests/tlsroute_with_backend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

//go:build e2e

package tests

import (
"testing"

"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/gateway-api/conformance/utils/http"
"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
"sigs.k8s.io/gateway-api/conformance/utils/suite"
)

func init() {
ConformanceTests = append(ConformanceTests, TLSRouteBackendFQDNTest)
ConformanceTests = append(ConformanceTests, TLSRouteBackendIPTest)
}

var TLSRouteBackendFQDNTest = suite.ConformanceTest{
ShortName: "TLSRouteBackendFQDNTest",
Description: "TLSRoutes with a backend ref to a Backend",
Manifests: []string{
"testdata/tlsroute-to-backend-fqdn.yaml",
},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
t.Run("TLSRoute with a FQDN type Backend", func(t *testing.T) {
testTLSRouteWithBackend(t, suite, "tlsroute-to-backend-fqdn", "backend-fqdn")
})
},
}

var TLSRouteBackendIPTest = suite.ConformanceTest{
ShortName: "TLSRouteBackendIPTest",
Description: "TLSRoutes with a backend ref to a Backend",
Manifests: []string{
"testdata/tlsroute-to-backend-ip.yaml",
},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
t.Run("TLSRoute with a IP type Backend", func(t *testing.T) {
testTLSRouteWithBackend(t, suite, "tlsroute-to-backend-ip", "backend-ip")
})
},
}

func testTLSRouteWithBackend(t *testing.T, suite *suite.ConformanceTestSuite, route, backend string) {
ns := "gateway-conformance-infra"
routeNN := types.NamespacedName{Name: route, Namespace: ns}
gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
gwAddr, _ := kubernetes.GatewayAndTLSRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN, "tls"), routeNN)
certNN := types.NamespacedName{Name: "backend-tls-certificate", Namespace: ns}

BackendMustBeAccepted(t, suite.Client, types.NamespacedName{Name: backend, Namespace: ns})

expected := http.ExpectedResponse{
Request: http.Request{
Host: "example.com",
Path: "/",
},
Response: http.Response{
StatusCode: 200,
},
Namespace: ns,
}

req := http.MakeRequest(t, &expected, gwAddr, "HTTPS", "https")

// This test uses the same key/cert pair as both a client cert and server cert
// Both backend and client treat the self-signed cert as a trusted CA
cPem, keyPem, err := GetTLSSecret(suite.Client, certNN)
if err != nil {
t.Fatalf("unexpected error finding TLS secret: %v", err)
}

WaitForConsistentMTLSResponse(
t,
suite.RoundTripper,
req,
expected,
suite.TimeoutConfig.RequiredConsecutiveSuccesses,
suite.TimeoutConfig.MaxTimeToConsistency,
cPem,
keyPem,
"example.com")
}

0 comments on commit 544bd9c

Please sign in to comment.