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.

142 lines
3.4 KiB

  1. #!/usr/bin/env sh
  2. # Vercel DNS API
  3. #
  4. # This is your API token which can be acquired on the account page.
  5. # https://vercel.com/account/tokens
  6. #
  7. # VERCEL_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
  8. VERCEL_API="https://api.vercel.com"
  9. #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
  10. dns_vercel_add() {
  11. fulldomain=$1
  12. txtvalue=$2
  13. _debug fulldomain "$fulldomain"
  14. _debug txtvalue "$txtvalue"
  15. VERCEL_TOKEN="${VERCEL_TOKEN:-$(_readaccountconf_mutable VERCEL_TOKEN)}"
  16. if [ -z "$VERCEL_TOKEN" ]; then
  17. VERCEL_TOKEN=""
  18. _err "You have not set the Vercel API token yet."
  19. _err "Please visit https://vercel.com/account/tokens to generate it."
  20. return 1
  21. fi
  22. _saveaccountconf_mutable VERCEL_TOKEN "$VERCEL_TOKEN"
  23. if ! _get_root "$fulldomain"; then
  24. _err "invalid domain"
  25. return 1
  26. fi
  27. _debug _sub_domain "$_sub_domain"
  28. _debug _domain "$_domain"
  29. _info "Adding record"
  30. if _vercel_rest POST "v2/domains/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}"; then
  31. if printf -- "%s" "$response" | grep "\"uid\":\"" >/dev/null; then
  32. _info "Added"
  33. return 0
  34. else
  35. _err "Unexpected response while adding text record."
  36. return 1
  37. fi
  38. fi
  39. _err "Add txt record error."
  40. }
  41. dns_vercel_rm() {
  42. fulldomain=$1
  43. txtvalue=$2
  44. if ! _get_root "$fulldomain"; then
  45. _err "invalid domain"
  46. return 1
  47. fi
  48. _vercel_rest GET "v2/domains/$_domain/records"
  49. count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ")
  50. if [ "$count" = "0" ]; then
  51. _info "Don't need to remove."
  52. else
  53. _record_id=$(printf "%s" "$response" | _egrep_o "\"id\":[^,]*,\"slug\":\"[^,]*\",\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\",\"value\":\"$txtvalue\"" | cut -d: -f2 | cut -d, -f1 | tr -d '"')
  54. if [ "$_record_id" ]; then
  55. echo "$_record_id" | while read -r item; do
  56. if _vercel_rest DELETE "v2/domains/$_domain/records/$item"; then
  57. _info "removed record" "$item"
  58. return 0
  59. else
  60. _err "failed to remove record" "$item"
  61. return 1
  62. fi
  63. done
  64. fi
  65. fi
  66. }
  67. #################### Private functions below ##################################
  68. #_acme-challenge.www.domain.com
  69. #returns
  70. # _sub_domain=_acme-challenge.www
  71. # _domain=domain.com
  72. _get_root() {
  73. domain="$1"
  74. ep="$2"
  75. i=1
  76. p=1
  77. while true; do
  78. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  79. if [ -z "$h" ]; then
  80. #not valid
  81. return 1
  82. fi
  83. if ! _vercel_rest GET "v4/domains/$h"; then
  84. return 1
  85. fi
  86. if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
  87. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  88. _domain=$h
  89. return 0
  90. fi
  91. p=$i
  92. i=$(_math "$i" + 1)
  93. done
  94. return 1
  95. }
  96. _vercel_rest() {
  97. m="$1"
  98. ep="$2"
  99. data="$3"
  100. path="$VERCEL_API/$ep"
  101. export _H1="Content-Type: application/json"
  102. export _H2="Authorization: Bearer $VERCEL_TOKEN"
  103. if [ "$m" != "GET" ]; then
  104. _secure_debug2 data "$data"
  105. response="$(_post "$data" "$path" "" "$m")"
  106. else
  107. response="$(_get "$path")"
  108. fi
  109. _ret="$?"
  110. _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
  111. _debug "http response code $_code"
  112. _secure_debug2 response "$response"
  113. if [ "$_ret" != "0" ]; then
  114. _err "error $ep"
  115. return 1
  116. fi
  117. response="$(printf "%s" "$response" | _normalizeJson)"
  118. return 0
  119. }