From 4cc460be642d1fd9f3bddf82e953e1d783fd1def Mon Sep 17 00:00:00 2001 From: Peter Vos Date: Tue, 24 Dec 2024 13:33:15 +0100 Subject: [PATCH 01/19] Added dns challenge for mijn.host --- dnsapi/dns_mijn_host.sh | 145 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 dnsapi/dns_mijn_host.sh diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh new file mode 100644 index 00000000..5caf5a22 --- /dev/null +++ b/dnsapi/dns_mijn_host.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env sh +# shellcheck disable=SC2034 +dns_mijnhost_info='mijn.host +Domains: mijn.host +Site: mijn.host +Docs: https://mijn.host/api/doc/api-3563900 +Options: + MIJN_HOST_API_KEY API Key +' + +######## Public functions ###################### Constants for your mijn-host API +MIJN_HOST_API="https://mijn.host/api/v2" + +# Add TXT record for domain verification +dns_mijn_host_add() { + fulldomain=$1 + txtvalue=$2 + + MIJN_HOST_API_KEY="${MIJN_HOST_API_KEY:-$(_readaccountconf_mutable MIJN_HOST_API_KEY)}" + if [ -z "$MIJN_HOST_API_KEY" ]; then + MIJN_HOST_API_KEY="" + _err "You haven't specified mijn-host API key yet." + _err "Please set it and try again." + return 1 + fi + + # Save the API key for future use + _saveaccountconf_mutable MIJN_HOST_API_KEY "$MIJN_HOST_API_KEY" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + + _debug "Add TXT record" + + # Build the payload for the API + data="{\"type\":\"TXT\",\"name\":\"$subdomain\",\"value\":\"$txtvalue\",\"ttl\":120}" + + export _H1="API-Key: $MIJN_HOST_API_KEY" + export _H2="Content-Type: application/json" + + extracted_domain="${fulldomain#*_acme-challenge.}" + + # Construct the API URL + api_url="$MIJN_HOST_API/domains/$extracted_domain/dns" + + # Getting preivous records + get_response="$(_get "$api_url")" + records=$(echo "$get_response" | jq -r '.data.records') + + # Updating the records + updated_records=$(echo "$records" | jq --argjson data "$data" '. += [$data]') + + # data + data="{\"records\": $updated_records}" + + # Use the _post method to make the API request + response="$(_post "$data" "$api_url" "" "PUT")" + + if _contains "$response" "error"; then + _err "Error adding TXT record: $response" + return 1 + fi + + _info "TXT record added successfully" + return 0 +} + +# Remove TXT record after verification +dns_mijn_host_rm() { + fulldomain=$1 + txtvalue=$2 + + MIJN_HOST_API_KEY="${MIJN_HOST_API_KEY:-$(_readaccountconf_mutable MIJN_HOST_API_KEY)}" + if [ -z "$MIJN_HOST_API_KEY" ]; then + MIJN_HOST_API_KEY="" + _err "You haven't specified mijn-host API key yet." + return 1 + fi + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Invalid domain" + return 1 + fi + + _debug "Removing TXT record" + + # Build the payload for the API + export _H1="API-Key: $MIJN_HOST_API_KEY" + export _H2="Content-Type: application/json" + + extracted_domain="${fulldomain#*_acme-challenge.}" + + # Construct the API URL + api_url="$MIJN_HOST_API/domains/$extracted_domain/dns" + + # Get current records + response="$(_get "$api_url")" + + updated_records=$(echo "$response" | jq '.data.records') + + updated_records=$(echo "$updated_records" | jq --arg value "$txtvalue" 'map(select(.value != $value))') + + # Build the new payload + data="{\"records\": $updated_records}" + + # Use the _put method to update the records + response="$(_post "$data" "$api_url" "" "PUT")" + + if _contains "$response" "error"; then + _err "Error updating TXT record: $response" + return 1 + fi + + _info "TXT record removed successfully" + return 0 +} + +# Helper function to detect the root zone +_get_root() { + domain=$1 + i=2 + p=1 + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f "$i"-) + if [ -z "$h" ]; then + return 1 + fi + + if _contains "$(dig ns "$h")" "mijn.host"; then + root_zone="$h" + subdomain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + return 0 + fi + + p=$i + i=$(_math "$i" + 1) + done + + return 1 +} From 5e9a067e8754a180b37f718154b33acde3651c80 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Tue, 24 Dec 2024 16:55:26 +0100 Subject: [PATCH 02/19] Fixed root domain detection and processing. --- dnsapi/dns_mijn_host.sh | 61 ++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh index 5caf5a22..e8ad398d 100644 --- a/dnsapi/dns_mijn_host.sh +++ b/dnsapi/dns_mijn_host.sh @@ -3,7 +3,7 @@ dns_mijnhost_info='mijn.host Domains: mijn.host Site: mijn.host -Docs: https://mijn.host/api/doc/api-3563900 +Docs: https://mijn.host/api/doc/ Options: MIJN_HOST_API_KEY API Key ' @@ -33,23 +33,26 @@ dns_mijn_host_add() { return 1 fi + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + _debug "Add TXT record" # Build the payload for the API - data="{\"type\":\"TXT\",\"name\":\"$subdomain\",\"value\":\"$txtvalue\",\"ttl\":120}" + data="{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\",\"ttl\":120}" export _H1="API-Key: $MIJN_HOST_API_KEY" export _H2="Content-Type: application/json" - extracted_domain="${fulldomain#*_acme-challenge.}" - # Construct the API URL - api_url="$MIJN_HOST_API/domains/$extracted_domain/dns" + api_url="$MIJN_HOST_API/domains/$_domain/dns" - # Getting preivous records + # Getting previous records get_response="$(_get "$api_url")" records=$(echo "$get_response" | jq -r '.data.records') + _debug2 "previous records" "$records" + # Updating the records updated_records=$(echo "$records" | jq --argjson data "$data" '. += [$data]') @@ -59,7 +62,9 @@ dns_mijn_host_add() { # Use the _post method to make the API request response="$(_post "$data" "$api_url" "" "PUT")" - if _contains "$response" "error"; then + _debug2 "Response" "$response" + + if ! _contains "$response" "200"; then _err "Error adding TXT record: $response" return 1 fi @@ -92,10 +97,8 @@ dns_mijn_host_rm() { export _H1="API-Key: $MIJN_HOST_API_KEY" export _H2="Content-Type: application/json" - extracted_domain="${fulldomain#*_acme-challenge.}" - # Construct the API URL - api_url="$MIJN_HOST_API/domains/$extracted_domain/dns" + api_url="$MIJN_HOST_API/domains/$_domain/dns" # Get current records response="$(_get "$api_url")" @@ -110,7 +113,7 @@ dns_mijn_host_rm() { # Use the _put method to update the records response="$(_post "$data" "$api_url" "" "PUT")" - if _contains "$response" "error"; then + if ! _contains "$response" "200"; then _err "Error updating TXT record: $response" return 1 fi @@ -122,24 +125,32 @@ dns_mijn_host_rm() { # Helper function to detect the root zone _get_root() { domain=$1 - i=2 - p=1 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f "$i"-) - if [ -z "$h" ]; then - return 1 - fi + # Get all domains + export _H1="API-Key: $MIJN_HOST_API_KEY" + export _H2="Content-Type: application/json" - if _contains "$(dig ns "$h")" "mijn.host"; then - root_zone="$h" - subdomain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + # Construct the API URL + api_url="$MIJN_HOST_API/domains" + + # Get current records + response="$(_get "$api_url")" + + if ! _contains "$response" "200"; then + _err "Error listing domains: $response" + return 1 + fi + + # Extract root oomains from response + rootDomains=$(echo "$response" | jq -r '.data.domains[].domain') + + for rootDomain in $rootDomains; do + if _contains "$domain" "$rootDomain"; then + _domain="$rootDomain" + _sub_domain=$(printf '%s\n' "${domain//."$rootDomain"/}") return 0 fi - - p=$i - i=$(_math "$i" + 1) done - return 1 + return 1 } From ab1a2045d9e5c1cca112a037d3b44d9e4174e834 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Tue, 24 Dec 2024 17:10:30 +0100 Subject: [PATCH 03/19] Made string removal in root domain detection posix compliant --- dnsapi/dns_mijn_host.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh index e8ad398d..55cd49a2 100644 --- a/dnsapi/dns_mijn_host.sh +++ b/dnsapi/dns_mijn_host.sh @@ -126,7 +126,7 @@ dns_mijn_host_rm() { _get_root() { domain=$1 - # Get all domains + # Get all domains export _H1="API-Key: $MIJN_HOST_API_KEY" export _H2="Content-Type: application/json" @@ -140,17 +140,17 @@ _get_root() { _err "Error listing domains: $response" return 1 fi - + # Extract root oomains from response rootDomains=$(echo "$response" | jq -r '.data.domains[].domain') for rootDomain in $rootDomains; do if _contains "$domain" "$rootDomain"; then _domain="$rootDomain" - _sub_domain=$(printf '%s\n' "${domain//."$rootDomain"/}") + _sub_domain=$(echo "$domain" | sed "s/$rootDomain//g") return 0 fi done - return 1 + return 1 } From c7cecd5b4fec49d9f4a67dbd04fe33fd21681de3 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Tue, 24 Dec 2024 17:30:50 +0100 Subject: [PATCH 04/19] Removed "." from _sub_domain to create a valid domain. --- dnsapi/dns_mijn_host.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh index 55cd49a2..0e279a98 100644 --- a/dnsapi/dns_mijn_host.sh +++ b/dnsapi/dns_mijn_host.sh @@ -147,7 +147,7 @@ _get_root() { for rootDomain in $rootDomains; do if _contains "$domain" "$rootDomain"; then _domain="$rootDomain" - _sub_domain=$(echo "$domain" | sed "s/$rootDomain//g") + _sub_domain=$(echo "$domain" | sed "s/.$rootDomain//g") return 0 fi done From 07220a324d53a3275659a0280a5d79932223a5d0 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Tue, 24 Dec 2024 23:21:50 +0100 Subject: [PATCH 05/19] Removed all jq references --- dnsapi/dns_mijn_host.sh | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh index 0e279a98..16d652b7 100644 --- a/dnsapi/dns_mijn_host.sh +++ b/dnsapi/dns_mijn_host.sh @@ -49,20 +49,24 @@ dns_mijn_host_add() { # Getting previous records get_response="$(_get "$api_url")" - records=$(echo "$get_response" | jq -r '.data.records') + records=$(echo "$get_response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') - _debug2 "previous records" "$records" + _debug "Current records" "$records" # Updating the records - updated_records=$(echo "$records" | jq --argjson data "$data" '. += [$data]') + updated_records=$(echo "$records" | sed -E "s/\]( *$)/,$data\]/") + + _debug "Updated records" "$updatedrecords" # data data="{\"records\": $updated_records}" + _debug "json data add_dns PUT call:" "$data" + # Use the _post method to make the API request response="$(_post "$data" "$api_url" "" "PUT")" - _debug2 "Response" "$response" + _debug "Response to PUT dns_add" "$response" if ! _contains "$response" "200"; then _err "Error adding TXT record: $response" @@ -102,17 +106,27 @@ dns_mijn_host_rm() { # Get current records response="$(_get "$api_url")" + + _debug "Get current records response:" "$response" - updated_records=$(echo "$response" | jq '.data.records') + records=$(echo "$get_response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') + + _debug "Current records:" "$records" - updated_records=$(echo "$updated_records" | jq --arg value "$txtvalue" 'map(select(.value != $value))') + updated_records=$(echo "$updated_records" | sed -E "s/\{[^}]*\"value\":\"$txtvalue\"[^}]*\},?//g" | sed 's/,]/]/g') + + _debug "Updated records:" "$updated_records" # Build the new payload data="{\"records\": $updated_records}" + + _debug "Payload:" "$data" # Use the _put method to update the records response="$(_post "$data" "$api_url" "" "PUT")" + _debug "Response:" "$response" + if ! _contains "$response" "200"; then _err "Error updating TXT record: $response" return 1 @@ -141,8 +155,10 @@ _get_root() { return 1 fi - # Extract root oomains from response - rootDomains=$(echo "$response" | jq -r '.data.domains[].domain') + # Extract root domains from response + rootDomains=$(echo "$response" | _egrep_o '"domain":"[^"]*"' | sed -E 's/"domain":"([^"]*)"/\1/') + + _debug "Root domains:" "$rootDomains" for rootDomain in $rootDomains; do if _contains "$domain" "$rootDomain"; then From 35f3b7088d4b50ccd14a3cd7e63036562cb65f11 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Wed, 25 Dec 2024 00:00:19 +0100 Subject: [PATCH 06/19] Updated PUT request to hold only fqdn domain name values# --- dnsapi/dns_mijn_host.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh index 16d652b7..62b0c144 100644 --- a/dnsapi/dns_mijn_host.sh +++ b/dnsapi/dns_mijn_host.sh @@ -39,7 +39,7 @@ dns_mijn_host_add() { _debug "Add TXT record" # Build the payload for the API - data="{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\",\"ttl\":120}" + data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"ttl\":120}" export _H1="API-Key: $MIJN_HOST_API_KEY" export _H2="Content-Type: application/json" @@ -55,8 +55,8 @@ dns_mijn_host_add() { # Updating the records updated_records=$(echo "$records" | sed -E "s/\]( *$)/,$data\]/") - - _debug "Updated records" "$updatedrecords" + + _debug "Updated records" "$updated_records" # data data="{\"records\": $updated_records}" @@ -106,20 +106,20 @@ dns_mijn_host_rm() { # Get current records response="$(_get "$api_url")" - + _debug "Get current records response:" "$response" records=$(echo "$get_response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') - + _debug "Current records:" "$records" updated_records=$(echo "$updated_records" | sed -E "s/\{[^}]*\"value\":\"$txtvalue\"[^}]*\},?//g" | sed 's/,]/]/g') - + _debug "Updated records:" "$updated_records" # Build the new payload data="{\"records\": $updated_records}" - + _debug "Payload:" "$data" # Use the _put method to update the records From 3cfa882fe1d88d49b99d55ab6c919e79957944f7 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Wed, 25 Dec 2024 08:52:09 +0100 Subject: [PATCH 07/19] Fixed error in dns_mijn_host_rm --- dnsapi/dns_mijn_host.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh index 62b0c144..e3f5bb60 100644 --- a/dnsapi/dns_mijn_host.sh +++ b/dnsapi/dns_mijn_host.sh @@ -39,7 +39,7 @@ dns_mijn_host_add() { _debug "Add TXT record" # Build the payload for the API - data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"ttl\":120}" + data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"ttl\":300}" export _H1="API-Key: $MIJN_HOST_API_KEY" export _H2="Content-Type: application/json" @@ -95,7 +95,7 @@ dns_mijn_host_rm() { return 1 fi - _debug "Removing TXT record" + _debug "Removing TXT record" "$txtvalue" # Build the payload for the API export _H1="API-Key: $MIJN_HOST_API_KEY" @@ -105,7 +105,7 @@ dns_mijn_host_rm() { api_url="$MIJN_HOST_API/domains/$_domain/dns" # Get current records - response="$(_get "$api_url")" + get_response="$(_get "$api_url")" _debug "Get current records response:" "$response" From 7512dbffbbc0b7a9e2cd7cb55fc3c6a74c289df3 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Wed, 25 Dec 2024 09:50:27 +0100 Subject: [PATCH 08/19] Fixed yet another error in dns_rm --- dnsapi/dns_mijn_host.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh index e3f5bb60..5a5634dd 100644 --- a/dnsapi/dns_mijn_host.sh +++ b/dnsapi/dns_mijn_host.sh @@ -107,25 +107,23 @@ dns_mijn_host_rm() { # Get current records get_response="$(_get "$api_url")" - _debug "Get current records response:" "$response" + _debug "Get current records response:" "$get_response" records=$(echo "$get_response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') _debug "Current records:" "$records" - updated_records=$(echo "$updated_records" | sed -E "s/\{[^}]*\"value\":\"$txtvalue\"[^}]*\},?//g" | sed 's/,]/]/g') + updated_records=$(echo "$records" | sed -E "s/\{[^}]*\"value\":\"$txtvalue\"[^}]*\},?//g" | sed 's/,]/]/g') _debug "Updated records:" "$updated_records" # Build the new payload data="{\"records\": $updated_records}" - _debug "Payload:" "$data" - # Use the _put method to update the records response="$(_post "$data" "$api_url" "" "PUT")" - _debug "Response:" "$response" + _debug "Response to PUT dns_rm:" "$response" if ! _contains "$response" "200"; then _err "Error updating TXT record: $response" From 150c708726248e2dda8e2691e2e2211feac0fe5a Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Wed, 25 Dec 2024 14:11:52 +0100 Subject: [PATCH 09/19] Better debug messages for root domain detection --- dnsapi/dns_mijn_host.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijn_host.sh index 5a5634dd..2cd9a865 100644 --- a/dnsapi/dns_mijn_host.sh +++ b/dnsapi/dns_mijn_host.sh @@ -162,6 +162,9 @@ _get_root() { if _contains "$domain" "$rootDomain"; then _domain="$rootDomain" _sub_domain=$(echo "$domain" | sed "s/.$rootDomain//g") + + _debug "Found root domain" "$_domain" "and subdomain" "$_sub_domain" "for" "$domain" + return 0 fi done From b0f566a80dc9ac0913d2acbe254e592aca023d67 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Thu, 26 Dec 2024 23:36:55 +0100 Subject: [PATCH 10/19] Name change to be in line with other API scripts Added time-out to _get calls at 120s to fix API timeouts --- dnsapi/{dns_mijn_host.sh => dns_mijnhost.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dnsapi/{dns_mijn_host.sh => dns_mijnhost.sh} (100%) diff --git a/dnsapi/dns_mijn_host.sh b/dnsapi/dns_mijnhost.sh similarity index 100% rename from dnsapi/dns_mijn_host.sh rename to dnsapi/dns_mijnhost.sh From 9ad794f2cc9fa1d74b18cf81ca6b61d42a820fff Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Fri, 27 Dec 2024 08:56:16 +0100 Subject: [PATCH 11/19] Name change, function name change to mijnhost --- dnsapi/dns_mijnhost.sh | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index 2cd9a865..760602c3 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -5,27 +5,27 @@ Domains: mijn.host Site: mijn.host Docs: https://mijn.host/api/doc/ Options: - MIJN_HOST_API_KEY API Key + MIJNHOST_API_KEY API Key ' ######## Public functions ###################### Constants for your mijn-host API -MIJN_HOST_API="https://mijn.host/api/v2" +MIJNHOST_API="https://mijn.host/api/v2" # Add TXT record for domain verification -dns_mijn_host_add() { +dns_mijnhost_add() { fulldomain=$1 txtvalue=$2 - MIJN_HOST_API_KEY="${MIJN_HOST_API_KEY:-$(_readaccountconf_mutable MIJN_HOST_API_KEY)}" - if [ -z "$MIJN_HOST_API_KEY" ]; then - MIJN_HOST_API_KEY="" + MIJNHOST_API_KEY="${MIJNHOST_API_KEY:-$(_readaccountconf_mutable MIJNHOST_API_KEY)}" + if [ -z "$MIJNHOST_API_KEY" ]; then + MIJNHOST_API_KEY="" _err "You haven't specified mijn-host API key yet." _err "Please set it and try again." return 1 fi # Save the API key for future use - _saveaccountconf_mutable MIJN_HOST_API_KEY "$MIJN_HOST_API_KEY" + _saveaccountconf_mutable MIJNHOST_API_KEY "$MIJNHOST_API_KEY" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -41,14 +41,14 @@ dns_mijn_host_add() { # Build the payload for the API data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"ttl\":300}" - export _H1="API-Key: $MIJN_HOST_API_KEY" + export _H1="API-Key: $MIJNHOST_API_KEY" export _H2="Content-Type: application/json" # Construct the API URL - api_url="$MIJN_HOST_API/domains/$_domain/dns" + api_url="$MIJNHOST_API/domains/$_domain/dns" # Getting previous records - get_response="$(_get "$api_url")" + get_response="$(_get "$api_url" "" "120")" records=$(echo "$get_response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') _debug "Current records" "$records" @@ -78,13 +78,13 @@ dns_mijn_host_add() { } # Remove TXT record after verification -dns_mijn_host_rm() { +dns_mijnhost_rm() { fulldomain=$1 txtvalue=$2 - MIJN_HOST_API_KEY="${MIJN_HOST_API_KEY:-$(_readaccountconf_mutable MIJN_HOST_API_KEY)}" - if [ -z "$MIJN_HOST_API_KEY" ]; then - MIJN_HOST_API_KEY="" + MIJNHOST_API_KEY="${MIJNHOST_API_KEY:-$(_readaccountconf_mutable MIJNHOST_API_KEY)}" + if [ -z "$MIJNHOST_API_KEY" ]; then + MIJNHOST_API_KEY="" _err "You haven't specified mijn-host API key yet." return 1 fi @@ -98,14 +98,14 @@ dns_mijn_host_rm() { _debug "Removing TXT record" "$txtvalue" # Build the payload for the API - export _H1="API-Key: $MIJN_HOST_API_KEY" + export _H1="API-Key: $MIJNHOST_API_KEY" export _H2="Content-Type: application/json" # Construct the API URL - api_url="$MIJN_HOST_API/domains/$_domain/dns" + api_url="$MIJNHOST_API/domains/$_domain/dns" # Get current records - get_response="$(_get "$api_url")" + get_response="$(_get "$api_url" "" "120")" _debug "Get current records response:" "$get_response" @@ -139,14 +139,14 @@ _get_root() { domain=$1 # Get all domains - export _H1="API-Key: $MIJN_HOST_API_KEY" + export _H1="API-Key: $MIJNHOST_API_KEY" export _H2="Content-Type: application/json" # Construct the API URL - api_url="$MIJN_HOST_API/domains" + api_url="$MIJNHOST_API/domains" # Get current records - response="$(_get "$api_url")" + response="$(_get "$api_url" "" "120")" if ! _contains "$response" "200"; then _err "Error listing domains: $response" From d093476da5ab6241e78dfe170e973f71f8dc2155 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Fri, 27 Dec 2024 12:55:12 +0100 Subject: [PATCH 12/19] Refactored REST calls to add generic retries, as mijn.host API times out at times. --- dnsapi/dns_mijnhost.sh | 151 +++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 57 deletions(-) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index 760602c3..3b0fc3f5 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -33,48 +33,47 @@ dns_mijnhost_add() { return 1 fi - _debug _sub_domain "$_sub_domain" - _debug _domain "$_domain" - - _debug "Add TXT record" - - # Build the payload for the API - data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"ttl\":300}" - - export _H1="API-Key: $MIJNHOST_API_KEY" - export _H2="Content-Type: application/json" + _debug2 _sub_domain "$_sub_domain" + _debug2 _domain "$_domain" + _debug "Adding TXT record" # Construct the API URL api_url="$MIJNHOST_API/domains/$_domain/dns" # Getting previous records - get_response="$(_get "$api_url" "" "120")" - records=$(echo "$get_response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') + _mijnhost_rest GET "$api_url" "" - _debug "Current records" "$records" + if [ "$_code" != "200" ]; then + _err "Error getting current DNS enties ($_code)" + return 1 + fi + + records=$(echo "$response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') + + _debug2 "Current records" "$records" + + # Build the payload for the API + data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"ttl\":300}" + + _debug2 "Record to add: " "$data" # Updating the records updated_records=$(echo "$records" | sed -E "s/\]( *$)/,$data\]/") - _debug "Updated records" "$updated_records" + _debug2 "Updated records" "$updated_records" # data data="{\"records\": $updated_records}" - _debug "json data add_dns PUT call:" "$data" - - # Use the _post method to make the API request - response="$(_post "$data" "$api_url" "" "PUT")" + _mijnhost_rest PUT "$api_url" "$data" - _debug "Response to PUT dns_add" "$response" - - if ! _contains "$response" "200"; then - _err "Error adding TXT record: $response" + if [ "$_code" = "200" ]; then + _info "DNS record succesfully added" + return 0 + else + _err "Error adding DNS record ($_code)" return 1 fi - - _info "TXT record added successfully" - return 0 } # Remove TXT record after verification @@ -95,79 +94,117 @@ dns_mijnhost_rm() { return 1 fi - _debug "Removing TXT record" "$txtvalue" - - # Build the payload for the API - export _H1="API-Key: $MIJNHOST_API_KEY" - export _H2="Content-Type: application/json" + _debug "Removing TXT record" "$txtvalue" "for" "$fulldomain" # Construct the API URL api_url="$MIJNHOST_API/domains/$_domain/dns" # Get current records - get_response="$(_get "$api_url" "" "120")" + _mijnhost_rest GET "$api_url" "" + + if [ "$_code" != "200" ]; then + _err "Error getting current DNS enties ($_code)" + return 1 + fi - _debug "Get current records response:" "$get_response" + _debug2 "Get current records response:" "$response" - records=$(echo "$get_response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') + records=$(echo "$response" | _egrep_o '"records":\[.*\]' | sed 's/"records"://') - _debug "Current records:" "$records" + _debug2 "Current records:" "$records" updated_records=$(echo "$records" | sed -E "s/\{[^}]*\"value\":\"$txtvalue\"[^}]*\},?//g" | sed 's/,]/]/g') - _debug "Updated records:" "$updated_records" + _debug2 "Updated records:" "$updated_records" # Build the new payload data="{\"records\": $updated_records}" # Use the _put method to update the records - response="$(_post "$data" "$api_url" "" "PUT")" - - _debug "Response to PUT dns_rm:" "$response" + _mijnhost_rest PUT "$api_url" "$data" - if ! _contains "$response" "200"; then - _err "Error updating TXT record: $response" + if [ "$_code" = "200" ]; then + _info "DNS record removed successfully" + return 0 + else + _err "Error removing DNS record ($_code)" return 1 fi - - _info "TXT record removed successfully" - return 0 } # Helper function to detect the root zone _get_root() { domain=$1 - # Get all domains - export _H1="API-Key: $MIJNHOST_API_KEY" - export _H2="Content-Type: application/json" - - # Construct the API URL - api_url="$MIJNHOST_API/domains" - # Get current records - response="$(_get "$api_url" "" "120")" + _debug "Getting current domains" + _mijnhost_rest GET "$MIJNHOST_API/domains" "" - if ! _contains "$response" "200"; then - _err "Error listing domains: $response" + if [ "$_code" != "200" ]; then + _err "error getting current domains ($_code)" return 1 fi # Extract root domains from response rootDomains=$(echo "$response" | _egrep_o '"domain":"[^"]*"' | sed -E 's/"domain":"([^"]*)"/\1/') - _debug "Root domains:" "$rootDomains" for rootDomain in $rootDomains; do if _contains "$domain" "$rootDomain"; then _domain="$rootDomain" _sub_domain=$(echo "$domain" | sed "s/.$rootDomain//g") - _debug "Found root domain" "$_domain" "and subdomain" "$_sub_domain" "for" "$domain" - return 0 fi done - return 1 } + +# Helper function for rest calls +_mijnhost_rest() { + m=$1 + ep="$2" + data="$3" + + MAX_REQUEST_RETRY_TIMES=5 + _request_retry_times=0 + while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do + _debug3 _request_retry_times "$_request_retry_times" + export _H1="API-Key: $MIJNHOST_API_KEY" + export _H2="Content-Type: application/json" + # clear headers from previous request to avoid getting wrong http code on timeouts + : >"$HTTP_HEADER" + _debug "$ep" + if [ "$m" != "GET" ]; then + _debug2 "data $data" + response="$(_post "$data" "$ep" "" "$m")" + else + response="$(_get "$ep")" + fi + _ret="$?" + _debug2 "response $response" + _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" + _debug "http response code $_code" + if [ "$_code" = "401" ]; then + # we have an invalid API token, maybe it is expired? + _err "Access denied. Invalid API token." + return 1 + fi + + if [ "$_ret" != "0" ] || [ -z "$_code" ]; then + _request_retry_times="$(_math "$_request_retry_times" + 1)" + _info "REST call error $_code retrying $ep in $_request_retry_times s" + # Sleep 10 times the number of retries in seconds, to increase backoff time + _sleep "$(_math "$_request_retry_times" \* 10)" + continue + fi + break + done + if [ "$_request_retry_times" = "$MAX_REQUEST_RETRY_TIMES" ]; then + _err "Error mijn.host API call was retried $MAX_REQUEST_RETRY_TIMES times." + _err "Calling $ep failed." + return 1 + fi + response="$(echo "$response" | _normalizeJson)" + return 0 +} From ac9852f9df6c904719e6241f8e9b049db06b21e4 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Fri, 27 Dec 2024 16:47:02 +0100 Subject: [PATCH 13/19] Added fix for specific API error that mijn.host sometimes throws. --- dnsapi/dns_mijnhost.sh | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index 3b0fc3f5..ea204353 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -19,8 +19,8 @@ dns_mijnhost_add() { MIJNHOST_API_KEY="${MIJNHOST_API_KEY:-$(_readaccountconf_mutable MIJNHOST_API_KEY)}" if [ -z "$MIJNHOST_API_KEY" ]; then MIJNHOST_API_KEY="" - _err "You haven't specified mijn-host API key yet." - _err "Please set it and try again." + _err "You haven't specified your mijn-host API key yet." + _err "Please add MIJNHOST_API_KEY to the env." return 1 fi @@ -35,7 +35,7 @@ dns_mijnhost_add() { _debug2 _sub_domain "$_sub_domain" _debug2 _domain "$_domain" - _debug "Adding TXT record" + _debug "Adding DNS record" "${fulldomain}." # Construct the API URL api_url="$MIJNHOST_API/domains/$_domain/dns" @@ -55,7 +55,7 @@ dns_mijnhost_add() { # Build the payload for the API data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"ttl\":300}" - _debug2 "Record to add: " "$data" + _debug2 "Record to add" "$data" # Updating the records updated_records=$(echo "$records" | sed -E "s/\]( *$)/,$data\]/") @@ -68,10 +68,10 @@ dns_mijnhost_add() { _mijnhost_rest PUT "$api_url" "$data" if [ "$_code" = "200" ]; then - _info "DNS record succesfully added" + _info "DNS record succesfully added." return 0 else - _err "Error adding DNS record ($_code)" + _err "Error adding DNS record ($_code)." return 1 fi } @@ -84,17 +84,18 @@ dns_mijnhost_rm() { MIJNHOST_API_KEY="${MIJNHOST_API_KEY:-$(_readaccountconf_mutable MIJNHOST_API_KEY)}" if [ -z "$MIJNHOST_API_KEY" ]; then MIJNHOST_API_KEY="" - _err "You haven't specified mijn-host API key yet." + _err "You haven't specified your mijn-host API key yet." + _err "Please add MIJNHOST_API_KEY to the env." return 1 fi - _debug "First detect the root zone" + _debug "Detecting root zone for" "${fulldomain}." if ! _get_root "$fulldomain"; then _err "Invalid domain" return 1 fi - _debug "Removing TXT record" "$txtvalue" "for" "$fulldomain" + _debug "Removing DNS record for TXT value" "${txtvalue}." # Construct the API URL api_url="$MIJNHOST_API/domains/$_domain/dns" @@ -124,10 +125,10 @@ dns_mijnhost_rm() { _mijnhost_rest PUT "$api_url" "$data" if [ "$_code" = "200" ]; then - _info "DNS record removed successfully" + _info "DNS record removed successfully." return 0 else - _err "Error removing DNS record ($_code)" + _err "Error removing DNS record ($_code)." return 1 fi } @@ -191,7 +192,7 @@ _mijnhost_rest() { return 1 fi - if [ "$_ret" != "0" ] || [ -z "$_code" ]; then + if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "400" ] || _contains "$response" "DNS records not managed by mijn.host"; then #Sometimes API errors out _request_retry_times="$(_math "$_request_retry_times" + 1)" _info "REST call error $_code retrying $ep in $_request_retry_times s" # Sleep 10 times the number of retries in seconds, to increase backoff time From 588123ed117de0dfddeeea4d85a8d9b3a1f8d458 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Fri, 27 Dec 2024 23:56:13 +0100 Subject: [PATCH 14/19] Updated backoff algorithm --- dnsapi/dns_mijnhost.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index ea204353..5fe43d93 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -169,6 +169,8 @@ _mijnhost_rest() { MAX_REQUEST_RETRY_TIMES=5 _request_retry_times=0 + _retry_sleep=5 #Initial sleep time in seconds. + while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do _debug3 _request_retry_times "$_request_retry_times" export _H1="API-Key: $MIJNHOST_API_KEY" @@ -195,8 +197,8 @@ _mijnhost_rest() { if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "400" ] || _contains "$response" "DNS records not managed by mijn.host"; then #Sometimes API errors out _request_retry_times="$(_math "$_request_retry_times" + 1)" _info "REST call error $_code retrying $ep in $_request_retry_times s" - # Sleep 10 times the number of retries in seconds, to increase backoff time - _sleep "$(_math "$_request_retry_times" \* 10)" + _sleep "$_retry_sleep" + _retry_sleep="$(_math "$_retry_sleep" \* 2)" continue fi break From 7a6101c4175efbfb0b781fb4543a25ce3b92a171 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Fri, 27 Dec 2024 23:56:13 +0100 Subject: [PATCH 15/19] Corrected sleep time message --- dnsapi/dns_mijnhost.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index ea204353..5fe43d93 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -169,6 +169,8 @@ _mijnhost_rest() { MAX_REQUEST_RETRY_TIMES=5 _request_retry_times=0 + _retry_sleep=5 #Initial sleep time in seconds. + while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do _debug3 _request_retry_times "$_request_retry_times" export _H1="API-Key: $MIJNHOST_API_KEY" @@ -195,8 +197,8 @@ _mijnhost_rest() { if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "400" ] || _contains "$response" "DNS records not managed by mijn.host"; then #Sometimes API errors out _request_retry_times="$(_math "$_request_retry_times" + 1)" _info "REST call error $_code retrying $ep in $_request_retry_times s" - # Sleep 10 times the number of retries in seconds, to increase backoff time - _sleep "$(_math "$_request_retry_times" \* 10)" + _sleep "$_retry_sleep" + _retry_sleep="$(_math "$_retry_sleep" \* 2)" continue fi break From 42862852b81e2b8071a3e3515f6f30f000e5d100 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Sat, 28 Dec 2024 12:41:26 +0100 Subject: [PATCH 16/19] Corrected sleep message --- dnsapi/dns_mijnhost.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index 5fe43d93..6dc9b8e0 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -196,7 +196,7 @@ _mijnhost_rest() { if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "400" ] || _contains "$response" "DNS records not managed by mijn.host"; then #Sometimes API errors out _request_retry_times="$(_math "$_request_retry_times" + 1)" - _info "REST call error $_code retrying $ep in $_request_retry_times s" + _info "REST call error $_code retrying $ep in $_retry_sleep s" _sleep "$_retry_sleep" _retry_sleep="$(_math "$_retry_sleep" \* 2)" continue From 234bc93ddbbe701348e9838014c7ec97cc1ef9a9 Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Sat, 28 Dec 2024 12:42:50 +0100 Subject: [PATCH 17/19] Removed superfluous debug message --- dnsapi/dns_mijnhost.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index 6dc9b8e0..c1f74389 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -172,7 +172,7 @@ _mijnhost_rest() { _retry_sleep=5 #Initial sleep time in seconds. while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do - _debug3 _request_retry_times "$_request_retry_times" + _debug2 _request_retry_times "$_request_retry_times" export _H1="API-Key: $MIJNHOST_API_KEY" export _H2="Content-Type: application/json" # clear headers from previous request to avoid getting wrong http code on timeouts From 9526dbadad48811f39bdc566dd99336aaa71e04c Mon Sep 17 00:00:00 2001 From: peterv99 <_hidden_> Date: Sat, 28 Dec 2024 17:26:52 +0100 Subject: [PATCH 18/19] mijn.host API unreliable, upped retry times to 15 --- dnsapi/dns_mijnhost.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index 699436ef..b52d65d9 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -167,7 +167,7 @@ _mijnhost_rest() { ep="$2" data="$3" - MAX_REQUEST_RETRY_TIMES=5 + MAX_REQUEST_RETRY_TIMES=15 _request_retry_times=0 _retry_sleep=5 #Initial sleep time in seconds. From 1ae7dd9b113513a24a6dcc7ef71ef6aa3943fa72 Mon Sep 17 00:00:00 2001 From: peterv99 <145142820+peterv99@users.noreply.github.com> Date: Sun, 29 Dec 2024 09:30:48 +0100 Subject: [PATCH 19/19] Updated info block --- dnsapi/dns_mijnhost.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dnsapi/dns_mijnhost.sh b/dnsapi/dns_mijnhost.sh index b52d65d9..9dafc702 100644 --- a/dnsapi/dns_mijnhost.sh +++ b/dnsapi/dns_mijnhost.sh @@ -4,6 +4,8 @@ dns_mijnhost_info='mijn.host Domains: mijn.host Site: mijn.host Docs: https://mijn.host/api/doc/ +Issues: https://github.com/acmesh-official/acme.sh/issues/6177 +Author: peterv99 Options: MIJNHOST_API_KEY API Key '