#!/usr/bin/env bash set -euo pipefail require() { command -v "$1" >/dev/null 2>&1 || { echo "missing command: $1" >&2; exit 1; } } require curl require python3 : "${PORKBUN_API_KEY:?set PORKBUN_API_KEY}" : "${PORKBUN_SECRET_API_KEY:?set PORKBUN_SECRET_API_KEY}" : "${BASE_DOMAIN:?set BASE_DOMAIN}" : "${SERVER_IP:?set SERVER_IP}" api_base="https://api.porkbun.com/api/json/v3" root_name="" git_name="git" registry_name="registry" payload() { local content="$1" printf '{"apikey":"%s","secretapikey":"%s","content":"%s","ttl":"600"}' \ "$PORKBUN_API_KEY" "$PORKBUN_SECRET_API_KEY" "$content" } list_records() { curl -sSf "$api_base/dns/retrieve/$BASE_DOMAIN" \ -H 'Content-Type: application/json' \ --data "{\"apikey\":\"$PORKBUN_API_KEY\",\"secretapikey\":\"$PORKBUN_SECRET_API_KEY\"}" } upsert_a_record() { local name="$1" local fqdn="$BASE_DOMAIN" [[ -n "$name" ]] && fqdn="$name.$BASE_DOMAIN" local record_id record_id=$(python3 - "$fqdn" "$(list_records)" <<'PY' import json,sys fqdn=sys.argv[1] data=json.loads(sys.argv[2]) for rec in data.get('records', []): if rec.get('type') == 'A' and rec.get('name') == fqdn: print(rec.get('id','')) break PY ) if [[ -n "$record_id" ]]; then curl -fsS "$api_base/dns/edit/$BASE_DOMAIN/$record_id" \ -H 'Content-Type: application/json' \ --data "$(payload "$SERVER_IP")" >/dev/null echo "updated A $fqdn -> $SERVER_IP" else local body body=$(printf '{"apikey":"%s","secretapikey":"%s","name":"%s","type":"A","content":"%s","ttl":"600"}' \ "$PORKBUN_API_KEY" "$PORKBUN_SECRET_API_KEY" "$name" "$SERVER_IP") curl -fsS "$api_base/dns/create/$BASE_DOMAIN" \ -H 'Content-Type: application/json' \ --data "$body" >/dev/null echo "created A $fqdn -> $SERVER_IP" fi } upsert_a_record "$root_name" upsert_a_record "$git_name" upsert_a_record "$registry_name" echo "porkbun dns updated for $BASE_DOMAIN, git.$BASE_DOMAIN, registry.$BASE_DOMAIN"