Compare commits

..
13 Commits
Author SHA1 Message Date
neil 37d064f7b5 Merge pull request #7337 from acmesh-official/dev
sync
2026-10-16 16:16:13 +08:00
neil 3688b094ad Merge pull request #7321 from acmesh-official/dev
sync
2026-10-12 18:00:45 +08:00
neil 807da64983 Merge pull request #7275 from acmesh-official/dev
allowed_signers: point the examples at 3.1.6
2026-09-20 13:14:12 +02:00
neil c37315c194 Merge pull request #7274 from acmesh-official/dev
Move the release signing baseline to 3.1.6 and catch lightweight tags…
2026-09-20 13:08:05 +02:00
neil d5fc938d80 Merge pull request #7271 from acmesh-official/dev
Dev
2026-09-19 19:22:24 +02:00
neil 2f8e8ed085 Merge pull request #7270 from acmesh-official/dev
sync
2026-09-19 15:49:12 +02:00
neil 181425b3c8 Merge pull request #7235 from acmesh-official/dev
fix
2026-09-04 16:23:49 +08:00
19980c86e8 sync (#7234)
* Merge pull request #7220 from moezx/dev

Add AK & SK based Huawei Cloud DNS API

* fix: dynv6 record parsing (#7197)

* unifios: extract JSON-split helper, document RSA/ECC name collision (#7200)

* Extract _uos_split_json helper, document RSA/ECC name-prefix collision

Per neilpang's non-blocking review notes on #7184: the _normalizeJson +
split-into-lines block was duplicated at both call sites, now shared via
_uos_split_json(). Also documents (without changing behavior, since it's
harmless today) that an RSA and ECC deploy of the same domain share the
generated name's prefix, each removing the other's entry on cleanup --
citing haproxy.sh/lighttpd.sh's existing .rsa/.ecdsa suffix pattern as
the fix if this ever needs addressing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Replace grep -F with a portable matcher, fix RSA/ECC name collision

grep -F isn't on Solaris, and dropping it naively breaks matching:
wildcard domains and dots collide as regex. _uos_grep_literal replaces
both call sites with a case-based literal match instead.

_uos_name now includes the key type, so RSA and ECC deploys of the
same domain no longer share a cleanup scope.

Per neilpang's review on #7200.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Fix echo's \n handling in _uos_grep_literal, drop unneeded Le_Keylength guard

echo does not behave consistently across different environments. dash
interprets literal \n in a line, splitting it.  printf '%s\n' does not and matches
_uos_split_json's existing pattern. printf behaves more consistently across
environments and is generally preferred over echo.

Le_Keylength guard was a no-op and didn't help under set -u either;
_isEccKey already handles empty. Kept the shellcheck warning suppressed
inline instead of assigning to a core Le_* var.

Per neilpang's review on #7200.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

* add trigger

* minor

---------

Co-authored-by: Mashiro <adadam@qq.com>
Co-authored-by: MBWhitestone <25477219+MBWhitestone@users.noreply.github.com>
Co-authored-by: Pablo <Pablo1@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 15:30:06 +08:00
neil 9656842a30 Merge pull request #7229 from acmesh-official/dev
sync
2026-09-01 21:09:15 +08:00
neil a7e6ceaab0 Merge pull request #7226 from acmesh-official/dev
sync
2026-08-30 22:14:29 +08:00
neil 261653ebf4 Merge pull request #7194 from acmesh-official/dev
sync
2026-08-13 17:01:02 +08:00
neil 2feb392bd0 Merge pull request #7133 from acmesh-official/dev
sync
2026-07-17 15:05:00 +08:00
neil 3661fd86b6 Merge pull request #7132 from acmesh-official/dev
sync
2026-07-17 10:01:37 +08:00
6 changed files with 10 additions and 410 deletions

No files matched your search

+4 -16
View File
@@ -666,15 +666,8 @@ _hex_dump() {
xxd -ps -c 20 -i | sed "s/ 0x/ /g" | tr -d ",\n" | tr -s " "
else
_debug3 "using _ascii_hex"
#line by line: the cut -c in _ascii_hex works per line, and a $(cat)
#capture would drop the trailing newlines (illumos without od in PATH)
while IFS= read -r _hd_line; do
_ascii_hex "$_hd_line"
printf " 0a"
done
if [ -n "$_hd_line" ]; then
_ascii_hex "$_hd_line"
fi
str=$(cat)
_ascii_hex "$str"
fi
}
@@ -914,12 +907,7 @@ _json_encode() {
_j_str="$(sed 's/"/\\"/g' | sed "s/\r/\\r/g")"
_debug3 "_json_encode"
_debug3 "_j_str" "$_j_str"
#printf, not echo: dash's echo interprets backslash escapes and would
#collapse the \\ sequences (e.g. Telegram MarkdownV2 escapes, issue 7212)
_j_hex="$(printf "%s\n" "$_j_str" | _hex_dump | _lower_case)"
#the hex line must end with a newline: Solaris sed drops an unterminated
#last line, which emptied the whole output
printf "%s\n" "$_j_hex" | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n"
echo "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n"
}
#from: http:\/\/ to http://
@@ -927,7 +915,7 @@ _json_decode() {
_j_str="$(sed 's#\\/#/#g')"
_debug3 "_json_decode"
_debug3 "_j_str" "$_j_str"
printf "%s\n" "$_j_str"
echo "$_j_str"
}
#extract the authorization URLs from an order response on stdin, as a
-207
View File
@@ -1,207 +0,0 @@
#!/usr/bin/env sh
# Here is a script to deploy cert to an HP printer's Embedded Web Server (EWS).
#
# Docs: https://github.com/acmesh-official/acme.sh/wiki/deployhooks#47-deploy-the-certificate-to-an-hp-printer-ews
#
# Tested on an HP Color LaserJet Pro MFP M479fdw, firmware
# CLRWTRXXXN002.2539E.00. It should work on any modern HP printer whose EWS
# exposes the "Install Certificate" flow at
# /Security/DeviceCertificates/NewCertWithPassword/Upload -- that endpoint
# takes a password-protected PKCS#12 bundle, which this hook builds from the
# issued certificate, its key and the CA chain.
#
# ```sh
# export HP_EWS_PASSWORD=mysecret
# export HP_EWS_INSECURE=1 # needed until the printer serves a trusted cert
# acme.sh --deploy -d printer.example.com --deploy-hook hp_ews
# ```
#
# Environment variables:
# HP_EWS_PASSWORD (required) EWS administrator password.
# HP_EWS_HOST (optional) IP or hostname of the printer.
# Default: the certificate's domain.
# HP_EWS_USERNAME (optional) EWS administrator user. Default: admin
# HP_EWS_PFX_PASSWORD (optional) Password for the generated PKCS#12
# bundle. A random one is used per run if
# unset; set it only if you want the
# bundle to be reproducible.
# HP_EWS_INSECURE (optional) Set to a non-empty value to skip TLS
# verification when talking to the
# printer. Needed on the first deploy,
# because the printer still serves its
# self-signed certificate at that point.
# acme.sh's global HTTPS_INSECURE is
# honoured as well.
#
# The hook authenticates with HTTP Basic auth. Printers whose EWS only offers
# Digest auth are not supported.
#
# Requires openssl, to build the PKCS#12 bundle.
#
# returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain pfx
hp_ews_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_cpfx="$6"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_debug _cpfx "$_cpfx"
_getdeployconf HP_EWS_HOST
_getdeployconf HP_EWS_USERNAME
_getdeployconf HP_EWS_PASSWORD
_getdeployconf HP_EWS_PFX_PASSWORD
_getdeployconf HP_EWS_INSECURE
HP_EWS_HOST="${HP_EWS_HOST:-$_cdomain}"
HP_EWS_USERNAME="${HP_EWS_USERNAME:-admin}"
_debug HP_EWS_HOST "$HP_EWS_HOST"
_debug HP_EWS_USERNAME "$HP_EWS_USERNAME"
_secure_debug HP_EWS_PASSWORD "$HP_EWS_PASSWORD"
_secure_debug HP_EWS_PFX_PASSWORD "$HP_EWS_PFX_PASSWORD"
_debug HP_EWS_INSECURE "$HP_EWS_INSECURE"
if [ -z "$HP_EWS_PASSWORD" ]; then
_err "HP_EWS_PASSWORD is required. Please set the password of the printer's EWS administrator account."
return 1
fi
_savedeployconf HP_EWS_HOST "$HP_EWS_HOST"
_savedeployconf HP_EWS_USERNAME "$HP_EWS_USERNAME"
_savedeployconf HP_EWS_PASSWORD "$HP_EWS_PASSWORD" "base64"
_savedeployconf HP_EWS_PFX_PASSWORD "$HP_EWS_PFX_PASSWORD" "base64"
_savedeployconf HP_EWS_INSECURE "$HP_EWS_INSECURE"
if ! _exists "${ACME_OPENSSL_BIN:-openssl}"; then
_err "openssl is required by this deploy hook, but was not found."
return 1
fi
# The bundle password only has to survive the single upload below, so a
# fresh random one is used unless the operator asked for a fixed value.
_HP_EWS_PFXPW="$HP_EWS_PFX_PASSWORD"
if [ -z "$_HP_EWS_PFXPW" ]; then
_HP_EWS_PFXPW="$(${ACME_OPENSSL_BIN:-openssl} rand -hex 24)"
if [ -z "$_HP_EWS_PFXPW" ]; then
_err "Could not generate a random password for the PKCS#12 bundle."
return 1
fi
fi
export _HP_EWS_PFXPW
# $6 is only materialised when Le_PFXPassword is set for this domain, and
# it would be built without the CA chain, so build our own bundle instead.
_hp_ews_pfx="$(_mktemp)"
_hp_ews_body="$(_mktemp)"
if [ -z "$_hp_ews_pfx" ] || [ -z "$_hp_ews_body" ]; then
_err "Could not create the temporary files needed for the upload."
_hp_ews_cleanup
return 1
fi
_hp_ews_ret=0
if ! _hp_ews_make_pfx; then
_hp_ews_ret=1
elif ! _hp_ews_upload; then
_hp_ews_ret=1
fi
_hp_ews_cleanup
return "$_hp_ews_ret"
}
#################### Private functions below ##################################
_hp_ews_cleanup() {
[ -n "$_hp_ews_pfx" ] && rm -f "$_hp_ews_pfx"
[ -n "$_hp_ews_body" ] && rm -f "$_hp_ews_body"
unset _HP_EWS_PFXPW
# Do not leak the request header into any hook that runs after this one.
export _H1=""
return 0
}
# Bundle key, certificate and chain into $_hp_ews_pfx, protected by
# $_HP_EWS_PFXPW. The password goes through the environment rather than the
# command line so that it does not show up in ps output.
_hp_ews_make_pfx() {
_info "Building the PKCS#12 bundle"
if ! ${ACME_OPENSSL_BIN:-openssl} pkcs12 -export \
-out "$_hp_ews_pfx" \
-inkey "$_ckey" \
-in "$_ccert" \
-certfile "$_cca" \
-passout env:_HP_EWS_PFXPW; then
_err "Failed to build the PKCS#12 bundle."
return 1
fi
if [ ! -s "$_hp_ews_pfx" ]; then
_err "The PKCS#12 bundle is empty."
return 1
fi
return 0
}
# Build the multipart body in $_hp_ews_body and POST it to the printer.
_hp_ews_upload() {
_hp_ews_url="https://${HP_EWS_HOST}/Security/DeviceCertificates/NewCertWithPassword/Upload"
_hp_ews_boundary="----------------------------acmesh$(${ACME_OPENSSL_BIN:-openssl} rand -hex 16)"
{
printf -- "--%s\r\n" "$_hp_ews_boundary"
printf "Content-Disposition: form-data; name=\"certificate\"; filename=\"%s.pfx\"\r\n" "$_cdomain"
printf "Content-Type: application/x-pkcs12\r\n\r\n"
cat "$_hp_ews_pfx"
printf "\r\n"
printf -- "--%s\r\n" "$_hp_ews_boundary"
printf "Content-Disposition: form-data; name=\"password\"\r\n\r\n%s\r\n" "$_HP_EWS_PFXPW"
printf -- "--%s--\r\n" "$_hp_ews_boundary"
} >"$_hp_ews_body"
_H1="Authorization: Basic $(printf "%s:%s" "$HP_EWS_USERNAME" "$HP_EWS_PASSWORD" | _base64)"
export _H1
if [ "$HP_EWS_INSECURE" ]; then
export HTTPS_INSECURE=1
fi
_info "Uploading the certificate to $_hp_ews_url"
if ! _post_file "$_hp_ews_body" "$_hp_ews_url" "" "POST" "multipart/form-data; boundary=$_hp_ews_boundary" >/dev/null; then
if [ -z "$HTTPS_INSECURE" ]; then
_err "If the printer still serves its self-signed certificate, set HP_EWS_INSECURE=1 and try again."
fi
return 1
fi
# The EWS answers 201 Created on a successful install.
_hp_ews_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
_debug _hp_ews_code "$_hp_ews_code"
if [ "$_hp_ews_code" != "201" ] && [ "$_hp_ews_code" != "200" ]; then
_err "The printer rejected the certificate (HTTP $_hp_ews_code)."
if [ "$_hp_ews_code" = "401" ] || [ "$_hp_ews_code" = "403" ]; then
_err "Check HP_EWS_USERNAME and HP_EWS_PASSWORD. Only HTTP Basic authentication is"
_err "supported; printers that only offer Digest cannot be used with this hook."
fi
return 1
fi
_info "Certificate installed (HTTP $_hp_ews_code). The printer restarts its web server shortly."
return 0
}
-21
View File
@@ -59,13 +59,6 @@ dns_gandi_livedns_rm() {
fulldomain=$1
txtvalue=$2
GANDI_LIVEDNS_KEY="${GANDI_LIVEDNS_KEY:-$(_readaccountconf_mutable GANDI_LIVEDNS_KEY)}"
GANDI_LIVEDNS_TOKEN="${GANDI_LIVEDNS_TOKEN:-$(_readaccountconf_mutable GANDI_LIVEDNS_TOKEN)}"
if [ -z "$GANDI_LIVEDNS_KEY" ] && [ -z "$GANDI_LIVEDNS_TOKEN" ]; then
_err "No Token or API key (deprecated) specified for Gandi LiveDNS."
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
@@ -87,20 +80,6 @@ dns_gandi_livedns_rm() {
_new_rrset_values=$(echo "$_new_rrset_values" | sed "s/\[ *,/\[/g")
_debug "New rrset_values" "$_new_rrset_values"
# Last value removed: delete the record instead of leaving an empty TXT rrset.
if [ "$(echo "$_new_rrset_values" | tr -d ' ')" = "[]" ]; then
if ! _gandi_livedns_rest DELETE "domains/$_domain/records/$_sub_domain/TXT"; then
return 1
fi
_gandi_livedns_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$_gandi_livedns_code" != "204" ]; then
_err "Error deleting record: $response"
return 1
fi
_info "Removing record $(__green "success")"
return 0
fi
_gandi_livedns_rest PUT \
"domains/$_domain/records/$_sub_domain/TXT" \
"{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" &&
+3 -6
View File
@@ -185,14 +185,13 @@ _get_root_by_getHosts() {
}
_namecheap_set_publicip() {
NAMECHEAP_SOURCEIP="${NAMECHEAP_SOURCEIP:-$(_readaccountconf_mutable NAMECHEAP_SOURCEIP)}"
if [ -z "$NAMECHEAP_SOURCEIP" ]; then
_err "No Source IP specified for Namecheap API."
_err "Use your public ip address or an url to retrieve it (e.g. https://ifconfig.co/ip) and export it as NAMECHEAP_SOURCEIP"
return 1
else
_saveaccountconf_mutable NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP"
_saveaccountconf NAMECHEAP_SOURCEIP "$NAMECHEAP_SOURCEIP"
_debug sourceip "$NAMECHEAP_SOURCEIP"
ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
@@ -253,8 +252,6 @@ _namecheap_parse_host() {
}
_namecheap_check_config() {
NAMECHEAP_API_KEY="${NAMECHEAP_API_KEY:-$(_readaccountconf_mutable NAMECHEAP_API_KEY)}"
NAMECHEAP_USERNAME="${NAMECHEAP_USERNAME:-$(_readaccountconf_mutable NAMECHEAP_USERNAME)}"
if [ -z "$NAMECHEAP_API_KEY" ]; then
_err "No API key specified for Namecheap API."
@@ -268,8 +265,8 @@ _namecheap_check_config() {
return 1
fi
_saveaccountconf_mutable NAMECHEAP_API_KEY "$NAMECHEAP_API_KEY"
_saveaccountconf_mutable NAMECHEAP_USERNAME "$NAMECHEAP_USERNAME"
_saveaccountconf NAMECHEAP_API_KEY "$NAMECHEAP_API_KEY"
_saveaccountconf NAMECHEAP_USERNAME "$NAMECHEAP_USERNAME"
return 0
}
-154
View File
@@ -1,154 +0,0 @@
#!/usr/bin/env sh
# shellcheck disable=SC2034
dns_primedns_info='PrimeDNS
Site: primedns.net
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_primedns
Options:
PRIMEDNS_API_KEY API Key. Scope acme:name:_acme-challenge.<hostname> for each name you issue (or dns:write)
OptionsAlt:
PRIMEDNS_API_URL API base URL. Optional, default https://api.primedns.net/v1
Issues: github.com/acmesh-official/acme.sh/issues/7330
Author: PrimeDNS <acme@primedns.net>
'
PRIMEDNS_Api_Default="https://api.primedns.net/v1"
######## Public functions #####################
#Usage: dns_primedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_primedns_add() {
fulldomain=$(_idn "$1")
txtvalue=$2
PRIMEDNS_API_KEY="${PRIMEDNS_API_KEY:-$(_readaccountconf_mutable PRIMEDNS_API_KEY)}"
if [ -z "$PRIMEDNS_API_KEY" ]; then
PRIMEDNS_API_KEY=""
_err "You didn't specify a PrimeDNS API key (PRIMEDNS_API_KEY) yet."
_err "Create one in the PrimeDNS panel (Account -> API Keys) with the scope acme:name:_acme-challenge.<hostname> for each name you issue."
return 1
fi
PRIMEDNS_API_URL="${PRIMEDNS_API_URL:-$(_readaccountconf_mutable PRIMEDNS_API_URL)}"
#save the credentials to the account conf file.
_saveaccountconf_mutable PRIMEDNS_API_KEY "$PRIMEDNS_API_KEY"
if [ "$PRIMEDNS_API_URL" ]; then
_saveaccountconf_mutable PRIMEDNS_API_URL "$PRIMEDNS_API_URL"
fi
_info "Using PrimeDNS"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
if ! _primedns_rest POST "$fulldomain" "$txtvalue"; then
return 1
fi
_info "Added, OK"
return 0
}
#Usage: dns_primedns_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_primedns_rm() {
fulldomain=$(_idn "$1")
txtvalue=$2
PRIMEDNS_API_KEY="${PRIMEDNS_API_KEY:-$(_readaccountconf_mutable PRIMEDNS_API_KEY)}"
if [ -z "$PRIMEDNS_API_KEY" ]; then
PRIMEDNS_API_KEY=""
_err "You didn't specify a PrimeDNS API key (PRIMEDNS_API_KEY) yet."
return 1
fi
PRIMEDNS_API_URL="${PRIMEDNS_API_URL:-$(_readaccountconf_mutable PRIMEDNS_API_URL)}"
_info "Using PrimeDNS"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
if ! _primedns_rest DELETE "$fulldomain" "$txtvalue"; then
return 1
fi
_info "Removed, OK"
return 0
}
#################### Private functions below ##################################
#Usage: _primedns_rest POST|DELETE _acme-challenge.www.domain.com txtvalue
#The API creates/removes the TXT record with exactly the name given, so the full
#name acme.sh passes (_acme-challenge.<domain>, or the name of a DNS alias) is
#sent as it is.
_primedns_rest() {
_method=$1
_name=$2
_value=$3
_url="${PRIMEDNS_API_URL:-$PRIMEDNS_Api_Default}/dns/acme-challenge"
#The body is built by hand, so refuse anything that would need JSON escaping.
case "$_name$_value" in
*\"* | *\\*)
_err "Refusing to send '$_name': it contains a quote or a backslash."
return 1
;;
esac
if [ -z "$_name" ] || _is_idn "$_name"; then
_err "Cannot send '$_name': it is not a plain ASCII host name. For an IDN name install idn (acme.sh converts it to punycode) or pass the punycode name."
return 1
fi
_body="{\"name\":\"$_name\",\"value\":\"$_value\"}"
_debug _body "$_body"
_primedns_retried=""
while true; do
#acme.sh sends _H1.._H5 with every later request of this process, so the API key
#header must not stay set once this call is done (it would reach other hosts).
_primedns_old_h1="$_H1"
export _H1="X-API-Key: $PRIMEDNS_API_KEY"
: >"$HTTP_HEADER"
response="$(_post "$_body" "$_url" "" "$_method" "application/json")"
_ret=$?
export _H1="$_primedns_old_h1"
_status=$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d '\r\n')
if [ "$_ret" != "0" ]; then
_err "Error calling the PrimeDNS API ($_method /dns/acme-challenge)."
return 1
fi
response="$(echo "$response" | _normalizeJson)"
_debug response "$response"
_debug _status "$_status"
#Rate limited or temporary server error: wait and try once more.
if [ -z "$_primedns_retried" ] && { [ "$_status" = "429" ] || [ "$_status" = "502" ] || [ "$_status" = "503" ] || [ "$_status" = "504" ]; }; then
_wait="$(_retryafter_seconds <"$HTTP_HEADER")"
case "$_wait" in
'' | *[!0-9]*) _wait=5 ;;
esac
[ "$_wait" -gt 60 ] && _wait=60
_info "PrimeDNS API answered HTTP $_status, retrying in $_wait seconds."
_sleep "$_wait"
_primedns_retried=1
continue
fi
break
done
if _contains "$response" '"success":true'; then
return 0
fi
if [ "$_status" = "401" ]; then
_err "The PrimeDNS API refused the key (HTTP 401): it is wrong, revoked or expired. Check PRIMEDNS_API_KEY."
elif _contains "$response" 'IP_NOT_ALLOWED'; then
_err "This PrimeDNS API key may not be used from this address (allowed_ips). Add the address to the key or run acme.sh from an allowed host."
elif _contains "$response" 'NAME_NOT_ALLOWED'; then
_err "This PrimeDNS API key may not write $_name: add the scope acme:name:$_name to the key, or the zone to its allowed zones."
elif _contains "$response" 'INSUFFICIENT_SCOPE'; then
_err "This PrimeDNS API key needs the scope acme:name:$_name (or dns:write)."
elif _contains "$response" 'DOMAIN_NOT_FOUND'; then
_err "$_name is not in a zone of the PrimeDNS account that owns this API key."
elif [ "$_status" = "429" ]; then
_err "PrimeDNS API rate limit still hit after a retry. Try again in a minute."
else
_err "PrimeDNS API error (HTTP $_status): $response"
fi
return 1
}
+3 -6
View File
@@ -106,16 +106,13 @@ dns_yc_add() {
_debug _domain "$_domain"
_debug "Getting txt records"
if ! _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$fulldomain"; then
if ! _yc_rest GET "zones/${_domain_id}:getRecordSet?type=TXT&name=$_sub_domain"; then
_err "Error: $response"
return 1
fi
_info "Adding record"
# The absolute name (trailing dot) also covers a record at the zone apex,
# e.g. with --domain-alias, which has no relative form: an empty name is
# rejected by the API.
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"merges\": [ { \"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"merges\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
if _contains "$response" "\"done\": *true"; then
_info "Added, OK"
return 0
@@ -170,7 +167,7 @@ dns_yc_rm() {
# upsertRecordSets.deletions removes only the given value from the rrset,
# leaving any other values at the same name (e.g. base + wildcard domain)
# intact -- no need to read the current data set and recompute it.
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"deletions\": [ { \"name\":\"$fulldomain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
if _yc_rest POST "zones/$_domain_id:upsertRecordSets" "{\"deletions\": [ { \"name\":\"$_sub_domain\",\"type\":\"TXT\",\"ttl\":\"120\",\"data\":[\"$txtvalue\"]}]}"; then
if _contains "$response" "\"done\": *true"; then
_info "Delete, OK"
return 0
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.