This repository has been archived on 2026-09-17. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
nixos-config/scripts/configure-pinix-identity-dns.sh

43 lines
1.9 KiB
Bash

#!/usr/bin/env bash
# Run with the agenix-backed Cloudflare EnvironmentFile, never with a token
# on the command line. Default is read-only; --apply creates missing records.
set -euo pipefail
set +x
mode=${1:---check}
[[ "$mode" == --check || "$mode" == --apply ]] || exit 2
: "${CLOUDFLARE_DNS_API_TOKEN:?Cloudflare environment required}"
api() {
printf 'Authorization: Bearer %s\n' "$CLOUDFLARE_DNS_API_TOKEN" |
curl --fail --silent --show-error --max-time 30 -H @- \
-H 'Content-Type: application/json' "$@"
}
base=https://api.cloudflare.com/client/v4
zone=$(api "$base/zones?name=lukasrosier.com" |
jq -er 'select(.success) | .result | select(length == 1) | .[0].id')
target=ipv6-test.0ff.space
missing=()
# Preflight all identity names before writing any of them. Never replace an existing
# service, delete a record, or touch the wildcard/mail/NS/0ff.space records.
for name in dex.lukasrosier.com head.lukasrosier.com lldap.lukasrosier.com; do
records=$(api "$base/zones/$zone/dns_records?name=$name&per_page=100" |
jq -ec 'select(.success) | .result')
if [[ $(jq length <<< "$records") == 0 ]]; then
missing+=("$name")
printf 'Missing: %s CNAME %s (DNS-only)\n' "$name" "$target"
elif jq -e --arg target "$target" \
'length == 1 and .[0].type == "CNAME" and
(.[0].content | rtrimstr(".")) == $target and .[0].proxied == false' \
<<< "$records" >/dev/null; then
printf 'Already correct: %s\n' "$name"
else
printf 'Refusing to replace existing records at %s\n' "$name" >&2
exit 1
fi
done
[[ "$mode" == --apply ]] || exit 0
for name in "${missing[@]}"; do
payload=$(jq -nc --arg name "$name" --arg target "$target" \
'{type:"CNAME",name:$name,content:$target,proxied:false,ttl:300}')
api -X POST "$base/zones/$zone/dns_records" --data "$payload" |
jq -e 'select(.success) | .result | {id,name,type,content,proxied,ttl}'
done