Capture current Ansible control plane state
Commit the accumulated infrastructure work that was living only in the working tree: monitoring stack, emergency access/bot, gyro allocator, grimmory, adguard, backup audit and the OpenCode agent definitions. Also ignore Python bytecode, local archives and Nix/direnv artifacts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
# Managed by Ansible: HomeLab PBS backup audit (L0 freshness)
|
||||
set -eu
|
||||
|
||||
LOG_FILE="{{ backup_audit_log_file }}"
|
||||
METRICS_DIR="{{ backup_audit_metrics_dir }}"
|
||||
METRICS_FILE="$METRICS_DIR/homelab_backup_audit_pbs.prom"
|
||||
METRICS_TMP=$(mktemp "$METRICS_FILE.XXXXXX")
|
||||
STATUS=OK
|
||||
NOW_EPOCH=$(date +%s)
|
||||
|
||||
trap 'rm -f "$METRICS_TMP"' EXIT
|
||||
|
||||
publish_metrics() {
|
||||
chmod 0644 "$METRICS_TMP"
|
||||
mv "$METRICS_TMP" "$METRICS_FILE"
|
||||
}
|
||||
|
||||
ts() { date '+%Y-%m-%dT%H:%M:%S%z'; }
|
||||
log() { echo "[$(ts)] [pbs] $*" | tee -a "$LOG_FILE"; }
|
||||
|
||||
get_latest_snapshot() {
|
||||
pvesm list pbs --vmid "$1" 2>/dev/null \
|
||||
| tail -n +2 \
|
||||
| awk '{print $1}' \
|
||||
| sort -t/ -k4 \
|
||||
| tail -1
|
||||
}
|
||||
|
||||
{% for entry in backup_audit_pbs_vmids %}
|
||||
audit_vmid_{{ entry.vmid }}() {
|
||||
vmid={{ entry.vmid }}
|
||||
max_age={{ entry.max_age_hours }}
|
||||
latest=$(get_latest_snapshot "$vmid")
|
||||
if [ -z "$latest" ]; then
|
||||
log "FAIL L0: vmid $vmid — no snapshots in PBS"
|
||||
printf 'homelab_backup_audit_snapshot_age_hours{profile="pbs",vmid="%s"} -1\n' "$vmid" >> "$METRICS_TMP"
|
||||
printf 'homelab_backup_audit_snapshot_success{profile="pbs",vmid="%s"} 0\n' "$vmid" >> "$METRICS_TMP"
|
||||
STATUS=FAIL
|
||||
return
|
||||
fi
|
||||
ts_str=$(printf '%s' "$latest" | sed -n 's#.*/\([0-9T:Z-]*\)$#\1#p')
|
||||
snap_epoch=$(date -d "$ts_str" +%s 2>/dev/null || echo 0)
|
||||
age_hours=$(( (NOW_EPOCH - snap_epoch) / 3600 ))
|
||||
if [ "$age_hours" -gt "$max_age" ]; then
|
||||
log "FAIL L0: vmid $vmid — latest snapshot age ${age_hours}h > ${max_age}h (snapshot: $ts_str)"
|
||||
printf 'homelab_backup_audit_snapshot_success{profile="pbs",vmid="%s"} 0\n' "$vmid" >> "$METRICS_TMP"
|
||||
STATUS=FAIL
|
||||
else
|
||||
log "OK L0: vmid $vmid — latest snapshot age ${age_hours}h"
|
||||
printf 'homelab_backup_audit_snapshot_success{profile="pbs",vmid="%s"} 1\n' "$vmid" >> "$METRICS_TMP"
|
||||
fi
|
||||
printf 'homelab_backup_audit_snapshot_age_hours{profile="pbs",vmid="%s"} %s\n' "$vmid" "$age_hours" >> "$METRICS_TMP"
|
||||
}
|
||||
audit_vmid_{{ entry.vmid }}
|
||||
|
||||
{% endfor %}
|
||||
if [ "$STATUS" = "OK" ]; then
|
||||
log "AUDIT PASSED"
|
||||
printf 'homelab_backup_audit_success{profile="pbs"} 1\n' >> "$METRICS_TMP"
|
||||
printf 'homelab_backup_audit_timestamp_seconds{profile="pbs"} %s\n' "$NOW_EPOCH" >> "$METRICS_TMP"
|
||||
publish_metrics
|
||||
exit 0
|
||||
else
|
||||
log "AUDIT FAILED"
|
||||
printf 'homelab_backup_audit_success{profile="pbs"} 0\n' >> "$METRICS_TMP"
|
||||
printf 'homelab_backup_audit_timestamp_seconds{profile="pbs"} %s\n' "$NOW_EPOCH" >> "$METRICS_TMP"
|
||||
publish_metrics
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user