]> git.proxmox.com Git - mirror_acme.sh.git/blame - dnsapi/dns_dnsservices.sh
Update dns_kappernet.sh
[mirror_acme.sh.git] / dnsapi / dns_dnsservices.sh
CommitLineData
688a2341
BB
1#!/usr/bin/env sh
2
3#This file name is "dns_dnsservices.sh"
04ca808e 4#Script for Danish DNS registra and DNS hosting provider https://dns.services
c8d17bc3 5
688a2341 6#Author: Bjarke Bruun <bbruun@gmail.com>
543c4423 7#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152
688a2341 8
a364ab4e 9# Global variable to connect to the DNS.Services API
688a2341
BB
10DNSServices_API=https://dns.services/api
11
12######## Public functions #####################
13
dc882e62 14#Usage: dns_dnsservices_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
688a2341 15dns_dnsservices_add() {
5c00afc6
BB
16 fulldomain="$1"
17 txtvalue="$2"
56a686d3
BB
18
19 _info "Using dns.services to create ACME DNS challenge"
20 _debug2 add_fulldomain "$fulldomain"
21 _debug2 add_txtvalue "$txtvalue"
22
23 # Read username/password from environment or .acme.sh/accounts.conf
24 DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}"
25 DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}"
26 if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
27 DnsServices_Username=""
28 DnsServices_Password=""
29 _err "You didn't specify dns.services api username and password yet."
30 _err "Set environment variables DnsServices_Username and DnsServices_Password"
31 return 1
32 fi
33
34 # Setup GET/POST/DELETE headers
35 _setup_headers
36
37 #save the credentials to the account conf file.
38 _saveaccountconf_mutable DnsServices_Username "$DnsServices_Username"
39 _saveaccountconf_mutable DnsServices_Password "$DnsServices_Password"
40
41 if ! _contains "$DnsServices_Username" "@"; then
42 _err "It seems that the username variable DnsServices_Username has not been set/left blank"
43 _err "or is not a valid email. Please correct and try again."
44 return 1
45 fi
46
47 if ! _get_root "${fulldomain}"; then
48 _err "Invalid domain ${fulldomain}"
49 return 1
50 fi
51
52 if ! createRecord "$fulldomain" "${txtvalue}"; then
53 _err "Error creating TXT record in domain $fulldomain in $rootZoneName"
54 return 1
55 fi
56
57 _debug2 challenge-created "Created $fulldomain"
58 return 0
688a2341
BB
59}
60
61#Usage: fulldomain txtvalue
62#Description: Remove the txt record after validation.
63dns_dnsservices_rm() {
5c00afc6
BB
64 fulldomain="$1"
65 txtvalue="$2"
56a686d3 66
c1ba4f1b 67 _info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue"
56a686d3
BB
68 _debug rm_fulldomain "$fulldomain"
69 _debug rm_txtvalue "$txtvalue"
70
71 # Read username/password from environment or .acme.sh/accounts.conf
72 DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}"
73 DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}"
74 if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
75 DnsServices_Username=""
76 DnsServices_Password=""
77 _err "You didn't specify dns.services api username and password yet."
78 _err "Set environment variables DnsServices_Username and DnsServices_Password"
79 return 1
80 fi
81
82 # Setup GET/POST/DELETE headers
83 _setup_headers
84
85 if ! _get_root "${fulldomain}"; then
86 _err "Invalid domain ${fulldomain}"
87 return 1
88 fi
89
90 _debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain"
91
92 if ! deleteRecord "${fulldomain}" "${txtvalue}"; then
93 _err "Error removing record: $fulldomain TXT ${txtvalue}"
94 return 1
95 fi
96
97 return 0
688a2341
BB
98}
99
100#################### Private functions below ##################################
101
102_setup_headers() {
56a686d3
BB
103 # Set up API Headers for _get() and _post()
104 # The <function>_add or <function>_rm must have been called before to work
688a2341 105
56a686d3
BB
106 if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
107 _err "Could not setup BASIC authentication headers, they are missing"
108 return 1
109 fi
688a2341 110
56a686d3
BB
111 DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)"
112 export _H1="Authorization: Basic $DnsServiceCredentials"
113 export _H2="Content-Type: application/json"
688a2341 114
56a686d3
BB
115 # Just return if headers are set
116 return 0
688a2341
BB
117}
118
119_get_root() {
5c00afc6 120 domain="$1"
56a686d3
BB
121 _debug2 _get_root "Get the root domain of ${domain} for DNS API"
122
123 # Setup _get() and _post() headers
124 #_setup_headers
125
126 result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns")
5c00afc6
BB
127 result2="$(printf "%s\n" "$result" | tr '[' '\n' | grep '"name"')"
128 result3="$(printf "%s\n" "$result2" | tr '}' '\n' | grep '"name"' | sed "s,^\,,,g" | sed "s,$,},g")"
129 useResult=""
56a686d3
BB
130 _debug2 _get_root "Got the following root domain(s) $result"
131 _debug2 _get_root "- JSON: $result"
132
5c00afc6 133 if [ "$(printf "%s\n" "$result" | tr '}' '\n' | grep -c '"name"')" -gt "1" ]; then
56a686d3
BB
134 checkMultiZones="true"
135 _debug2 _get_root "- multiple zones found"
136 else
137 checkMultiZones="false"
5c00afc6 138 _debug2 _get_root "- single zone found"
56a686d3
BB
139 fi
140
141 # Find/isolate the root zone to work with in createRecord() and deleteRecord()
142 rootZone=""
143 if [ "$checkMultiZones" = "true" ]; then
5c00afc6
BB
144 #rootZone=$(for x in $(printf "%s" "${result3}" | tr ',' '\n' | sed -n 's/.*"name":"\(.*\)",.*/\1/p'); do if [ "$(echo "$domain" | grep "$x")" != "" ]; then echo "$x"; fi; done)
145 rootZone=$(for x in $(printf "%s\n" "${result3}" | tr ',' '\n' | grep name | cut -d'"' -f4); do if [ "$(echo "$domain" | grep "$x")" != "" ]; then echo "$x"; fi; done)
146 if [ "$rootZone" != "" ]; then
147 _debug2 _rootZone "- root zone for $domain is $rootZone"
148 else
149 _err "Could not find root zone for $domain, is it correctly typed?"
150 return 1
151 fi
56a686d3 152 else
5c00afc6 153 rootZone=$(echo "$result" | tr '}' '\n' | _egrep_o '"name":"[^"]*' | cut -d'"' -f4)
56a686d3
BB
154 _debug2 _get_root "- only found 1 domain in API: $rootZone"
155 fi
156
157 if [ -z "$rootZone" ]; then
158 _err "Could not find root domain for $domain - is it correctly typed?"
159 return 1
160 fi
161
5c00afc6
BB
162 # Make sure we use the correct API zone data
163 useResult="$(printf "%s\n" "${result3}" tr ',' '\n' | grep "$rootZone")"
164 _debug2 _useResult "useResult=$useResult"
165
a364ab4e 166 # Setup variables used by other functions to communicate with DNS.Services API
5c00afc6
BB
167 #zoneInfo=$(printf "%s\n" "$useResult" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g')
168 zoneInfo=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep '"name"' | cut -d'"' -f4)
56a686d3 169 rootZoneName="$rootZone"
5c00afc6
BB
170 subDomainName="$(printf "%s\n" "$domain" | sed "s,\.$rootZone,,g")"
171 subDomainNameClean="$(printf "%s\n" "$domain" | sed "s,_acme-challenge.,,g")"
172 rootZoneDomainID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep domain_id | cut -d'"' -f4)
173 rootZoneServiceID=$(printf "%s\n" "$useResult" | tr ',' '\n' | grep service_id | cut -d'"' -f4)
56a686d3 174
ae71a5ab 175 _debug2 _zoneInfo "Zone info from API : $zoneInfo"
56a686d3
BB
176 _debug2 _get_root "Root zone name : $rootZoneName"
177 _debug2 _get_root "Root zone domain ID : $rootZoneDomainID"
178 _debug2 _get_root "Root zone service ID: $rootZoneServiceID"
179 _debug2 _get_root "Sub domain : $subDomainName"
180
181 _debug _get_root "Found valid root domain $rootZone for $subDomainNameClean"
182 return 0
688a2341
BB
183}
184
185createRecord() {
5c00afc6 186 fulldomain="$1"
56a686d3 187 txtvalue="$2"
04ca808e 188
a364ab4e 189 # Get root domain information - needed for DNS.Services API communication
56a686d3
BB
190 if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
191 _get_root "$fulldomain"
192 fi
5c00afc6
BB
193 if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
194 _err "Something happend - could not get the API zone information"
195 return 1
196 fi
04ca808e 197
56a686d3 198 _debug2 createRecord "CNAME TXT value is: $txtvalue"
04ca808e 199
56a686d3
BB
200 # Prepare data to send to API
201 data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}"
04ca808e 202
56a686d3
BB
203 _debug2 createRecord "data to API: $data"
204 result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST")
205 _debug2 createRecord "result from API: $result"
04ca808e 206
df199c57 207 if [ "$(echo "$result" | _egrep_o "\"success\":true")" = "" ]; then
56a686d3
BB
208 _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName"
209 _err "$result"
210 return 1
211 fi
04ca808e 212
56a686d3
BB
213 _info "Record \"$fulldomain TXT $txtvalue\" has been created"
214 return 0
688a2341
BB
215}
216
217deleteRecord() {
5c00afc6
BB
218 fulldomain="$1"
219 txtvalue="$2"
56a686d3 220
c1ba4f1b 221 _log deleteRecord "Deleting $fulldomain TXT $txtvalue record"
56a686d3
BB
222
223 if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
224 _get_root "$fulldomain"
225 fi
226
227 result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")"
5c00afc6
BB
228 #recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")"
229 #recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')"
230 recordID="$(printf "%s\n" "$result" | tr '}' '\n' | grep -- "$txtvalue" | tr ',' '\n' | grep '"id"' | cut -d'"' -f4)"
231 _debug2 _recordID "recordID used for deletion of record: $recordID"
56a686d3
BB
232
233 if [ -z "$recordID" ]; then
234 _info "Record $fulldomain TXT $txtvalue not found or already deleted"
235 return 0
236 else
237 _debug2 deleteRecord "Found recordID=$recordID"
238 fi
239
240 _debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID"
e4387e4a 241 _log "curl DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID"
56a686d3
BB
242 result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")"
243 _debug2 deleteRecord "API Delete result \"$result\""
e4387e4a 244 _log "curl API Delete result \"$result\""
56a686d3
BB
245
246 # Return OK regardless
247 return 0
688a2341 248}