Add identity-audit-check.sh and box identity-audit action
identity-audit-check.sh: proper script replacing the identity-audit-watch cron inline SSH one-liner. Reads a bl-local cache of the VM audit JSON (bl cannot SSH to VM; VM hourly audit should push to var/identity-audit.json). Exits 0 clean, 1 on drift, 2 if cache missing. box-ctl.py: new identity-audit action returning drift as JSON.
This commit is contained in:
@@ -697,6 +697,21 @@ def act_relay_health():
|
|||||||
out(all_healthy, relays=results, healthy=all_healthy)
|
out(all_healthy, relays=results, healthy=all_healthy)
|
||||||
|
|
||||||
|
|
||||||
|
def act_identity_audit():
|
||||||
|
"""Run identity-audit-check.sh and return drift as JSON."""
|
||||||
|
audit("identity-audit")
|
||||||
|
script = BIN / "identity-audit-check.sh"
|
||||||
|
r = subprocess.run([str(script)], capture_output=True, text=True, timeout=60)
|
||||||
|
if r.returncode == 2:
|
||||||
|
fail("AUDIT_UNAVAILABLE", (r.stderr or r.stdout).strip()[:500])
|
||||||
|
drift = []
|
||||||
|
for line in r.stdout.strip().split("\n"):
|
||||||
|
if line.startswith("DRIFT: "):
|
||||||
|
drift.append(line[len("DRIFT: "):])
|
||||||
|
clean = r.returncode == 0
|
||||||
|
out(clean, drift=drift, clean=clean)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def act_cdp_latency():
|
def act_cdp_latency():
|
||||||
"""Run cdp-latency-check.sh and return per-node latency JSON."""
|
"""Run cdp-latency-check.sh and return per-node latency JSON."""
|
||||||
@@ -1131,6 +1146,7 @@ fleet:
|
|||||||
watchdog-alerts
|
watchdog-alerts
|
||||||
relay-health
|
relay-health
|
||||||
cdp-latency
|
cdp-latency
|
||||||
|
identity-audit VM identity audit drift check
|
||||||
|
|
||||||
timer actions:
|
timer actions:
|
||||||
timer-list
|
timer-list
|
||||||
@@ -1363,6 +1379,10 @@ def main(argv):
|
|||||||
act_watchdog_alerts()
|
act_watchdog_alerts()
|
||||||
elif action == "relay-health":
|
elif action == "relay-health":
|
||||||
act_relay_health()
|
act_relay_health()
|
||||||
|
elif action == "identity-audit":
|
||||||
|
if rest:
|
||||||
|
fail("BAD_ARGS", "usage: identity-audit")
|
||||||
|
act_identity_audit()
|
||||||
elif action == "cdp-latency":
|
elif action == "cdp-latency":
|
||||||
act_cdp_latency()
|
act_cdp_latency()
|
||||||
elif action == "chrome-errors":
|
elif action == "chrome-errors":
|
||||||
|
|||||||
Executable
+70
@@ -0,0 +1,70 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# identity-audit-check.sh - Check VM identity audit for drift
|
||||||
|
#
|
||||||
|
# Lives on bl (/home/super/Projects/NetVM/bin/). Reads a bl-local cached
|
||||||
|
# copy of the VM's identity audit JSON and reports drift.
|
||||||
|
#
|
||||||
|
# Why a cache: bl cannot SSH to the VM (VM only accepts the operator
|
||||||
|
# container's key). The VM's hourly audit cron (/srv/board/bin/identity-audit.py)
|
||||||
|
# should scp /srv/board/data/identity-audit.json to bl at:
|
||||||
|
# /home/super/Projects/NetVM/var/identity-audit.json
|
||||||
|
# after each run. Until that push is wired, the cache is refreshed manually
|
||||||
|
# or by the identity-audit-watch cron.
|
||||||
|
#
|
||||||
|
# Called by:
|
||||||
|
# - the identity-audit-watch cron (replaces inline SSH one-liner)
|
||||||
|
# - box-ctl.py `identity-audit` action
|
||||||
|
#
|
||||||
|
# Exit codes:
|
||||||
|
# 0 - clean (no drift; warnings are expected and silent)
|
||||||
|
# 1 - drift detected (items printed to stdout, one per line)
|
||||||
|
# 2 - audit cache missing/unreadable (needs attention)
|
||||||
|
#
|
||||||
|
# Output on drift: one drift item per line, prefixed with "DRIFT: "
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
CACHE_PATH="/home/super/Projects/NetVM/var/identity-audit.json"
|
||||||
|
|
||||||
|
# Allow override for testing
|
||||||
|
if [ $# -ge 1 ] && [ -f "$1" ]; then
|
||||||
|
CACHE_PATH="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$CACHE_PATH" ]; then
|
||||||
|
echo "ERROR: identity audit cache missing: $CACHE_PATH" >&2
|
||||||
|
echo "The VM hourly audit should push /srv/board/data/identity-audit.json here after each run." >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
audit_json=$(cat "$CACHE_PATH" 2>/dev/null)
|
||||||
|
if [ -z "$audit_json" ]; then
|
||||||
|
echo "ERROR: identity audit cache unreadable: $CACHE_PATH" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse with python3
|
||||||
|
drift_output=$(printf '%s' "$audit_json" | python3 -c "
|
||||||
|
import json, sys
|
||||||
|
try:
|
||||||
|
data = json.load(sys.stdin)
|
||||||
|
except Exception as e:
|
||||||
|
print('ERROR: invalid JSON in audit cache: %s' % e, file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
for item in data.get('drift', []):
|
||||||
|
print('DRIFT: ' + str(item))
|
||||||
|
" 2>&1)
|
||||||
|
parse_rc=$?
|
||||||
|
|
||||||
|
if [ $parse_rc -eq 2 ]; then
|
||||||
|
echo "$drift_output" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$drift_output" ]; then
|
||||||
|
echo "$drift_output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean: no drift. Warnings are expected (agents not dialed in) — stay silent.
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user