| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #!/usr/bin/env sh
- # shellcheck disable=SC2034
- dns_virakcloud_info='VirakCloud DNS API
- Site: VirakCloud.com
- Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_virakcloud
- Options:
- VIRAKCLOUD_API_TOKEN VirakCloud API Bearer Token
- '
- VIRAKCLOUD_API_URL="https://public-api.virakcloud.com/dns"
- ######## Public functions #####################
- #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
- #Used to add txt record
- dns_virakcloud_add() {
- fulldomain=$1
- txtvalue=$2
- VIRAKCLOUD_API_TOKEN="${VIRAKCLOUD_API_TOKEN:-$(_readaccountconf_mutable VIRAKCLOUD_API_TOKEN)}"
- if [ -z "$VIRAKCLOUD_API_TOKEN" ]; then
- _err "You haven't configured your VirakCloud API token yet."
- _err "Please set VIRAKCLOUD_API_TOKEN environment variable or run:"
- _err " export VIRAKCLOUD_API_TOKEN=\"your-api-token\""
- return 1
- fi
- _saveaccountconf_mutable VIRAKCLOUD_API_TOKEN "$VIRAKCLOUD_API_TOKEN"
- _debug "First detect the root zone"
- if ! _get_root "$fulldomain"; then
- http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
- if [ "$http_code" = "401" ]; then
- return 1
- fi
- _err "Invalid domain"
- return 1
- fi
- _debug _domain "$_domain"
- _debug fulldomain "$fulldomain"
- _info "Adding TXT record"
- if _virakcloud_rest POST "domains/${_domain}/records" "{\"record\":\"${fulldomain}\",\"type\":\"TXT\",\"ttl\":3600,\"content\":\"${txtvalue}\"}"; then
- if echo "$response" | grep -q "success" || echo "$response" | grep -q "\"data\""; then
- _info "Added, OK"
- return 0
- elif echo "$response" | grep -q "already exists" || echo "$response" | grep -q "duplicate"; then
- _info "Record already exists, OK"
- return 0
- else
- _err "Add TXT record error."
- _err "Response: $response"
- return 1
- fi
- fi
- _err "Add TXT record error."
- return 1
- }
- #Usage: fulldomain txtvalue
- #Used to remove the txt record after validation
- dns_virakcloud_rm() {
- fulldomain=$1
- txtvalue=$2
- VIRAKCLOUD_API_TOKEN="${VIRAKCLOUD_API_TOKEN:-$(_readaccountconf_mutable VIRAKCLOUD_API_TOKEN)}"
- if [ -z "$VIRAKCLOUD_API_TOKEN" ]; then
- _err "You haven't configured your VirakCloud API token yet."
- return 1
- fi
- _debug "First detect the root zone"
- if ! _get_root "$fulldomain"; then
- http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
- if [ "$http_code" = "401" ]; then
- return 1
- fi
- _err "Invalid domain"
- return 1
- fi
- _debug _domain "$_domain"
- _debug fulldomain "$fulldomain"
- _debug txtvalue "$txtvalue"
- _info "Removing TXT record"
- _debug "Getting list of records to find content ID"
- if ! _virakcloud_rest GET "domains/${_domain}/records" ""; then
- return 1
- fi
- _debug2 "Records response" "$response"
- contentid=""
- # Extract innermost objects (content objects) which look like {"id":"...","content_raw":"..."}
- # We filter for the one containing txtvalue
- target_obj=$(echo "$response" | grep -o '{[^}]*}' | grep "$txtvalue" | _head_n 1)
- if [ -n "$target_obj" ]; then
- contentid=$(echo "$target_obj" | _egrep_o '"id":"[^"]*"' | cut -d '"' -f 4)
- fi
- if [ -z "$contentid" ]; then
- _debug "Could not find matching record ID in response"
- _info "Record not found, may have been already removed"
- return 0
- fi
- _debug contentid "$contentid"
- if _virakcloud_rest DELETE "domains/${_domain}/records/${fulldomain}/TXT/${contentid}" ""; then
- if echo "$response" | grep -q "success" || [ -z "$response" ]; then
- _info "Removed, OK"
- return 0
- elif echo "$response" | grep -q "not found" || echo "$response" | grep -q "404"; then
- _info "Record not found, OK"
- return 0
- else
- _err "Remove TXT record error."
- _err "Response: $response"
- return 1
- fi
- fi
- _err "Remove TXT record error."
- return 1
- }
- #################### Private functions below ##################################
- #_acme-challenge.www.domain.com
- #returns
- # _domain=domain.com
- _get_root() {
- domain=$1
- i=1
- p=1
- # Optimization: skip _acme-challenge subdomain to avoid 422 errors
- if echo "$domain" | grep -q "^_acme-challenge."; then
- i=2
- fi
- while true; do
- h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
- _debug h "$h"
- if [ -z "$h" ]; then
- return 1
- fi
- if ! _virakcloud_rest GET "domains/$h" ""; then
- http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
- if [ "$http_code" = "401" ]; then
- return 1
- fi
- p=$i
- i=$(_math "$i" + 1)
- continue
- fi
- if echo "$response" | grep -q "\"name\""; then
- _domain="$h"
- return 0
- fi
- p=$i
- i=$(_math "$i" + 1)
- done
- return 1
- }
- _virakcloud_rest() {
- m=$1
- ep="$2"
- data="$3"
- _debug "$ep"
- export _H1="Content-Type: application/json"
- export _H2="Authorization: Bearer $VIRAKCLOUD_API_TOKEN"
- if [ "$m" != "GET" ]; then
- _debug data "$data"
- response="$(_post "$data" "$VIRAKCLOUD_API_URL/$ep" "" "$m")"
- else
- response="$(_get "$VIRAKCLOUD_API_URL/$ep")"
- fi
- _ret="$?"
- if [ "$_ret" != "0" ]; then
- _err "error on $m $ep"
- return 1
- fi
- http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
- _debug "http response code" "$http_code"
- if [ "$http_code" = "401" ]; then
- _err "VirakCloud API returned 401 Unauthorized."
- _err "Your VIRAKCLOUD_API_TOKEN is invalid or expired."
- _err "Please check your API token and try again."
- return 1
- fi
- if [ "$http_code" = "403" ]; then
- _err "VirakCloud API returned 403 Forbidden."
- _err "Your API token does not have permission to access this resource."
- return 1
- fi
- if [ -n "$http_code" ] && [ "$http_code" -ge 400 ]; then
- _err "VirakCloud API error. HTTP code: $http_code"
- _err "Response: $response"
- return 1
- fi
- _debug2 response "$response"
- return 0
- }
|