#!/bin/bash # ============================================================================= # update-gitops-status.sh # # Purpose: # Runs drift-check playbook and generates a JSON status snapshot for # gitops-status-server. This replaces Pushgateway metric updates with # richer JSON status suitable for Grafana visualization. # # Usage: # ./update-gitops-status.sh # # Environment Variables: # GITOPS_STATUS_SERVER_URL - URL of gitops-status-server API # (default: http://gitops-status-server.observability-stack.svc.cluster.local:80) # REPO_NAME - Repository name (default: rsyslog) # SERVER_NAME - Server name (default: rsyslog-lab) # # Output: # Generates JSON structure: # { # "repo": "rsyslog", # "server": "rsyslog-lab", # "sync_status": "SYNCED" or "OUT_OF_SYNC", # "drift_count": , # "files": [{"name": "rsyslog.conf"}, ...], # "last_check": "2026-04-21T10:30:00Z" # } # # Exit codes: # 0 - Success (regardless of sync status) # 1 - Failure (playbook error, network error, etc.) # ============================================================================= set -e # Configuration GITOPS_STATUS_SERVER_URL="${GITOPS_STATUS_SERVER_URL:-http://gitops-status-server.observability-stack.svc.cluster.local:80}" REPO_NAME="${REPO_NAME:-rsyslog}" SERVER_NAME="${SERVER_NAME:-rsyslog-lab}" INVENTORY_FILE="ansible/inventory/hosts.yml" PLAYBOOK="ansible/playbooks/drift-check.yml" echo "==> Running drift check playbook..." echo " Inventory: $INVENTORY_FILE" echo " Playbook: $PLAYBOOK" # Run drift-check playbook in JSON output mode and capture results # We use --diff to get detailed change information # Exit code: 0 = synced, non-zero = drift or error set +e PLAYBOOK_OUTPUT=$(ANSIBLE_STDOUT_CALLBACK=json ansible-playbook \ -i "$INVENTORY_FILE" \ "$PLAYBOOK" \ 2>&1) DRIFT_RC=$? set -e # Determine sync status if [ "$DRIFT_RC" -eq 0 ]; then SYNC_STATUS="SYNCED" echo "==> Status: SYNCED - server configuration matches Git" else SYNC_STATUS="OUT_OF_SYNC" echo "==> Status: OUT_OF_SYNC - drift detected" fi # Parse changed files from playbook output # Look for tasks that reported changed=true CHANGED_FILES=() DRIFT_COUNT=0 # Extract file changes from JSON output # main_config_check tracks rsyslog.conf # rsyslogd_check tracks rsyslog.d/* files if echo "$PLAYBOOK_OUTPUT" | grep -q '"main_config_check".*"changed".*true'; then CHANGED_FILES+=("rsyslog.conf") ((DRIFT_COUNT++)) echo " - Drift detected: rsyslog.conf" fi # Check if rsyslog.d directory has changes if echo "$PLAYBOOK_OUTPUT" | grep -q '"rsyslogd_check".*"changed".*true'; then # Try to extract specific filenames from diff output # Format: files/rsyslog.d/30-lab.conf while IFS= read -r line; do if [[ "$line" =~ files/rsyslog\.d/([^[:space:]]+\.conf) ]]; then filename="${BASH_REMATCH[1]}" CHANGED_FILES+=("rsyslog.d/$filename") ((DRIFT_COUNT++)) echo " - Drift detected: rsyslog.d/$filename" fi done < <(echo "$PLAYBOOK_OUTPUT" | grep -oP 'files/rsyslog\.d/[^[:space:]]+\.conf' || true) # If we couldn't extract specific files but know rsyslog.d changed, # add a generic entry if [ ${#CHANGED_FILES[@]} -eq 0 ] || [ ${#CHANGED_FILES[@]} -eq 1 ]; then CHANGED_FILES+=("rsyslog.d/*") ((DRIFT_COUNT++)) echo " - Drift detected: rsyslog.d/* (multiple files)" fi fi # Check for missing files on server if echo "$PLAYBOOK_OUTPUT" | grep -q '"extra_files_on_server".*true'; then CHANGED_FILES+=("(missing files on server)") ((DRIFT_COUNT++)) echo " - Drift detected: files missing on server" fi echo "==> Drift count: $DRIFT_COUNT" # Build JSON file list FILES_JSON="[]" if [ ${#CHANGED_FILES[@]} -gt 0 ]; then FILES_JSON="[" for i in "${!CHANGED_FILES[@]}"; do if [ $i -gt 0 ]; then FILES_JSON+="," fi FILES_JSON+="{\"name\":\"${CHANGED_FILES[$i]}\"}" done FILES_JSON+="]" fi # Generate ISO timestamp TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") # Build complete JSON status STATUS_JSON=$(cat < Generated JSON status:" echo "$STATUS_JSON" | jq '.' 2>/dev/null || echo "$STATUS_JSON" # Send JSON to gitops-status-server # API endpoint: POST /api/status echo "==> Sending status to gitops-status-server..." echo " URL: $GITOPS_STATUS_SERVER_URL/api/status" HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ -X POST \ -H "Content-Type: application/json" \ -d "$STATUS_JSON" \ "$GITOPS_STATUS_SERVER_URL/api/status") if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then echo "==> Status update successful (HTTP $HTTP_CODE)" exit 0 else echo "==> ERROR: Status update failed (HTTP $HTTP_CODE)" exit 1 fi