← back to Coming Soon Template

scripts/godaddy_ns_flip.sh

43 lines

#!/usr/bin/env bash
# Flip GoDaddy nameservers to the Cloudflare-assigned pair for each domain.
# Reads data/zone-setup.json (produced by cf_zones_create.sh).
# SAFETY: any domain with live MX records is HELD BACK, not flipped.
# Dry-run by default; pass --apply to actually PATCH GoDaddy.
set -uo pipefail

ENV=~/Projects/secrets-manager/.env
KEY=$(grep '^GODADDY_API_KEY=' "$ENV" | cut -d= -f2)
SEC=$(grep '^GODADDY_API_SECRET=' "$ENV" | cut -d= -f2)
# Prefer a Bearer PAT when present (TK-10 key rotation); else legacy sso-key.
GD_PAT="${GODADDY_PAT:-$(grep '^GODADDY_PAT=' "$ENV" | cut -d= -f2-)}"
if [ -n "$GD_PAT" ]; then GD_AUTH="Bearer $GD_PAT"; else GD_AUTH="sso-key $KEY:$SEC"; fi
CST=~/Projects/coming-soon-template
IN="$CST/data/zone-setup.json"
APPLY=0; [ "${1:-}" = "--apply" ] && APPLY=1

[ -f "$IN" ] || { echo "missing $IN — run cf_zones_create.sh first" >&2; exit 1; }
echo "mode: $([ $APPLY -eq 1 ] && echo APPLY || echo DRY-RUN)"

python3 -c 'import json;[print(z["domain"]+"\t"+",".join(z.get("cf_ns",[]))+"\t"+(z.get("live_mx") or "")) for z in json.load(open("'"$IN"'")) if z.get("status") in ("created","already_exists")]' \
| while IFS=$'\t' read -r d ns mx; do
  if [ -n "$mx" ]; then
    echo "HOLD  $d  — live MX present ($mx); not flipping"
    continue
  fi
  if [ -z "$ns" ]; then echo "SKIP  $d  — no CF nameservers recorded"; continue; fi
  body=$(python3 -c 'import json,sys;print(json.dumps({"nameServers":sys.argv[1].split(",")}))' "$ns")
  if [ $APPLY -eq 1 ]; then
    code=$(curl -s -o /tmp/gd_resp -w '%{http_code}' -X PATCH \
      "https://api.godaddy.com/v1/domains/$d" \
      -H "Authorization: $GD_AUTH" -H "Content-Type: application/json" \
      --data "$body")
    if [ "$code" = "200" ] || [ "$code" = "204" ]; then
      echo "FLIP  $d  -> $ns  [HTTP $code]"
    else
      echo "FAIL  $d  [HTTP $code]  $(cat /tmp/gd_resp)"
    fi
  else
    echo "WOULD-FLIP  $d  -> $ns"
  fi
done