#!/usr/bin/env bash # ============================================================================= # L1 render check (offline, no cluster) — egress-class-render # Serves: R-NET-05 (egress is a declared property), R-NET-06/07 (vpn steering / # flip only changes the egress path). Run by conformance/run.sh --layer l1 and by # ci/l1.sh. Pure bash + the renderer (catalog/render.py); no cluster, no chainsaw. # # GIVEN two ServiceDefinitions identical except `egress: vpn` vs `egress: internet`, # WHEN the renderer produces resources, # THEN (1) each matches its committed golden byte-for-byte, # (2) the vpn render carries the egress-class=vpn steering label and the # internet render does NOT (fail-closed: no silent vpn path on internet), # (3) the two renders differ ONLY in the egress-class value (R-NET-07): # flipping the class changes the egress path, not the workload spec. # ============================================================================= 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 (egress-class-render): $*" >&2; exit 1; } # (1) golden match for both classes. "${PYTHON}" "${RENDER}" "${DIR}/fixtures/svcdef-egress-vpn.yaml" > "${tmp}/vpn.yaml" "${PYTHON}" "${RENDER}" "${DIR}/fixtures/svcdef-egress-internet.yaml" > "${tmp}/internet.yaml" diff -u "${DIR}/golden/egress-vpn.expected.yaml" "${tmp}/vpn.yaml" || fail "vpn render drifted from golden" diff -u "${DIR}/golden/egress-internet.expected.yaml" "${tmp}/internet.yaml" || fail "internet render drifted from golden" # (2) vpn steering label present on vpn, absent on internet (R-NET-05, fail-closed). grep -q "${LBL}/egress-class: vpn" "${tmp}/vpn.yaml" \ || fail "vpn render is missing the egress-class=vpn steering label" if grep -q "${LBL}/egress-class: vpn" "${tmp}/internet.yaml"; then fail "internet render must NOT carry the vpn steering label (fail-open leak)" fi grep -q "${LBL}/egress-class: internet" "${tmp}/internet.yaml" \ || fail "internet render is missing the egress-class=internet label" # (3) R-NET-07: the only difference is the egress-class value. Neutralize the class # value in each render; the rest MUST be byte-identical. sed 's#egress-class: vpn#egress-class: CLASS#' "${tmp}/vpn.yaml" > "${tmp}/vpn.norm" sed 's#egress-class: internet#egress-class: CLASS#' "${tmp}/internet.yaml" > "${tmp}/internet.norm" diff -u "${tmp}/vpn.norm" "${tmp}/internet.norm" \ || fail "flipping egress class changed more than the egress path (R-NET-07 violated)" echo "render-check OK: egress-class-render (R-NET-05/06/07)"