]> git.proxmox.com Git - mirror_acme.sh.git/blame_incremental - dnsapi/dns_huaweicloud.sh
added missing new line at EOF
[mirror_acme.sh.git] / dnsapi / dns_huaweicloud.sh
... / ...
CommitLineData
1#!/usr/bin/env sh
2
3# HUAWEICLOUD_Username
4# HUAWEICLOUD_Password
5# HUAWEICLOUD_DomainName
6
7iam_api="https://iam.myhuaweicloud.com"
8dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
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#
17# About "DomainName" parameters see: https://support.huaweicloud.com/api-iam/iam_01_0006.html
18#
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)}"
26 HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
27
28 # Check information
29 if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
30 _err "Not enough information provided to dns_huaweicloud!"
31 return 1
32 fi
33
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."
38 return 1
39 fi
40 _secure_debug "Access token is:" "${token}"
41
42 unset zoneid
43 zoneid="$(_get_zoneid "${token}" "${fulldomain}")"
44 if [ -z "${zoneid}" ]; then
45 _err "dns_api(dns_huaweicloud): Error getting zone id."
46 return 1
47 fi
48 _debug "Zone ID is:" "${zoneid}"
49
50 _debug "Adding Record"
51 _add_record "${token}" "${fulldomain}" "${txtvalue}"
52 ret="$?"
53 if [ "${ret}" != "0" ]; then
54 _err "dns_api(dns_huaweicloud): Error adding record."
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}"
61 _saveaccountconf_mutable HUAWEICLOUD_DomainName "${HUAWEICLOUD_DomainName}"
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)}"
77 HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
78
79 # Check information
80 if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
81 _err "Not enough information provided to dns_huaweicloud!"
82 return 1
83 fi
84
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."
89 return 1
90 fi
91 _secure_debug "Access token is:" "${token}"
92
93 unset zoneid
94 zoneid="$(_get_zoneid "${token}" "${fulldomain}")"
95 if [ -z "${zoneid}" ]; then
96 _err "dns_api(dns_huaweicloud): Error getting zone id."
97 return 1
98 fi
99 _debug "Zone ID is:" "${zoneid}"
100
101 # Remove all records
102 # Therotically HuaweiCloud does not allow more than one record set
103 # But remove them recurringly to increase robusty
104 while [ "${record_id}" != "0" ]; do
105 _debug "Removing Record"
106 _rm_record "${token}" "${zoneid}" "${record_id}"
107 record_id="$(_get_recordset_id "${token}" "${fulldomain}" "${zoneid}")"
108 done
109 return 0
110}
111
112################### Private functions below ##################################
113
114# _get_zoneid
115#
116# _token=$1
117# _domain_string=$2
118#
119# printf "%s" "${_zoneid}"
120_get_zoneid() {
121 _token=$1
122 _domain_string=$2
123 export _H1="X-Auth-Token: ${_token}"
124
125 i=1
126 while true; do
127 h=$(printf "%s" "${_domain_string}" | cut -d . -f $i-100)
128 if [ -z "$h" ]; then
129 #not valid
130 return 1
131 fi
132 _debug "$h"
133 response=$(_get "${dns_api}/v2/zones?name=${h}")
134 _debug2 "$response"
135 if _contains "${response}" '"id"'; then
136 zoneidlist=$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
137 zonenamelist=$(echo "${response}" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")
138 _debug2 "Return Zone ID(s):" "${zoneidlist}"
139 _debug2 "Return Zone Name(s):" "${zonenamelist}"
140 zoneidnum=0
141 zoneidcount=$(echo "${zoneidlist}" | grep -c '^')
142 _debug "Retund Zone ID(s) Count:" "${zoneidcount}"
143 while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do
144 zoneidnum=$(_math "$zoneidnum" + 1)
145 _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p")
146 zonename=$(echo "${zonenamelist}" | sed -n "${zoneidnum}p")
147 _debug "Check Zone Name" "${zonename}"
148 if [ "${zonename}" = "${h}." ]; then
149 _debug "Get Zone ID Success."
150 _debug "ZoneID:" "${_zoneid}"
151 printf "%s" "${_zoneid}"
152 return 0
153 fi
154 done
155 fi
156 i=$(_math "$i" + 1)
157 done
158 return 1
159}
160
161_get_recordset_id() {
162 _token=$1
163 _domain=$2
164 _zoneid=$3
165 export _H1="X-Auth-Token: ${_token}"
166
167 response=$(_get "${dns_api}/v2/zones/${_zoneid}/recordsets?name=${_domain}")
168 if _contains "${response}" '"id"'; then
169 _id="$(echo "${response}" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | tr -d " ")"
170 printf "%s" "${_id}"
171 return 0
172 fi
173 printf "%s" "0"
174 return 1
175}
176
177_add_record() {
178 _token=$1
179 _domain=$2
180 _txtvalue=$3
181
182 # Get Existing Records
183 export _H1="X-Auth-Token: ${_token}"
184 response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}")
185
186 _debug2 "${response}"
187 _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g')
188 _debug "${_exist_record}"
189
190 # Check if record exist
191 # Generate body data
192 if [ -z "${_exist_record}" ]; then
193 _post_body="{
194 \"name\": \"${_domain}.\",
195 \"description\": \"ACME Challenge\",
196 \"type\": \"TXT\",
197 \"ttl\": 1,
198 \"records\": [
199 \"\\\"${_txtvalue}\\\"\"
200 ]
201 }"
202 else
203 _post_body="{
204 \"name\": \"${_domain}.\",
205 \"description\": \"ACME Challenge\",
206 \"type\": \"TXT\",
207 \"ttl\": 1,
208 \"records\": [
209 ${_exist_record},
210 \"\\\"${_txtvalue}\\\"\"
211 ]
212 }"
213 fi
214
215 _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
216 _debug "Record Set ID is:" "${_record_id}"
217
218 # Remove all records
219 while [ "${_record_id}" != "0" ]; do
220 _debug "Removing Record"
221 _rm_record "${_token}" "${zoneid}" "${_record_id}"
222 _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")"
223 done
224
225 # Add brand new records with all old and new records
226 export _H2="Content-Type: application/json"
227 export _H1="X-Auth-Token: ${_token}"
228
229 _debug2 "${_post_body}"
230 _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null
231 _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
232 if [ "$_code" != "202" ]; then
233 _err "dns_huaweicloud: http code ${_code}"
234 return 1
235 fi
236 return 0
237}
238
239# _rm_record $token $zoneid $recordid
240# assume ${dns_api} exist
241# no output
242# return 0
243_rm_record() {
244 _token=$1
245 _zone_id=$2
246 _record_id=$3
247
248 export _H2="Content-Type: application/json"
249 export _H1="X-Auth-Token: ${_token}"
250
251 _post "" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null
252 return $?
253}
254
255_get_token() {
256 _username=$1
257 _password=$2
258 _domain_name=$3
259
260 _debug "Getting Token"
261 body="{
262 \"auth\": {
263 \"identity\": {
264 \"methods\": [
265 \"password\"
266 ],
267 \"password\": {
268 \"user\": {
269 \"name\": \"${_username}\",
270 \"password\": \"${_password}\",
271 \"domain\": {
272 \"name\": \"${_domain_name}\"
273 }
274 }
275 }
276 },
277 \"scope\": {
278 \"project\": {
279 \"name\": \"ap-southeast-1\"
280 }
281 }
282 }
283 }"
284 export _H1="Content-Type: application/json;charset=utf8"
285 _post "${body}" "${iam_api}/v3/auth/tokens" >/dev/null
286 _code=$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")
287 _token=$(grep "^X-Subject-Token" "$HTTP_HEADER" | cut -d " " -f 2-)
288 _secure_debug "${_code}"
289 printf "%s" "${_token}"
290 return 0
291}