#!/usr/bin/env bash set -euo pipefail namespace="${CNPG_NAMESPACE:-databases}" clusters=( apps-pg forgejo-db net-kingdom-pg state-hub-db ) if ! kubectl get ns "$namespace" >/dev/null 2>&1; then echo "ERROR: namespace $namespace is not reachable from the current kubeconfig" >&2 exit 1 fi echo "CNPG backup posture in namespace ${namespace}" echo missing=0 for cluster in "${clusters[@]}"; do if ! kubectl get cluster "$cluster" -n "$namespace" >/dev/null 2>&1; then echo "${cluster}: MISSING (Cluster CR not found)" missing=$((missing + 1)) echo continue fi backup_spec="$(kubectl get cluster "$cluster" -n "$namespace" \ -o jsonpath='{.spec.backup}' 2>/dev/null || true)" if [[ -z "$backup_spec" || "$backup_spec" == "null" ]]; then echo "${cluster}: backup spec = null" else echo "${cluster}: backup spec configured" fi scheduled="$(kubectl get scheduledbackup -n "$namespace" \ -o jsonpath="{range .items[?(@.spec.cluster.name=='${cluster}')]}{.metadata.name}{' '}{end}" 2>/dev/null || true)" scheduled="${scheduled%" "}" if [[ -z "$scheduled" ]]; then echo "${cluster}: ScheduledBackup = none" missing=$((missing + 1)) else echo "${cluster}: ScheduledBackup = ${scheduled}" fi if command -v kubectl >/dev/null 2>&1 && kubectl cnpg status "$cluster" -n "$namespace" >/dev/null 2>&1; then echo "${cluster}: kubectl cnpg status available" kubectl cnpg status "$cluster" -n "$namespace" | sed -n '1,8p' else phase="$(kubectl get cluster "$cluster" -n "$namespace" -o jsonpath='{.status.phase}' 2>/dev/null || true)" instances="$(kubectl get cluster "$cluster" -n "$namespace" -o jsonpath='{.status.instances}' 2>/dev/null || true)" echo "${cluster}: phase=${phase:-unknown} instances=${instances:-unknown}" fi echo done if (( missing > 0 )); then echo "RESULT: degraded — ${missing} cluster(s) lack ScheduledBackup coverage" echo "See docs/app-data-backup-restore-handoff.md and manifests/cnpg-backup-readiness.yaml" exit 1 fi echo "RESULT: ok — all tracked clusters have ScheduledBackup resources"