Add reuse-webhook-smoke and rotation runbook links
RAILIANCE-WP-0011-T04: smoke checks unsigned 401, signed no-op 200, ESO Ready, and /v1/federated; point operator docs at platform rotation runbook.
This commit is contained in:
parent
85e9163bb0
commit
0968f1d5d5
3 changed files with 101 additions and 8 deletions
87
tools/reuse-webhook-smoke.sh
Executable file
87
tools/reuse-webhook-smoke.sh
Executable file
|
|
@ -0,0 +1,87 @@
|
|||
#!/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 ]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue