]> git.proxmox.com Git - mirror_acme.sh.git/blame - dnsapi/dns_clouddns.sh
Merge pull request #4820 from acmesh-official/dev
[mirror_acme.sh.git] / dnsapi / dns_clouddns.sh
CommitLineData
e7d130cc
RS
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
9CLOUDDNS_API='https://admin.vshosting.cloud/clouddns'
10CLOUDDNS_LOGIN_API='https://admin.vshosting.cloud/api/public/auth/login'
11
12######## Public functions #####################
13
36e0feea 14# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
e7d130cc
RS
15dns_clouddns_add() {
16 fulldomain=$1
17 txtvalue=$2
36e0feea 18 _debug "fulldomain" "$fulldomain"
e7d130cc
RS
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=""
36e0feea 28 _err "You didn't specify a CloudDNS password, email and client ID yet."
e7d130cc
RS
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
23f26770
RS
50 # Add TXT record
51 data="{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"value\":\"$txtvalue\",\"domainId\":\"$_domain_id\"}"
52 if _clouddns_api POST "record-txt" "$data"; then
e7d130cc
RS
53 if _contains "$response" "$txtvalue"; then
54 _info "Added, OK"
55 elif _contains "$response" '"code":4136'; then
56 _info "Already exists, OK"
57 else
36e0feea 58 _err "Add TXT record error."
e7d130cc
RS
59 return 1
60 fi
61 fi
62
e7d130cc
RS
63 _debug "Publishing record changes"
64 _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}"
65}
66
36e0feea 67# Usage: rm _acme-challenge.www.domain.com
e7d130cc
RS
68dns_clouddns_rm() {
69 fulldomain=$1
36e0feea 70 _debug "fulldomain" "$fulldomain"
e7d130cc
RS
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
36e0feea 78 _err "Invalid domain"
e7d130cc
RS
79 return 1
80 fi
81 _debug _domain_id "$_domain_id"
82 _debug _sub_domain "$_sub_domain"
83 _debug _domain "$_domain"
84
36e0feea 85 # Get record ID
23f26770 86 _clouddns_api GET "domain/$_domain_id"
e7d130cc 87 if _contains "$response" "lastDomainRecordList"; then
5c7feba7 88 re="\"lastDomainRecordList\".*\"id\":\"([^\"}]*)\"[^}]*\"name\":\"$fulldomain.\","
e7d130cc
RS
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
36e0feea 94 _err "Could not retrieve record ID"
e7d130cc
RS
95 return 1
96 fi
5c7feba7 97
e7d130cc
RS
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
e7d130cc
RS
106 _debug "Publishing record changes"
107 _clouddns_api PUT "domain/$_domain_id/publish" "{\"soaTtl\":300}"
108}
109
110#################### Private functions below ##################################
36e0feea
RS
111
112# Usage: _get_root _acme-challenge.www.domain.com
113# Returns:
e7d130cc
RS
114# _sub_domain=_acme-challenge.www
115# _domain=domain.com
116# _domain_id=sdjkglgdfewsdfg
117_get_root() {
118 domain=$1
69392f67
RS
119
120 # Get domain root
121 data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}]}"
5c7feba7 122 _clouddns_api "POST" "domain/search" "$data"
69392f67
RS
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
e7d130cc
RS
131
132 # Get domain id
133 data="{\"search\": [{\"name\": \"clientId\", \"operator\": \"eq\", \"value\": \"$CLOUDDNS_CLIENT_ID\"}, \
36e0feea 134 {\"name\": \"domainName\", \"operator\": \"eq\", \"value\": \"$domain_root.\"}]}"
23f26770 135 _clouddns_api "POST" "domain/search" "$data"
e7d130cc
RS
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
36e0feea
RS
150# Usage: _clouddns_api GET domain/search '{"data": "value"}'
151# Returns:
152# response='{"message": "api response"}'
e7d130cc
RS
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"
23f26770 169 response="$(_post "$data" "$CLOUDDNS_API/$endpoint" "" "$method" | tr -d '\t\r\n ')"
e7d130cc 170 else
23f26770 171 response="$(_get "$CLOUDDNS_API/$endpoint" | tr -d '\t\r\n ')"
e7d130cc
RS
172 fi
173
6b675117 174 # shellcheck disable=SC2181
e7d130cc 175 if [ "$?" != "0" ]; then
36e0feea 176 _err "Error $endpoint"
e7d130cc
RS
177 return 1
178 fi
23f26770 179 _debug2 response "$response"
e7d130cc
RS
180 return 0
181}
182
36e0feea
RS
183# Returns:
184# CLOUDDNS_TOKEN=dslfje2rj23l
e7d130cc
RS
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")"
e7d130cc
RS
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}