#!/usr/bin/env bash # Smoke checks for reuse-surface Forgejo webhook receiver (RAILIANCE-WP-0011-T04). # Uses the live cluster Secret for HMAC — never prints the secret value. set -euo pipefail REUSE_URL="${REUSE_URL:-https://reuse.coulomb.social}" WEBHOOK_PATH="${REUSE_WEBHOOK_PATH:-/v1/webhooks/forgejo}" KUBECONFIG_PATH="${KUBECONFIG:-$HOME/.kube/config-hosteurope}" SECRET_NS="${REUSE_SECRET_NAMESPACE:-reuse}" SECRET_NAME="${REUSE_SECRET_NAME:-reuse-surface-env}" SECRET_KEY="${REUSE_WEBHOOK_SECRET_KEY:-REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET}" pass=0 fail=0 ok() { echo " PASS $*"; pass=$((pass + 1)); } bad() { echo " FAIL $*" >&2; fail=$((fail + 1)); } echo "reuse-surface webhook smoke — ${REUSE_URL}${WEBHOOK_PATH}" echo "kubeconfig: ${KUBECONFIG_PATH}" echo unsigned_code="$( curl -sS -o /dev/null -w "%{http_code}" -X POST \ "${REUSE_URL}${WEBHOOK_PATH}" \ -H "Content-Type: application/json" -d '{}' 2>/dev/null || true )" unsigned_code="${unsigned_code:-000}" if [[ "${unsigned_code}" == "401" ]]; then ok "unsigned POST returns 401" else bad "unsigned POST expected 401, got ${unsigned_code}" fi if kubectl --kubeconfig "${KUBECONFIG_PATH}" get externalsecret reuse-surface-runtime \ -n "${SECRET_NS}" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null \ | grep -q True; then ok "ExternalSecret reuse-surface-runtime Ready" else bad "ExternalSecret reuse-surface-runtime not Ready" fi export REUSE_URL WEBHOOK_PATH KUBECONFIG_PATH SECRET_NS SECRET_NAME SECRET_KEY if python3 <<'PY' import base64, hashlib, hmac, json, os, subprocess, sys, urllib.error, urllib.request reuse_url = os.environ["REUSE_URL"] webhook_path = os.environ["WEBHOOK_PATH"] kc = os.environ["KUBECONFIG_PATH"] ns = os.environ["SECRET_NS"] name = os.environ["SECRET_NAME"] key = os.environ["SECRET_KEY"] raw = subprocess.check_output([ "kubectl", "--kubeconfig", kc, "get", "secret", name, "-n", ns, "-o", f"jsonpath={{.data.{key}}}", ], text=True) secret = base64.b64decode(raw).decode() payload = {"commits": [{"added": ["README.md"], "modified": [], "removed": []}]} body = json.dumps(payload).encode() sig = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest() req = urllib.request.Request( f"{reuse_url.rstrip('/')}{webhook_path}", data=body, headers={"Content-Type": "application/json", "X-Forgejo-Signature": sig}, method="POST", ) with urllib.request.urlopen(req, timeout=15) as resp: data = json.loads(resp.read().decode()) if resp.status != 200 or data.get("accepted") is not False: raise SystemExit(f"unexpected response: {data!r}") PY then ok "signed no-op POST returns 200 accepted=false" else bad "signed no-op POST failed" fi if curl -fsS "${REUSE_URL}/v1/federated" -o /dev/null 2>/dev/null; then ok "GET /v1/federated returns 200" else bad "GET /v1/federated failed" fi echo echo "summary: ${pass} passed, ${fail} failed" [[ "${fail}" -eq 0 ]]