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