]> git.proxmox.com Git - mirror_acme.sh.git/blame - dnsapi/dns_huaweicloud.sh
fix: fix shfmt
[mirror_acme.sh.git] / dnsapi / dns_huaweicloud.sh
CommitLineData
b8e5c0d8
EM
1#!/usr/bin/env sh
2
3# HUAWEICLOUD_Username
4# HUAWEICLOUD_Password
789ebb89 5# HUAWEICLOUD_DomainName
6
b8e5c0d8 7iam_api="https://iam.myhuaweicloud.com"
86639dbc 8dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
b8e5c0d8
EM
9
10######## Public functions #####################
11
12# Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
13# Used to add txt record
14#
15# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/zh-cn_topic_0132421999.html
16#
789ebb89 17# About "DomainName" parameters see: https://support.huaweicloud.com/api-iam/iam_01_0006.html
18#
b8e5c0d8
EM
19
20dns_huaweicloud_add() {
21 fulldomain=$1
22 txtvalue=$2
23
24 HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
25 HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
789ebb89 26 HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
b8e5c0d8 27
c4ddddd4 28 # Check information
789ebb89 29 if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
c4ddddd4 30 _err "Not enough information provided to dns_huaweicloud!"
f6f6550b
EM
31 return 1
32 fi
33
86639dbc 34 unset token # Clear token
789ebb89 35 token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
86639dbc
EM
36 if [ -z "${token}" ]; then # Check token
37 _err "dns_api(dns_huaweicloud): Error getting token."
38 return 1
39 fi
9d2ee212 40 _secure_debug "Access token is:" "${token}"
86639dbc
EM
41
42 unset zoneid
b8e5c0d8 43 zoneid="$(_get_zoneid "${token}" "${fulldomain}")"
86639dbc
EM
44 if [ -z "${zoneid}" ]; then
45 _err "dns_api(dns_huaweicloud): Error getting zone id."
46 return 1
47 fi
9d2ee212 48 _debug "Zone ID is:" "${zoneid}"
b8e5c0d8
EM
49
50 _debug "Adding Record"
51 _add_record "${token}" "${fulldomain}" "${txtvalue}"
52 ret="$?"
53 if [ "${ret}" != "0" ]; then
86639dbc 54 _err "dns_api(dns_huaweicloud): Error adding record."
b8e5c0d8
EM
55 return 1
56 fi
57
58 # Do saving work if all succeeded
59 _saveaccountconf_mutable HUAWEICLOUD_Username "${HUAWEICLOUD_Username}"
60 _saveaccountconf_mutable HUAWEICLOUD_Password "${HUAWEICLOUD_Password}"
789ebb89 61 _saveaccountconf_mutable HUAWEICLOUD_DomainName "${HUAWEICLOUD_DomainName}"
b8e5c0d8
EM
62 return 0
63}
64
65# Usage: fulldomain txtvalue
66# Used to remove the txt record after validation
67#
68# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/dns_api_64005.html
69#
70
71dns_huaweicloud_rm() {
72 fulldomain=$1
73 txtvalue=$2
74
75 HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
76 HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
789ebb89 77 HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
b8e5c0d8 78
c4ddddd4 79 # Check information
789ebb89 80 if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
c4ddddd4 81 _err "Not enough information provided to dns_huaweicloud!"
e01fb503
EM
82 return 1
83 fi
84
86639dbc 85 unset token # Clear token
789ebb89 86 token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
86639dbc
EM
87 if [ -z "${token}" ]; then # Check token
88 _err "dns_api(dns_huaweicloud): Error getting token."
89 return 1
90 fi
9d2ee212 91 _secure_debug "Access token is:" "${token}"
86639dbc
EM
92
93 unset zoneid
b8e5c0d8 94 zoneid="$(_get_zoneid "${token}" "${fulldomain}")"
86639dbc
EM
95 if [ -z "${zoneid}" ]; then
96 _err "dns_api(dns_huaweicloud): Error getting zone id."
97 return 1
98 fi
9d2ee212 99 _debug "Zone ID is:" "${zoneid}"
7db592d2 100
0cce2d60 101 record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
acbd8bce
EM
102 _recursive_rm_record "${token}" "${fulldomain}" "${zoneid}" "${record_id}"
103 ret="$?"
104 if [ "${ret}" != "0" ]; then
105 _err "dns_api(dns_huaweicloud): Error removing record."
106 return 1
107 fi
4dba84d0 108
acbd8bce
EM
109 return 0
110}
111
112################### Private functions below ##################################
113
acbd8bce
EM
114# _recursive_rm_record
115# remove all records from the record set
4dba84d0 116#
acbd8bce
EM
117# _token=$1
118# _domain=$2
119# _zoneid=$3
120# _record_id=$4
121#
122# Returns 0 on success
123_recursive_rm_record() {
124 _token=$1
125 _domain=$2
126 _zoneid=$3
127 _record_id=$4
128
129 # Most likely to have problems will huaweicloud side if more than 50 attempts but still cannot fully remove the record set
130 # Maybe can be removed manually in the dashboard
131 _retry_cnt=50
132
7db592d2 133 # Remove all records
c4ddddd4
EM
134 # Therotically HuaweiCloud does not allow more than one record set
135 # But remove them recurringly to increase robusty
acbd8bce 136
0cce2d60 137 while [ "${_record_id}" != "0" ] && [ "${_retry_cnt}" != "0" ]; do
28ce1c12 138 _debug "Removing Record"
0cce2d60 139 _retry_cnt=$((_retry_cnt - 1))
acbd8bce
EM
140 _rm_record "${_token}" "${_zoneid}" "${_record_id}"
141 _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${_zoneid}")"
142 _debug2 "Checking record exists: record_id=${_record_id}"
b8e5c0d8 143 done
acbd8bce
EM
144
145 # Check if retry count is reached
0cce2d60 146 if [ "${_retry_cnt}" = "0" ]; then
acbd8bce
EM
147 _debug "Failed to remove record after 50 attempts, please try removing it manually in the dashboard"
148 return 1
149 fi
150
b8e5c0d8
EM
151 return 0
152}
153
b8e5c0d8
EM
154# _get_zoneid
155#
156# _token=$1
157# _domain_string=$2
158#
159# printf "%s" "${_zoneid}"
160_get_zoneid() {
161 _token=$1
162 _domain_string=$2
163 export _H1="X-Auth-Token: ${_token}"
164
165 i=1
166 while true; do
0cce2d60 167 h=$(printf "%s" "${_domain_string}" | cut -d . -f "$i"-100)
b8e5c0d8
EM
168 if [ -z "$h" ]; then
169 #not valid
170 return 1
171 fi
172 _debug "$h"
173 response=$(_get "${dns_api}/v2/zones?name=${h}")
9d2ee212 174 _debug2 "$response"
e49ece87
YM
175 if _contains "${response}" '"id"'; then
176 zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
177 zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
9d2ee212
YM
178 _debug2 "Return Zone ID(s):" "${zoneidlist}"
179 _debug2 "Return Zone Name(s):" "${zonenamelist}"
e49ece87 180 zoneidnum=0
9088c874
YM
181 zoneidcount=$(echo "${zoneidlist}" | grep -c '^')
182 _debug "Retund Zone ID(s) Count:" "${zoneidcount}"
183 while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do
e49ece87 184 zoneidnum=$(_math "$zoneidnum" + 1)
9088c874
YM
185 _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p")
186 zonename=$(echo "${zonenamelist}" | sed -n "${zoneidnum}p")
9d2ee212 187 _debug "Check Zone Name" "${zonename}"
e49ece87
YM
188 if [ "${zonename}" = "${h}." ]; then
189 _debug "Get Zone ID Success."
9088c874 190 _debug "ZoneID:" "${_zoneid}"
e49ece87
YM
191 printf "%s" "${_zoneid}"
192 return 0
193 fi
194 done
b8e5c0d8 195 fi
b8e5c0d8
EM
196 i=$(_math "$i" + 1)
197 done
198 return 1
199}
200
201_get_recordset_id() {
202 _token=$1
203 _domain=$2
204 _zoneid=$3
205 export _H1="X-Auth-Token: ${_token}"
206
207 response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}")
e49ece87 208 if _contains "${response}" '"id"'; then
b8e5c0d8
EM
209 _id="$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")"
210 printf "%s" "${_id}"
211 return 0
212 fi
213 printf "%s" "0"
214 return 1
215}
216
217_add_record() {
218 _token=$1
219 _domain=$2
220 _txtvalue=$3
f6f6550b
EM
221
222 # Get Existing Records
223 export _H1="X-Auth-Token: ${_token}"
5d0657c4
EM
224 response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}")
225
c4ddddd4 226 _debug2 "${response}"
fd511966 227 _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g')
f6f6550b
EM
228 _debug "${_exist_record}"
229
230 # Check if record exist
231 # Generate body data
f6f6550b 232 if [ -z "${_exist_record}" ]; then
5d0657c4 233 _post_body="{
f6f6550b
EM
234 \"name\": \"${_domain}.\",
235 \"description\": \"ACME Challenge\",
236 \"type\": \"TXT\",
237 \"ttl\": 1,
238 \"records\": [
239 \"\\\"${_txtvalue}\\\"\"
240 ]
241 }"
c4ddddd4
EM
242 else
243 _post_body="{
244 \"name\": \"${_domain}.\",
245 \"description\": \"ACME Challenge\",
246 \"type\": \"TXT\",
247 \"ttl\": 1,
248 \"records\": [
249 ${_exist_record},
250 \"\\\"${_txtvalue}\\\"\"
251 ]
252 }"
f6f6550b 253 fi
5d0657c4
EM
254
255 _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
9d2ee212 256 _debug "Record Set ID is:" "${_record_id}"
5d0657c4
EM
257
258 # Remove all records
acbd8bce
EM
259 _recursive_rm_record "${token}" "${_domain}" "${_zoneid}" "${_record_id}"
260 ret="$?"
261 if [ "${ret}" != "0" ]; then
262 return 1
263 fi
5d0657c4
EM
264
265 # Add brand new records with all old and new records
b8e5c0d8
EM
266 export _H2="Content-Type: application/json"
267 export _H1="X-Auth-Token: ${_token}"
268
c4ddddd4 269 _debug2 "${_post_body}"
5d0657c4 270 _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
b8e5c0d8
EM
271 _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
272 if [ "$_code" != "202" ]; then
273 _err "dns_huaweicloud: http code ${_code}"
274 return 1
275 fi
276 return 0
277}
278
5d0657c4
EM
279# _rm_record $token $zoneid $recordid
280# assume ${dns_api} exist
281# no output
282# return 0
b8e5c0d8
EM
283_rm_record() {
284 _token=$1
285 _zone_id=$2
286 _record_id=$3
287
288 export _H2="Content-Type: application/json"
289 export _H1="X-Auth-Token: ${_token}"
290
5d0657c4
EM
291 _post "" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null
292 return $?
b8e5c0d8
EM
293}
294
295_get_token() {
296 _username=$1
297 _password=$2
789ebb89 298 _domain_name=$3
b8e5c0d8
EM
299
300 _debug "Getting Token"
301 body="{
302 \"auth\": {
303 \"identity\": {
304 \"methods\": [
305 \"password\"
306 ],
307 \"password\": {
308 \"user\": {
309 \"name\": \"${_username}\",
310 \"password\": \"${_password}\",
311 \"domain\": {
789ebb89 312 \"name\": \"${_domain_name}\"
b8e5c0d8
EM
313 }
314 }
315 }
316 },
317 \"scope\": {
318 \"project\": {
789ebb89 319 \"name\": \"ap-southeast-1\"
b8e5c0d8
EM
320 }
321 }
322 }
323 }"
324 export _H1="Content-Type: application/json;charset=utf8"
325 _post "${body}" "${iam_api}/v3/auth/tokens" >/dev/null
326 _code=$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")
327 _token=$(grep "^X-Subject-Token" "$HTTP_HEADER" | cut -d " " -f 2-)
9d2ee212 328 _secure_debug "${_code}"
b8e5c0d8
EM
329 printf "%s" "${_token}"
330 return 0
331}