You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
5.9 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. #!/usr/bin/env sh
  2. # shellcheck disable=SC2034
  3. dns_constellix_info='Constellix.com
  4. Site: Constellix.com
  5. Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_constellix
  6. Options:
  7. CONSTELLIX_Key API Key
  8. CONSTELLIX_Secret API Secret
  9. Issues: github.com/acmesh-official/acme.sh/issues/2724
  10. Author: Wout Decre <wout@canodus.be>
  11. '
  12. CONSTELLIX_Api="https://api.dns.constellix.com/v1"
  13. ######## Public functions #####################
  14. # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  15. # Used to add txt record
  16. dns_constellix_add() {
  17. fulldomain=$1
  18. txtvalue=$2
  19. CONSTELLIX_Key="${CONSTELLIX_Key:-$(_readaccountconf_mutable CONSTELLIX_Key)}"
  20. CONSTELLIX_Secret="${CONSTELLIX_Secret:-$(_readaccountconf_mutable CONSTELLIX_Secret)}"
  21. if [ -z "$CONSTELLIX_Key" ] || [ -z "$CONSTELLIX_Secret" ]; then
  22. _err "You did not specify the Contellix API key and secret yet."
  23. return 1
  24. fi
  25. _saveaccountconf_mutable CONSTELLIX_Key "$CONSTELLIX_Key"
  26. _saveaccountconf_mutable CONSTELLIX_Secret "$CONSTELLIX_Secret"
  27. if ! _get_root "$fulldomain"; then
  28. _err "Invalid domain"
  29. return 1
  30. fi
  31. # The TXT record might already exist when working with wildcard certificates. In that case, update the record by adding the new value.
  32. _debug "Search TXT record"
  33. if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then
  34. if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then
  35. _info "Adding TXT record"
  36. if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":60,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then
  37. if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then
  38. _info "Added"
  39. return 0
  40. else
  41. _err "Error adding TXT record"
  42. fi
  43. fi
  44. else
  45. _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
  46. if _constellix_rest GET "domains/${_domain_id}/records/TXT/${_record_id}"; then
  47. _new_rr_values=$(printf "%s\n" "$response" | _egrep_o '"roundRobin":\[[^]]*\]' | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/")
  48. _debug _new_rr_values "$_new_rr_values"
  49. _info "Updating TXT record"
  50. if _constellix_rest PUT "domains/${_domain_id}/records/TXT/${_record_id}" "{\"name\":\"${_sub_domain}\",\"ttl\":60,${_new_rr_values}}"; then
  51. if printf -- "%s" "$response" | grep "{\"success\":\"Record.*updated successfully\"}" >/dev/null; then
  52. _info "Updated"
  53. return 0
  54. elif printf -- "%s" "$response" | grep "{\"errors\":\[\"Contents are identical\"\]}" >/dev/null; then
  55. _info "Already exists, no need to update"
  56. return 0
  57. else
  58. _err "Error updating TXT record"
  59. fi
  60. fi
  61. fi
  62. fi
  63. fi
  64. return 1
  65. }
  66. # Usage: fulldomain txtvalue
  67. # Used to remove the txt record after validation
  68. dns_constellix_rm() {
  69. fulldomain=$1
  70. txtvalue=$2
  71. CONSTELLIX_Key="${CONSTELLIX_Key:-$(_readaccountconf_mutable CONSTELLIX_Key)}"
  72. CONSTELLIX_Secret="${CONSTELLIX_Secret:-$(_readaccountconf_mutable CONSTELLIX_Secret)}"
  73. if [ -z "$CONSTELLIX_Key" ] || [ -z "$CONSTELLIX_Secret" ]; then
  74. _err "You did not specify the Contellix API key and secret yet."
  75. return 1
  76. fi
  77. if ! _get_root "$fulldomain"; then
  78. _err "Invalid domain"
  79. return 1
  80. fi
  81. # The TXT record might have been removed already when working with some wildcard certificates.
  82. _debug "Search TXT record"
  83. if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then
  84. if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then
  85. _info "Removed"
  86. return 0
  87. else
  88. _info "Removing TXT record"
  89. if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"delete\":true,\"filter\":{\"field\":\"name\",\"op\":\"eq\",\"value\":\"${_sub_domain}\"}}]"; then
  90. if printf -- "%s" "$response" | grep "{\"success\":\"0 record(s) added, 0 record(s) updated, 1 record(s) deleted\"}" >/dev/null; then
  91. _info "Removed"
  92. return 0
  93. else
  94. _err "Error removing TXT record"
  95. fi
  96. fi
  97. fi
  98. fi
  99. return 1
  100. }
  101. #################### Private functions below ##################################
  102. _get_root() {
  103. domain=$1
  104. i=2
  105. p=1
  106. _debug "Detecting root zone"
  107. while true; do
  108. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  109. if [ -z "$h" ]; then
  110. return 1
  111. fi
  112. if ! _constellix_rest GET "domains/search?exact=$h"; then
  113. return 1
  114. fi
  115. if _contains "$response" "\"name\":\"$h\""; then
  116. _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
  117. if [ "$_domain_id" ]; then
  118. _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p)
  119. _domain="$h"
  120. _debug _domain_id "$_domain_id"
  121. _debug _sub_domain "$_sub_domain"
  122. _debug _domain "$_domain"
  123. return 0
  124. fi
  125. return 1
  126. fi
  127. p=$i
  128. i=$(_math "$i" + 1)
  129. done
  130. return 1
  131. }
  132. _constellix_rest() {
  133. m=$1
  134. ep="$2"
  135. data="$3"
  136. _debug "$ep"
  137. rdate=$(date +"%s")"000"
  138. hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_Secret" | _hex_dump | tr -d ' ')" | _base64)
  139. export _H1="x-cnsdns-apiKey: $CONSTELLIX_Key"
  140. export _H2="x-cnsdns-requestDate: $rdate"
  141. export _H3="x-cnsdns-hmac: $hmac"
  142. export _H4="Accept: application/json"
  143. export _H5="Content-Type: application/json"
  144. if [ "$m" != "GET" ]; then
  145. _debug data "$data"
  146. response="$(_post "$data" "$CONSTELLIX_Api/$ep" "" "$m")"
  147. else
  148. response="$(_get "$CONSTELLIX_Api/$ep")"
  149. fi
  150. if [ "$?" != "0" ]; then
  151. _err "Error $ep"
  152. return 1
  153. fi
  154. _debug response "$response"
  155. return 0
  156. }