From 366902305b8a16688ad02d252a3ba6b6c5c7c2cf Mon Sep 17 00:00:00 2001 From: stelar7 Date: Mon, 30 Mar 2026 13:01:45 +0200 Subject: [PATCH 1/2] Add Abion.com DNS API --- dnsapi/dns_abion.sh | 91 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 dnsapi/dns_abion.sh diff --git a/dnsapi/dns_abion.sh b/dnsapi/dns_abion.sh new file mode 100644 index 0000000000..a920d73e6a --- /dev/null +++ b/dnsapi/dns_abion.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_abion_info='abion.com +Site: abion.com +Options: + ABION_API_KEY key +' + +ABION_Api_Endpoint="https://api.abion.com/v1" + +##################### Public functions ##################### + +# Usage: dns_abion_add +# Example: dns_abion_add www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_abion_add() { + fulldomain=$1 + txtvalue=$2 + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + ABION_API_KEY="${ABION_API_KEY:-$(_readaccountconf_mutable ABION_API_KEY)}" + + if [ -z "$ABION_API_KEY" ]; then + ABION_API_KEY="" + _err "You need to spesify ABION_API_KEY." + return 1 + fi + + _saveaccountconf_mutable ABION_API_KEY "$ABION_API_KEY" + + _abion_rest PATCH "zones/$_domain" "{\"data\":{\"type\":\"zone\",\"id\":\"$_domain\",\"attributes\":{\"records\":{\"$_sub_domain\":{\"TXT\":[{\"rdata\":\"$txtvalue\",\"ttl\":300}]}}}}}" +} + +##################### Private functions ##################### + +_get_root() { + domain=$1 + + if ! _abion_rest GET "zones" "" >/dev/null; then + return 1 + fi + + zones=$(echo "$response" | jq -r ".data | map(.id) | .[]") + + num_labels=$(echo "$domain" | tr '.' '\n' | wc -l) + i=2 + while [ "$i" -le "$num_labels" ]; do + candidate=$(echo "$domain" | cut -d'.' -f${i}-) + + for zone in $zones; do + if [ "$zone" = "$candidate" ]; then + _sub_domain=$(echo "$domain" | cut -d'.' -f1-$((i - 1))) + _domain="$candidate" + return 0 + fi + done + + i=$((i + 1)) + done + + return 1 +} + +_abion_rest() { + method=$1 + endpoint=$2 + data=$3 + + export _H1="X-API-KEY: $ABION_API_KEY" + export _H2="Content-Type: application/json" + +if [ "$method" == "GET" ]; then + response="$(_get "$ABION_Api_Endpoint/$endpoint")" + else + response="$(_post "$data" "$ABION_Api_Endpoint/$endpoint" "" "$method")" + fi + + if [ "$?" != "0" ]; then + _err "error $endpoint" + return 1 + fi + + return 0 +} From b912091030edd9613daae92558ac7b74726b0090 Mon Sep 17 00:00:00 2001 From: stelar7 Date: Mon, 29 Jun 2026 10:31:45 +0200 Subject: [PATCH 2/2] Update dns_abion.sh --- dnsapi/dns_abion.sh | 84 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_abion.sh b/dnsapi/dns_abion.sh index a920d73e6a..68b3d6b0ad 100644 --- a/dnsapi/dns_abion.sh +++ b/dnsapi/dns_abion.sh @@ -3,7 +3,7 @@ dns_abion_info='abion.com Site: abion.com Options: - ABION_API_KEY key + ABION_API_KEY API key for abion.com; obtain it from your Abion account/API settings ' ABION_Api_Endpoint="https://api.abion.com/v1" @@ -16,6 +16,16 @@ dns_abion_add() { fulldomain=$1 txtvalue=$2 + ABION_API_KEY="${ABION_API_KEY:-$(_readaccountconf_mutable ABION_API_KEY)}" + + if [ -z "$ABION_API_KEY" ]; then + ABION_API_KEY="" + _err "You need to specify ABION_API_KEY." + return 1 + fi + + _saveaccountconf_mutable ABION_API_KEY "$ABION_API_KEY" + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -25,17 +35,64 @@ dns_abion_add() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" + if ! _abion_rest PATCH "zones/$_domain" "{\"data\":{\"type\":\"zone\",\"id\":\"$_domain\",\"attributes\":{\"records\":{\"$_sub_domain\":{\"TXT\":[{\"rdata\":\"$txtvalue\",\"ttl\":60}]}}}}}"; then + return 1 + fi + + if ! echo "$response" | _egrep_o '"id"' > /dev/null; then + _err "Unexpected API response: $response" + return 1 + fi + + return 0 +} + +# Usage: dns_abion_rm +dns_abion_rm() { + fulldomain=$1 + txtvalue=$2 + ABION_API_KEY="${ABION_API_KEY:-$(_readaccountconf_mutable ABION_API_KEY)}" if [ -z "$ABION_API_KEY" ]; then ABION_API_KEY="" - _err "You need to spesify ABION_API_KEY." + _err "You need to specify ABION_API_KEY." return 1 fi - _saveaccountconf_mutable ABION_API_KEY "$ABION_API_KEY" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" - _abion_rest PATCH "zones/$_domain" "{\"data\":{\"type\":\"zone\",\"id\":\"$_domain\",\"attributes\":{\"records\":{\"$_sub_domain\":{\"TXT\":[{\"rdata\":\"$txtvalue\",\"ttl\":300}]}}}}}" + if ! _abion_rest GET "zones/$_domain"; then + return 1 + fi + + _remaining=$(echo "$response" | _normalizeJson \ + | sed "s/.*\"${_sub_domain}\"://" \ + | _egrep_o '"TXT":\[[^]]*\]' \ + | _egrep_o '"rdata":"[^"]*"' \ + | sed 's/^"rdata":"//;s/"$//' \ + | grep -v "^${txtvalue}$" \ + | sed 's/.*/{"rdata":"&","ttl":60}/' \ + | tr '\n' ',' \ + | sed 's/,$//') + + if ! _abion_rest PATCH "zones/$_domain" "{\"data\":{\"type\":\"zone\",\"id\":\"$_domain\",\"attributes\":{\"records\":{\"$_sub_domain\":{\"TXT\":[${_remaining}]}}}}}"; then + return 1 + fi + + if ! echo "$response" | _egrep_o '"id"' > /dev/null; then + _err "Unexpected API response: $response" + return 1 + fi + + return 0 } ##################### Private functions ##################### @@ -43,26 +100,28 @@ dns_abion_add() { _get_root() { domain=$1 - if ! _abion_rest GET "zones" "" >/dev/null; then + if ! _abion_rest GET "zones" ""; then return 1 fi - zones=$(echo "$response" | jq -r ".data | map(.id) | .[]") + zones=$(echo "$response" | _normalizeJson | sed 's/},{/}\ +{/g' | _egrep_o '"id":"[^"]*"' | sed 's/^"id":"//; s/"$//') - num_labels=$(echo "$domain" | tr '.' '\n' | wc -l) - i=2 + num_labels=$(echo "$domain" | tr '.' '\n' | wc -l | tr -d '[:space:]') + i=1 while [ "$i" -le "$num_labels" ]; do - candidate=$(echo "$domain" | cut -d'.' -f${i}-) + candidate=$(echo "$domain" | cut -d'.' -f"${i}"-) for zone in $zones; do if [ "$zone" = "$candidate" ]; then - _sub_domain=$(echo "$domain" | cut -d'.' -f1-$((i - 1))) + _sub_len=$(_math "$i" - 1) + _sub_domain=$(echo "$domain" | cut -d'.' -f1-"$_sub_len") _domain="$candidate" return 0 fi done - i=$((i + 1)) + i=$(_math "$i" + 1) done return 1 @@ -76,7 +135,7 @@ _abion_rest() { export _H1="X-API-KEY: $ABION_API_KEY" export _H2="Content-Type: application/json" -if [ "$method" == "GET" ]; then + if [ "$method" = "GET" ]; then response="$(_get "$ABION_Api_Endpoint/$endpoint")" else response="$(_post "$data" "$ABION_Api_Endpoint/$endpoint" "" "$method")" @@ -87,5 +146,6 @@ if [ "$method" == "GET" ]; then return 1 fi + _debug2 response "$response" return 0 }