mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2025-05-10 12:02:51 +00:00
Create a draft version of pleskxml API for DNS01
This DNS01 method allows acme.sh to set DNS TXT records using the Plesk XML API described at: https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709 and more specifically: https://docs.plesk.com/en-US/12.5/api-rpc/reference.28784 This may be needed if the DNS provider doesn't make the standard Plesk API available to a user - in which case, Plesk can't be configured using usual means or RFC1236. But the XML API is often still left accessible, and is well documented, so it can be used instead, for acme.sh purposes. Note that I have tested the API calls work as expected, and is sanely structured, but I'm not an experienced shell coder. So I expect any number of stylistic and other amendments/corrections. It also includes a ton of debug code which won't hurt to leave in while checking. Please help me to knock this module into shape for merging, and be gentle with me on it - I'm sure it needs a lot of attention! Thanks :)
This commit is contained in:
parent
c883ec40d7
commit
aa75a6d028
992
dnsapi/dns_pleskxml.sh
Normal file
992
dnsapi/dns_pleskxml.sh
Normal file
@ -0,0 +1,992 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Name: dns_pleskxml.sh
|
||||
# Created by Stilez.
|
||||
# Uses Plesk XML API to add/remove text records
|
||||
# Repository: https://github.com/Neilpang/acme.sh
|
||||
|
||||
# v0.1 alpha - 2018-08-13
|
||||
|
||||
# This DNS01 method allows acme.sh to set DNS TXT records
|
||||
# using the Plesk XML API described at:
|
||||
# https://docs.plesk.com/en-US/12.5/api-rpc/about-xml-api.28709
|
||||
# and more specifically: https://docs.plesk.com/en-US/12.5/api-rpc/reference.28784
|
||||
|
||||
|
||||
# This may be needed if the DNS provider doesn't make the standard Plesk API available to a user.
|
||||
# As a result, Plesk can't be configured using usual means or RFC1236. But the XML API is often
|
||||
# still left accessible, and is well documented, so it can be used instead, for acme.sh purposes.
|
||||
|
||||
|
||||
# API NOTES:
|
||||
|
||||
# 1) The API uses a user/password combination. It should therefore require cURL over HTTPS
|
||||
# with a MAXIMALLY SECURE TLS CIPHER AND GOOD CERT + REVOCATION CHECKS ON THE API URI,
|
||||
# in (almost) all cases.
|
||||
|
||||
# Acceptable/valid ciphers and certificate checks can be specified via optional cURL variables (see below).
|
||||
# Note that edge cases may exist where SSL is not yet set up
|
||||
# (e.g. testing Plesk on ones own network), so although highly recommended, this can be OVERRIDDEN.
|
||||
|
||||
# 2) --anyauth is used with cURL, to ensure the highest available level of encryption.
|
||||
|
||||
# 3) The API references domains by a domain ID, when manipulating records. So the code must
|
||||
# initially convert domain names (string) to Plesk domain IDs (numeric).
|
||||
|
||||
|
||||
# REQUIRED VARIABLES:
|
||||
|
||||
# You need to provide the Plesk URI and login (username and password) as follows:
|
||||
|
||||
# export pleskxml_uri="https://www.plesk_uri.org:8443/enterprise/control/agent.php"
|
||||
# (or something similar)
|
||||
# export pleskxml_user="johndoe"
|
||||
# export pleskxml_pass="kj8we8dej38e8d#q0q3!!!qa"
|
||||
|
||||
|
||||
# OPTIONAL VARIABLES:
|
||||
|
||||
# To use an insecure Plesk URI, set the following:
|
||||
# export pleskxml_allow_insecure_uri=yes
|
||||
|
||||
# Extra cURL args (for certificate handling, timeout etc):
|
||||
# export pleskxml_optional_curl_args=LIST_OF_ARGS
|
||||
# (eg =-v or ="-H 'HEADER STRINGS'")
|
||||
|
||||
# Debug level (0/absent=none, 1=all, 2=major msgs only, 3=minimum msgs/most severe only)
|
||||
# If debug level is nonzero, all DBG messages equal to or more severe than this, are displayed.
|
||||
# By design if DBG level is 9 for a message, it is ALWAYS shown, this is used for _info and _err
|
||||
# export pleskxml_debug_min_level=2
|
||||
|
||||
|
||||
############ Before anything else, define dedug functions to be sure they are detected even if while testing #####################
|
||||
|
||||
_DBG_EARLY_CHECK_MODE() {
|
||||
|
||||
if printf '%s' "${pleskxml_debug_min_level:-0}" | grep -qE '^[0-3]$' ; then
|
||||
_pleskxml_DBG_LEVEL="${pleskxml_debug_min_level:-0}"
|
||||
_pleskxml_DBG_COUNT=0
|
||||
else
|
||||
_err "Invalid debug level, exiting. \$pleskxml_debug_min_level = '${pleskxml_debug_min_level}' "
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "plesk XML running in debug mode. Debug level = '${_pleskxml_DBG_LEVEL}' "
|
||||
# This won't display if DBG level was set to zero.
|
||||
}
|
||||
|
||||
# arg1 = severity level (1=least serious, 3=most serious)
|
||||
# By design if DBG level is 9 for a MESSAGE, the message is ALWAYS shown, this is used for _info and _err
|
||||
# arg2 = message
|
||||
_DBG() {
|
||||
if [ "$1" -eq 9 ] || ( [ "$_pleskxml_DBG_LEVEL" -gt 0 ] && [ "$1" -ge "$_pleskxml_DBG_LEVEL" ] ); then
|
||||
case $1 in
|
||||
1) _pleskxml_severity='INFO'
|
||||
;;
|
||||
2) _pleskxml_severity='WARN'
|
||||
;;
|
||||
3) _pleskxml_severity='ERR'
|
||||
;;
|
||||
9) _pleskxml_severity='_ACME.SH'
|
||||
;;
|
||||
esac
|
||||
_pleskxml_DBG_COUNT=$(( _pleskxml_DBG_COUNT + 1 ))
|
||||
printf '%04d DEBUG [%s]:\n%s\n\n' "$_pleskxml_DBG_COUNT" "$_pleskxml_severity" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# arg1 = severity level (1=least serious, 3=most serious)
|
||||
# arg2 = message (vardump will be appended)
|
||||
_DBG_VARDUMP() {
|
||||
_DBG "$1" "$( printf '%s: 1st lines of current defined variables are now:\n%s\n\n' "${2:-NO_FURTHER_MSG}" "$( set | grep '_pleskxml' | sort )" )"
|
||||
}
|
||||
|
||||
|
||||
_DBG_ERR_TRAP() {
|
||||
echo "Error on line $1"
|
||||
}
|
||||
|
||||
|
||||
|
||||
############ Start of module itself ##############################
|
||||
|
||||
|
||||
# Trap errors and perform early check for debug mode.
|
||||
# Traps currently ignored
|
||||
|
||||
# set -e
|
||||
# trap '_DBG_ERR_TRAP ${LINENO:-NO_LINE}' .....
|
||||
|
||||
_DBG_EARLY_CHECK_MODE
|
||||
|
||||
|
||||
############ Set up static/private variables #####################
|
||||
|
||||
|
||||
_pleskxml_curlpath=/usr/local/bin/curl
|
||||
|
||||
_pleskxml_newline='
|
||||
'
|
||||
|
||||
|
||||
# Plesk XML templates.
|
||||
# Note ALL TEMPLATES MUST HAVE EXACTLY 3 %s PLACEHOLDERS
|
||||
# (otherwise printf repeats the string causing the API call to fail)
|
||||
|
||||
_pleskxml_tplt_get_domain_id="<packet><webspace><get><filter><name>%s</name></filter><dataset></dataset></get></webspace></packet>"
|
||||
# Convert domain name to a Plesk internal domain ID
|
||||
# Args:
|
||||
# the domain name to query
|
||||
|
||||
_pleskxml_tplt_add_txt_record="<packet><dns><add_rec><site-id>%s</site-id><type>TXT</type><host>%s</host><value>%s</value></add_rec></dns></packet>"
|
||||
# Adds a TXT record to a domain
|
||||
# Args:
|
||||
# the Plesk internal domain ID for the domain
|
||||
# the "host" entry within the domain, to add this to (eg '_acme_challenge')
|
||||
# the TXT record value
|
||||
|
||||
_pleskxml_tplt_rmv_dns_record="<packet><dns><del_rec><filter><id>%s</id></filter></del_rec></dns></packet>"
|
||||
# Adds a TXT record to a domain
|
||||
# Args:
|
||||
# the Plesk internal ID for the dns record to delete
|
||||
|
||||
_pleskxml_tplt_get_dns_records="<packet><dns><get_rec><filter><site-id>%s</site-id></filter></get_rec></dns></packet>"
|
||||
# Gets all DNS records for a Plesk domain ID
|
||||
# Args:
|
||||
# the domain id to query
|
||||
|
||||
|
||||
############ Define public functions #####################
|
||||
|
||||
# Usage: dns_pleskxml_add _acme-challenge.domain.org "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
|
||||
dns_pleskxml_add() {
|
||||
|
||||
|
||||
_DBG 2 "Entered dns_pleskxml_add($*)..."
|
||||
|
||||
_pleskxml_FQDN=$1
|
||||
_pleskxml_TXT_string=$2
|
||||
|
||||
# validate variables set by user.
|
||||
# If valid, then matching internal variables will be set with the appropriate checked values
|
||||
# Otherwise exit with an error
|
||||
|
||||
_info "Plesk XML: Trying to add a DNS TXT record for acme validation."
|
||||
_info "Plesk XML: Domain = $_pleskxml_FQDN. DNS TXT string = '$_pleskxml_TXT_string'."
|
||||
_info "Plesk XML: Checking login and other variables supplied by user"
|
||||
|
||||
_pleskxml_get_variables
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
_DBG_VARDUMP 2 'Called _pleskxml_get_variables()'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ]; then
|
||||
_err "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$_pleskxml_allow_insecure" ]; then
|
||||
_info 'Plesk XML: You have allowed insecure http connections to Plesk. Passwords and logins may be sent in plain text.\nPlease do not use this setting unless very sure of security!'
|
||||
fi
|
||||
|
||||
# Try to convert the domain name to a plesk domain ID. This also lets us know if the URI and authentication are OK.
|
||||
|
||||
_info "Plesk XML: Variables loaded."
|
||||
_info "Trying to connect to Plesk ($_pleskxml_uri), and request Plesk's internal reference ID for domain '${_pleskxml_domain}'"
|
||||
|
||||
_DBG 2 "Calling API to get domain ID for $_pleskxml_domain"
|
||||
|
||||
_pleskxml_domain_id="$( _pleskxml_get_domain_ID "$_pleskxml_domain" )"
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
_DBG_VARDUMP 2 'Call has returned'
|
||||
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_err "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK, valid response containing a valid domain ID must have been found
|
||||
# If not we should have got an error.
|
||||
|
||||
# Try to add the TXT record
|
||||
|
||||
_DBG 2 "Calling API to add TXT record to domain ID #$_pleskxml_domain_id ('$_pleskxml_domain')"
|
||||
|
||||
_info "Plesk XML: Trying to add TXT record to domain ID $_pleskxml_domain_id ('$_pleskxml_domain'), host '$_pleskxml_host'. The TXT string is: '$_pleskxml_TXT_string'."
|
||||
|
||||
_pleskxml_add_dns_txt_record "$_pleskxml_domain_id" "$_pleskxml_host" "$_pleskxml_TXT_string"
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
_DBG_VARDUMP 2 'Call has returned'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_err "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info 'An ACME Challenge TXT record for '"$_pleskxml_domain"' was added to Plesk. Plesk returned a successful response.\nThe TXT field was: '"'$_pleskxml_TXT_string'"
|
||||
_info "(TO CHECK?: Note that all subdomains under this domain uses the same TXT record.) <-- MAY NOT BE NEEDED"
|
||||
|
||||
_DBG 2 "SUCCESSFULLY exiting dns_pleskxml_add()..."
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Usage: dns_pleskxml_rm _acme-challenge.domain.org "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
# Remove a TXT record after validation
|
||||
|
||||
dns_pleskxml_rm() {
|
||||
|
||||
_DBG 2 "Entered dns_pleskxml_rm($*)..."
|
||||
|
||||
_pleskxml_FQDN=$1
|
||||
_pleskxml_TXT_string=$2
|
||||
|
||||
# validate variables set by user.
|
||||
# If valid, then matching internal variables will be set with the appropriate checked values
|
||||
# Otherwise exit with an error
|
||||
|
||||
_info "Plesk XML: Trying to remove a recently-added DNS TXT record for following acme validation."
|
||||
_info "Plesk XML: Domain = $_pleskxml_FQDN. DNS TXT string = '$_pleskxml_TXT_string'."
|
||||
_info "Plesk XML: Checking login and other variables supplied by user"
|
||||
|
||||
_pleskxml_get_variables
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
_DBG_VARDUMP 2 'Called _pleskxml_get_variables()'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ]; then
|
||||
_err "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$_pleskxml_allow_insecure" ]; then
|
||||
_info 'Plesk XML: You have allowed insecure http connections to Plesk. Passwords and logins may be sent in plain text.\nPlease do not use this setting unless very sure of security!'
|
||||
fi
|
||||
|
||||
# Try to convert the domain name to a plesk domain ID. This also lets us know if the URI and authentication are OK.
|
||||
|
||||
_info "Plesk XML: Variables loaded."
|
||||
_info "Trying to connect to Plesk ($_pleskxml_uri), and request Plesk's internal reference ID for domain '${_pleskxml_domain}'"
|
||||
|
||||
_DBG 2 "Calling API to get domain ID for $_pleskxml_domain"
|
||||
|
||||
_pleskxml_domain_id="$( _pleskxml_get_domain_ID "$_pleskxml_domain" )"
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
_DBG_VARDUMP 2 'Call has returned'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_err "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK, valid response containing a valid domain ID must have been found
|
||||
# If not we should have got an error.
|
||||
|
||||
# Try to remove the TXT record. First step - get all TXT records
|
||||
|
||||
_info "Plesk XML: Trying to remove TXT record from domain ID $_pleskxml_domain_id ('$_pleskxml_domain'), host '$_pleskxml_host'."
|
||||
|
||||
_DBG 2 "Calling API to remove TXT record from domain ID #$_pleskxml_domain_id ('$_pleskxml_domain')"
|
||||
|
||||
_pleskxml_rmv_txt_record "$_pleskxml_domain_id" "$_pleskxml_host" "$_pleskxml_TXT_string"
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
_DBG_VARDUMP 2 'Call has returned'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_err "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info 'A TXT record for '"$_pleskxml_domain"' was removed from Plesk. Plesk returned a successful response.\nThe TXT field was: '"'$_pleskxml_TXT_string'"
|
||||
|
||||
_DBG 2 "SUCCESSFULLY exiting dns_pleskxml_rm()..."
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#################### Define private functions ##################################
|
||||
|
||||
|
||||
#################### Plesk related functions
|
||||
|
||||
_pleskxml_get_variables() {
|
||||
|
||||
_DBG_VARDUMP 2 'Entered _pleskxml_get_variables()'
|
||||
|
||||
_pleskxml_errors=''
|
||||
|
||||
# The Plesk XML API needs the base domain (mydomain.com) and host (_acme_challenge) split out from the FQDN
|
||||
# supplied to this module, to manage the relevant DNS records
|
||||
# We assume ACME.SH does most of the validation, but even so, let's check some basic character compliance.
|
||||
# Not checking just [a-z0-9] since the FQDN could be unicode, but this should be reasonably sane.
|
||||
# If not, it'll be over-cautious and block unicode based on bytes, and need fixing.
|
||||
# At most the check can be removed. But it needs to be able to split out a host and a domain.
|
||||
|
||||
if printf '%s' "$_pleskxml_FQDN" | grep -iEq '^[^][/.:[:space:]^$*'\''"`-][^][/.:[:space:]^$*'\''"`]*(\.[^][/.:[:space:]^$*'\''"`_]+)+$'; then
|
||||
_pleskxml_host="$( printf '%s' "$_pleskxml_FQDN" | sed -E 's/^([^.]+)\..*$/\1/' )"
|
||||
_pleskxml_domain="$( printf '%s' "$_pleskxml_FQDN" | sed -E 's/^[^.]+\.(.*)$/\1/' )"
|
||||
else
|
||||
_pleskxml_errors="An invalid domain name (FQDN) was supplied."
|
||||
fi
|
||||
|
||||
# Now process other variables
|
||||
|
||||
_pleskxml_allow_insecure="${pleskxml_allow_insecure_uri:-no}"
|
||||
if [ "$_pleskxml_allow_insecure" = "yes" ] || [ "$_pleskxml_allow_insecure" = "Yes" ] || [ "$_pleskxml_allow_insecure" = "YES" ]; then
|
||||
# Allow insecure (non-SSL) URI for Plesk. "s" is optional within the "https" URI
|
||||
_pleskxml_allow_insecure=1
|
||||
_pleskxml_uri_prefix_match='https?://'
|
||||
else
|
||||
# Require secure (SSL) URI for Plesk. "s" is mandatory within the "https" URI
|
||||
_pleskxml_allow_insecure=0
|
||||
_pleskxml_uri_prefix_match='https://'
|
||||
fi
|
||||
|
||||
|
||||
if printf '%s' "${pleskxml_uri:-}" | grep -qiE "^${_pleskxml_uri_prefix_match}"'([a-z0-9][a-z0-9.:-]*|\[[a-f0-9][a-f0-9.:]+\])(:[0-9]{1,5})?(/|$)'; then
|
||||
# URI is "valid enough" to use, and uses https if this is mandatory (= pleskxml_allow_insecure_uri wasn't set)
|
||||
_pleskxml_uri="$pleskxml_uri"
|
||||
else
|
||||
_pleskxml_errors="$_pleskxml_errors"'\nBad or unacceptable URI (If non-SSL HTTP is required, did you set "pleskxml_allow_insecure_uri"?).\nYou should set and export '"$pleskxml_uri"', containing the URI for your Plesk XML API.\nThe URI usually looks like this: https://my_plesk_uri.tld:8443'
|
||||
fi
|
||||
|
||||
if printf '%s' "${pleskxml_user:-}" | grep -qiE '^[a-z0-9@%._-]+$'; then
|
||||
# USER is "valid enough" to use - Plesk doesn't stipulate valid chars, but thewse are probably "safe enough". We will find out if they aren't, the hard way :)
|
||||
# Note, we cannot assume "safe" characters when we use this value!
|
||||
_pleskxml_user="$pleskxml_user"
|
||||
else
|
||||
_pleskxml_errors="$_pleskxml_errors"'\nBad or unacceptable USER ACCOUNT for Plesk authentication. You should set and export '"$pleskxml_user."
|
||||
fi
|
||||
|
||||
if [ "${pleskxml_pass:-}" != "" ]; then
|
||||
# PASS is "valid enough" to use - Plesk doesn't stipulate valid chars, but thewse are probably "safe enough". We will find out if they aren't, the hard way :)
|
||||
# Note, we cannot assume "safe" characters when we use this value!
|
||||
_pleskxml_pass="$pleskxml_pass"
|
||||
else
|
||||
_pleskxml_errors="$_pleskxml_errors"'\nEmpty USER PASSWORD for Plesk authentication. You should set and export '"$pleskxml_pass."
|
||||
fi
|
||||
|
||||
# Ensure if not supplied, optional curl args are an empty string
|
||||
_pleskxml_optional_curl_args="${pleskxml_optional_curl_args:-}"
|
||||
|
||||
if [ -n "$_pleskxml_errors" ]; then
|
||||
_DBG_VARDUMP 2 "UNSUCCESSFULLY exiting _pleskxml_get_variables() (UNSUCCESSFUL CALL!)"
|
||||
return 1
|
||||
else
|
||||
_DBG_VARDUMP 2 "SUCCESSFULLY exiting _pleskxml_get_variables()"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Build a cURL request for the Plesk API
|
||||
# ARGS:
|
||||
# First arg is a Plesk XML API template. Further args (up to 3 items) are substituted into it via printf
|
||||
|
||||
_pleskxml_api_request() {
|
||||
|
||||
|
||||
_DBG 2 "Entered _pleskxml_api_request($*), to make an XML request.${_pleskxml_newline} arg1=^$1^${_pleskxml_newline} arg2=^$2^${_pleskxml_newline} arg3=^$3^${_pleskxml_newline} arg4=^$4^"
|
||||
|
||||
_pleskxml_errors=''
|
||||
_pleskxml_result=''
|
||||
_pleskxml_prettyprint_result=''
|
||||
_pleskxml_result=''
|
||||
|
||||
# Of all the API commands we use, just one of them can return multiple results sections
|
||||
# so the validation process after cURL returns, will differ for that case.....
|
||||
|
||||
if [ "$1" = "$_pleskxml_tplt_get_dns_records" ]; then
|
||||
_pleskxml_multiple_results_allowed=1
|
||||
else
|
||||
_pleskxml_multiple_results_allowed=0
|
||||
fi
|
||||
|
||||
# Sanitise user+pw for single quote enclosure, ands build Plesk arg string
|
||||
|
||||
_pleskxml_user="$( printf '%s' "$_pleskxml_user" | sed "s/'/'\\''/g" )"
|
||||
_pleskxml_pass="$( printf '%s' "$_pleskxml_pass" | sed "s/'/'\\''/g" )"
|
||||
_pleskxml_APICMD="$( printf "$1 %0.0s%0.0s%0.0s" "$2" "$3" "$4" )"
|
||||
# Add some %0.0s at the end of the format string in the 1st arg, to cope with ("absorb") variable number of further args
|
||||
# otherwise this will repeat the format string which we don't want.
|
||||
# If there weren't additional args, these will evaluate to empty strings/blank, and be harmless.
|
||||
|
||||
_pleskxml_curlargs="--anyauth \
|
||||
-X POST \
|
||||
-H 'Content-Type: text/xml' \
|
||||
-H 'HTTP_PRETTY_PRINT: TRUE' \
|
||||
-H 'HTTP_AUTH_LOGIN: ${_pleskxml_user}' \
|
||||
-H 'HTTP_AUTH_PASSWD: ${_pleskxml_pass}' \
|
||||
-d '${_pleskxml_APICMD}' \
|
||||
${_pleskxml_optional_curl_args}"
|
||||
|
||||
_DBG_VARDUMP 2 'About to call Plesk via cURL'
|
||||
|
||||
_DBG 2 "$( printf 'cURL command: %s %s %s' "$_pleskxml_curlpath" "$_pleskxml_curlargs" "$_pleskxml_uri" )"
|
||||
_pleskxml_prettyprint_result="$( eval "$_pleskxml_curlpath" "$_pleskxml_curlargs" "$_pleskxml_uri" 2>/dev/null )"
|
||||
_pleskxml_retcode="$?"
|
||||
_DBG 1 "_pleskxml_prettyprint_result =${_pleskxml_newline}'$_pleskxml_prettyprint_result' "
|
||||
_DBG 2 "retcode = $_pleskxml_retcode"
|
||||
|
||||
# BUGFIX TO CHECK - WILL RETCODE FROM cURL BE AVAILABLE HERE?
|
||||
|
||||
# Abort if cURL failed
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ]; then
|
||||
_pleskxml_errors="Exiting due to cURL error when querying Plesk XML API. The cURL return code was: $_pleskxml_retcode."
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK. Next, check XML reply was OK. Start by pushing it into one line, with leading/trailing space trimmed.
|
||||
|
||||
# _pleskxml_result="$( printf '%s' "$_pleskxml_prettyprint_result" | \
|
||||
# awk '{$1=$1};1' | \
|
||||
# tr -d '\n' \
|
||||
# )"
|
||||
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_prettyprint_result" | \
|
||||
sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' | \
|
||||
tr -d '\n' \
|
||||
)"
|
||||
|
||||
_DBG_VARDUMP 2 'cURL succeeded, valid cURL response obtained'
|
||||
|
||||
# Now we need to check item by item if it's OK.
|
||||
# As we go, we will strip out "known OK" stuff to leave the core reply.
|
||||
|
||||
# XML header and packet version?
|
||||
|
||||
_DBG 2 'Checking <?xml> and <packet> tags exist...'
|
||||
|
||||
if printf '%s' "$_pleskxml_result" | grep -qiEv '^<\?xml version=[^>]+><packet version=[^>]+>.*</packet>$'; then
|
||||
# Error - should have <?xml><packet>...</packet>. Abort
|
||||
_pleskxml_errors="Error when querying Plesk XML API. The API did not return a valid XML response. The response was:${_pleskxml_newline}${_pleskxml_prettyprint_result}${_pleskxml_newline}The collapsed version was:${_pleskxml_newline}'${_pleskxml_result}'${_pleskxml_newline}"
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
else
|
||||
# So far so good. Strip the <?xml> and <packet>...</packet> tags and continue
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed -E 's/^<\?xml version[^>]+><packet version[^>]+>(.*)<\/packet>$/\1/' \
|
||||
)"
|
||||
fi
|
||||
|
||||
_DBG 2 "Checking <system> tags don't exist..."
|
||||
|
||||
# <system> section found anywhere in response?
|
||||
# This usually means some kind of basic API error such as login failure, bad XML request, etc
|
||||
|
||||
|
||||
if printf '%s' "$_pleskxml_result" | grep -qiE '<system>.*</system>'; then
|
||||
# Error - shouldn't contain <system>...</system>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The result contained a <system> tag.\nThis usually indicates an invalid login, badly formatted API request or other error. The response was:\n'"$_pleskxml_prettyprint_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
_DBG 2 'Checking 1 or >=1 <result> tag (or tags) found, each containing 'status:ok'...'
|
||||
|
||||
|
||||
# Check results section. Most commands only have one results section.
|
||||
# But some (i.e., get all DNS records for a domain) have many results sections,
|
||||
# and we will need to check each <results>...</results> section separately.
|
||||
# So this gets a bit messy, especially as we don't have non-greedy regex
|
||||
# and we will have to work around that as well.
|
||||
|
||||
# For this, we will split the string up again with exactly 1 <result> section per line.
|
||||
# We check there is at least one result section. Then we add newlines before and after
|
||||
# any <result>...</result> and ignore any lines that don't contain '<result>'.
|
||||
|
||||
if printf '%s' "$_pleskxml_result" | grep -qiEv '<result>.*</result>'; then
|
||||
# Error - doesn't contain <result>...</result>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The result did not contain a <result> section.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_DBG 2 'Found at least 1 <result> section. Splitting each result section to a separate line'
|
||||
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed "s/<result>/\\${_pleskxml_newline}<result>/g" | \
|
||||
sed "s/<\/result>/<\/result>\\${_pleskxml_newline}/g" | \
|
||||
grep '<result>' \
|
||||
)"
|
||||
|
||||
# Detect and abort if there are >1 <result> sections and we're ponly expecting 1 section.
|
||||
|
||||
_pleskxml_linecount=$( printf '%s\n' "$_pleskxml_result" | wc -l )
|
||||
|
||||
_DBG 2 "Result is: '$_pleskxml_result' (${_pleskxml_linecount} line(s))"
|
||||
|
||||
_DBG_VARDUMP 2 'Testing <result> section linecount is OK (1 or >=1 as required)'
|
||||
|
||||
if [ $_pleskxml_multiple_results_allowed -eq 0 ] && [ "$_pleskxml_linecount" -gt 1 ]; then
|
||||
# Error - contains multiple <result> sections. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The result contained more than one <result> section.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_DBG 2 "Found ${_pleskxml_linecount} <result> section(s), checking each has status:ok..."
|
||||
|
||||
# Loop through each <result> section, checking every line has exactly one result section,
|
||||
# containing exactly one status section, which contains <status>ok</status>
|
||||
|
||||
while IFS= read -r _pleskxml_line; do
|
||||
|
||||
# _pleskxml_line *should* contain a single result section.
|
||||
# Check this is correct.
|
||||
|
||||
|
||||
# _DBG "Checking a <result> section... content is ${_pleskxml_line}"
|
||||
|
||||
if printf '%s' "$_pleskxml_line" | grep -qiEv '^<result>.*</result>$'; then
|
||||
# Error - doesn't contain <result>...</result>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. A <result> section was not found where expected.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\n'
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Now strip the <results> tag and check there is precisely one <status> section and its ciontents are "ok"
|
||||
|
||||
_pleskxml_line="$( printf '%s' "$_pleskxml_line" | sed -E 's/^<result>(.*)<\/result>$/\1/' )"
|
||||
|
||||
if printf '%s' "$_pleskxml_line" | grep -qiEv '<status>.*</status>'; then
|
||||
# Error - doesn't contain <status>...</status>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. A <result> section did not contain a <status> section.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
elif printf '%s' "$_pleskxml_line" | grep -qiE '<status>.*</status>.*<status>'; then
|
||||
# Error - contains <status>...</status>...<status>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. A <result> section contained more than one <status> section.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
elif printf '%s' "$_pleskxml_line" | grep -qiEv '<status>ok</status>'; then
|
||||
# Error - doesn't contain <status>ok</status>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. A <status> tag did not contain "<status>ok</status>". The response was:\n'"$_pleskxml_prettyprint_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# _DBG "Line is OK. Looping to next line or exiting..."
|
||||
|
||||
done << EOL
|
||||
$_pleskxml_result
|
||||
EOL
|
||||
|
||||
# So far so good. Remove all <status>ok</status> sections as they're checked now.
|
||||
|
||||
_DBG 2 "All results lines had status:ok. Exiting loop, and removing all <status>ok</status> tags now they've been checked"
|
||||
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed -E 's/<status>ok<\/status>//g' \
|
||||
)"
|
||||
|
||||
# Result is OK. Remove any redundant self-closing tags, and <data> or </data> tags, and exit
|
||||
|
||||
_DBG 2 'Now removing any self-closing tags, or <data>...</data> tags'
|
||||
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed -E 's/(<[a-zA-Z0-9._-]+[[:space:]]*\/>|<\/?data\/?>)//g' \
|
||||
)"
|
||||
|
||||
_DBG 2 "About to exit API function. Result = ${_pleskxml_newline}'${_pleskxml_result}' "
|
||||
|
||||
_DBG_VARDUMP 2 'Successfully exiting Plesk XML API function'
|
||||
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
_pleskxml_get_domain_ID() {
|
||||
|
||||
_DBG 2 "Entered Plesk get_domain_ID($*), to get the domain's Plesk ID."
|
||||
|
||||
# Call cURL to convert a domain name to a plesk domain ID.
|
||||
|
||||
_DBG 2 'About to make API request (domain name -> domain ID)'
|
||||
|
||||
_pleskxml_api_request "$_pleskxml_tplt_get_domain_id" "$1"
|
||||
_pleskxml_retcode=$?
|
||||
# $1 is the domain name we wish to convert to a Plesk domain ID
|
||||
|
||||
_DBG 2 'Returned from API request, now back in get_domain_ID()'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK, we should have a domain ID. Let's check and return it if so.
|
||||
|
||||
# Result should comprise precisely one <result> section
|
||||
|
||||
_DBG 2 'Testing API return data for one <result> and removing if so'
|
||||
|
||||
if printf '%s' "$_pleskxml_result" | grep -qiEv '^<result>.*</result>$'; then
|
||||
# Error - doesn't comprise <result>DOMAINNAME</result>. Something's wrong. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The API did not comprise a <result> section containing all other data.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\nand the exact test string was:\n'"$_pleskxml_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
elif printf '%s' "$_pleskxml_result" | grep -qiE '<result>.*<result>'; then
|
||||
# Error - contains <result>...</result>...<result>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The API contained more than one <result> section.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\nand the exact test string was:\n'"$_pleskxml_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
else
|
||||
# So far so good. Remove the <result>...</result> section and continue
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed -E 's/(^<result>|<\/result>$)//g' \
|
||||
)"
|
||||
fi
|
||||
|
||||
# Result should contain precisely one <filter-id> section, containing the domain name inquired.
|
||||
|
||||
_DBG 2 'Testing API return data for one <filter-id> and removing if so'
|
||||
|
||||
if printf '%s' "$_pleskxml_result" | grep -qiv "<filter-id>$1</filter-id>"; then
|
||||
# Error - doesn't contain <filter-id>DOMAINNAME</filter-id>. Something's wrong. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The API did not contain the expected <filter-id> section containing the domain name.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\nand the exact test string was:\n'"$_pleskxml_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
elif printf '%s' "$_pleskxml_result" | grep -qiE '<filter-id>.*<filter-id>'; then
|
||||
# Error - contains <filter-id>...</filter-id>...<filter-id>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The API contained more than one <filter-id> section.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\nand the exact test string was:\n'"$_pleskxml_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
else
|
||||
# So far so good. Remove the <filter-id>...</filter-id> section and continue
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed "s/<filter-id>$1<\/filter-id>//" \
|
||||
)"
|
||||
fi
|
||||
|
||||
# All that should be left is one section, containing <id>DOMAIN_ID</id>
|
||||
|
||||
_DBG 2 "Remaining part of result is now: '$_pleskxml_result' "
|
||||
|
||||
if printf '%s' "$_pleskxml_result" | grep -qiEv '^<id>[0-9]+</id>$'; then
|
||||
# Error - doesn't contain just <id>NUMBERS</id>. Something's wrong. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The API did not contain the expected <id>[NUMERIC_ID]</id> section, or contained other unexpected values as well.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\nand the exact test string was:\n'"$_pleskxml_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# SUCCESS! Remove the surrounding <id> tag and return the value!
|
||||
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed -E 's/^<id>([0-9]+)<\/id>$/\1/' \
|
||||
)"
|
||||
|
||||
_DBG_VARDUMP 2 'SUCCESSFULLY exiting Plesk get_domain_ID'
|
||||
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
|
||||
# 1st arg is the domain ID
|
||||
# 2nd arg (optional) is the TYPE of arg(s) to keep
|
||||
# format = valid regex WITHOUT ^ or $, such as TXT, or (A|AAAA|CNAME)
|
||||
|
||||
_pleskxml_get_dns_records() {
|
||||
|
||||
_DBG 2 "Entered Plesk _pleskxml_get_dns_records($*)"
|
||||
|
||||
# First, we need to get all DNS records, and check the list is valid
|
||||
|
||||
_DBG 2 'About to make API request (get DNS records)'
|
||||
|
||||
_pleskxml_api_request "$_pleskxml_tplt_get_dns_records" "$1"
|
||||
_pleskxml_retcode=$?
|
||||
# $1 is the Plesk internal domain ID for the domain
|
||||
|
||||
_DBG 2 'Returned from API request, now back in get_txt_records()'
|
||||
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK, we should have a <result> section containing a list of DNS records.
|
||||
# Now keep only the TXT records
|
||||
|
||||
|
||||
_DBG 2 "Full DNS records were:${_pleskxml_newline}${_pleskxml_newline}'${_pleskxml_result}' "
|
||||
|
||||
if [ -n "${2:-}" ]; then
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
grep "<type>$2</type>" \
|
||||
)"
|
||||
_DBG 2 "Filtered relevant DNS records. Records to be returned are:${_pleskxml_newline}${_pleskxml_newline}'${_pleskxml_result}' "
|
||||
else
|
||||
_DBG 2 'Not filtering DNS records. All records will be returned.'
|
||||
fi
|
||||
|
||||
_DBG 2 "SUCCESSFULLY exiting _pleskxml_get_dns_records"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
_pleskxml_add_txt_record() {
|
||||
|
||||
_DBG 2 "Entered Plesk _pleskxml_add_txt_record($*)"
|
||||
|
||||
_DBG 2 'About to make API request (add TXT record)'
|
||||
|
||||
_pleskxml_api_request "$_pleskxml_tplt_add_txt_record" "$1" "$2" "$3"
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
# $1 is the Plesk internal domain ID for the domain
|
||||
# $2 is the "host" entry within the domain, to add this to (eg '_acme_challenge')
|
||||
# $3 is the TXT record value
|
||||
|
||||
_DBG 2 'Returned from API request, now back in add_txt_record()'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK, we should have added a TXT record. Let's check and return success if so.
|
||||
# All that should be left in the result, is one section, containing <result><id>PLESK_NEW_DNS_RECORD_ID</id></result>
|
||||
|
||||
if printf '%s' "$_pleskxml_result" | grep -qivE '^<result><id>[0-9]+</id></result>$'; then
|
||||
# Error - doesn't contain just <id>NUMBERS</id>. Something's wrong. Abort
|
||||
_pleskxml_errors='Error when calling Plesk XML API. The API did not contain the expected <id>[PLESK_NEW_DNS_RECORD_ID]</id> section, or contained other unexpected values as well.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\nand the exact test string was:\n'"$_pleskxml_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# SUCCESS! Remove the surrounding <result><id> tags and return the value!
|
||||
# (although we don't actually use it!
|
||||
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed -E "s/^<result><id>([0-9]+)<\/id><\/result>$/\1/" \
|
||||
)"
|
||||
|
||||
_DBG_VARDUMP 2 'SUCCESSFULLY exiting Plesk _pleskxml_add_txt_record'
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_pleskxml_rmv_dns_record() {
|
||||
|
||||
_DBG 2 "Entered Plesk _pleskxml_rmv_dns_record($*)"
|
||||
|
||||
_DBG 2 'About to make API request (rmv TXT record)'
|
||||
|
||||
_pleskxml_api_request "$_pleskxml_tplt_rmv_dns_record" "$1"
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
# $1 is the Plesk internal domain ID for the TXT record
|
||||
|
||||
_DBG 2 'Returned from API request, now back in rmv_dns_record()'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK, we should have removed a TXT record. If it failed, there wouldn't have been a "status:ok" above
|
||||
|
||||
_DBG_VARDUMP 2 'SUCCESSFULLY exiting Plesk _pleskxml_rmv_dns_record'
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# 1st arg = domain ID
|
||||
# 2nd arg = host that the record exists for
|
||||
# 3rd arg = value of TXT record string to be found and removed
|
||||
_pleskxml_rmv_txt_record() {
|
||||
|
||||
|
||||
_DBG 2 "Entered Plesk _pleskxml_rmv_dns_TXT_record($*). Getting DNS TXT records for the domain ID"
|
||||
|
||||
_pleskxml_get_dns_records "$1" 'TXT'
|
||||
_pleskxml_retcode=$?
|
||||
# $1 is the Plesk internal domain ID for the domain
|
||||
|
||||
_DBG 2 'Returned from API request, now back in rmv_txt_record()'
|
||||
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# OK, we should have a <result> section containing a list of DNS TXT records.
|
||||
# Now we need to find our desired record in it (if it exists).
|
||||
# and might as well collapse any successful matches to a signle line for line-count purposes at the same time
|
||||
|
||||
_DBG 2 "Filters to apply (as literal strings):${_pleskxml_newline}'<host>${2:-<NON_MATCHING_GARBAGE>}.'${_pleskxml_newline}'<value>${3:-<NON_MATCHING_GARBAGE>}</value>' "
|
||||
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
grep -F "<host>${2:-<NON_MATCHING_GARBAGE>}." | \
|
||||
grep -F "<value>${3:-<NON_MATCHING_GARBAGE>}</value>" | \
|
||||
sed -E 's/(^[[:space:]]+|[[:space:]]+$)//g' | \
|
||||
tr -d '\n' \
|
||||
)"
|
||||
# Run 2 separate GREP filters, because the host and value order isn't mandatory in the API return data
|
||||
# ands this avoids regex and escaping which is easier
|
||||
# NOTE: the returned "host" field is actually the FQDN, not just the host ID, hence the grep match on that field.
|
||||
|
||||
_DBG 2 "Filtered result:${_pleskxml_newline}'$_pleskxml_result' "
|
||||
|
||||
if printf '%s' "$_pleskxml_result" | grep -qiE "<result>.*<result>"; then
|
||||
# Error - contains <result>...</result>...<result>. Abort
|
||||
_pleskxml_errors='Error when querying Plesk XML API. The API contained more than one <result> section.\nThis is unexpected: something has gone wrong. Please raise this as a bug/issue in the module. The response was:\n'"$_pleskxml_prettyprint_result"'\nand the exact test string was:\n'"$_pleskxml_result"'\n'
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if printf '%s\n' "$_pleskxml_result" | grep -qiv "<result>"; then
|
||||
# No matching TXT records, so we're done.
|
||||
_info "Couldn't find a TXT record matching the requested host/value. Not an error, but a concern..."
|
||||
_DBG 2 "Exiting Plesk _pleskxml_rmv_txt_record (without raising an error), as nothing more to do: the record requested for deletion doesn't exist"
|
||||
_pleskxml_result=''
|
||||
return 0
|
||||
fi
|
||||
|
||||
# If we get here, there was a single TXT record match, so we delete it.
|
||||
|
||||
_pleskxml_result="$( printf '%s' "$_pleskxml_result" | \
|
||||
sed -E 's/^.*<id>([0-9]+)<\/id>.*$/\1/' \
|
||||
)"
|
||||
|
||||
_DBG 2 "A unique matching DNS TXT record was found, with Plesk record ID = '$_pleskxml_result'. Calling API to delete this record."
|
||||
|
||||
_pleskxml_rmv_dns_record "$_pleskxml_result"
|
||||
_pleskxml_retcode=$?
|
||||
|
||||
_DBG 2 'Returned from API request, now back in rmv_txt_record()'
|
||||
|
||||
if [ $_pleskxml_retcode -ne 0 ] || [ "$_pleskxml_errors" != '' ] || [ "$_pleskxml_result" = '' ]; then
|
||||
# Really, just testing return code should be enough, based on above code, but let's go "all-in" and test all variables returned
|
||||
_DBG 2 "$_pleskxml_errors"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_DBG_VARDUMP 2 'SUCCESSFULLY exiting Plesk _pleskxml_rmv_txt_record'
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
exit
|
||||
|
||||
# ---------------------- TEST CODE ------------------------------
|
||||
|
||||
|
||||
# defined by user
|
||||
pleskxml_uri="https://plesk.XXXXX.net:8443/enterprise/control/agent.php"
|
||||
pleskxml_user="XXXXX"
|
||||
pleskxml_pass="XXXXX"
|
||||
pleskxml_debug_min_level=3
|
||||
|
||||
# defined from args by module
|
||||
_pleskxml_FQDN="_acme_challenge.XXXXX.com"
|
||||
_pleskxml_TXT_string='~test~string~'
|
||||
|
||||
printf '\n\n\n\n======================================================================== START OF RUN\n\n'
|
||||
|
||||
_info 'Checking debug mode...'
|
||||
|
||||
_DBG_EARLY_CHECK_MODE
|
||||
|
||||
_DBG 3 'Debug mode done. Now testing _pleskxml_get_variables()'
|
||||
|
||||
_pleskxml_get_variables
|
||||
_DBG 3 "$( printf 'RESULT:\n _pleskxml_errors: "%s"\n _pleskxml_retcode: "%s"\n _pleskxml_result: "%s"\n\n' "$_pleskxml_errors" "$_pleskxml_retcode" "$_pleskxml_result" )"
|
||||
|
||||
_DBG 3 '==============================================================='
|
||||
|
||||
_DBG 3 'Testing _pleskxml_get_domain_ID()'
|
||||
_pleskxml_get_domain_ID "atticflat.uk"
|
||||
|
||||
_DBG 3 "$( printf 'RESULT:\n _pleskxml_errors: "%s"\n _pleskxml_retcode: "%s"\n _pleskxml_result: "%s"\n\n' "$_pleskxml_errors" "$_pleskxml_retcode" "$_pleskxml_result" )"
|
||||
|
||||
_DBG_VARDUMP 2
|
||||
|
||||
_DBG 3 '==============================================================='
|
||||
|
||||
test_string="TEST STRING ADDED @ $( date )"
|
||||
|
||||
_DBG 3 "Testing add a TXT string: '$test_string' "
|
||||
_pleskxml_add_txt_record 874 '_test_subdomain' "$test_string"
|
||||
|
||||
_DBG 3 "$( printf 'RESULT:\n _pleskxml_errors: "%s"\n _pleskxml_retcode: "%s"\n _pleskxml_result: "%s"\n\n' "$_pleskxml_errors" "$_pleskxml_retcode" "$_pleskxml_result" )"
|
||||
|
||||
_DBG_VARDUMP 2
|
||||
|
||||
_DBG 3 '==============================================================='
|
||||
|
||||
_DBG 3 'Testing get DNS records (ALL)'
|
||||
_pleskxml_get_dns_records 874
|
||||
|
||||
_DBG 3 "$( printf 'RESULT:\n _pleskxml_errors: "%s"\n _pleskxml_retcode: "%s"\n _pleskxml_result: "%s"\n\n' "$_pleskxml_errors" "$_pleskxml_retcode" "$_pleskxml_result" )"
|
||||
|
||||
_DBG_VARDUMP 2
|
||||
|
||||
_DBG 3 '==============================================================='
|
||||
|
||||
_DBG 3 'Testing get DNS records (TXT ONLY)'
|
||||
_pleskxml_get_dns_records 874 TXT
|
||||
|
||||
_DBG 3 "$( printf 'RESULT:\n _pleskxml_errors: "%s"\n _pleskxml_retcode: "%s"\n _pleskxml_result: "%s"\n\n' "$_pleskxml_errors" "$_pleskxml_retcode" "$_pleskxml_result" )"
|
||||
|
||||
_DBG_VARDUMP 2
|
||||
|
||||
_DBG 3 '==============================================================='
|
||||
|
||||
_DBG 3 'Testing rmv a TXT string'
|
||||
_pleskxml_rmv_txt_record 874 '_test_subdomain' "$test_string"
|
||||
|
||||
_DBG 3 "$( printf 'RESULT:\n _pleskxml_errors: "%s"\n _pleskxml_retcode: "%s"\n _pleskxml_result: "%s"\n\n' "$_pleskxml_errors" "$_pleskxml_retcode" "$_pleskxml_result" )"
|
||||
|
||||
_DBG_VARDUMP 2
|
||||
|
||||
_DBG 3 '==============================================================='
|
||||
|
||||
_DBG 3 'Re-testing get DNS records (TXT ONLY) after TXT string removal'
|
||||
_pleskxml_get_dns_records 874 TXT
|
||||
|
||||
_DBG 3 "$( printf 'RESULT:\n _pleskxml_errors: "%s"\n _pleskxml_retcode: "%s"\n _pleskxml_result: "%s"\n\n' "$_pleskxml_errors" "$_pleskxml_retcode" "$_pleskxml_result" )"
|
||||
|
||||
_DBG_VARDUMP 2
|
||||
|
||||
_DBG 3 '==============================================================='
|
||||
|
||||
_DBG 3 'Testing rmv a TXT string, with a non-matching string'
|
||||
_pleskxml_rmv_txt_record 874 '_test_subdomain' 'JUNKegqw4bw4bb2'
|
||||
|
||||
_DBG 3 "$( printf 'RESULT:\n _pleskxml_errors: "%s"\n _pleskxml_retcode: "%s"\n _pleskxml_result: "%s"\n\n' "$_pleskxml_errors" "$_pleskxml_retcode" "$_pleskxml_result" )"
|
||||
|
||||
_DBG_VARDUMP 2
|
||||
|
||||
_DBG 3 '=============================================================== END OF RUN'
|
Loading…
x
Reference in New Issue
Block a user