163 lines
4.8 KiB
Bash
163 lines
4.8 KiB
Bash
#!/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": <number>,
|
|
# "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 <<EOF
|
|
{
|
|
"repo": "$REPO_NAME",
|
|
"server": "$SERVER_NAME",
|
|
"sync_status": "$SYNC_STATUS",
|
|
"drift_count": $DRIFT_COUNT,
|
|
"files": $FILES_JSON,
|
|
"last_check": "$TIMESTAMP"
|
|
}
|
|
EOF
|
|
)
|
|
|
|
echo "==> 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
|