RAILIANCE-WP-0015: Option A CNPG logical backup coverage healthy
Materialize offsite Secret from OpenBao, deploy per-cluster CronJobs, generalize multi-cluster logical backup + status health for Option A, seed encrypted uploads and restore-drill evidence; workplan finished.
This commit is contained in:
parent
374ebed349
commit
6635fdc976
11 changed files with 929 additions and 69 deletions
67
tools/cnpg-backup-offsite-secret-apply.sh
Executable file
67
tools/cnpg-backup-offsite-secret-apply.sh
Executable file
|
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env bash
|
||||
# Materialize databases/cnpg-backup-offsite from OpenBao (RAILIANCE-WP-0015-T02).
|
||||
# Never prints secret values. Does not place AGE_PRIVATE_KEY in-cluster.
|
||||
set -euo pipefail
|
||||
|
||||
NAMESPACE="${CNPG_NAMESPACE:-databases}"
|
||||
SECRET_NAME="${CNPG_BACKUP_OFFSITE_SECRET:-cnpg-backup-offsite}"
|
||||
BAO_PATH="${RAILIANCE_BACKUP_BAO_PATH:-platform/workloads/railiance/backup/offsite-lane}"
|
||||
AGE_PUBLIC_KEY="${RAILIANCE_BACKUP_AGE_PUBLIC_KEY:-age1zvryunvjhvpkmasskauga2heeg0ztnte9ymgppvjge36ekumk50syr3tsz}"
|
||||
DRY_RUN="${DRY_RUN:-0}"
|
||||
|
||||
if ! command -v bao >/dev/null 2>&1; then
|
||||
echo "ERROR: bao CLI required" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v kubectl >/dev/null 2>&1; then
|
||||
echo "ERROR: kubectl required" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! bao token lookup >/dev/null 2>&1; then
|
||||
echo "ERROR: no valid OpenBao token" >&2
|
||||
echo "Run: bao login -method=oidc -path=netkingdom role=railiance-backup-workload-kv-read" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! bao kv metadata get "$BAO_PATH" >/dev/null 2>&1; then
|
||||
echo "ERROR: cannot read metadata for ${BAO_PATH}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Fetch into env without echoing
|
||||
NC_WEBDAV_TOKEN="$(bao kv get -field=NC_WEBDAV_TOKEN "$BAO_PATH")"
|
||||
NC_WEBDAV_URL="$(bao kv get -field=NC_WEBDAV_URL "$BAO_PATH")"
|
||||
|
||||
if [[ -z "${NC_WEBDAV_TOKEN}" || -z "${NC_WEBDAV_URL}" ]]; then
|
||||
echo "ERROR: NC_WEBDAV_TOKEN or NC_WEBDAV_URL empty at ${BAO_PATH}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "cnpg-backup-offsite secret apply"
|
||||
echo " namespace: ${NAMESPACE}"
|
||||
echo " secret: ${SECRET_NAME}"
|
||||
echo " source: ${BAO_PATH}"
|
||||
echo " keys: NC_WEBDAV_TOKEN, NC_WEBDAV_URL, AGE_PUBLIC_KEY"
|
||||
echo " dry-run: ${DRY_RUN}"
|
||||
|
||||
if [[ "$DRY_RUN" == "1" ]]; then
|
||||
echo "ok: dry-run — would create/update Secret ${NAMESPACE}/${SECRET_NAME}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
kubectl create secret generic "$SECRET_NAME" \
|
||||
-n "$NAMESPACE" \
|
||||
--from-literal=NC_WEBDAV_TOKEN="$NC_WEBDAV_TOKEN" \
|
||||
--from-literal=NC_WEBDAV_URL="$NC_WEBDAV_URL" \
|
||||
--from-literal=AGE_PUBLIC_KEY="$AGE_PUBLIC_KEY" \
|
||||
--dry-run=client -o yaml \
|
||||
| kubectl apply -f -
|
||||
|
||||
# Clear locals
|
||||
unset NC_WEBDAV_TOKEN NC_WEBDAV_URL
|
||||
|
||||
# Non-secret verification
|
||||
keys="$(kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" -o jsonpath='{.data}' \
|
||||
| python3 -c 'import sys,json; print(",".join(sorted(json.load(sys.stdin).keys())))')"
|
||||
echo "ok: Secret ${NAMESPACE}/${SECRET_NAME} applied (keys: ${keys})"
|
||||
Loading…
Add table
Add a link
Reference in a new issue