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.

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