CloudFlare A records failover script using CloudFlare api v4 (https://api.cloudflare.com) required jq and curl to run.
#!/bin/bash | |
# Copyright (C) 2016 Arash Shams <https://github.com/Ara4Sh>. | |
# | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
#Setting Environment | |
#set -o errexit | |
#set -o nounset | |
#set -o pipefail | |
#CloudFlare Configs | |
#CloudFlare API Key : https://www.cloudflare.com/a/account/my-account | |
CF_KEY= | |
#Zone Name : example.com | |
CF_ZONE= | |
#Zone Identifier | |
CF_ID= | |
#CloudFlare Username : user@example.com | |
CF_USER= | |
#Cloudflare TTL for record, between 120 and 86400 seconds | |
CF_TTL= | |
#Domain Name to check | |
DOMAIN= | |
#IP Addresses | |
A_IPS=() | |
#Get Params | |
while getopts k:z:i:u:t:d:a: opts; do | |
case ${opts} in | |
k) CF_KEY=${OPTARG} ;; | |
z) CF_ZONE=${OPTARG};; | |
i) CF_ID=${OPTARG} ;; | |
u) CF_USER=${OPTARG} ;; | |
t) CF_TTL=${OPTARG} ;; | |
d) DOMAIN=${OPTARG} ;; | |
a) A_IPS+=(${OPTARG}) ;; | |
esac | |
done | |
#Checking for Required Parameters | |
if [[ "$CF_KEY" = "" ]]; then | |
echo "Missing API Key, get at https://www.cloudflare.com/a/account/my-account" | |
echo "and save in ${0} or using -k flag" | |
exit 2 | |
fi | |
if [[ "$CF_USER" = "" ]]; then | |
echo "Missing Username , its your Email address that registered in CloudFlare" | |
echo "and save in ${0} or using the -u flag" | |
exit 2 | |
fi | |
if [[ "$CF_TTL" = "" ]]; then | |
echo "Missing TTL , Choose between 120 and 86400 seconds " | |
echo "Setting default TTL to 120" | |
CF_TTL=120 | |
echo "You can specify TTL manually and save in ${0} or using the -t flag" | |
fi | |
if [[ "$CF_ZONE" = "" ]]; then | |
echo "Missing Zone parameter" | |
echo "Listing All Available zones (Make sure API is valid)" | |
curl -s -X GET "https://api.cloudflare.com/client/v4/zones" \ | |
-H "X-Auth-Email: $CF_USER" \ | |
-H "X-Auth-Key: $CF_KEY" \ | |
-H "Content-Type: application/json" \ | |
| jq -r '.result[].name' | |
echo "Please specify one of available zone in ${0} or specify using the -z flag" | |
exit 2 | |
fi | |
if [[ "$DOMAIN" = "" ]]; then | |
echo "Missing Domain Name" | |
echo "Automatically set Domain name to $CF_ZONE" | |
DOMAIN=$CF_ZONE | |
echo "You can specify domain name manually in ${0} or using -d flag" | |
fi | |
if [[ "$CF_ID" = "" ]]; then | |
echo "Missing Zone Identifier" | |
echo "Set Automatically zone Identifier" | |
CF_ID=$(curl -s -X GET https://api.cloudflare.com/client/v4/zones?name=$CF_ZONE \ | |
-H "X-Auth-Email: $CF_USER" \ | |
-H "X-Auth-Key: $CF_KEY" \ | |
-H "Content-Type: application/json" \ | |
| jq -r '.result[].id') | |
echo "Zone Identifier is now $CF_ID" | |
if [[ -z $CF_ID ]]; then | |
echo "Problem in Automaticly set CF_ID" | |
echo "Please specify CF_ID in ${0} or specify using the -i flag" | |
fi | |
fi | |
if [[ "${#A_IPS[@]}" -eq 0 ]]; then | |
echo "Missing A Records" | |
echo "Please specify A_IPS in ${0} or specify using multiple -a flag" | |
echo "Listing Available A records" | |
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ID/dns_records?type=A&name=$DOMAIN" \ | |
-H "X-Auth-Email: $CF_USER" \ | |
-H "X-Auth-Key: $CF_KEY" \ | |
-H "Content-Type: application/json" \ | |
| jq -r '.result[].content' | |
exit 2 | |
fi | |
check_domains() { | |
domain=$1 | |
check_domain=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones" \ | |
-H "X-Auth-Email: $CF_USER" \ | |
-H "X-Auth-Key: $CF_KEY" \ | |
-H "Content-Type: application/json" \ | |
| jq -r '.result[].name'\ | |
| grep -c $domain) | |
if [[ $check_domain -eq 0 ]]; then | |
echo "Error : $domain is not present in CloudFlare" | |
exit 2 | |
fi | |
} | |
add_a_record() { | |
a_record=$1 | |
check_a=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ID/dns_records?type=A&name=$DOMAIN" \ | |
-H "X-Auth-Email: $CF_USER" \ | |
-H "X-Auth-Key: $CF_KEY" \ | |
-H "Content-Type: application/json" \ | |
| jq -r '.result[].content' \ | |
| grep -c $a_record) | |
if [[ $check_a -eq 0 ]]; then | |
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ID/dns_records" \ | |
-H "X-Auth-Email: $CF_USER" \ | |
-H "X-Auth-Key: $CF_KEY" \ | |
-H "Content-Type: application/json" \ | |
--data '{"type":"A","name":"'$DOMAIN'","content":"'$a_record'","ttl":'$CF_TTL'}' > /dev/null 2>&1 | |
fi | |
} | |
delete_a_record() { | |
a_record=$1 | |
REC_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ID/dns_records?type=A&name=$DOMAIN&content=$a_record" \ | |
-H "X-Auth-Email: $CF_USER" \ | |
-H "X-Auth-Key: $CF_KEY" \ | |
-H "Content-Type: application/json" \ | |
| jq -r '.result[].id') | |
curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/$CF_ID/dns_records/$REC_ID" \ | |
-H "X-Auth-Email: $CF_USER" \ | |
-H "X-Auth-Key: $CF_KEY" \ | |
-H "Content-Type: application/json" > /dev/null 2>&1 | |
} | |
#Gathering Recordst | |
#A_RECS=($(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ID/dns_records?type=A&name=$DOMAIN" \ | |
# -H "X-Auth-Email: $CF_USER" \ | |
# -H "X-Auth-Key: $CF_KEY" \ | |
# -H "Content-Type: application/json" \ | |
# | jq -r '.result[].content')) | |
for ip in "${A_IPS[@]}" | |
do | |
CHK_REC=$(curl -s -m 2 -I "Host: $domain" $ip | head -n1 | grep -c 200) | |
if [[ $CHK_REC -eq 0 ]]; then | |
delete_a_record $ip | |
else | |
add_a_record $ip | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment