add cfdns

This commit is contained in:
Freya Murphy 2024-09-29 15:11:09 -04:00
parent ed35463a36
commit df6a2032fa
Signed by: freya
GPG key ID: 744AB800E383AE52
3 changed files with 237 additions and 0 deletions

View file

@ -15,3 +15,7 @@ converts one font type to another with fontforge, (just an alias posing as a bas
using lets encrypt, allows checking and renewal of lets encrypt certificates. usefull for cron jobs using lets encrypt, allows checking and renewal of lets encrypt certificates. usefull for cron jobs
this uses certbot with webroot, so make sure to have DOMAIN/.well-known/acme-challenge pointed to /var/www/html/.well-known/acme-challenge on your system this uses certbot with webroot, so make sure to have DOMAIN/.well-known/acme-challenge pointed to /var/www/html/.well-known/acme-challenge on your system
#### cfdns
allows creation or updating of existing cloudflare dns records

233
cfdns Executable file
View file

@ -0,0 +1,233 @@
#!/usr/bin/env bash
quiet=0 # should i shut up?!?!? :<
token="" # the api token
domain="" # the domain to update
record="A" # the record type
ttl="60" # the new time to live
content="" # the new record content
usage() {
printf "usage: cfdns [-hq] [-d DOMAIN] [-t TOKEN] [-r RECORD] [-l TTL] [-cC CONTENT]\n\n"
printf "\t-h\t\tshow the help message\n"
printf "\t-q\t\tquiet output\n"
printf "\t-d DOMAIN\tthe domain name to update\n"
printf "\t-t TOKEN\tthe api token\n"
printf "\t-r RECORD\tthe new record type\n"
printf "\t-l TTL\t\tthe new time to live\n"
printf "\t-c CONTENT\tthe new contents of the record\n"
printf "\t-C RAW CONTENT\tthe new conents of the record (as raw json)\n"
}
chk_command() {
if ! command -v "$1" > /dev/null; then
>&2 echo "error: command '$1' could not be found"
exit 1
fi
}
chk_command "getopts"
chk_command "curl"
chk_command "jq"
while getopts "hqd:t:r:l:c:C:" arg > /dev/null; do
case $arg in
h)
usage
exit 0
;;
q)
quiet=1
;;
d)
domain="${OPTARG}"
;;
t)
token="${OPTARG}"
;;
r)
record="${OPTARG}"
;;
l)
ttl="${OPTARG}"
;;
c)
content="\"content\": \"${OPTARG}\""
;;
C)
content="${OPTARG}"
;;
?)
exit 1
;;
esac
done
if [ ! "$cert" = "cert.pem" ] && [ "$key" = "cert.key" ]; then
name=${cert%.*}
key="$name.key"
fi
log() {
if [ $quiet = 0 ]; then
printf "$*\n" 1>&2
fi
}
step() {
if [ $quiet = 0 ]; then
printf "\033[32m>>> \033[0m$*\n" 1>&2
fi
}
error() {
printf "\033[31merror: \033[0m$*\n" > /dev/stderr
}
die() {
kill $$
}
handle_error() {
errs="$1"
count="$(echo $errs | jq -r ". | length")"
for i in $(seq 0 $(($count - 1))); do
err="$(echo $errs | jq -r ".[$i]")"
error "$(echo $err | jq -r '.message')"
chain="$(echo $err | jq -r '.error_chain')"
if ! [ "$chain" = "null" ]; then
count="$(echo $chain | jq -r ". | length")"
for j in $(seq 0 $(($count - 1))); do
error "$(echo $chain | jq -r ".[$j].message")"
done
fi
done
}
_curl() {
RESPONSE=$(curl --silent --request $1 \
--url "https://api.cloudflare.com/client/v4$2" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $token" \
--data "$3")
SUCCESS=$(echo $RESPONSE | jq -r ".success")
if [ "$SUCCESS" != "true" ]; then
errs="$(echo $RESPONSE | jq -r .errors)"
handle_error "$errs"
die
fi
echo $RESPONSE | jq ".result"
}
patch() {
_curl "PATCH" "$1" "$2"
}
post() {
_curl "POST" "$1" "$2"
}
get() {
_curl "GET" "$1" ""
}
# Step 1: get the zone the domain is in
zone=$(echo "$domain" | awk -F'.' '{print $(NF-1)"."$(NF);}' 2>/dev/null)
if [ "$zone" = "" ]; then
error "invalid domain: '$domain'"
die
fi
step "fetching zones..."
zones=$(get "/zones")
zone_id="null"
i=0
while true; do
json="$(echo "$zones" | jq ".[$i]")"
if [ "$json" == "null" ]; then
break
fi
name="$(echo "$json" | jq -r ".name")"
id="$(echo "$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: $zone"
die
fi
# Step 2: get the current record id if it exists
step "fetching records..."
records="$(get "/zones/$zone_id/dns_records")"
current="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 ".name")"
id="$(echo "$_record" | jq -r ".id")"
log "found record: $name $type \"$_content\" ($id)"
if [ "$name" == "$domain" ] && [ "$record" = "$type" ]; then
current="$id"
break
fi
((i=i+1))
done
# Step 3: update record
step "updating record"
update() {
patch "/zones/$zone_id/dns_records/$1" "$2"
}
create() {
post "/zones/$zone_id/dns_records" "$1"
}
json="{
\"name\": \"$domain\",
\"proxied\": false,
\"type\": \"$record\",
$content
}"
log $(echo "$json" | jq -C)
if [ "$current" == "null" ]; then
log "no record found... creating new one"
create "$json"
else
log "record found... updating"
update "$current" "$json"
fi
step "successfully updated record"

0
recert Normal file → Executable file
View file