Skip to content

Instantly share code, notes, and snippets.

@rallisf1
Created July 18, 2024 13:25
Show Gist options
  • Save rallisf1/6f695add1bb3ea1dd800e917871b5e5e to your computer and use it in GitHub Desktop.
Save rallisf1/6f695add1bb3ea1dd800e917871b5e5e to your computer and use it in GitHub Desktop.
Import Cloudflare DNS Entries into Enhance CP
#!/bin/bash
# KNOWN BUG: DNS records of subdomains created as main websites will be stored in the main domain's website
CF_API_TOKEN=""
ENH_DOMAIN=""
ENH_ORG_ID=""
ENH_API_TOKEN=""
DRY=true
PROXIED_TTL=300 # Cloudflare default, 5 minutes
STANDARD_TTL=3600 # 1 hour
ZONE_RES=$(curl -X GET 'https://api.cloudflare.com/client/v4/zones' -H "Authorization: Bearer $CF_API_TOKEN" -H 'Content-Type:application/json')
CF_DOMAINS=()
CF_DOMAIN_IDS=()
TOTAL_PAGES=$(echo "${ZONE_RES}" | jq -r '.result_info.total_pages')
END=$((TOTAL_PAGES + 1))
for i in $(seq 2 $END)
do
for row in $(echo "${ZONE_RES}" | jq -r '.result.[] | @base64')
do
_jq() {
echo ${row} | base64 --decode | jq -r ${1}
}
CF_DOMAINS+=( $(_jq '.name') )
CF_DOMAIN_IDS+=( $(_jq '.id') )
done
ZONE_RES=$(curl -X GET "https://api.cloudflare.com/client/v4/zones?page=$i" -H "Authorization: Bearer $CF_API_TOKEN" -H 'Content-Type:application/json')
done
ENH_RES=$(curl -X GET "https://$ENH_DOMAIN/api/orgs/$ENH_ORG_ID/websites?showDeleted=false" -H "Authorization: Bearer $ENH_API_TOKEN" -H 'Content-Type:application/json')
for row in $(echo "${ENH_RES}" | jq -r '.items.[] | @base64')
do
_jq() {
echo ${row} | base64 --decode | jq -r ${1}
}
DOMAIN_COUNTER=0
for i in "${CF_DOMAINS[@]}"
do
if [ "$i" == $(_jq '.domain.domain') ]
then
echo "Processing domain $i..."
# domain exists in both Enhance and Cloudflare
# delete all DNS entries in Enhance
ENH_DNS_RES=$(curl -X GET "https://$ENH_DOMAIN/api/orgs/$ENH_ORG_ID/websites/$(_jq '.id')/domains/$(_jq '.domain.id')/dns-zone" -H "Authorization: Bearer $ENH_API_TOKEN" -H 'Content-Type:application/json')
for row2 in $(echo "${ENH_DNS_RES}" | jq -r '.records.[] | @base64')
do
_jqh() {
echo ${row2} | base64 --decode | jq -r ${1}
}
if [ "$DRY" = true ]
then
echo "I would DELETE /websites/$(_jq '.id')/domains/$(_jq '.domain.id')/dns-zone/records/$(_jqh '.id')"
else
curl -X DELETE "https://$ENH_DOMAIN/api/orgs/$ENH_ORG_ID/websites/$(_jq '.id')/domains/$(_jq '.domain.id')/dns-zone/records/$(_jqh '.id')" -H "Authorization: Bearer $ENH_API_TOKEN" -H 'Content-Type:application/json'
fi
done
# get Cloudflare dns entries.
# default pagination is 100 records, which is fine for 99.99% of cases
CF_DNS_RES=$(curl -X GET "https://api.cloudflare.com/client/v4/zones/${CF_DOMAIN_IDS[$DOMAIN_COUNTER]}/dns_records" -H "Authorization: Bearer $CF_API_TOKEN" -H 'Content-Type:application/json')
# insert cloudflare DNS entries in Enhance
for row2 in $(echo "${CF_DNS_RES}" | jq -r '.result.[] | @base64')
do
_jqc() {
echo ${row2} | base64 --decode | jq -r ${1}
}
if [ "true" == $(_jqc '.proxied') ]
then
TTL=$PROXIED_TTL
else
TTL=$STANDARD_TTL
fi
NAME=$(_jqc '.name')
if [ "$i" == $NAME ]
then
NAME="@"
else
DOMAIN_LENGTH=${#i}
NAME_LENGTH=${#NAME}
NEW_LENGTH=NAME_LENGTH-DOMAIN_LENGTH-1
NAME=${NAME:0:NEW_LENGTH}
fi
VALUE=$(_jqc '.content')
for special in "SRV" "MX" "CNAME"
do
if [ "$special" == $(_jqc '.type') ]
then
VALUE="$(_jqc '.content')."
break
fi
done
if [ "$special" != "CNAME" ]
then
VALUE="$(_jqc '.priority') $VALUE"
fi
if [ "$DRY" = true ]
then
echo "I would ADD /websites/$(_jq '.id')/domains/$(_jq '.domain.id')/dns-zone/records {\"kind\":\"$(_jqc '.type')\",\"name\":\"$NAME\",\"value\":\"$VALUE\",\"ttl\":$TTL,\"proxy\":$(_jqc '.proxied')}"
else
curl -X POST "https://$ENH_DOMAIN/api/orgs/$ENH_ORG_ID/websites/$(_jq '.id')/domains/$(_jq '.domain.id')/dns-zone/records" -H "Authorization: Bearer $ENH_API_TOKEN" -H 'Content-Type:application/json' -d "{\"kind\":\"$(_jqc '.type')\",\"name\":\"$NAME\",\"value\":\"$VALUE\",\"ttl\":$TTL,\"proxy\":$(_jqc '.proxied')}"
fi
done
fi
DOMAIN_COUNTER=$((DOMAIN_COUNTER + 1))
done
done
@rallisf1
Copy link
Author

You will need curl and jq packages in the machine you run this code. It doesn't need to be an enhance server, any linux enrivonment will do.

The records are not automatically synced, you need to add/edit any record for them to be pushed to cloudflare.

Syncing SRV records is currently broken (they don't sync over to Cloudflare)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment