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.

168 lines
4.3 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #!/usr/bin/env sh
  2. # shellcheck disable=SC2034
  3. dns_netlify_info='Netlify.com
  4. Site: Netlify.com
  5. Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi2#dns_netlify
  6. Options:
  7. NETLIFY_ACCESS_TOKEN API Token
  8. Issues: github.com/acmesh-official/acme.sh/issues/3088
  9. '
  10. NETLIFY_HOST="api.netlify.com/api/v1/"
  11. NETLIFY_URL="https://$NETLIFY_HOST"
  12. ######## Public functions #####################
  13. #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  14. dns_netlify_add() {
  15. fulldomain=$1
  16. txtvalue=$2
  17. NETLIFY_ACCESS_TOKEN="${NETLIFY_ACCESS_TOKEN:-$(_readaccountconf_mutable NETLIFY_ACCESS_TOKEN)}"
  18. if [ -z "$NETLIFY_ACCESS_TOKEN" ]; then
  19. NETLIFY_ACCESS_TOKEN=""
  20. _err "Please specify your Netlify Access Token and try again."
  21. return 1
  22. else
  23. _saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
  24. fi
  25. _info "Using Netlify"
  26. _debug fulldomain "$fulldomain"
  27. _debug txtvalue "$txtvalue"
  28. if ! _get_root "$fulldomain"; then
  29. _err "invalid domain"
  30. return 1
  31. fi
  32. _debug _domain_id "$_domain_id"
  33. _debug _sub_domain "$_sub_domain"
  34. _debug _domain "$_domain"
  35. dnsRecordURI="dns_zones/$_domain_id/dns_records"
  36. body="{\"type\":\"TXT\", \"hostname\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"ttl\":\"10\"}"
  37. _netlify_rest POST "$dnsRecordURI" "$body" "$NETLIFY_ACCESS_TOKEN"
  38. _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
  39. if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
  40. _info "validation value added"
  41. return 0
  42. else
  43. _err "error adding validation value ($_code)"
  44. return 1
  45. fi
  46. _err "Not fully implemented!"
  47. return 1
  48. }
  49. #Usage: dns_myapi_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  50. #Remove the txt record after validation.
  51. dns_netlify_rm() {
  52. _info "Using Netlify"
  53. txtdomain="$1"
  54. txt="$2"
  55. _debug txtdomain "$txtdomain"
  56. _debug txt "$txt"
  57. NETLIFY_ACCESS_TOKEN="${NETLIFY_ACCESS_TOKEN:-$(_readaccountconf_mutable NETLIFY_ACCESS_TOKEN)}"
  58. if ! _get_root "$txtdomain"; then
  59. _err "invalid domain"
  60. return 1
  61. fi
  62. _debug _domain_id "$_domain_id"
  63. _debug _sub_domain "$_sub_domain"
  64. _debug _domain "$_domain"
  65. dnsRecordURI="dns_zones/$_domain_id/dns_records"
  66. _netlify_rest GET "$dnsRecordURI" "" "$NETLIFY_ACCESS_TOKEN"
  67. _record_id=$(echo "$response" | _egrep_o "\"type\":\"TXT\",[^\}]*\"value\":\"$txt\"" | head -n 1 | _egrep_o "\"id\":\"[^\"\}]*\"" | cut -d : -f 2 | tr -d \")
  68. _debug _record_id "$_record_id"
  69. if [ "$_record_id" ]; then
  70. _netlify_rest DELETE "$dnsRecordURI/$_record_id" "" "$NETLIFY_ACCESS_TOKEN"
  71. _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
  72. if [ "$_code" = "200" ] || [ "$_code" = '204' ]; then
  73. _info "validation value removed"
  74. return 0
  75. else
  76. _err "error removing validation value ($_code)"
  77. return 1
  78. fi
  79. return 0
  80. fi
  81. return 1
  82. }
  83. #################### Private functions below ##################################
  84. _get_root() {
  85. domain=$1
  86. accesstoken=$2
  87. i=1
  88. p=1
  89. _netlify_rest GET "dns_zones" "" "$accesstoken"
  90. while true; do
  91. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  92. _debug2 "Checking domain: $h"
  93. if [ -z "$h" ]; then
  94. #not valid
  95. _err "Invalid domain"
  96. return 1
  97. fi
  98. if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
  99. _domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h\"" | cut -d , -f 1 | tr -d \")
  100. if [ "$_domain_id" ]; then
  101. if [ "$i" = 1 ]; then
  102. #create the record at the domain apex (@) if only the domain name was provided as --domain-alias
  103. _sub_domain="@"
  104. else
  105. _sub_domain=$(echo "$domain" | cut -d . -f 1-$p)
  106. fi
  107. _domain=$h
  108. return 0
  109. fi
  110. return 1
  111. fi
  112. p=$i
  113. i=$(_math "$i" + 1)
  114. done
  115. return 1
  116. }
  117. _netlify_rest() {
  118. m=$1
  119. ep="$2"
  120. data="$3"
  121. _debug "$ep"
  122. token_trimmed=$(echo "$NETLIFY_ACCESS_TOKEN" | tr -d '"')
  123. export _H1="Content-Type: application/json"
  124. export _H2="Authorization: Bearer $token_trimmed"
  125. : >"$HTTP_HEADER"
  126. if [ "$m" != "GET" ]; then
  127. _debug data "$data"
  128. response="$(_post "$data" "$NETLIFY_URL$ep" "" "$m")"
  129. else
  130. response="$(_get "$NETLIFY_URL$ep")"
  131. fi
  132. if [ "$?" != "0" ]; then
  133. _err "error $ep"
  134. return 1
  135. fi
  136. _debug2 response "$response"
  137. return 0
  138. }