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.

175 lines
4.6 KiB

4 years ago
8 years ago
4 years ago
4 years ago
  1. #!/usr/bin/env sh
  2. # Gandi LiveDNS v5 API
  3. # https://doc.livedns.gandi.net/
  4. # currently under beta
  5. #
  6. # Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
  7. #
  8. #Author: Frédéric Crozat <fcrozat@suse.com>
  9. # Dominik Röttsches <drott@google.com>
  10. #Report Bugs here: https://github.com/fcrozat/acme.sh
  11. #
  12. ######## Public functions #####################
  13. GANDI_LIVEDNS_API="https://dns.api.gandi.net/api/v5"
  14. #Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  15. dns_gandi_livedns_add() {
  16. fulldomain=$1
  17. txtvalue=$2
  18. if [ -z "$GANDI_LIVEDNS_KEY" ]; then
  19. _err "No API key specified for Gandi LiveDNS."
  20. _err "Create your key and export it as GANDI_LIVEDNS_KEY"
  21. return 1
  22. fi
  23. _saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY"
  24. _debug "First detect the root zone"
  25. if ! _get_root "$fulldomain"; then
  26. _err "invalid domain"
  27. return 1
  28. fi
  29. _debug fulldomain "$fulldomain"
  30. _debug txtvalue "$txtvalue"
  31. _debug domain "$_domain"
  32. _debug sub_domain "$_sub_domain"
  33. _dns_gandi_append_record "$_domain" "$_sub_domain" "$txtvalue"
  34. }
  35. #Usage: fulldomain txtvalue
  36. #Remove the txt record after validation.
  37. dns_gandi_livedns_rm() {
  38. fulldomain=$1
  39. txtvalue=$2
  40. _debug "First detect the root zone"
  41. if ! _get_root "$fulldomain"; then
  42. _err "invalid domain"
  43. return 1
  44. fi
  45. _debug fulldomain "$fulldomain"
  46. _debug domain "$_domain"
  47. _debug sub_domain "$_sub_domain"
  48. _debug txtvalue "$txtvalue"
  49. if ! _dns_gandi_existing_rrset_values "$_domain" "$_sub_domain"; then
  50. return 1
  51. fi
  52. _new_rrset_values=$(echo "$_rrset_values" | sed "s/...$txtvalue...//g")
  53. # Cleanup dangling commata.
  54. _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, ,/ ,/g")
  55. _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, *\]/\]/g")
  56. _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/\[ *,/\[/g")
  57. _debug "New rrset_values" "$_new_rrset_values"
  58. _gandi_livedns_rest PUT \
  59. "domains/$_domain/records/$_sub_domain/TXT" \
  60. "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" &&
  61. _contains "$response" '{"message": "DNS Record Created"}' &&
  62. _info "Removing record $(__green "success")"
  63. }
  64. #################### Private functions below ##################################
  65. #_acme-challenge.www.domain.com
  66. #returns
  67. # _sub_domain=_acme-challenge.www
  68. # _domain=domain.com
  69. _get_root() {
  70. domain=$1
  71. i=2
  72. p=1
  73. while true; do
  74. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  75. _debug h "$h"
  76. if [ -z "$h" ]; then
  77. #not valid
  78. return 1
  79. fi
  80. if ! _gandi_livedns_rest GET "domains/$h"; then
  81. return 1
  82. fi
  83. if _contains "$response" '"code": 401'; then
  84. _err "$response"
  85. return 1
  86. elif _contains "$response" '"code": 404'; then
  87. _debug "$h not found"
  88. else
  89. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  90. _domain="$h"
  91. return 0
  92. fi
  93. p="$i"
  94. i=$(_math "$i" + 1)
  95. done
  96. return 1
  97. }
  98. _dns_gandi_append_record() {
  99. domain=$1
  100. sub_domain=$2
  101. txtvalue=$3
  102. if _dns_gandi_existing_rrset_values "$domain" "$sub_domain"; then
  103. _debug "Appending new value"
  104. _rrset_values=$(echo "$_rrset_values" | sed "s/\"]/\",\"$txtvalue\"]/")
  105. else
  106. _debug "Creating new record" "$_rrset_values"
  107. _rrset_values="[\"$txtvalue\"]"
  108. fi
  109. _debug new_rrset_values "$_rrset_values"
  110. _gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \
  111. "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" &&
  112. _contains "$response" '{"message": "DNS Record Created"}' &&
  113. _info "Adding record $(__green "success")"
  114. }
  115. _dns_gandi_existing_rrset_values() {
  116. domain=$1
  117. sub_domain=$2
  118. if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then
  119. return 1
  120. fi
  121. if ! _contains "$response" '"rrset_type": "TXT"'; then
  122. _debug "Does not have a _acme-challenge TXT record yet."
  123. return 1
  124. fi
  125. if _contains "$response" '"rrset_values": \[\]'; then
  126. _debug "Empty rrset_values for TXT record, no previous TXT record."
  127. return 1
  128. fi
  129. _debug "Already has TXT record."
  130. _rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' |
  131. _egrep_o '\[".*\"]')
  132. return 0
  133. }
  134. _gandi_livedns_rest() {
  135. m=$1
  136. ep="$2"
  137. data="$3"
  138. _debug "$ep"
  139. export _H1="Content-Type: application/json"
  140. export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY"
  141. if [ "$m" = "GET" ]; then
  142. response="$(_get "$GANDI_LIVEDNS_API/$ep")"
  143. else
  144. _debug data "$data"
  145. response="$(_post "$data" "$GANDI_LIVEDNS_API/$ep" "" "$m")"
  146. fi
  147. if [ "$?" != "0" ]; then
  148. _err "error $ep"
  149. return 1
  150. fi
  151. _debug2 response "$response"
  152. return 0
  153. }