169 lines
3.2 KiB
Bash
Executable file
169 lines
3.2 KiB
Bash
Executable file
#!/usr/bin/env sh
|
|
|
|
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"
|