Skip to content

Commit 1c6199d

Browse files
committed
test: add e2e for TrafficProtectionPolicy Enforce serving traffic
Chainsaw regression for #243. Deploys a backend, a Gateway on the WAF GatewayClass with an HTTPRoute, and a TrafficProtectionPolicy in Enforce mode, then probes the downstream Envoy over the wire and asserts a benign GET returns 200 rather than the empty/5xx reply the unescaped error-page body produces. Gateway.status.Programmed alone is insufficient — Envoy Gateway reports it from its own translation, independent of Envoy's xDS ACK — so the test asserts on an actual HTTP response. Requires the WAF data plane (extension-server + the extensionManager Envoy Gateway on the datum-downstream-gateway class); environments without it skip via the unmet Programmed assertion. Refs #243 Key changes: - add test/e2e/trafficprotectionpolicy-enforce/chainsaw-test.yaml
1 parent 7419999 commit 1c6199d

1 file changed

Lines changed: 161 additions & 0 deletions

File tree

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
2+
apiVersion: chainsaw.kyverno.io/v1alpha1
3+
kind: Test
4+
metadata:
5+
name: trafficprotectionpolicy-enforce-serves-traffic
6+
# Regression for issue #243: a TrafficProtectionPolicy in Enforce mode must not
7+
# take the gateway offline. The branded error page NSO injects into Envoy's
8+
# local_reply_config is a SubstitutionFormatString, so an unescaped '%' in the
9+
# page (e.g. CSS "height: 100%") makes Envoy reject the whole listener and, with
10+
# failOpen:false, drops the xDS update fleet-wide — every request then fails
11+
# with an empty reply instead of the backend's 200.
12+
#
13+
# Precondition: the downstream (nso-infra) must have the WAF data plane wired up
14+
# (extension-server + the extensionManager Envoy Gateway registered on the
15+
# `datum-downstream-gateway` GatewayClass, with the Coraza filter). The stock
16+
# `make prepare-infra-cluster` does NOT install this; this test is skipped by
17+
# CI environments without it (the Gateway never reaches Programmed=True).
18+
spec:
19+
cluster: nso-infra
20+
# EG only reconciles namespaces carrying this label.
21+
namespaceTemplate:
22+
metadata:
23+
labels:
24+
meta.datumapis.com/upstream-cluster-name: e2e
25+
bindings:
26+
- name: hostname
27+
value: (join('.', [$namespace, 'e2e.test']))
28+
steps:
29+
- name: Deploy a backend
30+
try:
31+
- apply:
32+
resource:
33+
apiVersion: apps/v1
34+
kind: Deployment
35+
metadata:
36+
name: echo
37+
spec:
38+
replicas: 1
39+
selector:
40+
matchLabels:
41+
app: echo
42+
template:
43+
metadata:
44+
labels:
45+
app: echo
46+
spec:
47+
containers:
48+
- name: echo
49+
image: hashicorp/http-echo:1.0
50+
args: ["-text=hello from backend", "-listen=:8080"]
51+
ports:
52+
- containerPort: 8080
53+
- apply:
54+
resource:
55+
apiVersion: v1
56+
kind: Service
57+
metadata:
58+
name: echo
59+
spec:
60+
selector:
61+
app: echo
62+
ports:
63+
- port: 80
64+
targetPort: 8080
65+
- assert:
66+
resource:
67+
apiVersion: apps/v1
68+
kind: Deployment
69+
metadata:
70+
name: echo
71+
status:
72+
availableReplicas: 1
73+
74+
- name: Route through the WAF gateway with an Enforce policy
75+
try:
76+
- apply:
77+
resource:
78+
apiVersion: gateway.networking.k8s.io/v1
79+
kind: Gateway
80+
metadata:
81+
name: waf-gw
82+
spec:
83+
gatewayClassName: datum-downstream-gateway
84+
listeners:
85+
- name: http
86+
protocol: HTTP
87+
port: 80
88+
hostname: ($hostname)
89+
allowedRoutes:
90+
namespaces:
91+
from: Same
92+
- apply:
93+
resource:
94+
apiVersion: gateway.networking.k8s.io/v1
95+
kind: HTTPRoute
96+
metadata:
97+
name: echo
98+
spec:
99+
parentRefs:
100+
- name: waf-gw
101+
hostnames:
102+
- ($hostname)
103+
rules:
104+
- matches:
105+
- path:
106+
type: PathPrefix
107+
value: /
108+
backendRefs:
109+
- name: echo
110+
port: 80
111+
- apply:
112+
resource:
113+
apiVersion: networking.datumapis.com/v1alpha
114+
kind: TrafficProtectionPolicy
115+
metadata:
116+
name: enforce-waf
117+
spec:
118+
mode: Enforce
119+
targetRefs:
120+
- group: gateway.networking.k8s.io
121+
kind: Gateway
122+
name: waf-gw
123+
ruleSets:
124+
- type: OWASPCoreRuleSet
125+
owaspCoreRuleSet: {}
126+
- assert:
127+
resource:
128+
apiVersion: gateway.networking.k8s.io/v1
129+
kind: Gateway
130+
metadata:
131+
name: waf-gw
132+
status:
133+
(conditions[?type == 'Programmed']):
134+
- status: "True"
135+
136+
- name: Benign traffic must reach the backend (not an empty/5xx reply)
137+
description: >
138+
Probe the downstream Envoy via the kind hostPort (30080). Before the fix
139+
the listener is rejected and curl returns 000 / empty reply; after the
140+
fix a benign GET returns the backend's 200. Gateway.status.Programmed is
141+
not sufficient on its own — EG reports Programmed from its own
142+
translation, independent of Envoy's xDS ACK — so this asserts on the
143+
wire.
144+
try:
145+
- script:
146+
env:
147+
- name: HOSTNAME
148+
value: ($hostname)
149+
content: |
150+
set -u
151+
for i in $(seq 1 30); do
152+
code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 5 \
153+
-H "Host: ${HOSTNAME}" http://localhost:30080/) || code=000
154+
echo "attempt ${i}: HTTP ${code}"
155+
if [ "${code}" = "200" ]; then
156+
exit 0
157+
fi
158+
sleep 3
159+
done
160+
echo "benign request never returned 200 (issue #243 regression)"
161+
exit 1

0 commit comments

Comments
 (0)