#!/usr/bin/env bash # Compare bcos.dev (DEV) vs bcos.cloud (PROD) deployment config, side by side. # # ./compare-prod-dev.sh # DRIFT SUMMARY: which configs differ / are env-only # ./compare-prod-dev.sh incident # FULL DIFF of every config matching "incident" # ./compare-prod-dev.sh api # FULL DIFF of the nginx api.conf, etc. # # PROD = hiveiq-openmetal/hiveops/instances/services (bcos.cloud, 173.231.195.250) # DEV = hiveiq-openmetal-dev/hiveops/instances/dev (bcos.dev, 173.231.195.251) # # Both repos are structurally parallel: compose/.yml + nginx/conf.d/.conf. set -uo pipefail HERE=$(cd "$(dirname "$0")" && pwd) PROD="$HERE/hiveiq-openmetal-prod/hiveops/instances/services" DEV="$HERE/hiveiq-openmetal-dev/hiveops/instances/dev" [ -d "$PROD" ] || { echo "PROD config not found: $PROD"; exit 1; } [ -d "$DEV" ] || { echo "DEV config not found: $DEV (clone hiveiq-openmetal-dev next to hiveiq-openmetal)"; exit 1; } FILTER="${1:-}" scan() { # $1 = subdir ; $2 = glob local sub="$1" glob="$2" df pf n echo "## $sub" for df in "$DEV/$sub"/$glob; do [ -e "$df" ] || continue; n=$(basename "$df") pf="$PROD/$sub/$n" if [ ! -e "$pf" ]; then echo " [dev-only] $n" elif ! diff -q "$pf" "$df" >/dev/null 2>&1; then echo " [DIFFERS] $n"; fi done for pf in "$PROD/$sub"/$glob; do [ -e "$pf" ] || continue; n=$(basename "$pf") [ -e "$DEV/$sub/$n" ] || echo " [prod-only] $n" done } if [ -n "$FILTER" ]; then echo "=== FULL DIFF (prod → dev) for *$FILTER* ===" for sub in compose nginx/conf.d; do for df in "$DEV/$sub/"*"$FILTER"*; do [ -e "$df" ] || continue; n=$(basename "$df"); pf="$PROD/$sub/$n" echo "--- $sub/$n ---" if [ -e "$pf" ]; then diff -u "$pf" "$df" || true; else echo " (dev-only — no prod counterpart)"; fi done done else echo "=== DRIFT SUMMARY: bcos.dev (DEV) vs bcos.cloud (PROD) ===" scan compose '*.yml' scan nginx/conf.d '*.conf' echo "" echo "→ './compare-prod-dev.sh ' for the full diff of one config (e.g. incident, api, auth)." fi