#!/usr/bin/env bash # ============================================================================= # L1 render check (offline, no cluster) — default-deny-baseline-render # Serves: R-NET-01 (every namespace renders a default-deny baseline). Run by # conformance/run.sh --layer l1 and ci/l1.sh. Pure bash + catalog/render.py. # # GIVEN any onboarded service (this fixture declares NO dependencies), # WHEN its resources are rendered, # THEN (1) the render matches the committed golden byte-for-byte, and # (2) it includes a NetworkPolicy labelled baseline=default-deny that denies # all ingress (ingress: []) and covers BOTH Ingress and Egress — the # render-time partner of the Kyverno L0 gate and the L2 behavioral test. # ============================================================================= set -euo pipefail DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT="$(cd "${DIR}/../../../.." && pwd)" # repo root RENDER="${ROOT}/catalog/render.py" PYTHON="${PYTHON:-python3}" LBL="homelab.keithjackson.dev" tmp="$(mktemp -d)" trap 'rm -rf "${tmp}"' EXIT fail() { echo "RENDER-CHECK FAIL (default-deny-baseline-render): $*" >&2; exit 1; } "${PYTHON}" "${RENDER}" "${DIR}/fixtures/svcdef.yaml" > "${tmp}/out.yaml" # (1) golden match. diff -u "${DIR}/golden/expected.yaml" "${tmp}/out.yaml" || fail "render drifted from golden" # (2) the baseline is present and shaped as deny-all + both directions. grep -q "${LBL}/baseline: default-deny" "${tmp}/out.yaml" \ || fail "render is missing the default-deny baseline NetworkPolicy (R-NET-01)" # Structural assertion via the renderer's own parse (deterministic, no cluster): # find the default-deny NetworkPolicy and assert its shape. "${PYTHON}" - "${tmp}/out.yaml" <<'PY' || fail "default-deny baseline is malformed (R-NET-01)" import sys, yaml docs = [d for d in yaml.safe_load_all(open(sys.argv[1])) if d] np = [d for d in docs if d.get("kind") == "NetworkPolicy" and d.get("metadata", {}).get("labels", {}).get( "homelab.keithjackson.dev/baseline") == "default-deny"] assert len(np) == 1, f"expected exactly one default-deny baseline, got {len(np)}" spec = np[0]["spec"] assert spec.get("ingress") == [], "baseline must deny ALL ingress (ingress: [])" assert set(spec.get("policyTypes", [])) == {"Ingress", "Egress"}, \ "baseline must cover BOTH Ingress and Egress" PY echo "render-check OK: default-deny-baseline-render (R-NET-01)"