Skip to content

Commit af206d2

Browse files
committed
Add TLSRoute + ReferenceGrant check
This checks ReferenceGrant rules for TLSRoute against accepting an invalid ReferenceGrant for the backend service. Signed-off-by: Maartje Eyskens <[email protected]>
1 parent 45ba21f commit af206d2

File tree

3 files changed

+235
-0
lines changed

3 files changed

+235
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
Copyright 2022 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+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"k8s.io/apimachinery/pkg/types"
24+
25+
"sigs.k8s.io/gateway-api/apis/v1beta1"
26+
"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
27+
"sigs.k8s.io/gateway-api/conformance/utils/suite"
28+
)
29+
30+
func init() {
31+
ConformanceTests = append(ConformanceTests, TLSRouteInvalidReferenceGrant)
32+
}
33+
34+
var TLSRouteInvalidReferenceGrant = suite.ConformanceTest{
35+
ShortName: "TLSRouteInvalidReferenceGrant",
36+
Description: "A single TLSRoute in the gateway-conformance-infra namespace, with a backendRef in another namespace without valid ReferenceGrant, should not attach to Gateway in the gateway-conformance-infra namespace",
37+
Features: []suite.SupportedFeature{
38+
suite.SupportGateway,
39+
suite.SupportTLSRoute,
40+
suite.SupportReferenceGrant,
41+
},
42+
Manifests: []string{"tests/tlsroute-invalid-reference-grant.yaml"},
43+
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
44+
routeNN := types.NamespacedName{Name: "gateway-conformance-infra-test", Namespace: "gateway-conformance-infra"}
45+
gwNN := types.NamespacedName{Name: "gateway-tlsroute", Namespace: "gateway-conformance-infra"}
46+
47+
kubernetes.GatewayAndTLSRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
48+
49+
t.Run("TLSRoute with BackendRef in another namespace and no ReferenceGrant covering the Service has a ResolvedRefs Condition with status False and Reason RefNotPermitted", func(t *testing.T) {
50+
51+
resolvedRefsCond := metav1.Condition{
52+
Type: string(v1beta1.RouteConditionResolvedRefs),
53+
Status: metav1.ConditionFalse,
54+
Reason: string(v1beta1.RouteReasonRefNotPermitted),
55+
}
56+
57+
kubernetes.TLSRouteMustHaveCondition(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN, resolvedRefsCond)
58+
})
59+
},
60+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
apiVersion: gateway.networking.k8s.io/v1beta1
3+
kind: ReferenceGrant
4+
metadata:
5+
name: reference-grant-wrong-namespace
6+
namespace: gateway-conformance-infra
7+
spec:
8+
from:
9+
- group: gateway.networking.k8s.io
10+
kind: TLSRoute
11+
namespace: gateway-conformance-infra
12+
to:
13+
- group: ""
14+
kind: Service
15+
name: tls-backend
16+
---
17+
apiVersion: gateway.networking.k8s.io/v1beta1
18+
kind: ReferenceGrant
19+
metadata:
20+
name: reference-grant-wrong-from-group
21+
namespace: gateway-conformance-tls-backend
22+
spec:
23+
from:
24+
- group: not-the-group-youre-looking-for
25+
kind: TLSRoute
26+
namespace: gateway-conformance-infra
27+
to:
28+
- group: ""
29+
kind: Service
30+
name: tls-backend
31+
---
32+
apiVersion: gateway.networking.k8s.io/v1beta1
33+
kind: ReferenceGrant
34+
metadata:
35+
name: reference-grant-wrong-from-kind
36+
namespace: gateway-conformance-tls-backend
37+
spec:
38+
from:
39+
- group: gateway.networking.k8s.io
40+
kind: Gateway
41+
namespace: gateway-conformance-infra
42+
to:
43+
- group: ""
44+
kind: Service
45+
name: tls-backend
46+
---
47+
apiVersion: gateway.networking.k8s.io/v1beta1
48+
kind: ReferenceGrant
49+
metadata:
50+
name: reference-grant-wrong-from-namespace
51+
namespace: gateway-conformance-tls-backend
52+
spec:
53+
from:
54+
- group: gateway.networking.k8s.io
55+
kind: TLSRoute
56+
namespace: not-the-namespace-youre-looking-for
57+
to:
58+
- group: ""
59+
kind: Service
60+
name: tls-backend
61+
---
62+
apiVersion: gateway.networking.k8s.io/v1beta1
63+
kind: ReferenceGrant
64+
metadata:
65+
name: reference-grant-wrong-to-group
66+
namespace: gateway-conformance-tls-backend
67+
spec:
68+
from:
69+
- group: gateway.networking.k8s.io
70+
kind: TLSRoute
71+
namespace: gateway-conformance-infra
72+
to:
73+
- group: not-the-group-youre-looking-for
74+
kind: Service
75+
name: tls-backend
76+
---
77+
apiVersion: gateway.networking.k8s.io/v1beta1
78+
kind: ReferenceGrant
79+
metadata:
80+
name: reference-grant-wrong-to-kind
81+
namespace: gateway-conformance-tls-backend
82+
spec:
83+
from:
84+
- group: gateway.networking.k8s.io
85+
kind: TLSRoute
86+
namespace: gateway-conformance-infra
87+
to:
88+
- group: ""
89+
kind: Secret
90+
name: tls-backend
91+
---
92+
apiVersion: gateway.networking.k8s.io/v1beta1
93+
kind: ReferenceGrant
94+
metadata:
95+
name: reference-grant-wrong-to-name
96+
namespace: gateway-conformance-tls-backend
97+
spec:
98+
from:
99+
- group: gateway.networking.k8s.io
100+
kind: TLSRoute
101+
namespace: gateway-conformance-infra
102+
to:
103+
- group: ""
104+
kind: Service
105+
name: not-the-service-youre-looking-for
106+
---
107+
apiVersion: gateway.networking.k8s.io/v1alpha2
108+
kind: TLSRoute
109+
metadata:
110+
name: gateway-conformance-infra-test
111+
namespace: gateway-conformance-infra
112+
spec:
113+
parentRefs:
114+
- name: gateway-tlsroute
115+
hostnames:
116+
- abc.example.com
117+
rules:
118+
- backendRefs:
119+
- name: tls-backend
120+
namespace: gateway-conformance-tls-backend
121+
port: 443
122+
---
123+
apiVersion: gateway.networking.k8s.io/v1beta1
124+
kind: Gateway
125+
metadata:
126+
name: gateway-tlsroute
127+
namespace: gateway-conformance-infra
128+
spec:
129+
gatewayClassName: "{GATEWAY_CLASS_NAME}"
130+
listeners:
131+
- name: https
132+
port: 443
133+
protocol: TLS
134+
hostname: "*.example.com"
135+
allowedRoutes:
136+
namespaces:
137+
from: Same
138+
kinds:
139+
- kind: TLSRoute
140+
tls:
141+
mode: Passthrough

conformance/utils/kubernetes/helpers.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,40 @@ func GatewayAndTLSRoutesMustBeAccepted(t *testing.T, c client.Client, timeoutCon
611611
return gwAddr, hostnames
612612
}
613613

614+
// TLSRouteMustHaveCondition checks that the supplied TLSRoute has the supplied Condition,
615+
// halting after the specified timeout is exceeded.
616+
func TLSRouteMustHaveCondition(t *testing.T, client client.Client, timeoutConfig config.TimeoutConfig, routeNN types.NamespacedName, gwNN types.NamespacedName, condition metav1.Condition) {
617+
t.Helper()
618+
619+
waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, timeoutConfig.TLSRouteMustHaveCondition, true, func(ctx context.Context) (bool, error) {
620+
route := &v1alpha2.TLSRoute{}
621+
err := client.Get(ctx, routeNN, route)
622+
if err != nil {
623+
return false, fmt.Errorf("error fetching TLSRoute: %w", err)
624+
}
625+
626+
parents := route.Status.Parents
627+
var conditionFound bool
628+
for _, parent := range parents {
629+
if err := ConditionsHaveLatestObservedGeneration(route, parent.Conditions); err != nil {
630+
631+
t.Logf("TLSRoute(parentRef=%v) %v", parentRefToString(parent.ParentRef), err)
632+
return false, nil
633+
}
634+
635+
if parent.ParentRef.Name == v1beta1.ObjectName(gwNN.Name) && (parent.ParentRef.Namespace == nil || string(*parent.ParentRef.Namespace) == gwNN.Namespace) {
636+
if findConditionInList(t, parent.Conditions, condition.Type, string(condition.Status), condition.Reason) {
637+
conditionFound = true
638+
}
639+
}
640+
}
641+
642+
return conditionFound, nil
643+
})
644+
645+
require.NoErrorf(t, waitErr, "error waiting for TLSRoute status to have a Condition matching expectations")
646+
}
647+
614648
// TODO(mikemorris): this and parentsMatch could possibly be rewritten as a generic function?
615649
func listenersMatch(t *testing.T, expected, actual []v1beta1.ListenerStatus) bool {
616650
t.Helper()

0 commit comments

Comments
 (0)