K2 DONE: L2 network behavior tests pass against the live cluster

R-NET-01 default-deny + R-NET-02 deny-undeclared PASS via run.sh (JUnit+coverage,
exit 0). Fixed 3 real bugs found by running them:
- chainsaw strict list-matching: assert scalar 'phase: Running' not a conditions[] element.
- default-deny blocks the kubelet readiness probe -> drop probes (dest pods just need to run).
- chainsaw report path ../_artifacts resolved to repo-root -> fix to _artifacts (was exit 1).
- swap agnhost->busybox httpd listeners (cached everywhere; cache-timing-proof).
Logged the kubelet-probe finding for WS-NET's T-2.2 default-deny baseline design.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-16 15:46:00 -05:00
1 parent 1b6e59c074
commit e20f17b896
4 files changed
+38 -23

No files matched your search

+3 -1
View File
@@ -46,4 +46,6 @@ spec:
report:
format: JUNIT-TEST
name: chainsaw-report
path: ../_artifacts
# relative to run.sh's CWD (conformance/), which creates this dir; ../_artifacts
# wrongly resolved to repo-root/_artifacts and made chainsaw exit 1 on report write.
path: _artifacts
@@ -44,18 +44,20 @@ spec:
kind: Pod
metadata: { name: declared-dest }
status:
conditions:
- type: Ready
status: "True"
# scalar match — chainsaw does strict (length-equal) list matching, so asserting a
# single condition against the pod's full conditions[] list fails. Running is enough:
# the listener is up once the container runs (no readinessProbe under default-deny).
phase: Running
- assert:
resource:
apiVersion: v1
kind: Pod
metadata: { name: other-dest }
status:
conditions:
- type: Ready
status: "True"
# scalar match — chainsaw does strict (length-equal) list matching, so asserting a
# single condition against the pod's full conditions[] list fails. Running is enough:
# the listener is up once the container runs (no readinessProbe under default-deny).
phase: Running
# -- THEN(declared succeeds): source -> declared-dest:8080 connects. Green Job = allowed.
- name: then-declared-succeeds
@@ -82,21 +82,19 @@ metadata:
spec:
containers:
- name: dest-8080
image: registry.k8s.io/e2e-test-images/agnhost:2.47
args: ["netexec", "--http-port=8080"]
image: busybox:1.36.1
command: ["httpd", "-f", "-p", "8080", "-h", "/tmp"]
ports:
- containerPort: 8080
readinessProbe:
tcpSocket: { port: 8080 }
periodSeconds: 2
# No readinessProbe: under the default-deny baseline the kubelet TCP probe
# (node->pod ingress) is dropped, so the pod would never go Ready. Without a
# probe the container is Ready once running — sufficient for a fixture listener.
- name: dest-9090
image: registry.k8s.io/e2e-test-images/agnhost:2.47
args: ["netexec", "--http-port=9090"]
image: busybox:1.36.1
command: ["httpd", "-f", "-p", "9090", "-h", "/tmp"]
ports:
- containerPort: 9090
readinessProbe:
tcpSocket: { port: 9090 }
periodSeconds: 2
# No readinessProbe (see above): avoids the kubelet-probe-under-default-deny trap.
---
apiVersion: v1
kind: Service
@@ -121,13 +119,13 @@ metadata:
spec:
containers:
- name: dest-8080
image: registry.k8s.io/e2e-test-images/agnhost:2.47
args: ["netexec", "--http-port=8080"]
image: busybox:1.36.1
command: ["httpd", "-f", "-p", "8080", "-h", "/tmp"]
ports:
- containerPort: 8080
readinessProbe:
tcpSocket: { port: 8080 }
periodSeconds: 2
# No readinessProbe: under the default-deny baseline the kubelet TCP probe
# (node->pod ingress) is dropped, so the pod would never go Ready. Without a
# probe the container is Ready once running — sufficient for a fixture listener.
---
apiVersion: v1
kind: Service