Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
Made-with: Cursor
93 lines
3.1 KiB
Bash
Executable File
93 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Read-only: compare expected VMIDs from config/proxmox-operational-template.json
|
|
# to live Proxmox inventory (pct/qm list) over SSH. No cluster changes.
|
|
#
|
|
# Usage (from repo root):
|
|
# bash scripts/verify/audit-proxmox-operational-template.sh
|
|
# SSH_USER=root SSH_OPTS="-o BatchMode=yes" bash scripts/verify/audit-proxmox-operational-template.sh
|
|
#
|
|
# Env:
|
|
# PROXMOX_HOSTS Space-separated IPs (default: sources config/ip-addresses.conf — ML110, R630-01, R630-02)
|
|
# SSH_USER default root
|
|
# SSH_OPTS extra ssh options (e.g. -i /path/key)
|
|
#
|
|
# Exit: 0 always (report-only). Prints [MISSING_ON_CLUSTER] / [EXTRA_ON_CLUSTER] when SSH works.
|
|
|
|
set -uo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
TEMPLATE_JSON="$PROJECT_ROOT/config/proxmox-operational-template.json"
|
|
SSH_USER="${SSH_USER:-root}"
|
|
SSH_OPTS="${SSH_OPTS:--o ConnectTimeout=6 -o StrictHostKeyChecking=accept-new}"
|
|
|
|
cd "$PROJECT_ROOT"
|
|
|
|
if ! command -v jq &>/dev/null; then
|
|
echo "[WARN] jq not installed; install jq to compare VMIDs."
|
|
exit 0
|
|
fi
|
|
|
|
if [[ ! -f "$TEMPLATE_JSON" ]]; then
|
|
echo "[ERROR] Missing $TEMPLATE_JSON"
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck source=/dev/null
|
|
source "$PROJECT_ROOT/config/ip-addresses.conf" 2>/dev/null || true
|
|
PROXMOX_HOSTS="${PROXMOX_HOSTS:-${PROXMOX_HOST_ML110:-192.168.11.10} ${PROXMOX_HOST_R630_01:-192.168.11.11} ${PROXMOX_HOST_R630_02:-192.168.11.12}}"
|
|
|
|
EXPECTED_VMIDS=$(jq -r '.services[] | select(.vmid != null) | .vmid' "$TEMPLATE_JSON" | sort -n | uniq)
|
|
|
|
echo "=== Proxmox template audit (read-only) ==="
|
|
echo "Template: $TEMPLATE_JSON"
|
|
echo "Expected VMIDs (non-null): $(echo "$EXPECTED_VMIDS" | wc -l) rows"
|
|
echo ""
|
|
|
|
ALL_LIVE=""
|
|
for h in $PROXMOX_HOSTS; do
|
|
out=$(ssh $SSH_OPTS "${SSH_USER}@${h}" "pct list 2>/dev/null | awk 'NR>1 {print \$1}'; qm list 2>/dev/null | awk 'NR>1 {print \$1}'" 2>/dev/null || true)
|
|
if [[ -z "$out" ]]; then
|
|
echo "[SKIP] No inventory from $h (SSH failed or empty)"
|
|
continue
|
|
fi
|
|
echo "--- Live inventory: $h ---"
|
|
while IFS= read -r vid; do
|
|
[[ -z "${vid:-}" ]] && continue
|
|
echo " VMID $vid"
|
|
ALL_LIVE+="$vid"$'\n'
|
|
done <<< "$out"
|
|
done
|
|
|
|
LIVE_SORTED=$(echo "$ALL_LIVE" | sed '/^$/d' | sort -n | uniq)
|
|
|
|
if [[ -z "$LIVE_SORTED" ]]; then
|
|
echo ""
|
|
echo "[INFO] No live VMIDs collected (no SSH to cluster). Run from LAN with keys to Proxmox nodes."
|
|
exit 0
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Diff (template expected vs union of live VMIDs) ==="
|
|
MISSING=0
|
|
while IFS= read -r ev; do
|
|
[[ -z "${ev:-}" ]] && continue
|
|
if ! echo "$LIVE_SORTED" | grep -qx "$ev"; then
|
|
echo "[MISSING_ON_CLUSTER] VMID $ev (in template, not seen on scanned nodes)"
|
|
MISSING=$((MISSING + 1))
|
|
fi
|
|
done <<< "$EXPECTED_VMIDS"
|
|
|
|
EXTRA=0
|
|
while IFS= read -r lv; do
|
|
[[ -z "${lv:-}" ]] && continue
|
|
if ! echo "$EXPECTED_VMIDS" | grep -qx "$lv"; then
|
|
echo "[EXTRA_ON_CLUSTER] VMID $lv (on cluster, not in template services[])"
|
|
EXTRA=$((EXTRA + 1))
|
|
fi
|
|
done <<< "$LIVE_SORTED"
|
|
|
|
echo ""
|
|
echo "Summary: missing_on_template_scan=$MISSING extra_vs_template=$EXTRA"
|
|
echo "Note: VMIDs on nodes not scanned (other hosts) appear as MISSING. Expand PROXMOX_HOSTS if needed."
|