← 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