← back to Coming Soon Template

scripts/cf_zones_create.sh

53 lines

#!/usr/bin/env bash
# Create Cloudflare zones for every domain in manifest.json.
# Idempotent: if a zone already exists, reuses it. Records assigned NS + live MX.
# Output: data/zone-setup.json  (consumed by godaddy_ns_flip.sh)
set -uo pipefail

ENV=~/Projects/secrets-manager/.env
TOK=$(grep '^CLOUDFLARE_API_TOKEN=' "$ENV" | cut -d= -f2)
ACCT=$(grep '^CLOUDFLARE_ACCOUNT_ID=' "$ENV" | cut -d= -f2)
CST=~/Projects/coming-soon-template
OUT="$CST/data/zone-setup.json"
mkdir -p "$CST/data"

domains=$(python3 -c 'import json;[print(d["domain"]) for d in json.load(open("'"$CST"'/manifest.json"))["domains"]]')

echo "[" > "$OUT"
first=1
for d in $domains; do
  # already a zone?
  zr=$(curl -s "https://api.cloudflare.com/client/v4/zones?name=$d&account.id=$ACCT" \
        -H "Authorization: Bearer $TOK")
  zid=$(echo "$zr" | python3 -c 'import sys,json;r=json.load(sys.stdin).get("result",[]);print(r[0]["id"] if r else "")')

  if [ -z "$zid" ]; then
    cr=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones" \
          -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
          --data "{\"account\":{\"id\":\"$ACCT\"},\"name\":\"$d\",\"type\":\"full\"}")
    ok=$(echo "$cr" | python3 -c 'import sys,json;print(json.load(sys.stdin).get("success"))')
    if [ "$ok" != "True" ]; then
      err=$(echo "$cr" | python3 -c 'import sys,json;print("; ".join(f"{e.get(\"code\")}:{e.get(\"message\")}" for e in json.load(sys.stdin).get("errors",[])))')
      echo "FAIL  $d  -> $err" >&2
      [ $first -eq 0 ] && echo "," >> "$OUT"; first=0
      python3 -c 'import json;print(json.dumps({"domain":"'"$d"'","status":"create_failed","error":"'"$err"'"}))' >> "$OUT"
      continue
    fi
    zid=$(echo "$cr" | python3 -c 'import sys,json;print(json.load(sys.stdin)["result"]["id"])')
    ns=$(echo "$cr" | python3 -c 'import sys,json;print(",".join(json.load(sys.stdin)["result"].get("name_servers",[])))')
    state="created"
  else
    ns=$(echo "$zr" | python3 -c 'import sys,json;print(",".join(json.load(sys.stdin)["result"][0].get("name_servers",[])))')
    state="already_exists"
  fi

  # live MX check (queries current authoritative DNS, pre-flip)
  mx=$(/usr/bin/dig +short MX "$d" 2>/dev/null | head -3 | tr '\n' ';' | sed 's/;$//')
  echo "OK    $d  [$state]  ns=$ns  mx=${mx:-none}" >&2

  [ $first -eq 0 ] && echo "," >> "$OUT"; first=0
  python3 -c 'import json,sys;print(json.dumps({"domain":"'"$d"'","status":"'"$state"'","zone_id":"'"$zid"'","cf_ns":"'"$ns"'".split(","),"live_mx":"""'"$mx"'"""}))' >> "$OUT"
done
echo "]" >> "$OUT"
echo "--- wrote $OUT ---" >&2