prole/scripts/reset-ns.sh

164 lines
5.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
reset-ns.sh -n <namespace> [options]
Required:
-n <namespace> Namespace to reset (REQUIRED; no implicit default)
Options:
--delete-pvcs Delete all PVCs in the namespace (DANGEROUS: wipes state)
--delete-config Delete ConfigMaps and Secrets (VERY DANGEROUS)
-h, --help Show this help
Notes:
• This script NEVER deletes the namespace itself — only resources inside it.
• It will NOT delete the CNPG operator (cluster-wide), but if CNPG CRDs exist,
it WILL delete CNPG Cluster resources IN THE TARGET NAMESPACE so pods stop respawning.
• It will NEVER delete Service "kubernetes" in the default namespace.
Examples:
./reset-ns.sh -n default
./reset-ns.sh -n default --delete-pvcs
EOF
}
NS=""
DELETE_PVCS=false
DELETE_CONFIG=false
[[ $# -eq 0 ]] && usage && exit 1
while [[ $# -gt 0 ]]; do
case "$1" in
-n) NS="${2:-}"; shift 2 ;;
--delete-pvcs) DELETE_PVCS=true; shift ;;
--delete-config) DELETE_CONFIG=true; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown argument: $1"; echo; usage; exit 1 ;;
esac
done
if [[ -z "${NS}" ]]; then
echo "ERROR: -n <namespace> is required"
echo
usage
exit 1
fi
# Refuse truly critical system namespaces; allow "default" if explicitly passed.
case "$NS" in
kube-system|kube-public|kube-node-lease)
echo "REFUSING to operate on protected namespace: $NS"
exit 2
;;
esac
echo "Resetting namespace: $NS"
echo " DELETE_PVCS=$DELETE_PVCS"
echo " DELETE_CONFIG=$DELETE_CONFIG"
echo
# -------------------------
# CNPG: stop respawning in THIS namespace by deleting CNPG Cluster CRs
# Detect via CRD existence (more reliable than kubectl api-resources on some setups)
# -------------------------
if kubectl get crd clusters.postgresql.cnpg.io >/dev/null 2>&1; then
echo "CNPG detected (CRD clusters.postgresql.cnpg.io exists)."
echo "Deleting CNPG resources in namespace '$NS' (operator NOT touched)..."
# List first (helpful visibility; won't fail the script)
kubectl -n "$NS" get clusters.postgresql.cnpg.io 2>/dev/null || true
# Delete Cluster CRs (this is what causes StatefulSets/Pods to be recreated)
kubectl -n "$NS" delete clusters.postgresql.cnpg.io --all --ignore-not-found --wait=false
# Related CNPG CRs (safe best-effort)
if kubectl get crd poolers.postgresql.cnpg.io >/dev/null 2>&1; then
kubectl -n "$NS" delete poolers.postgresql.cnpg.io --all --ignore-not-found --wait=false || true
fi
if kubectl get crd backups.postgresql.cnpg.io >/dev/null 2>&1; then
kubectl -n "$NS" delete backups.postgresql.cnpg.io --all --ignore-not-found --wait=false || true
fi
if kubectl get crd scheduledbackups.postgresql.cnpg.io >/dev/null 2>&1; then
kubectl -n "$NS" delete scheduledbackups.postgresql.cnpg.io --all --ignore-not-found --wait=false || true
fi
# Small pause so the operator observes deletion and stops reconciling
sleep 2
else
echo "CNPG not detected via CRD check; skipping CNPG cleanup."
fi
# -------------------------
# Scale down controllers to reduce churn
# -------------------------
echo "Scaling down Deployments/StatefulSets..."
kubectl -n "$NS" scale deploy --all --replicas=0 2>/dev/null || true
kubectl -n "$NS" scale sts --all --replicas=0 2>/dev/null || true
# -------------------------
# Delete common workload controllers
# -------------------------
echo "Deleting workload controllers..."
kubectl -n "$NS" delete deploy,sts,ds,rs,job,cronjob --all --ignore-not-found --wait=false
# -------------------------
# Delete services safely (NEVER delete "kubernetes" service in default)
# -------------------------
echo "Deleting services (excluding service/kubernetes)..."
for s in $(kubectl -n "$NS" get svc -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null || true); do
if [[ "$NS" == "default" && "$s" == "kubernetes" ]]; then
echo " skipping protected service: default/kubernetes"
continue
fi
kubectl -n "$NS" delete svc "$s" --ignore-not-found --wait=false
done
echo "Deleting ingress & networkpolicy..."
kubectl -n "$NS" delete ingress,networkpolicy --all --ignore-not-found --wait=false
# -------------------------
# Delete HPA / PDB
# -------------------------
echo "Deleting HPA / PDB (if any)..."
kubectl -n "$NS" delete hpa,pdb --all --ignore-not-found --wait=false 2>/dev/null || true
# -------------------------
# Optional config wipe
# -------------------------
if [[ "$DELETE_CONFIG" == "true" ]]; then
echo "Deleting ConfigMaps..."
kubectl -n "$NS" delete configmap --all --ignore-not-found --wait=false
echo "Deleting Secrets (excluding service-account tokens)..."
for s in $(kubectl -n "$NS" get secret -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null || true); do
type=$(kubectl -n "$NS" get secret "$s" -o jsonpath='{.type}' 2>/dev/null || true)
[[ "$type" == "kubernetes.io/service-account-token" ]] && continue
kubectl -n "$NS" delete secret "$s" --ignore-not-found --wait=false
done
fi
# -------------------------
# Optional PVC wipe
# -------------------------
if [[ "$DELETE_PVCS" == "true" ]]; then
echo "Deleting PVCs..."
kubectl -n "$NS" delete pvc --all --ignore-not-found --wait=false
fi
# -------------------------
# Final pod cleanup
# -------------------------
echo "Deleting remaining pods..."
kubectl -n "$NS" delete pod --all --ignore-not-found --wait=false
echo "Waiting for pods to terminate..."
kubectl -n "$NS" wait --for=delete pod --all --timeout=180s 2>/dev/null || true
echo
echo "Namespace '$NS' reset complete (namespace preserved)."