File: //bigscoots/cloudflare/manager.sh
#!/usr/bin/env bash
# ARGUMENTS
DOMAIN=$1
OLD_IP=$2
NEW_IP=$3
# WEBHOOK CONFIG
LOOKUP_URL="https://n8n.bigscoots.dev/webhook/bbc77722-f123-4a9c-9361-f60845150553"
LOOKUP_TOKEN="O@e9aw8daWDO2wa9ida82da8a87"
# Validation
if [[ -z "$DOMAIN" || -z "$OLD_IP" || -z "$NEW_IP" ]]; then
echo "ERROR: Missing arguments."
echo "Usage: bash $0 <domain.com> <old_ip> <new_ip>"
exit 1
fi
if [[ -z "$TOKEN" ]]; then
echo "ERROR: Cloudflare API Token (for updates) not provided."
exit 1
fi
echo "--------------------------------------------------------"
echo " Cloudflare Update: $DOMAIN"
echo " Mapping: $OLD_IP -> $NEW_IP"
echo "--------------------------------------------------------"
# 1. GET THE ZONE ID VIA LOOKUP WEBHOOK
echo "[*] Locating Zone ID via BigScoots Lookup..."
LOOKUP_RESP=$(curl -s -X POST "$LOOKUP_URL" \
-H "Authorization: Bearer $LOOKUP_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"domain\": \"$DOMAIN\"}")
ZONE_ID=$(echo "$LOOKUP_RESP" | jq -r '.data.zone_id // empty')
if [[ -z "$ZONE_ID" || "$ZONE_ID" == "null" ]]; then
echo "[!] Error: Could not find Zone ID for $DOMAIN via lookup webhook."
echo " Response: $LOOKUP_RESP"
exit 1
fi
echo "[+] Target Zone ID: $ZONE_ID"
# 2. UPDATE A RECORDS (Standard IP swap)
echo "[*] Checking A records..."
A_RECORDS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=A&content=$OLD_IP" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json")
echo "$A_RECORDS" | jq -c '.result[]' | while read -r record; do
REC_ID=$(echo "$record" | jq -r '.id')
REC_NAME=$(echo "$record" | jq -r '.name')
echo -n " -> A Record: $REC_NAME... "
UPDATE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$REC_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data "{\"content\":\"$NEW_IP\"}")
[[ $(echo "$UPDATE" | jq -r '.success') == "true" ]] && echo "SUCCESS." || echo "FAILED."
done
# 3. UPDATE SPF (TXT RECORDS)
echo "[*] Checking SPF/TXT records..."
TXT_RECORDS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=TXT" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" | jq -c ".result[] | select(.content | contains(\"$OLD_IP\"))")
if [[ -z "$TXT_RECORDS" ]]; then
echo " -> No TXT/SPF records found containing $OLD_IP."
else
echo "$TXT_RECORDS" | while read -r record; do
REC_ID=$(echo "$record" | jq -r '.id')
# We strip literal quotes here using tr -d '"'
OLD_CONTENT=$(echo "$record" | jq -r '.content' | tr -d '"')
# Swap the IP
NEW_CONTENT=$(echo "$OLD_CONTENT" | sed "s/$OLD_IP/$NEW_IP/g")
echo -n " -> SPF Update: $OLD_CONTENT -> $NEW_CONTENT... "
# Send the clean string
UPDATE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$REC_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data "{\"content\":\"$NEW_CONTENT\"}")
[[ $(echo "$UPDATE" | jq -r '.success') == "true" ]] && echo "SUCCESS." || echo "FAILED."
done
fi
echo "--------------------------------------------------------"