← back to Coming Soon Template
add CF zone-create + GoDaddy NS-flip scripts for 21 abrams/butler domains
5341e9944a663dbd84ef08b89e8778ff0a9264dc · 2026-05-18 11:37:45 -0700 · SteveStudio2
Files touched
A scripts/cf_zones_create.shA scripts/godaddy_ns_flip.sh
Diff
commit 5341e9944a663dbd84ef08b89e8778ff0a9264dc
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Mon May 18 11:37:45 2026 -0700
add CF zone-create + GoDaddy NS-flip scripts for 21 abrams/butler domains
---
scripts/cf_zones_create.sh | 52 ++++++++++++++++++++++++++++++++++++++++++++++
scripts/godaddy_ns_flip.sh | 39 ++++++++++++++++++++++++++++++++++
2 files changed, 91 insertions(+)
diff --git a/scripts/cf_zones_create.sh b/scripts/cf_zones_create.sh
new file mode 100644
index 0000000..1d8a4b7
--- /dev/null
+++ b/scripts/cf_zones_create.sh
@@ -0,0 +1,52 @@
+#!/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
diff --git a/scripts/godaddy_ns_flip.sh b/scripts/godaddy_ns_flip.sh
new file mode 100755
index 0000000..f0663bd
--- /dev/null
+++ b/scripts/godaddy_ns_flip.sh
@@ -0,0 +1,39 @@
+#!/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)
+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: sso-key $KEY:$SEC" -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
← 67ff39c Add Cloudflare Pages deploy script — artifact-dir only, neve
·
back to Coming Soon Template
·
rewrite CF zone setup in Node — real error capture (token la 78446c1 →