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
5
Makefile
5
Makefile
|
|
@ -330,6 +330,9 @@ reuse-runtime-es-deploy: check-railiance01-kubeconfig reuse-openbao-store-deploy
|
||||||
reuse-runtime-es-status: check-railiance01-kubeconfig ## Show reuse-surface runtime ExternalSecret sync status
|
reuse-runtime-es-status: check-railiance01-kubeconfig ## Show reuse-surface runtime ExternalSecret sync status
|
||||||
KUBECONFIG="$(REUSE_KUBECONFIG)" kubectl get externalsecret,secret -n $(REUSE_NAMESPACE) reuse-surface-runtime reuse-surface-env
|
KUBECONFIG="$(REUSE_KUBECONFIG)" kubectl get externalsecret,secret -n $(REUSE_NAMESPACE) reuse-surface-runtime reuse-surface-env
|
||||||
|
|
||||||
|
reuse-webhook-smoke: check-railiance01-kubeconfig ## Webhook + ESO + federated smoke (RAILIANCE-WP-0011-T04)
|
||||||
|
bash tools/reuse-webhook-smoke.sh
|
||||||
|
|
||||||
##@ Help
|
##@ Help
|
||||||
|
|
||||||
help: ## Show this help
|
help: ## Show this help
|
||||||
|
|
@ -337,4 +340,4 @@ help: ## Show this help
|
||||||
/^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } \
|
/^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } \
|
||||||
/^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
|
/^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
.PHONY: check-tools check-sops k8s-server-dry-run apps-pg-status check-railiance01-kubeconfig check-inter-hub-image-tag check-inter-hub-image vergabe-dry-run vergabe-deploy vergabe-ingress-deploy vergabe-status vergabe-migrate vergabe-seed vergabe-superuser vergabe-logs vergabe-db-url-secret eso-deploy forgejo-openbao-eso-token-apply forgejo-openbao-store-deploy forgejo-mailer-es-deploy forgejo-mailer-es-status forgejo-dry-run forgejo-server-dry-run forgejo-deploy forgejo-ingress-deploy forgejo-ssh-nodeport-deploy forgejo-status forgejo-smoke forgejo-npm-smoke forgejo-verify forgejo-operator-bootstrap forgejo-runner-registration-sops-bootstrap forgejo-secrets-check forgejo-logs forgejo-runner-registration-deploy forgejo-runner-deploy forgejo-runner-status forgejo-runner-logs inter-hub-render-baseline inter-hub-dry-run inter-hub-server-dry-run inter-hub-deploy inter-hub-status inter-hub-release-info inter-hub-smoke inter-hub-logs reuse-dry-run reuse-deploy reuse-status reuse-smoke reuse-logs reuse-forgejo-webhook reuse-openbao-eso-token-apply reuse-openbao-store-deploy reuse-runtime-es-deploy reuse-runtime-es-status help
|
.PHONY: check-tools check-sops k8s-server-dry-run apps-pg-status check-railiance01-kubeconfig check-inter-hub-image-tag check-inter-hub-image vergabe-dry-run vergabe-deploy vergabe-ingress-deploy vergabe-status vergabe-migrate vergabe-seed vergabe-superuser vergabe-logs vergabe-db-url-secret eso-deploy forgejo-openbao-eso-token-apply forgejo-openbao-store-deploy forgejo-mailer-es-deploy forgejo-mailer-es-status forgejo-dry-run forgejo-server-dry-run forgejo-deploy forgejo-ingress-deploy forgejo-ssh-nodeport-deploy forgejo-status forgejo-smoke forgejo-npm-smoke forgejo-verify forgejo-operator-bootstrap forgejo-runner-registration-sops-bootstrap forgejo-secrets-check forgejo-logs forgejo-runner-registration-deploy forgejo-runner-deploy forgejo-runner-status forgejo-runner-logs inter-hub-render-baseline inter-hub-dry-run inter-hub-server-dry-run inter-hub-deploy inter-hub-status inter-hub-release-info inter-hub-smoke inter-hub-logs reuse-dry-run reuse-deploy reuse-status reuse-smoke reuse-logs reuse-forgejo-webhook reuse-openbao-eso-token-apply reuse-openbao-store-deploy reuse-runtime-es-deploy reuse-runtime-es-status reuse-webhook-smoke help
|
||||||
|
|
|
||||||
|
|
@ -69,13 +69,18 @@ kubectl --kubeconfig ~/.kube/config-hosteurope rollout restart deployment/reuse-
|
||||||
kubectl --kubeconfig ~/.kube/config-hosteurope rollout status deployment/reuse-surface -n reuse
|
kubectl --kubeconfig ~/.kube/config-hosteurope rollout status deployment/reuse-surface -n reuse
|
||||||
```
|
```
|
||||||
|
|
||||||
**Bootstrap / rotate** (update OpenBao fields — never commit or paste into chat):
|
**Rotation** (never commit or paste values into chat):
|
||||||
|
|
||||||
|
Full procedure: `railiance-platform/docs/reuse-surface-runtime-secrets-rotation-runbook.md`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Operator: update both fields in OpenBao, then refresh ESO and roll the Deployment
|
# After updating field(s) in OpenBao — force ESO sync, roll hub, reconcile webhook if needed
|
||||||
|
kubectl --kubeconfig ~/.kube/config-hosteurope annotate externalsecret \
|
||||||
|
reuse-surface-runtime -n reuse force-sync="$(date +%s)" --overwrite
|
||||||
make reuse-runtime-es-status
|
make reuse-runtime-es-status
|
||||||
kubectl --kubeconfig ~/.kube/config-hosteurope rollout restart deployment/reuse-surface -n reuse
|
kubectl --kubeconfig ~/.kube/config-hosteurope rollout restart deployment/reuse-surface -n reuse
|
||||||
make reuse-forgejo-webhook # required when rotating REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET
|
make reuse-forgejo-webhook # required when REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET changed
|
||||||
|
make reuse-webhook-smoke
|
||||||
```
|
```
|
||||||
|
|
||||||
One-time lane bootstrap (CCR-2026-0005):
|
One-time lane bootstrap (CCR-2026-0005):
|
||||||
|
|
@ -113,12 +118,10 @@ Requires a Forgejo admin API token at `/tmp/forgejo-tegwick-api-token` (or
|
||||||
make reuse-forgejo-webhook
|
make reuse-forgejo-webhook
|
||||||
```
|
```
|
||||||
|
|
||||||
Manual verification (unsigned body should return `401`, not `503`):
|
Smoke (unsigned `401`, signed no-op `200`, ESO Ready, `/v1/federated`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsS -o /dev/null -w "%{http_code}\n" -X POST \
|
make reuse-webhook-smoke
|
||||||
https://reuse.coulomb.social/v1/webhooks/forgejo \
|
|
||||||
-H "Content-Type: application/json" -d '{}'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Live status (2026-07-07): org webhook id `1` on `coulomb` →
|
Live status (2026-07-07): org webhook id `1` on `coulomb` →
|
||||||
|
|
|
||||||
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