]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_dgon.sh
Merge pull request #746 from Neilpang/dev
[mirror_acme.sh.git] / dnsapi / dns_dgon.sh
1 #!/usr/bin/env sh
2
3 ## Will be called by acme.sh to add the txt record to your api system.
4 ## returns 0 means success, otherwise error.
5
6 ## Author: thewer <github at thewer.com>
7 ## GitHub: https://github.com/gitwer/acme.sh
8
9 ##
10 ## Environment Variables Required:
11 ##
12 ## DO_API_KEY="75310dc4ca779ac39a19f6355db573b49ce92ae126553ebd61ac3a3ae34834cc"
13 ##
14
15 ##################### Public functions #####################
16
17 ## Create the text record for validation.
18 ## Usage: fulldomain txtvalue
19 ## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
20 dns_dgon_add() {
21 fulldomain="$(echo "$1" | _lower_case)"
22 txtvalue=$2
23 _info "Using digitalocean dns validation - add record"
24 _debug fulldomain "$fulldomain"
25 _debug txtvalue "$txtvalue"
26
27 ## save the env vars (key and domain split location) for later automated use
28 _saveaccountconf DO_API_KEY "$DO_API_KEY"
29
30 ## split the domain for DO API
31 if ! _get_base_domain "$fulldomain"; then
32 _err "domain not found in your account for addition"
33 return 1
34 fi
35 _debug _sub_domain "$_sub_domain"
36 _debug _domain "$_domain"
37
38 ## Set the header with our post type and key auth key
39 export _H1="Content-Type: application/json"
40 export _H2="Authorization: Bearer $DO_API_KEY"
41 PURL='https://api.digitalocean.com/v2/domains/'$_domain'/records'
42 PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'"}'
43
44 _debug PURL "$PURL"
45 _debug PBODY "$PBODY"
46
47 ## the create request - post
48 ## args: BODY, URL, [need64, httpmethod]
49 response="$(_post "$PBODY" "$PURL")"
50
51 ## check response
52 if [ "$?" != "0" ]; then
53 _err "error in response: $response"
54 return 1
55 fi
56 _debug2 response "$response"
57
58 ## finished correctly
59 return 0
60 }
61
62 ## Remove the txt record after validation.
63 ## Usage: fulldomain txtvalue
64 ## EG: "_acme-challenge.www.other.domain.com" "XKrxpRBosdq0HG9i01zxXp5CPBs"
65 dns_dgon_rm() {
66 fulldomain="$(echo "$1" | _lower_case)"
67 txtvalue=$2
68 _info "Using digitalocean dns validation - remove record"
69 _debug fulldomain "$fulldomain"
70 _debug txtvalue "$txtvalue"
71
72 ## split the domain for DO API
73 if ! _get_base_domain "$fulldomain"; then
74 _err "domain not found in your account for removal"
75 return 1
76 fi
77 _debug _sub_domain "$_sub_domain"
78 _debug _domain "$_domain"
79
80 ## Set the header with our post type and key auth key
81 export _H1="Content-Type: application/json"
82 export _H2="Authorization: Bearer $DO_API_KEY"
83 ## get URL for the list of domains
84 ## may get: "links":{"pages":{"last":".../v2/domains/DOM/records?page=2","next":".../v2/domains/DOM/records?page=2"}}
85 GURL="https://api.digitalocean.com/v2/domains/$_domain/records"
86
87 ## while we dont have a record ID we keep going
88 while [ -z "$record" ]; do
89 ## 1) get the URL
90 ## the create request - get
91 ## args: URL, [onlyheader, timeout]
92 domain_list="$(_get "$GURL")"
93 ## 2) find record
94 ## check for what we are looing for: "type":"A","name":"$_sub_domain"
95 record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*\d+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
96 ## 3) check record and get next page
97 if [ -z "$record" ]; then
98 ## find the next page if we dont have a match
99 nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=\d+")"
100 if [ -z "$nextpage" ]; then
101 _err "no record and no nextpage in digital ocean DNS removal"
102 return 1
103 fi
104 _debug2 nextpage "$nextpage"
105 GURL="$nextpage"
106 fi
107 ## we break out of the loop when we have a record
108 done
109
110 ## we found the record
111 rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*\d+" | _egrep_o "\d+")"
112 _debug rec_id "$rec_id"
113
114 ## delete the record
115 ## delete URL for removing the one we dont want
116 DURL="https://api.digitalocean.com/v2/domains/$_domain/records/$rec_id"
117
118 ## the create request - delete
119 ## args: BODY, URL, [need64, httpmethod]
120 response="$(_post "" "$DURL" "" "DELETE")"
121
122 ## check response (sort of)
123 if [ "$?" != "0" ]; then
124 _err "error in remove response: $response"
125 return 1
126 fi
127 _debug2 response "$response"
128
129 ## finished correctly
130 return 0
131 }
132
133 ##################### Private functions below #####################
134
135 ## Split the domain provided into the "bade domain" and the "start prefix".
136 ## This function searches for the longest subdomain in your account
137 ## for the full domain given and splits it into the base domain (zone)
138 ## and the prefix/record to be added/removed
139 ## USAGE: fulldomain
140 ## EG: "_acme-challenge.two.three.four.domain.com"
141 ## returns
142 ## _sub_domain="_acme-challenge.two"
143 ## _domain="three.four.domain.com" *IF* zone "three.four.domain.com" exists
144 ## if only "domain.com" exists it will return
145 ## _sub_domain="_acme-challenge.two.three.four"
146 ## _domain="domain.com"
147 _get_base_domain() {
148 # args
149 fulldomain="$(echo "$1" | tr '[:upper:]' '[:lower:]')"
150 _debug fulldomain "$fulldomain"
151
152 # domain max legal length = 253
153 MAX_DOM=255
154
155 ## get a list of domains for the account to check thru
156 ## Set the headers
157 export _H1="Content-Type: application/json"
158 export _H2="Authorization: Bearer $DO_API_KEY"
159 _debug DO_API_KEY "$DO_API_KEY"
160 ## get URL for the list of domains
161 ## havent seen this request paginated, tested with 18 domains (more requires manual requests with DO)
162 DOMURL="https://api.digitalocean.com/v2/domains"
163
164 ## get the domain list (DO gives basically a full XFER!)
165 domain_list="$(_get "$DOMURL")"
166
167 ## check response
168 if [ "$?" != "0" ]; then
169 _err "error in domain_list response: $domain_list"
170 return 1
171 fi
172 _debug2 domain_list "$domain_list"
173
174 ## for each shortening of our $fulldomain, check if it exists in the $domain_list
175 ## can never start on 1 (aka whole $fulldomain) as $fulldomain starts with "_acme-challenge"
176 i=2
177 while [ $i -gt 0 ]; do
178 ## get next longest domain
179 _domain=$(printf "%s" "$fulldomain" | cut -d . -f "$i"-"$MAX_DOM")
180 ## check we got something back from our cut (or are we at the end)
181 if [ -z "$_domain" ]; then
182 ## we got to the end of the domain - invalid domain
183 _err "domain not found in DigitalOcean account"
184 return 1
185 fi
186 ## we got part of a domain back - grep it out
187 found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")"
188 ## check if it exists
189 if [ ! -z "$found" ]; then
190 ## exists - exit loop returning the parts
191 sub_point=$(_math $i - 1)
192 _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
193 _debug _domain "$_domain"
194 _debug _sub_domain "$_sub_domain"
195 return 0
196 fi
197 ## increment cut point $i
198 i=$(_math $i + 1)
199 done
200
201 ## we went through the entire domain zone list and dint find one that matched
202 ## doesnt look like we can add in the record
203 _err "domain not found in DigitalOcean account, but we should never get here"
204 return 1
205 }