Files
OpenBAO/scripts/apply-policies.sh
Lutz Finsterle f12034bab9 apply-policies: fix header always showing [dry-run]
${DRY:+...} expanded on DRY=0 (non-empty). Gate the label on DRY=1 instead;
the apply logic was already correct.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-01 10:03:12 +02:00

40 lines
2.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Policy-as-code: apply every policies/*.hcl to OpenBAO. Idempotent.
# apply-policies.sh --dry-run # read-only: show NEW/CHANGED/unchanged, change nothing
# apply-policies.sh # apply (writes policies that are NEW or CHANGED)
#
# Auth: needs a token allowed to write sys/policies/acl/* (root or admin).
# Uses $BAO_TOKEN if set, else falls back to the root token in init-output.json.
# Built-in `default`/`root` policies have no file here and are never touched.
set -euo pipefail
SELF="$(cd "$(dirname "$0")" && pwd)"; ROOT_DIR="$(cd "$SELF/.." && pwd)"
DIR="$ROOT_DIR/policies"; INIT="$ROOT_DIR/init-output.json"
ADDR="${BAO_ADDR:-http://127.0.0.1:8200}"
DRY=0; [ "${1:-}" = "--dry-run" ] && DRY=1
TOKEN="${BAO_TOKEN:-}"
[ -z "$TOKEN" ] && [ -r "$INIT" ] && TOKEN="$(python3 -c "import json;print(json.load(open('$INIT'))['root_token'])")"
[ -n "$TOKEN" ] || { echo "no token (set BAO_TOKEN or provide init-output.json)" >&2; exit 1; }
# functional comparison: ignore comments and blank lines
norm(){ grep -vE '^[[:space:]]*#' | grep -vE '^[[:space:]]*$' | sed 's/[[:space:]]*$//'; }
echo "$([ "$DRY" = 1 ] && printf '[dry-run] ')policies under $DIR -> $ADDR"
for f in "$DIR"/*.hcl; do
name="$(basename "$f" .hcl)"; filetxt="$(cat "$f")"
live="$(curl -sS -H "X-Vault-Token: $TOKEN" "$ADDR/v1/sys/policies/acl/$name" \
| python3 -c "import sys,json;d=json.load(sys.stdin);print(d.get('data',{}).get('policy','') if 'data' in d else '')" 2>/dev/null || true)"
if [ -z "$live" ]; then status="NEW"
elif [ "$(printf '%s' "$filetxt" | norm)" = "$(printf '%s' "$live" | norm)" ]; then status="unchanged"
else status="CHANGED"; fi
if [ "$DRY" = 1 ] || [ "$status" = unchanged ]; then
printf ' %-10s %s\n' "$status" "$name"; continue
fi
code="$(printf '%s' "$filetxt" | python3 -c 'import json,sys;print(json.dumps({"policy":sys.stdin.read()}))' \
| curl -sS -o /dev/null -w '%{http_code}' -H "X-Vault-Token: $TOKEN" --data @- "$ADDR/v1/sys/policies/acl/$name")"
printf ' %-10s %s (HTTP %s)\n' "applied[$status]" "$name" "$code"
done
[ "$DRY" = 1 ] && echo "(dry-run — nothing changed)" || true