#!/usr/bin/env bash set -euo pipefail : "${CLOUDFLARE_API_TOKEN:?set CLOUDFLARE_API_TOKEN}" : "${CLOUDFLARE_ZONE_ID:?set CLOUDFLARE_ZONE_ID}" : "${BASE_DOMAIN:?set BASE_DOMAIN}" : "${PUBLIC_DOMAIN:=$BASE_DOMAIN}" : "${DNS_MODE:=upsert}" api() { curl -fsS -X "$1" "https://api.cloudflare.com/client/v4$2" \ -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ -H 'Content-Type: application/json' \ ${3:+--data "$3"} } lookup_record_id() { local type="$1" local name="$2" curl -fsS "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records?type=$type&name=$name" \ -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ -H 'Content-Type: application/json' | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d["result"][0]["id"] if d.get("result") else "")' } upsert_record() { local type="$1" local name="$2" local content="$3" local proxied="${4:-false}" local existing_id existing_id=$(lookup_record_id "$type" "$name") local payload payload=$(printf '{"type":"%s","name":"%s","content":"%s","ttl":120,"proxied":%s}' "$type" "$name" "$content" "$proxied") if [[ -n "$existing_id" ]]; then api PUT "/zones/$CLOUDFLARE_ZONE_ID/dns_records/$existing_id" "$payload" >/dev/null else api POST "/zones/$CLOUDFLARE_ZONE_ID/dns_records" "$payload" >/dev/null fi } delete_record() { local type="$1" local name="$2" local existing_id existing_id=$(lookup_record_id "$type" "$name") if [[ -n "$existing_id" ]]; then api DELETE "/zones/$CLOUDFLARE_ZONE_ID/dns_records/$existing_id" >/dev/null echo "deleted $type $name" else echo "skipped missing $type $name" fi } records=( "$PUBLIC_DOMAIN" "git.$PUBLIC_DOMAIN" "registry.$PUBLIC_DOMAIN" "grafana.$PUBLIC_DOMAIN" ) case "$DNS_MODE" in upsert) : "${SERVER_IP:?set SERVER_IP}" upsert_record A "${records[0]}" "$SERVER_IP" false upsert_record A "${records[1]}" "$SERVER_IP" false upsert_record A "${records[2]}" "$SERVER_IP" false upsert_record A "${records[3]}" "$SERVER_IP" false echo "cloudflare dns updated for ${records[*]}" ;; delete) delete_record A "${records[0]}" delete_record A "${records[1]}" delete_record A "${records[2]}" delete_record A "${records[3]}" echo "cloudflare dns cleanup finished for ${records[*]}" ;; *) echo "unsupported DNS_MODE: $DNS_MODE" >&2 exit 1 ;; esac