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.

195 lines
6.3 KiB

  1. #!/usr/bin/env sh
  2. # Author: Radek Sprta <sprta@vshosting.cz>
  3. #CLOUDDNS_EMAIL=XXXXX
  4. #CLOUDDNS_PASSWORD="YYYYYYYYY"
  5. #CLOUDDNS_CLIENT_ID=XXXXX
  6. CLOUDDNS_API='https://admin.vshosting.cloud/clouddns'
  7. CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login'
  8. ######## Public functions #####################
  9. #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  10. dns_clouddns_add() {
  11. fulldomain=$1
  12. txtvalue=$2
  13. CLOUDDNS_CLIENT_ID="${CLOUDDNS_CLIENT_ID:-$(_readaccountconf_mutable CLOUDDNS_CLIENT_ID)}"
  14. CLOUDDNS_EMAIL="${CLOUDDNS_EMAIL:-$(_readaccountconf_mutable CLOUDDNS_EMAIL)}"
  15. CLOUDDNS_PASSWORD="${CLOUDDNS_PASSWORD:-$(_readaccountconf_mutable CLOUDDNS_PASSWORD)}"
  16. if [ -z "$CLOUDDNS_PASSWORD" ] || [ -z "$CLOUDDNS_EMAIL" ] || [ -z "$CLOUDDNS_CLIENT_ID" ]; then
  17. CLOUDDNS_CLIENT_ID=""
  18. CLOUDDNS_EMAIL=""
  19. CLOUDDNS_PASSWORD=""
  20. _err "You didn't specify a CloudDNS password, email and client id yet."
  21. return 1
  22. fi
  23. if ! _contains "$CLOUDDNS_EMAIL" "@"; then
  24. _err "It seems that the CLOUDDNS_EMAIL=$CLOUDDNS_EMAIL is not a valid email address."
  25. _err "Please check and retry."
  26. return 1
  27. fi
  28. # Save CloudDNS client id, email and password to config file
  29. _saveaccountconf_mutable CLOUDDNS_CLIENT_ID "$CLOUDDNS_CLIENT_ID"
  30. _saveaccountconf_mutable CLOUDDNS_EMAIL "$CLOUDDNS_EMAIL"
  31. _saveaccountconf_mutable CLOUDDNS_PASSWORD "$CLOUDDNS_PASSWORD"
  32. _debug "First detect the root zone"
  33. if ! _get_root "$fulldomain"; then
  34. _err "Invalid domain"
  35. return 1
  36. fi
  37. _debug _domain_id "$_domain_id"
  38. _debug _sub_domain "$_sub_domain"
  39. _debug _domain "$_domain"
  40. # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
  41. # we can not use updating anymore.
  42. _info "Adding record"
  43. if _clouddns_api POST "record-txt" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"domainId\":\"$_domain_id\"}"; then
  44. if _contains "$response" "$txtvalue"; then
  45. _info "Added, OK"
  46. elif _contains "$response" '"code":4136'; then
  47. _info "Already exists, OK"
  48. else
  49. _err "Add txt record error."
  50. return 1
  51. fi
  52. fi
  53. # Publish challenge record
  54. _debug "Publishing record changes"
  55. _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}"
  56. }
  57. #fulldomain txtvalue
  58. dns_clouddns_rm() {
  59. fulldomain=$1
  60. txtvalue=$2
  61. CLOUDDNS_CLIENT_ID="${CLOUDDNS_CLIENT_ID:-$(_readaccountconf_mutable CLOUDDNS_CLIENT_ID)}"
  62. CLOUDDNS_EMAIL="${CLOUDDNS_EMAIL:-$(_readaccountconf_mutable CLOUDDNS_EMAIL)}"
  63. CLOUDDNS_PASSWORD="${CLOUDDNS_PASSWORD:-$(_readaccountconf_mutable CLOUDDNS_PASSWORD)}"
  64. _debug "First detect the root zone"
  65. if ! _get_root "$fulldomain"; then
  66. _err "invalid domain"
  67. return 1
  68. fi
  69. _debug _domain_id "$_domain_id"
  70. _debug _sub_domain "$_sub_domain"
  71. _debug _domain "$_domain"
  72. # Get record Id
  73. response="$(_clouddns_api GET "domain/$_domain_id" | tr -d '\t\r\n ')"
  74. _debug response "$response"
  75. if _contains "$response" "lastDomainRecordList"; then
  76. re="\"lastDomainRecordList\".*\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\","
  77. _last_domains=$(echo "$response" | _egrep_o "$re")
  78. re2="\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\","
  79. _record_id=$(echo "$_last_domains" | _egrep_o "$re2" | _head_n 1 | cut -d : -f 2 | cut -d , -f 1 | tr -d "\"")
  80. _debug _record_id "$_record_id"
  81. else
  82. _err "Could not retrieve record id"
  83. return 1
  84. fi
  85. _info "Removing record"
  86. if _clouddns_api DELETE "record/$_record_id"; then
  87. if _contains "$response" "\"error\":"; then
  88. _err "Could not remove record"
  89. return 1
  90. fi
  91. fi
  92. # Publish challenge record
  93. _debug "Publishing record changes"
  94. _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}"
  95. }
  96. #################### Private functions below ##################################
  97. #_acme-challenge.www.domain.com
  98. #returns
  99. # _sub_domain=_acme-challenge.www
  100. # _domain=domain.com
  101. # _domain_id=sdjkglgdfewsdfg
  102. _get_root() {
  103. domain=$1
  104. # Get domain root
  105. data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}]}"
  106. response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')"
  107. _debug2 "response" "$response"
  108. domain_slice="$domain"
  109. while [ -z "$domain_root" ]; do
  110. if _contains "$response" "\"domainName\":\"$domain_slice\.\""; then
  111. domain_root="$domain_slice"
  112. _debug domain_root "$domain_root"
  113. fi
  114. domain_slice="$(echo "$domain_slice" | cut -d . -f 2-)"
  115. done
  116. # Get domain id
  117. data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}, \
  118. {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}"
  119. response="$(_clouddns_api "POST" "domain/search" "$data" | tr -d '\t\r\n ')"
  120. if _contains "$response" "\"id\":\""; then
  121. re='domainType\":\"[^\"]*\",\"id\":\"([^\"]*)\",' # Match domain id
  122. _domain_id=$(echo "$response" | _egrep_o "$re" | _head_n 1 | cut -d : -f 3 | tr -d "\",")
  123. if [ "$_domain_id" ]; then
  124. _sub_domain=$(printf "%s" "$domain" | sed "s/.$domain_root//")
  125. _domain="$domain_root"
  126. return 0
  127. fi
  128. _err 'Domain name not found on your CloudDNS account'
  129. return 1
  130. fi
  131. return 1
  132. }
  133. _clouddns_api() {
  134. method=$1
  135. endpoint="$2"
  136. data="$3"
  137. _debug endpoint "$endpoint"
  138. if [ -z "$CLOUDDNS_TOKEN" ]; then
  139. _clouddns_login
  140. fi
  141. _debug CLOUDDNS_TOKEN "$CLOUDDNS_TOKEN"
  142. export _H1="Content-Type: application/json"
  143. export _H2="Authorization: Bearer $CLOUDDNS_TOKEN"
  144. if [ "$method" != "GET" ]; then
  145. _debug data "$data"
  146. response="$(_post "$data" "$CLOUDDNS_API/$endpoint" "" "$method")"
  147. else
  148. response="$(_get "$CLOUDDNS_API/$endpoint")"
  149. fi
  150. if [ "$?" != "0" ]; then
  151. _err "error $endpoint"
  152. return 1
  153. fi
  154. printf "%s" "$response"
  155. return 0
  156. }
  157. _clouddns_login() {
  158. login_data="{\"email\": \"$CLOUDDNS_EMAIL\", \"password\": \"$CLOUDDNS_PASSWORD\"}"
  159. response="$(_post "$login_data" "$CLOUDDNS_LOGIN_API" "" "POST" "Content-Type: application/json")"
  160. _debug2 response "$response"
  161. if _contains "$response" "\"accessToken\":\""; then
  162. CLOUDDNS_TOKEN=$(echo "$response" | _egrep_o "\"accessToken\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")
  163. export CLOUDDNS_TOKEN
  164. else
  165. echo 'Could not get CloudDNS access token; check your credentials'
  166. return 1
  167. fi
  168. return 0
  169. }