]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_clouddns.sh
Merge pull request #4531 from NCDGHA/bugfix/issue_4530_fix_http_status_503
[mirror_acme.sh.git] / dnsapi / dns_clouddns.sh
1 #!/usr/bin/env sh
2
3 # Author: Radek Sprta <sprta@vshosting.cz>
4
5 #CLOUDDNS_EMAIL=XXXXX
6 #CLOUDDNS_PASSWORD="YYYYYYYYY"
7 #CLOUDDNS_CLIENT_ID=XXXXX
8
9 CLOUDDNS_API='https://admin.vshosting.cloud/clouddns'
10 CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login'
11
12 ######## Public functions #####################
13
14 # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
15 dns_clouddns_add() {
16 fulldomain=$1
17 txtvalue=$2
18 _debug "fulldomain" "$fulldomain"
19
20 CLOUDDNS_CLIENT_ID="${CLOUDDNS_CLIENT_ID:-$(_readaccountconf_mutable CLOUDDNS_CLIENT_ID)}"
21 CLOUDDNS_EMAIL="${CLOUDDNS_EMAIL:-$(_readaccountconf_mutable CLOUDDNS_EMAIL)}"
22 CLOUDDNS_PASSWORD="${CLOUDDNS_PASSWORD:-$(_readaccountconf_mutable CLOUDDNS_PASSWORD)}"
23
24 if [ -z "$CLOUDDNS_PASSWORD" ] || [ -z "$CLOUDDNS_EMAIL" ] || [ -z "$CLOUDDNS_CLIENT_ID" ]; then
25 CLOUDDNS_CLIENT_ID=""
26 CLOUDDNS_EMAIL=""
27 CLOUDDNS_PASSWORD=""
28 _err "You didn't specify a CloudDNS password, email and client ID yet."
29 return 1
30 fi
31 if ! _contains "$CLOUDDNS_EMAIL" "@"; then
32 _err "It seems that the CLOUDDNS_EMAIL=$CLOUDDNS_EMAIL is not a valid email address."
33 _err "Please check and retry."
34 return 1
35 fi
36 # Save CloudDNS client id, email and password to config file
37 _saveaccountconf_mutable CLOUDDNS_CLIENT_ID "$CLOUDDNS_CLIENT_ID"
38 _saveaccountconf_mutable CLOUDDNS_EMAIL "$CLOUDDNS_EMAIL"
39 _saveaccountconf_mutable CLOUDDNS_PASSWORD "$CLOUDDNS_PASSWORD"
40
41 _debug "First detect the root zone"
42 if ! _get_root "$fulldomain"; then
43 _err "Invalid domain"
44 return 1
45 fi
46 _debug _domain_id "$_domain_id"
47 _debug _sub_domain "$_sub_domain"
48 _debug _domain "$_domain"
49
50 # Add TXT record
51 data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"domainId\":\"$_domain_id\"}"
52 if _clouddns_api POST "record-txt" "$data"; then
53 if _contains "$response" "$txtvalue"; then
54 _info "Added, OK"
55 elif _contains "$response" '"code":4136'; then
56 _info "Already exists, OK"
57 else
58 _err "Add TXT record error."
59 return 1
60 fi
61 fi
62
63 _debug "Publishing record changes"
64 _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}"
65 }
66
67 # Usage: rm _acme-challenge.www.domain.com
68 dns_clouddns_rm() {
69 fulldomain=$1
70 _debug "fulldomain" "$fulldomain"
71
72 CLOUDDNS_CLIENT_ID="${CLOUDDNS_CLIENT_ID:-$(_readaccountconf_mutable CLOUDDNS_CLIENT_ID)}"
73 CLOUDDNS_EMAIL="${CLOUDDNS_EMAIL:-$(_readaccountconf_mutable CLOUDDNS_EMAIL)}"
74 CLOUDDNS_PASSWORD="${CLOUDDNS_PASSWORD:-$(_readaccountconf_mutable CLOUDDNS_PASSWORD)}"
75
76 _debug "First detect the root zone"
77 if ! _get_root "$fulldomain"; then
78 _err "Invalid domain"
79 return 1
80 fi
81 _debug _domain_id "$_domain_id"
82 _debug _sub_domain "$_sub_domain"
83 _debug _domain "$_domain"
84
85 # Get record ID
86 _clouddns_api GET "domain/$_domain_id"
87 if _contains "$response" "lastDomainRecordList"; then
88 re="\"lastDomainRecordList\".*\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\","
89 _last_domains=$(echo "$response" | _egrep_o "$re")
90 re2="\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\","
91 _record_id=$(echo "$_last_domains" | _egrep_o "$re2" | _head_n 1 | cut -d : -f 2 | cut -d , -f 1 | tr -d "\"")
92 _debug _record_id "$_record_id"
93 else
94 _err "Could not retrieve record ID"
95 return 1
96 fi
97
98 _info "Removing record"
99 if _clouddns_api DELETE "record/$_record_id"; then
100 if _contains "$response" "\"error\":"; then
101 _err "Could not remove record"
102 return 1
103 fi
104 fi
105
106 _debug "Publishing record changes"
107 _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}"
108 }
109
110 #################### Private functions below ##################################
111
112 # Usage: _get_root _acme-challenge.www.domain.com
113 # Returns:
114 # _sub_domain=_acme-challenge.www
115 # _domain=domain.com
116 # _domain_id=sdjkglgdfewsdfg
117 _get_root() {
118 domain=$1
119
120 # Get domain root
121 data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}]}"
122 _clouddns_api "POST" "domain/search" "$data"
123 domain_slice="$domain"
124 while [ -z "$domain_root" ]; do
125 if _contains "$response" "\"domainName\":\"$domain_slice\.\""; then
126 domain_root="$domain_slice"
127 _debug domain_root "$domain_root"
128 fi
129 domain_slice="$(echo "$domain_slice" | cut -d . -f 2-)"
130 done
131
132 # Get domain id
133 data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}, \
134 {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}"
135 _clouddns_api "POST" "domain/search" "$data"
136 if _contains "$response" "\"id\":\""; then
137 re='domainType\":\"[^\"]*\",\"id\":\"([^\"]*)\",' # Match domain id
138 _domain_id=$(echo "$response" | _egrep_o "$re" | _head_n 1 | cut -d : -f 3 | tr -d "\",")
139 if [ "$_domain_id" ]; then
140 _sub_domain=$(printf "%s" "$domain" | sed "s/.$domain_root//")
141 _domain="$domain_root"
142 return 0
143 fi
144 _err 'Domain name not found on your CloudDNS account'
145 return 1
146 fi
147 return 1
148 }
149
150 # Usage: _clouddns_api GET domain/search '{"data": "value"}'
151 # Returns:
152 # response='{"message": "api response"}'
153 _clouddns_api() {
154 method=$1
155 endpoint="$2"
156 data="$3"
157 _debug endpoint "$endpoint"
158
159 if [ -z "$CLOUDDNS_TOKEN" ]; then
160 _clouddns_login
161 fi
162 _debug CLOUDDNS_TOKEN "$CLOUDDNS_TOKEN"
163
164 export _H1="Content-Type: application/json"
165 export _H2="Authorization: Bearer $CLOUDDNS_TOKEN"
166
167 if [ "$method" != "GET" ]; then
168 _debug data "$data"
169 response="$(_post "$data" "$CLOUDDNS_API/$endpoint" "" "$method" | tr -d '\t\r\n ')"
170 else
171 response="$(_get "$CLOUDDNS_API/$endpoint" | tr -d '\t\r\n ')"
172 fi
173
174 # shellcheck disable=SC2181
175 if [ "$?" != "0" ]; then
176 _err "Error $endpoint"
177 return 1
178 fi
179 _debug2 response "$response"
180 return 0
181 }
182
183 # Returns:
184 # CLOUDDNS_TOKEN=dslfje2rj23l
185 _clouddns_login() {
186 login_data="{\"email\": \"$CLOUDDNS_EMAIL\", \"password\": \"$CLOUDDNS_PASSWORD\"}"
187 response="$(_post "$login_data" "$CLOUDDNS_LOGIN_API" "" "POST" "Content-Type: application/json")"
188
189 if _contains "$response" "\"accessToken\":\""; then
190 CLOUDDNS_TOKEN=$(echo "$response" | _egrep_o "\"accessToken\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")
191 export CLOUDDNS_TOKEN
192 else
193 echo 'Could not get CloudDNS access token; check your credentials'
194 return 1
195 fi
196 return 0
197 }