summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-09-29 15:11:09 -0400
committerFreya Murphy <freya@freyacat.org>2024-09-29 15:11:09 -0400
commitdf6a2032fae9afef123fc0feb78348e8acb39cd4 (patch)
tree64ccf374fef3e2d0fc6a41042cae1050cebf6243
parentupdate recert (make it acutaly work) (diff)
downloadscripts-df6a2032fae9afef123fc0feb78348e8acb39cd4.tar.gz
scripts-df6a2032fae9afef123fc0feb78348e8acb39cd4.tar.bz2
scripts-df6a2032fae9afef123fc0feb78348e8acb39cd4.zip
add cfdns
-rw-r--r--README.md4
-rwxr-xr-xcfdns233
-rwxr-xr-x[-rw-r--r--]recert0
3 files changed, 237 insertions, 0 deletions
diff --git a/README.md b/README.md
index 1e3b563..730be22 100644
--- a/README.md
+++ b/README.md
@@ -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
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
diff --git a/cfdns b/cfdns
new file mode 100755
index 0000000..2476ad0
--- /dev/null
+++ b/cfdns
@@ -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"
diff --git a/recert b/recert
index 356ce62..356ce62 100644..100755
--- a/recert
+++ b/recert