Browse Source

Simplify zone detection with API check

Instead of fetching all zones and matching, iterate through domain
parts and check each against the API until a valid zone is found.
Same approach as GoDaddy DNS plugin.

Example: _acme-challenge.test.example.com
- Try: test.example.com → 404
- Try: example.com → 200 ✓ → zone found!

Script reduced from 304 to 255 lines.
pull/6760/head
Kilian Ries 4 days ago
parent
commit
163eb1acb9
  1. 112
      dnsapi/dns_opusdns.sh

112
dnsapi/dns_opusdns.sh

@ -124,7 +124,8 @@ dns_opusdns_rm() {
######## Private functions ###########
# Detect zone from FQDN by querying OpusDNS API
# Detect zone from FQDN by checking against OpusDNS API
# Iterates through domain parts until a valid zone is found
# Sets global variables: _zone, _record_name
_get_zone() {
domain=$1
@ -133,100 +134,41 @@ _get_zone() {
# Remove trailing dot if present
domain=$(echo "$domain" | sed 's/\.$//')
# Get all zones from OpusDNS with pagination support
export _H1="X-Api-Key: $OPUSDNS_API_Key"
zones=""
page=1
has_more=1
while [ $has_more -eq 1 ]; do
_debug2 "Fetching zones page $page"
response=$(_get "$OPUSDNS_API_Endpoint/v1/dns?page=$page&page_size=100")
if [ $? -ne 0 ]; then
_err "Failed to query zones from OpusDNS API (page $page)"
_debug "Response: $response"
# Start from position 2 (skip first part like _acme-challenge)
i=2
p=1
while true; do
# Extract potential zone (domain parts from position i onwards)
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
_debug "Trying zone: $h"
if [ -z "$h" ]; then
# No more parts to try
_err "Could not find a valid zone for: $domain"
return 1
fi
_debug2 "Zones response (page $page): $response"
# Extract zone names from this page
# The API returns: {"results":[{"name":"zone.com.",...},...],"pagination":{"has_next_page":true,...}}
if _exists jq; then
page_zones=$(echo "$response" | jq -r '.results[].name' 2>/dev/null | sed 's/\.$//')
has_next=$(echo "$response" | jq -r '.pagination.has_next_page // false' 2>/dev/null)
else
# Fallback: extract zone names using grep/sed
# Extract only top-level zone names from results array (before rrsets)
# Pattern: "results":[{"...","name":"zonename.com.","domain_parts":
page_zones=$(echo "$response" | sed 's/,"rrsets":\[[^]]*\]//g' | grep -o '"results":\[.*\]' | grep -o '"name":"[^"]*"' | sed 's/"name":"//g;s/"//g;s/\.$//')
# Extract has_next_page from pagination object
if echo "$response" | grep -q '"has_next_page":true'; then
has_next="true"
else
has_next="false"
fi
fi
_debug2 "Page $page zones: $page_zones"
_debug2 "Has next page: $has_next"
# Append zones from this page
if [ -n "$page_zones" ]; then
if [ -z "$zones" ]; then
zones="$page_zones"
else
zones="$zones
$page_zones"
fi
fi
# Check if this zone exists in OpusDNS
response=$(_get "$OPUSDNS_API_Endpoint/v1/dns/$h")
# Check if there are more pages
if [ "$has_next" = "true" ]; then
page=$((page + 1))
else
has_more=0
if _contains "$response" '"name"'; then
# Zone found
_record_name=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
_zone="$h"
_debug "Found zone: $_zone"
_debug "Record name: $_record_name"
return 0
fi
done
if [ -z "$zones" ]; then
_err "No zones found in OpusDNS account"
_debug "API Response: $response"
return 1
fi
_debug2 "Available zones (all pages): $zones"
# Find longest matching zone
_zone=""
_zone_length=0
for zone in $zones; do
zone_with_dot="${zone}."
if _endswith "$domain." "$zone_with_dot"; then
zone_length=${#zone}
if [ "$zone_length" -gt "$_zone_length" ]; then
_zone="$zone"
_zone_length=$zone_length
fi
fi
_debug "$h not found, trying next"
p="$i"
i=$(_math "$i" + 1)
done
if [ -z "$_zone" ]; then
_err "No matching zone found for domain: $domain"
_err "Available zones: $zones"
return 1
fi
# Calculate record name (subdomain part)
# Use parameter expansion instead of sed to avoid regex metacharacter issues
_record_name="${domain%."${_zone}"}"
# Handle case where domain equals zone (remove trailing dot if present)
if [ "$_record_name" = "$domain" ]; then
_record_name="${domain%"${_zone}"}"
_record_name="${_record_name%.}"
fi
return 1
}
if [ -z "$_record_name" ]; then
_record_name="@"

Loading…
Cancel
Save