Validate cadence contract and require functional MFA verification
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06ea3-7939-7b63-8125-699f8b50bedd
This commit is contained in:
tegwick 2026-09-05 01:28:05 +02:00
parent d4d61b722e
commit 4e07d60ff1
34 changed files with 1640 additions and 364 deletions

View file

@ -121,7 +121,8 @@ else
fi
prompt_secret "one-time MFA code for $MFA_USER@$MFA_REALM" "$tmp/otp"
if python3 - "$tmp/pi-admin" "$tmp/lldap-new" "$tmp/lldap-old" "$tmp/otp" \
PI_HELPER_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
if PYTHONPATH="$PI_HELPER_DIR${PYTHONPATH:+:$PYTHONPATH}" python3 - "$tmp/pi-admin" "$tmp/lldap-new" "$tmp/lldap-old" "$tmp/otp" \
"$PI_URL" "$LLDAP_AUTH_URL" "$LLDAP_URL" "$LLDAP_BASE_DN" "$LLDAP_BIND_DN" \
"$RESOLVER_NAME" "$MFA_USER" "$MFA_REALM" "$KEYCAPE_DISCOVERY_URL" "$MODE" "$tmp/phase" "$PREDECESSOR" \
"$LDAP_TIMEOUT" "$LDAP_CACHE_TIMEOUT" "$LDAP_SIZELIMIT" <<'PY'
@ -148,33 +149,7 @@ def secret(path: str) -> str:
raise RuntimeError("empty protected input")
return value
def request(url: str, payload: dict | None = None, token: str | None = None) -> tuple[int, dict | None]:
# Content-Type is only set on requests with a body — Werkzeug 3.x raises
# BadRequest if Content-Type: application/json is sent on a bodyless GET,
# and the rejection happens in front of privacyIDEA, so the reply is an HTML
# error page rather than a JSON result. Same fix as bootstrap-realm.sh's
# pi_api helper.
headers = {}
if payload is not None:
headers["Content-Type"] = "application/json"
if token:
headers["Authorization"] = token
data = json.dumps(payload).encode("utf-8") if payload is not None else None
req = urllib.request.Request(url, data=data, headers=headers, method="POST" if payload is not None else "GET")
try:
with urllib.request.urlopen(req, timeout=20) as response:
status = response.status
body = response.read()
if not body:
return status, None
try:
return status, json.loads(body)
except json.JSONDecodeError:
return status, None
except urllib.error.HTTPError as exc:
return exc.code, None
except (urllib.error.URLError, TimeoutError):
return 0, None
from pi_api import request
def check_k8s_ready() -> None:
workloads = (("sso", "lldap"), ("mfa", "privacyidea"), ("sso", "keycape"),