# ============================================================================= # L3 FAULT-INJECTION SCAFFOLD — VPN kill-switch (R-NET-06) *SAFETY-CRITICAL* # Catalog: docs/14 "VPN kill-switch (R-NET-06, L3)"; ADR-0013 (PIA/Gluetun). # # GIVEN a `vpn`-class workload with a HEALTHY tunnel, # WHEN the tunnel is FORCED DOWN (fault injection), # THEN the workload has ZERO egress to the plain internet (fail-closed), and # `internet`-class workloads are UNAFFECTED; # WHEN the tunnel recovers, THEN connectivity returns. # # R-TEST-05: this MUST break the tunnel and assert no-leak — a happy-path check # does not satisfy R-NET-06. `finally` ALWAYS restores the tunnel so a failure # mid-test never leaves the gateway down (self-healing fixture). # # STATUS: scaffold — needs T-3.0 (fault harness) + T-3.2 (Gluetun gateway). # ============================================================================= apiVersion: chainsaw.kyverno.io/v1alpha1 kind: Test metadata: name: vpn-killswitch labels: conformance.home.k3s/R-NET-06: "true" annotations: conformance.home.k3s/requirements: "R-NET-06" conformance.home.k3s/layer: "L3" conformance.home.k3s/safety-critical: "true" conformance.home.k3s/intent: >- Tunnel down => vpn workload leaks nothing; internet workloads unaffected; recovery restores connectivity. spec: steps: - name: given-healthy-tunnel-and-two-workloads try: - apply: file: fixtures/vpn-and-internet-pods.yaml # TODO(T-3.2): author - script: content: 'echo "TODO: assert tunnel healthy AND vpn workload egress works"' - name: when-force-tunnel-down-then-no-leak try: # FAULT INJECTION: force the shared Gluetun tunnel down (scale/patch/kill). - script: content: | set -euo pipefail echo "TODO(T-3.0): scale gluetun to 0 / drop wg iface (force tunnel DOWN)" - script: # THEN: vpn workload must reach NOTHING on the plain internet. content: | set -euo pipefail if kubectl -n "$NAMESPACE" exec egress-vpn -- \ curl -fsS --max-time 5 https://api.ipify.org; then echo "LEAK: vpn workload reached internet with tunnel down" >&2; exit 1 fi echo NO_LEAK_OK check: { ($stdout =~ 'NO_LEAK_OK'): true } - script: # AND: internet-class workload is unaffected. content: | set -euo pipefail kubectl -n "$NAMESPACE" exec egress-internet -- \ curl -fsS --max-time 5 https://api.ipify.org && echo INTERNET_UNAFFECTED_OK check: { ($stdout =~ 'INTERNET_UNAFFECTED_OK'): true } - name: when-tunnel-recovers-connectivity-returns try: - script: content: 'echo "TODO(T-3.0): restore gluetun; assert vpn egress returns"' # ALWAYS restore the tunnel, even if an assertion above failed. finally: - script: content: | echo "TODO(T-3.0): guarantee gluetun scaled back / wg iface restored"