5 # Author: Gerd Naschenweng
6 # https://github.com/magicdude4eva
9 # https://help.dyn.com/dns-api-knowledge-base/
11 # It is recommended to add a "Dyn Managed DNS" user specific for API access.
12 # The "Zones & Records Permissions" required by this script are:
24 # Pass credentials before "acme.sh --issue --dns dns_dyn ..."
26 # export DYN_Customer="customer"
27 # export DYN_Username="apiuser"
28 # export DYN_Password="secret"
31 DYN_API
="https://api.dynect.net/REST"
34 ######## Public functions #####################
36 #Usage: add _acme-challenge.www.domain.com "Challenge-code"
41 DYN_Customer
="${DYN_Customer:-$(_readaccountconf_mutable DYN_Customer)}"
42 DYN_Username
="${DYN_Username:-$(_readaccountconf_mutable DYN_Username)}"
43 DYN_Password
="${DYN_Password:-$(_readaccountconf_mutable DYN_Password)}"
44 if [ -z "$DYN_Customer" ] ||
[ -z "$DYN_Username" ] ||
[ -z "$DYN_Password" ]; then
48 _err
"You must export variables: DYN_Customer, DYN_Username and DYN_Password"
52 #save the config variables to the account conf file.
53 _saveaccountconf_mutable DYN_Customer
"$DYN_Customer"
54 _saveaccountconf_mutable DYN_Username
"$DYN_Username"
55 _saveaccountconf_mutable DYN_Password
"$DYN_Password"
57 if ! _dyn_get_authtoken
; then
61 if [ -z "$_dyn_authtoken" ]; then
66 if ! _dyn_get_zone
; then
71 if ! _dyn_add_record
; then
76 if ! _dyn_publish_zone
; then
86 #Usage: fulldomain txtvalue
87 #Remove the txt record after validation.
92 DYN_Customer
="${DYN_Customer:-$(_readaccountconf_mutable DYN_Customer)}"
93 DYN_Username
="${DYN_Username:-$(_readaccountconf_mutable DYN_Username)}"
94 DYN_Password
="${DYN_Password:-$(_readaccountconf_mutable DYN_Password)}"
95 if [ -z "$DYN_Customer" ] ||
[ -z "$DYN_Username" ] ||
[ -z "$DYN_Password" ]; then
99 _err
"You must export variables: DYN_Customer, DYN_Username and DYN_Password"
103 if ! _dyn_get_authtoken
; then
107 if [ -z "$_dyn_authtoken" ]; then
112 if ! _dyn_get_zone
; then
117 if ! _dyn_get_record_id
; then
122 if [ -z "$_dyn_record_id" ]; then
127 if ! _dyn_rm_record
; then
132 if ! _dyn_publish_zone
; then
142 #################### Private functions below ##################################
145 _dyn_get_authtoken
() {
147 _info
"Start Dyn API Session"
149 data
="{\"customer_name\":\"$DYN_Customer\", \"user_name\":\"$DYN_Username\", \"password\":\"$DYN_Password\"}"
150 dyn_url
="$DYN_API/Session/"
154 _debug dyn_url
"$dyn_url"
156 export _H1
="Content-Type: application/json"
158 response
="$(_post "$data" "$dyn_url" "" "$method")"
159 sessionstatus
="$(printf "%s
\n" "$response" | _egrep_o '"status
" *: *"[^
"]*' | _head_n 1 | sed 's#^"status
" *: *"##')"
161 _debug response
"$response"
162 _debug sessionstatus
"$sessionstatus"
164 if [ "$sessionstatus" = "success" ]; then
165 _dyn_authtoken
="$(printf "%s
\n" "$response" | _egrep_o '"token
" *: *"[^
"]*' | _head_n 1 | sed 's#^"token
" *: *"##')"
166 _info
"Token received"
167 _debug _dyn_authtoken
"$_dyn_authtoken"
172 _err
"get token failed"
176 #fulldomain=_acme-challenge.www.domain.com
178 # _dyn_zone=domain.com
182 domain
="$(printf "%s
" "$fulldomain" | cut -d . -f "$i-100")"
183 if [ -z "$domain" ]; then
187 dyn_url
="$DYN_API/Zone/$domain/"
189 export _H1
="Auth-Token: $_dyn_authtoken"
190 export _H2
="Content-Type: application/json"
192 response
="$(_get "$dyn_url" "" "")"
193 sessionstatus
="$(printf "%s
\n" "$response" | _egrep_o '"status
" *: *"[^
"]*' | _head_n 1 | sed 's#^"status
" *: *"##')"
195 _debug dyn_url
"$dyn_url"
196 _debug response
"$response"
197 _debug sessionstatus
"$sessionstatus"
199 if [ "$sessionstatus" = "success" ]; then
207 _err
"get zone failed"
214 _info
"Adding TXT record"
216 data
="{\"rdata\":{\"txtdata\":\"$txtvalue\"},\"ttl\":\"300\"}"
217 dyn_url
="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/"
220 export _H1
="Auth-Token: $_dyn_authtoken"
221 export _H2
="Content-Type: application/json"
223 response
="$(_post "$data" "$dyn_url" "" "$method")"
224 sessionstatus
="$(printf "%s
\n" "$response" | _egrep_o '"status
" *: *"[^
"]*' | _head_n 1 | sed 's#^"status
" *: *"##')"
226 _debug response
"$response"
227 _debug sessionstatus
"$sessionstatus"
229 if [ "$sessionstatus" = "success" ]; then
230 _info
"TXT Record successfully added"
234 _err
"add TXT record failed"
239 _dyn_publish_zone
() {
241 _info
"Publishing zone"
243 data
="{\"publish\":\"true\"}"
244 dyn_url
="$DYN_API/Zone/$_dyn_zone/"
247 export _H1
="Auth-Token: $_dyn_authtoken"
248 export _H2
="Content-Type: application/json"
250 response
="$(_post "$data" "$dyn_url" "" "$method")"
251 sessionstatus
="$(printf "%s
\n" "$response" | _egrep_o '"status
" *: *"[^
"]*' | _head_n 1 | sed 's#^"status
" *: *"##')"
253 _debug response
"$response"
254 _debug sessionstatus
"$sessionstatus"
256 if [ "$sessionstatus" = "success" ]; then
257 _info
"Zone published"
261 _err
"publish zone failed"
265 #get record_id of TXT record so we can delete the record
266 _dyn_get_record_id
() {
268 _info
"Getting record_id of TXT record"
270 dyn_url
="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/"
272 export _H1
="Auth-Token: $_dyn_authtoken"
273 export _H2
="Content-Type: application/json"
275 response
="$(_get "$dyn_url" "" "")"
276 sessionstatus
="$(printf "%s
\n" "$response" | _egrep_o '"status
" *: *"[^
"]*' | _head_n 1 | sed 's#^"status
" *: *"##')"
278 _debug response
"$response"
279 _debug sessionstatus
"$sessionstatus"
281 if [ "$sessionstatus" = "success" ]; then
282 _dyn_record_id
="$(printf "%s
\n" "$response" | _egrep_o "\"data
\" *: *\
[\"/REST
/TXTRecord
/$_dyn_zone/$fulldomain/[^
\"]*" | _head_n 1 | sed "s
#^\"data\" *: *\[\"/REST/TXTRecord/$_dyn_zone/$fulldomain/##")"
283 _debug _dyn_record_id
"$_dyn_record_id"
288 _err
"getting record_id failed"
295 _info
"Deleting TXT record"
297 dyn_url
="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/$_dyn_record_id/"
300 _debug dyn_url
"$dyn_url"
302 export _H1
="Auth-Token: $_dyn_authtoken"
303 export _H2
="Content-Type: application/json"
305 response
="$(_post "" "$dyn_url" "" "$method")"
306 sessionstatus
="$(printf "%s
\n" "$response" | _egrep_o '"status
" *: *"[^
"]*' | _head_n 1 | sed 's#^"status
" *: *"##')"
308 _debug response
"$response"
309 _debug sessionstatus
"$sessionstatus"
311 if [ "$sessionstatus" = "success" ]; then
312 _info
"TXT record successfully deleted"
316 _err
"delete TXT record failed"
323 _info
"End Dyn API Session"
325 dyn_url
="$DYN_API/Session/"
328 _debug dyn_url
"$dyn_url"
330 export _H1
="Auth-Token: $_dyn_authtoken"
331 export _H2
="Content-Type: application/json"
333 response
="$(_post "" "$dyn_url" "" "$method")"
335 _debug response
"$response"