mirror of
https://github.com/acmesh-official/acme.sh
synced 2025-12-02 23:31:22 +08:00
Merge pull request #1 from PKlapp/dns_hetznercloud_improvements
DNS Hetzner Cloud improvements
This commit is contained in:
@@ -8,11 +8,13 @@ Options:
|
|||||||
Optional:
|
Optional:
|
||||||
HETZNER_TTL Custom TTL for new TXT rrsets (default 120)
|
HETZNER_TTL Custom TTL for new TXT rrsets (default 120)
|
||||||
HETZNER_API Override API endpoint (default https://api.hetzner.cloud/v1)
|
HETZNER_API Override API endpoint (default https://api.hetzner.cloud/v1)
|
||||||
|
HETZNER_MAX_ATTEMPTS Number of 1s polls to wait for async actions (default 120)
|
||||||
Issues: github.com/acmesh-official/acme.sh/issues
|
Issues: github.com/acmesh-official/acme.sh/issues
|
||||||
'
|
'
|
||||||
|
|
||||||
HETZNERCLOUD_API_DEFAULT="https://api.hetzner.cloud/v1"
|
HETZNERCLOUD_API_DEFAULT="https://api.hetzner.cloud/v1"
|
||||||
HETZNERCLOUD_TTL_DEFAULT=120
|
HETZNERCLOUD_TTL_DEFAULT=120
|
||||||
|
HETZNER_MAX_ATTEMPTS_DEFAULT=120
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
@@ -57,6 +59,9 @@ dns_hetznercloud_add() {
|
|||||||
|
|
||||||
case "${_hetznercloud_last_http_code}" in
|
case "${_hetznercloud_last_http_code}" in
|
||||||
200 | 201 | 202 | 204)
|
200 | 201 | 202 | 204)
|
||||||
|
if ! _hetznercloud_handle_action_response "TXT record add"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
_info "Hetzner Cloud TXT record added."
|
_info "Hetzner Cloud TXT record added."
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
@@ -116,6 +121,9 @@ dns_hetznercloud_rm() {
|
|||||||
fi
|
fi
|
||||||
case "${_hetznercloud_last_http_code}" in
|
case "${_hetznercloud_last_http_code}" in
|
||||||
200 | 201 | 202 | 204)
|
200 | 201 | 202 | 204)
|
||||||
|
if ! _hetznercloud_handle_action_response "TXT record remove"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
_info "Hetzner Cloud TXT record removed."
|
_info "Hetzner Cloud TXT record removed."
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
@@ -171,6 +179,17 @@ _hetznercloud_init() {
|
|||||||
fi
|
fi
|
||||||
_saveaccountconf_mutable HETZNER_TTL "${HETZNER_TTL}"
|
_saveaccountconf_mutable HETZNER_TTL "${HETZNER_TTL}"
|
||||||
|
|
||||||
|
HETZNER_MAX_ATTEMPTS="${HETZNER_MAX_ATTEMPTS:-$(_readaccountconf_mutable HETZNER_MAX_ATTEMPTS)}"
|
||||||
|
if [ -z "${HETZNER_MAX_ATTEMPTS}" ]; then
|
||||||
|
HETZNER_MAX_ATTEMPTS="${HETZNER_MAX_ATTEMPTS_DEFAULT}"
|
||||||
|
fi
|
||||||
|
attempts_check=$(printf "%s" "${HETZNER_MAX_ATTEMPTS}" | tr -d '0-9')
|
||||||
|
if [ -n "${attempts_check}" ]; then
|
||||||
|
_err "HETZNER_MAX_ATTEMPTS must be an integer value."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_saveaccountconf_mutable HETZNER_MAX_ATTEMPTS "${HETZNER_MAX_ATTEMPTS}"
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,9 +309,15 @@ _hetznercloud_parse_zone_fields() {
|
|||||||
if [ -z "${zone_id}" ] || [ -z "${zone_name}" ]; then
|
if [ -z "${zone_id}" ] || [ -z "${zone_name}" ]; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
zone_name_trimmed=$(printf "%s" "${zone_name}" | sed 's/\.$//')
|
||||||
|
if zone_name_ascii=$(_idn "${zone_name_trimmed}"); then
|
||||||
|
zone_name="${zone_name_ascii}"
|
||||||
|
else
|
||||||
|
zone_name="${zone_name_trimmed}"
|
||||||
|
fi
|
||||||
_hetznercloud_zone_id="${zone_id}"
|
_hetznercloud_zone_id="${zone_id}"
|
||||||
_hetznercloud_zone_name="${zone_name}"
|
_hetznercloud_zone_name="${zone_name}"
|
||||||
_hetznercloud_zone_name_lc=$(printf "%s" "${zone_name}" | sed 's/\.$//' | _lower_case)
|
_hetznercloud_zone_name_lc=$(printf "%s" "${zone_name}" | _lower_case)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,3 +454,140 @@ _hetznercloud_api() {
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_hetznercloud_handle_action_response() {
|
||||||
|
context="${1}"
|
||||||
|
if [ -z "${response}" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
normalized=$(printf "%s" "${response}" | _normalizeJson)
|
||||||
|
|
||||||
|
failed_message=""
|
||||||
|
if failed_message=$(_hetznercloud_extract_failed_action_message "${normalized}"); then
|
||||||
|
if [ -n "${failed_message}" ]; then
|
||||||
|
_err "Hetzner Cloud DNS ${context} failed: ${failed_message}"
|
||||||
|
else
|
||||||
|
_err "Hetzner Cloud DNS ${context} failed."
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
action_ids=""
|
||||||
|
if action_ids=$(_hetznercloud_extract_action_ids "${normalized}"); then
|
||||||
|
for action_id in ${action_ids}; do
|
||||||
|
if [ -z "${action_id}" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if ! _hetznercloud_wait_for_action "${action_id}" "${context}"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_hetznercloud_extract_failed_action_message() {
|
||||||
|
normalized="${1}"
|
||||||
|
failed_section=$(printf "%s" "${normalized}" | _egrep_o '"failed_actions":\[[^]]*\]')
|
||||||
|
if [ -z "${failed_section}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if _contains "${failed_section}" '"failed_actions":[]'; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
message=$(printf "%s" "${failed_section}" | _egrep_o '"message":"[^"]*"' | _head_n 1 | cut -d : -f 2 | tr -d '"')
|
||||||
|
if [ -n "${message}" ]; then
|
||||||
|
printf "%s" "${message}"
|
||||||
|
else
|
||||||
|
printf "%s" "${failed_section}"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_hetznercloud_extract_action_ids() {
|
||||||
|
normalized="${1}"
|
||||||
|
actions_section=$(printf "%s" "${normalized}" | _egrep_o '"actions":\[[^]]*\]')
|
||||||
|
if [ -z "${actions_section}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
action_ids=$(printf "%s" "${actions_section}" | _egrep_o '"id":[0-9]*' | cut -d : -f 2 | tr -d '"' | tr '\n' ' ')
|
||||||
|
action_ids=$(printf "%s" "${action_ids}" | tr -s ' ')
|
||||||
|
action_ids=$(printf "%s" "${action_ids}" | sed 's/^ //;s/ $//')
|
||||||
|
if [ -z "${action_ids}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
printf "%s" "${action_ids}"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_hetznercloud_wait_for_action() {
|
||||||
|
action_id="${1}"
|
||||||
|
context="${2}"
|
||||||
|
attempts="0"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if ! _hetznercloud_api GET "/actions/${action_id}"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "${_hetznercloud_last_http_code}" != "200" ]; then
|
||||||
|
_hetznercloud_log_http_error "Hetzner Cloud DNS action ${action_id} query failed" "${_hetznercloud_last_http_code}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
normalized=$(printf "%s" "${response}" | _normalizeJson)
|
||||||
|
action_status=$(_hetznercloud_action_status_from_normalized "${normalized}")
|
||||||
|
|
||||||
|
if [ -z "${action_status}" ]; then
|
||||||
|
_err "Hetzner Cloud DNS ${context} action ${action_id} returned no status."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${action_status}" = "success" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${action_status}" = "error" ]; then
|
||||||
|
if action_error=$(_hetznercloud_action_error_from_normalized "${normalized}"); then
|
||||||
|
_err "Hetzner Cloud DNS ${context} action ${action_id} failed: ${action_error}"
|
||||||
|
else
|
||||||
|
_err "Hetzner Cloud DNS ${context} action ${action_id} failed."
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
attempts=$(_math "${attempts}" + 1)
|
||||||
|
if [ "${attempts}" -ge "${HETZNER_MAX_ATTEMPTS}" ]; then
|
||||||
|
_err "Hetzner Cloud DNS ${context} action ${action_id} did not complete after ${HETZNER_MAX_ATTEMPTS} attempts."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_sleep 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_hetznercloud_action_status_from_normalized() {
|
||||||
|
normalized="${1}"
|
||||||
|
status=$(printf "%s" "${normalized}" | _egrep_o '"status":"[^"]*"' | _head_n 1 | cut -d : -f 2 | tr -d '"')
|
||||||
|
printf "%s" "${status}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_hetznercloud_action_error_from_normalized() {
|
||||||
|
normalized="${1}"
|
||||||
|
error_section=$(printf "%s" "${normalized}" | _egrep_o '"error":{[^}]*}')
|
||||||
|
if [ -z "${error_section}" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
message=$(printf "%s" "${error_section}" | _egrep_o '"message":"[^"]*"' | _head_n 1 | cut -d : -f 2 | tr -d '"')
|
||||||
|
if [ -n "${message}" ]; then
|
||||||
|
printf "%s" "${message}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
code=$(printf "%s" "${error_section}" | _egrep_o '"code":"[^"]*"' | _head_n 1 | cut -d : -f 2 | tr -d '"')
|
||||||
|
if [ -n "${code}" ]; then
|
||||||
|
printf "%s" "${code}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user