HEX
Server: nginx/1.29.3
System: Linux 11979.bigscoots-wpo.com 6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025 x86_64
User: nginx (1068)
PHP: 7.4.33
Disabled: exec,system,passthru,shell_exec,proc_open,proc_close,popen,show_source,cmd# Do not modify this line # 1684243876
Upload Files
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 "--------------------------------------------------------"