diff options
Diffstat (limited to 'dns.sh')
-rwxr-xr-x | dns.sh | 167 |
1 files changed, 167 insertions, 0 deletions
@@ -0,0 +1,167 @@ +API_TOKEN="${API_TOKEN:-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcd}" +ZONE="${ZONE:-example.com}" +DOMAIN="${DOMAIN:-example.com}" + +EVENT() { + printf "\x1b[95m>>> \x1b[0m\x1b[98m$1\n" +} + +LOG() { + printf "\x1b[98m$1\n" +} + +ERROR() { + >&2 printf "\x1b[91mError: \x1b[0m\x1b[98m$1\n" +} + +CURL() { + RESPONSE=$(curl --silent --request $1 \ + --url "https://api.cloudflare.com/client/v4$2" \ + --header "Content-Type: application/json" \ + --header "Authorization: Bearer $API_TOKEN" \ + --data "$3") + SUCCESS=$(echo $RESPONSE | jq -r ".success") + if [ "$SUCCESS" != "true" ]; then + ERROR "$(echo $RESPONSE | jq -r ".errors[0].message")" + kill $$ + fi + + echo $RESPONSE | jq ".result" +} + +PATCH() { + CURL "PATCH" "$1" "$2" +} + +POST() { + CURL "POST" "$1" "$2" +} + +GET() { + CURL "GET" "$1" "" +} + +EVENT "Getting Zones" +ZONES=$(GET "/zones") +ZONE_ID="null" + +i=0 +while true; do + + ZONE_JSON=$(echo $ZONES | jq ".[$i]") + + if [ "$ZONE_JSON" == "null" ]; then + break + fi + + NAME=$(echo $ZONE_JSON | jq -r ".name") + ID=$(echo $ZONE_JSON | jq -r ".id") + + LOG "Found Zone $NAME ($ID)" + + if [ "$NAME" == "$ZONE" ]; then + ZONE_ID=$ID + break + fi + + ((i=i+1)) + +done + +if [ "$ZONE_ID" == "null" ]; then + ERROR "Could not find zone $DOMAIN" + exit 1 +fi + +EVENT "Getting Records" + +RECORDS=$(GET "/zones/$ZONE_ID/dns_records") + +IPv4Current="null" +IPv6Current="null" +IPv4Id="null" +IPv6Id="null" + +i=0 +while true; do + + RECORD=$(echo $RECORDS | jq ".[$i]") + + if [ "$RECORD" == "null" ]; then + break + fi + + NAME=$(echo $RECORD | jq -r '.name') + TYPE=$(echo $RECORD | jq -r '.type') + CONTENT=$(echo $RECORD | jq -r '.content') + ID=$(echo $RECORD | jq -r '.id') + + LOG "Found record $NAME $TYPE \"$CONTENT\" ($ID)" + + if [ "$NAME" == "$DOMAIN" ] && [ "$TYPE" == "A" ]; then + IPv4Current="$CONTENT" + IPv4Id="$ID" + fi + + if [ "$NAME" == "$DOMAIN" ] && [ "$TYPE" == "AAAA" ]; then + IPv6Current="$CONTENT" + IPv6Id="$ID" + fi + + ((i=i+1)) + +done + +EVENT "Getting current IPs" + +IPv4New=$(curl ip.me -4sL --silent) +LOG "Using IPv4 $IPv4New" + +IPv6New=$(curl ip.me -6sL --silent) +LOG "Using IPv6 $IPv6New" + +UPDATE() { + PATCH "/zones/$ZONE_ID/dns_records/$1" "$2" > /dev/null +} + +CREATE() { + POST "/zones/$ZONE_ID/dns_records" "$1" > /dev/null +} + +IPv4JSON="{ + \"content\": \"$IPv4New\", + \"name\": \"$DOMAIN\", + \"proxied\": false, + \"type\": \"A\" +}" + +IPv6JSON="{ + \"content\": \"$IPv6New\", + \"name\": \"$DOMAIN\", + \"proxied\": false, + \"type\": \"AAAA\" +}" + +EVENT "Updating Records" + +if [ "$IPv4Id" == "null" ]; then + LOG "No IPv4 record found... creating new one" + CREATE "$IPv4JSON" +elif [ "$IPv4Current" != "$IPv4New" ]; then + LOG "IPv4 record found... updating" + UPDATE "$IPv4Id" "$IPv4JSON" +else + LOG "IPv4 is up to date... skipping" +fi + +if [ "$IPv6Id" == "null" ]; then + LOG "No IPv6 record found... creating new one" + CREATE "$IPv6JSON" +elif [ "$IPv6Current" != "$IPv6New" ]; then + LOG "IPv6 record found... updating" + UPDATE "$IPv6Id" "$IPv6JSON" +else + LOG "IPv6 is up to date... skipping" +fi + +EVENT "Successfully updated records" |