Files
nas-tools/scripts/cloudflare-dns.sh
T
Gan, Jimmy 95daf1f167
Deploy Reasonix / Build & Deploy Reasonix (push) Has been cancelled
ci(reasonix): add deploy workflow + Cloudflare DNS upsert script
2026-07-11 05:31:38 +08:00

93 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# Cloudflare DNS upsert — create or update a DNS record.
# Usage: CLOUDFLARE_API_TOKEN=xxx ./scripts/cloudflare-dns.sh <zone> <type> <name> <content> [ttl]
#
# Examples:
# cloudflare-dns.sh jimmygan.com A code 161.33.182.109
# cloudflare-dns.sh jimmygan.com CNAME www jimmygan.com 120
set -euo pipefail
ZONE="${1:?Usage: $0 <zone> <type> <name> <content> [ttl]}"
TYPE="${2:?}"
NAME="${3:?}"
CONTENT="${4:?}"
TTL="${5:-120}"
if [ -z "${CLOUDFLARE_API_TOKEN:-}" ]; then
echo "❌ CLOUDFLARE_API_TOKEN not set" >&2
exit 1
fi
API="https://api.cloudflare.com/client/v4"
AUTH_HEADER="Authorization: Bearer $CLOUDFLARE_API_TOKEN"
CONTENT_TYPE="Content-Type: application/json"
echo "🔍 Looking up zone: $ZONE"
ZONE_RESP=$(curl -s -H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
"$API/zones?name=$ZONE&status=active")
ZONE_ID=$(echo "$ZONE_RESP" | python3 -c "
import sys, json
d = json.load(sys.stdin)
if not d.get('success'):
print('API error:', d.get('errors'), file=sys.stderr)
sys.exit(1)
result = d.get('result', [])
if not result:
print('Zone not found:', '$ZONE', file=sys.stderr)
sys.exit(1)
print(result[0]['id'])
")
echo "✅ Zone ID: $ZONE_ID"
echo "🔍 Checking existing record: $NAME.$ZONE ($TYPE)"
RECORD_RESP=$(curl -s -H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
"$API/zones/$ZONE_ID/dns_records?type=$TYPE&name=$NAME.$ZONE")
RECORD_ID=$(echo "$RECORD_RESP" | python3 -c "
import sys, json
d = json.load(sys.stdin)
if not d.get('success'):
sys.exit(0) # skip, will create
result = d.get('result', [])
if result:
# Prefer exact content match
for r in result:
if r['content'] == '$CONTENT':
print(r['id'])
sys.exit(0)
# Fall back to first match
print(result[0]['id'])
")
FULL_NAME="$NAME.$ZONE"
if [ -n "$RECORD_ID" ]; then
echo "🔄 Updating existing record ($RECORD_ID): $FULL_NAME$CONTENT"
RESP=$(curl -s -X PUT \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d "{\"type\":\"$TYPE\",\"name\":\"$FULL_NAME\",\"content\":\"$CONTENT\",\"ttl\":$TTL,\"proxied\":false}" \
"$API/zones/$ZONE_ID/dns_records/$RECORD_ID")
SUCCESS=$(echo "$RESP" | python3 -c "import sys,json; d=json.load(sys.stdin); print('true' if d.get('success') else 'false')")
if [ "$SUCCESS" = "true" ]; then
echo "✅ Updated: $FULL_NAME$CONTENT"
else
echo "❌ Failed to update:" >&2
echo "$RESP" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('errors'))" >&2
exit 1
fi
else
echo "🆕 Creating new record: $FULL_NAME$CONTENT"
RESP=$(curl -s -X POST \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d "{\"type\":\"$TYPE\",\"name\":\"$FULL_NAME\",\"content\":\"$CONTENT\",\"ttl\":$TTL,\"proxied\":false}" \
"$API/zones/$ZONE_ID/dns_records")
SUCCESS=$(echo "$RESP" | python3 -c "import sys,json; d=json.load(sys.stdin); print('true' if d.get('success') else 'false')")
if [ "$SUCCESS" = "true" ]; then
echo "✅ Created: $FULL_NAME$CONTENT"
else
echo "❌ Failed to create:" >&2
echo "$RESP" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('errors'))" >&2
exit 1
fi
fi