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.

179 lines
5.4 KiB

  1. #!/usr/bin/env sh
  2. ## Will be called by acme.sh to add the txt record to your api system.
  3. ## returns 0 means success, otherwise error.
  4. ## Author: thewer <github at thewer.com>
  5. ## GitHub: https://github.com/gitwer/acme.sh
  6. ##
  7. ## Environment Variables Required:
  8. ##
  9. ## DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc"
  10. ##
  11. ## DO_DOMAIN_START="3"
  12. ## start of the digital ocean dns base domain from the LEFT
  13. ## (EG: one.two.three.four.five.com -> one.two & three.four.five.com)
  14. ##
  15. ##################### Public functions #####################
  16. ## Create the text record for validation.
  17. ## Usage: fulldomain txtvalue
  18. ## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
  19. dns_dgon_add() {
  20. fulldomain=$1
  21. txtvalue=$2
  22. _info "Using digitalocean dns validation - add record"
  23. _debug fulldomain "$fulldomain"
  24. _debug txtvalue "$txtvalue"
  25. _debug DO_DOMAIN_START "$DO_DOMAIN_START"
  26. ## save the env vars (key and domain split location) for later automated use
  27. _saveaccountconf DO_API_KEY "$DO_API_KEY"
  28. _saveaccountconf DO_DOMAIN_START "$DO_DOMAIN_START"
  29. ## split the domain for DO API
  30. if ! _get_base_domain "$fulldomain" "$DO_DOMAIN_START"; then
  31. _err "invalid domain or split"
  32. return 1
  33. fi
  34. _debug _sub_domain "$_sub_domain"
  35. _debug _domain "$_domain"
  36. ## Set the header with our post type and key auth key
  37. export _H1="Content-Type: application/json"
  38. export _H2="Authorization: Bearer $DO_API_KEY"
  39. PURL='https://api.digitalocean.com/v2/domains/'$_domain'/records'
  40. PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'"}'
  41. _debug PURL "$PURL"
  42. _debug PBODY "$PBODY"
  43. ## the create request - post
  44. ## args: BODY, URL, [need64, httpmethod]
  45. response="$(_post "$PBODY" "$PURL")"
  46. ## check response (sort of)
  47. if [ "$?" != "0" ]; then
  48. _err "error in response: $response"
  49. return 1
  50. fi
  51. _debug2 response "$response"
  52. ## finished correctly
  53. return 0
  54. }
  55. ## Remove the txt record after validation.
  56. ## Usage: fulldomain txtvalue
  57. ## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
  58. dns_dgon_rm() {
  59. fulldomain=$1
  60. txtvalue=$2
  61. _info "Using digitalocean dns validation - remove record"
  62. _debug fulldomain "$fulldomain"
  63. _debug txtvalue "$txtvalue"
  64. _debug DO_DOMAIN_START "$DO_DOMAIN_START"
  65. ## split the domain for DO API
  66. if ! _get_base_domain "$fulldomain" "$DO_DOMAIN_START"; then
  67. _err "invalid domain or split in remove"
  68. return 1
  69. fi
  70. _debug _sub_domain "$_sub_domain"
  71. _debug _domain "$_domain"
  72. ## Set the header with our post type and key auth key
  73. export _H1="Content-Type: application/json"
  74. export _H2="Authorization: Bearer $DO_API_KEY"
  75. ## get URL for the list of domains
  76. ## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
  77. GURL="https://api.digitalocean.com/v2/domains/$_domain/records"
  78. ## while we dont have a record ID we keep going
  79. while [ -z "$record" ]; do
  80. ## 1) get the URL
  81. ## the create request - get
  82. ## args: URL, [onlyheader, timeout]
  83. domain_list="$(_get "$GURL")"
  84. ## 2) find record
  85. ## check for what we are looing for: "type":"A","name":"$_sub_domain"
  86. record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*\d+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
  87. ## 3) check record and get next page
  88. if [ -z "$record" ]; then
  89. ## find the next page if we dont have a match
  90. nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=\d+")"
  91. if [ -z "$nextpage" ]; then
  92. _err "no record and no nextpage in digital ocean DNS removal"
  93. return 1
  94. fi
  95. _debug2 nextpage "$nextpage"
  96. GURL="$nextpage"
  97. fi
  98. ## we break out of the loop when we have a record
  99. done
  100. ## we found the record
  101. rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*\d+" | _egrep_o "\d+")"
  102. _debug rec_id "$rec_id"
  103. ## delete the record
  104. ## delete URL for removing the one we dont want
  105. DURL="https://api.digitalocean.com/v2/domains/$_domain/records/$rec_id"
  106. ## the create request - delete
  107. ## args: BODY, URL, [need64, httpmethod]
  108. response="$(_post "" "$DURL" "" "DELETE")"
  109. ## check response (sort of)
  110. if [ "$?" != "0" ]; then
  111. _err "error in remove response: $response"
  112. return 1
  113. fi
  114. _debug2 response "$response"
  115. ## finished correctly
  116. return 0
  117. }
  118. ##################### Private functions below #####################
  119. ## Split the domain provided at "base_domain_start_position" from the FRONT
  120. ## USAGE: fulldomain base_domain_start_position
  121. ## EG: "_acme-challenge.two.three.four.domain.com" "3"
  122. ## returns
  123. ## _sub_domain="_acme-challenge.two"
  124. ## _domain="three.four.domain.com"
  125. _get_base_domain() {
  126. # args
  127. domain=$1
  128. dom_point=$2
  129. sub_point=$(_math "$dom_point" - 1)
  130. _debug "split domain" "$domain"
  131. _debug "split dom_point" "$dom_point"
  132. _debug "split sub_point" "$sub_point"
  133. # domain max length - 253
  134. MAX_DOM=255
  135. ## cut in half and check
  136. _domain=$(printf "%s" "$domain" | cut -d . -f "$dom_point"-"$MAX_DOM")
  137. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$sub_point")
  138. if [ -z "$_domain" ]; then
  139. ## not valid
  140. _err "invalid split location"
  141. return 1
  142. fi
  143. if [ -z "$_sub_domain" ]; then
  144. ## not valid
  145. _err "invalid split location"
  146. return 1
  147. fi
  148. _debug "split _domain" "$_domain"
  149. _debug "split _sub_domain" "$_sub_domain"
  150. ## all ok
  151. return 0
  152. }