3 # Author: Radek Sprta <sprta@vshosting.cz>
6 #CLOUDDNS_PASSWORD="YYYYYYYYY"
7 #CLOUDDNS_CLIENT_ID=XXXXX
9 CLOUDDNS_API
='https://admin.vshosting.cloud/clouddns'
10 CLOUDDNS_LOGIN_API
='https://admin.vshosting.cloud/api/public/auth/login'
12 ######## Public functions #####################
14 # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
18 _debug
"fulldomain" "$fulldomain"
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)}"
24 if [ -z "$CLOUDDNS_PASSWORD" ] ||
[ -z "$CLOUDDNS_EMAIL" ] ||
[ -z "$CLOUDDNS_CLIENT_ID" ]; then
28 _err
"You didn't specify a CloudDNS password, email and client ID yet."
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."
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"
41 _debug
"First detect the root zone"
42 if ! _get_root
"$fulldomain"; then
46 _debug _domain_id
"$_domain_id"
47 _debug _sub_domain
"$_sub_domain"
48 _debug _domain
"$_domain"
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
55 elif _contains
"$response" '"code":4136'; then
56 _info
"Already exists, OK"
58 _err
"Add TXT record error."
63 _debug
"Publishing record changes"
64 _clouddns_api PUT
"domain/$_domain_id/publish" "{\"soaTtl\":300}"
67 # Usage: rm _acme-challenge.www.domain.com
70 _debug
"fulldomain" "$fulldomain"
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)}"
76 _debug
"First detect the root zone"
77 if ! _get_root
"$fulldomain"; then
81 _debug _domain_id
"$_domain_id"
82 _debug _sub_domain
"$_sub_domain"
83 _debug _domain
"$_domain"
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"
94 _err
"Could not retrieve record ID"
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"
106 _debug
"Publishing record changes"
107 _clouddns_api PUT
"domain/$_domain_id/publish" "{\"soaTtl\":300}"
110 #################### Private functions below ##################################
112 # Usage: _get_root _acme-challenge.www.domain.com
114 # _sub_domain=_acme-challenge.www
116 # _domain_id=sdjkglgdfewsdfg
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"
129 domain_slice
="$(echo "$domain_slice" | cut -d . -f 2-)"
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"
144 _err
'Domain name not found on your CloudDNS account'
150 # Usage: _clouddns_api GET domain/search '{"data": "value"}'
152 # response='{"message": "api response"}'
157 _debug endpoint
"$endpoint"
159 if [ -z "$CLOUDDNS_TOKEN" ]; then
162 _debug CLOUDDNS_TOKEN
"$CLOUDDNS_TOKEN"
164 export _H1
="Content-Type: application/json"
165 export _H2
="Authorization: Bearer $CLOUDDNS_TOKEN"
167 if [ "$method" != "GET" ]; then
169 response
="$(_post "$data" "$CLOUDDNS_API/$endpoint" "" "$method" | tr -d '\t\r\n ')"
171 response
="$(_get "$CLOUDDNS_API/$endpoint" | tr -d '\t\r\n ')"
174 # shellcheck disable=SC2181
175 if [ "$?" != "0" ]; then
176 _err
"Error $endpoint"
179 _debug2 response
"$response"
184 # CLOUDDNS_TOKEN=dslfje2rj23l
186 login_data
="{\"email\": \"$CLOUDDNS_EMAIL\", \"password\": \"$CLOUDDNS_PASSWORD\"}"
187 response
="$(_post "$login_data" "$CLOUDDNS_LOGIN_API" "" "POST
" "Content-Type
: application
/json
")"
189 if _contains
"$response" "\"accessToken\":\""; then
190 CLOUDDNS_TOKEN
=$
(echo "$response" | _egrep_o
"\"accessToken\":\"[^\"]*\"" | cut
-d : -f 2 |
tr -d \")
191 export CLOUDDNS_TOKEN
193 echo 'Could not get CloudDNS access token; check your credentials'