From b2e6173b1a4e780533d6413b39b9eabc809c8fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20N=C3=A6ss?= <102598494+InvisibleDuck@users.noreply.github.com> Date: Sat, 3 Oct 2026 07:48:58 +0200 Subject: [PATCH] fix: poweradmin dnsapi leaves hanging txt records (#7232) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: improved record txt record matching matching txt records sometimes failed if they contained certain chars causing leftover challenges in dns zone * fix(dns_poweradmin): use portable record and zone matching grep -o and grep -F are not supported by Solaris /usr/bin/grep. Split JSON objects with the core _egrep_o wrapper and match name, type and content with case, which is literal by construction. Loop over a here-doc since case inside $(...) breaks bash 3.2 and Solaris sh. Apply the same to _get_root. Drop _json_escape: hostnames and base64url challenge values cannot contain quotes or backslashes, so escaping was a no-op. Co-Authored-By: Claude Opus 5.5 (1M context) --------- Co-authored-by: neil Co-authored-by: Jakob Næss Co-authored-by: Claude Opus 5.5 (1M context) --- dnsapi/dns_poweradmin.sh | 52 ++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/dnsapi/dns_poweradmin.sh b/dnsapi/dns_poweradmin.sh index a4c81835..2ae86347 100644 --- a/dnsapi/dns_poweradmin.sh +++ b/dnsapi/dns_poweradmin.sh @@ -114,21 +114,32 @@ _rm_record() { full=$1 txtvalue=$2 - if ! _poweradmin_rest "GET" "/api/v${POWERADMIN_API_VERSION}/zones/$_zone_id/records"; then + if ! _poweradmin_rest "GET" "/api/v${POWERADMIN_API_VERSION}/zones/$_zone_id/records?type=TXT"; then _err "Failed to retrieve records" return 1 fi - # The API returns: {"success":true,"data":[{"id":..., "name":"...", "type":"TXT", "content":"...", ...}]} - _txt_record_obj=$( - printf '%s\n' "$response" | - sed 's/^.*"data":\[//; s/\],"message":.*$//' | - awk '{ gsub(/},{/, "}\n{"); print }' | - grep -F "\"name\":\"$full\"" | - grep -F "\"type\":\"TXT\"" | - grep -F "\"content\":\"$txtvalue\"" | - _head_n 1 - ) + # The API returns: {"success":true,"data":{"records":[{"id":..., "name":"...", "type":"TXT", "content":"...", ...}]},"message":"..."} + _records="$(printf '%s\n' "$response" | tr -d '\r\n' | _egrep_o '\{[^{}]*\}')" + _txt_record_obj="" + while IFS= read -r _rec || [ -n "$_rec" ]; do + case "$_rec" in + *"\"name\":\"$full\""*) ;; + *) continue ;; + esac + case "$_rec" in + *"\"type\":\"TXT\""*) ;; + *) continue ;; + esac + case "$_rec" in + *"\"content\":\"$txtvalue\""*) + _txt_record_obj="$_rec" + break + ;; + esac + done <