5 # HUAWEICLOUD_DomainName
7 iam_api
="https://iam.myhuaweicloud.com"
8 dns_api
="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
10 ######## Public functions #####################
12 # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
13 # Used to add txt record
15 # Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/zh-cn_topic_0132421999.html
17 # About "DomainName" parameters see: https://support.huaweicloud.com/api-iam/iam_01_0006.html
20 dns_huaweicloud_add
() {
24 HUAWEICLOUD_Username
="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
25 HUAWEICLOUD_Password
="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
26 HUAWEICLOUD_DomainName
="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}"
29 if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
30 _err
"Not enough information provided to dns_huaweicloud!"
34 unset token
# Clear token
35 token
="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
36 if [ -z "${token}" ]; then # Check token
37 _err
"dns_api(dns_huaweicloud): Error getting token."
40 _secure_debug
"Access token is:" "${token}"
43 zoneid
="$(_get_zoneid "${token}" "${fulldomain}")"
44 if [ -z "${zoneid}" ]; then
45 _err
"dns_api(dns_huaweicloud): Error getting zone id."
48 _debug
"Zone ID is:" "${zoneid}"
50 _debug
"Adding Record"
51 _add_record
"${token}" "${fulldomain}" "${txtvalue}"
53 if [ "${ret}" != "0" ]; then
54 _err
"dns_api(dns_huaweicloud): Error adding record."
58 # Do saving work if all succeeded
59 _saveaccountconf_mutable HUAWEICLOUD_Username
"${HUAWEICLOUD_Username}"
60 _saveaccountconf_mutable HUAWEICLOUD_Password
"${HUAWEICLOUD_Password}"
61 _saveaccountconf_mutable HUAWEICLOUD_DomainName
"${HUAWEICLOUD_DomainName}"
65 # Usage: fulldomain txtvalue
66 # Used to remove the txt record after validation
68 # Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/dns_api_64005.html
71 dns_huaweicloud_rm
() {
75 HUAWEICLOUD_Username
="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
76 HUAWEICLOUD_Password
="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
77 HUAWEICLOUD_DomainName
="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_DomainName)}"
80 if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
81 _err
"Not enough information provided to dns_huaweicloud!"
85 unset token
# Clear token
86 token
="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
87 if [ -z "${token}" ]; then # Check token
88 _err
"dns_api(dns_huaweicloud): Error getting token."
91 _secure_debug
"Access token is:" "${token}"
94 zoneid
="$(_get_zoneid "${token}" "${fulldomain}")"
95 if [ -z "${zoneid}" ]; then
96 _err
"dns_api(dns_huaweicloud): Error getting zone id."
99 _debug
"Zone ID is:" "${zoneid}"
101 record_id
="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
102 _recursive_rm_record
"${token}" "${fulldomain}" "${zoneid}" "${record_id}"
104 if [ "${ret}" != "0" ]; then
105 _err
"dns_api(dns_huaweicloud): Error removing record."
112 ################### Private functions below ##################################
114 # _recursive_rm_record
115 # remove all records from the record set
122 # Returns 0 on success
123 _recursive_rm_record
() {
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
134 # Therotically HuaweiCloud does not allow more than one record set
135 # But remove them recurringly to increase robusty
137 while [ "${_record_id}" != "0" ] && [ "${_retry_cnt}" != "0" ]; do
138 _debug
"Removing Record"
139 _retry_cnt
=$
((_retry_cnt
- 1))
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}"
145 # Check if retry count is reached
146 if [ "${_retry_cnt}" = "0" ]; then
147 _debug
"Failed to remove record after 50 attempts, please try removing it manually in the dashboard"
159 # printf "%s" "${_zoneid}"
163 export _H1
="X-Auth-Token: ${_token}"
167 h
=$
(printf "%s" "${_domain_string}" | cut
-d .
-f "$i"-100)
173 response
=$
(_get
"${dns_api}/v2/zones?name=${h}")
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 " ")
178 _debug2
"Returned Zone ID(s):" "${zoneidlist}"
179 _debug2
"Returned Zone Name(s):" "${zonenamelist}"
181 zoneidcount
=$
(echo "${zoneidlist}" |
grep -c '^')
182 _debug
"Returned Zone ID(s) Count:" "${zoneidcount}"
183 while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do
184 zoneidnum
=$
(_math
"$zoneidnum" + 1)
185 _zoneid
=$
(echo "${zoneidlist}" |
sed -n "${zoneidnum}p")
186 zonename
=$
(echo "${zonenamelist}" |
sed -n "${zoneidnum}p")
187 _debug
"Check Zone Name" "${zonename}"
188 if [ "${zonename}" = "${h}." ]; then
189 _debug
"Get Zone ID Success."
190 _debug
"ZoneID:" "${_zoneid}"
191 printf "%s" "${_zoneid}"
201 _get_recordset_id
() {
205 export _H1
="X-Auth-Token: ${_token}"
207 response
=$
(_get
"${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}")
208 if _contains
"${response}" '"id"'; then
209 _id
="$(echo "${response}" | _egrep_o "\"id
\": *\"[^
\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")"
222 # Get Existing Records
223 export _H1
="X-Auth-Token: ${_token}"
224 response
=$
(_get
"${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}")
226 _debug2
"${response}"
227 _exist_record
=$
(echo "${response}" | _egrep_o
'"records":[^]]*' |
sed 's/\"records\"\:\[//g')
228 _debug
"${_exist_record}"
230 # Check if record exist
232 if [ -z "${_exist_record}" ]; then
234 \"name\": \"${_domain}.\",
235 \"description\": \"ACME Challenge\",
239 \"\\\"${_txtvalue}\\\"\"
244 \"name\": \"${_domain}.\",
245 \"description\": \"ACME Challenge\",
249 ${_exist_record},\"\\\"${_txtvalue}\\\"\"
254 _record_id
="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
255 _debug
"Record Set ID is:" "${_record_id}"
257 # Add brand new records with all old and new records
258 export _H2
="Content-Type: application/json"
259 export _H1
="X-Auth-Token: ${_token}"
261 _debug2
"${_post_body}"
262 if [ -z "${_exist_record}" ]; then
263 _post
"${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev
/null
265 _post
"${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets/${_record_id}" false
"PUT" >/dev
/null
267 _code
="$(grep "^HTTP
" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r
\\n
")"
268 if [ "$_code" != "202" ]; then
269 _err
"dns_huaweicloud: http code ${_code}"
275 # _rm_record $token $zoneid $recordid
276 # assume ${dns_api} exist
284 export _H2
="Content-Type: application/json"
285 export _H1
="X-Auth-Token: ${_token}"
287 _post
"" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false
"DELETE" >/dev
/null
296 _debug
"Getting Token"
305 \"name\": \"${_username}\",
306 \"password\": \"${_password}\",
308 \"name\": \"${_domain_name}\"
315 \"name\": \"ap-southeast-1\"
320 export _H1
="Content-Type: application/json;charset=utf8"
321 _post
"${body}" "${iam_api}/v3/auth/tokens" >/dev
/null
322 _code
=$
(grep "^HTTP" "$HTTP_HEADER" | _tail_n
1 | cut
-d " " -f 2 |
tr -d "\\r\\n")
323 _token
=$
(grep "^X-Subject-Token" "$HTTP_HEADER" | cut
-d " " -f 2-)
324 _secure_debug
"${_code}"
325 printf "%s" "${_token}"