]>
Commit | Line | Data |
---|---|---|
b8e5c0d8 EM |
1 | #!/usr/bin/env sh |
2 | ||
3 | # HUAWEICLOUD_Username | |
4 | # HUAWEICLOUD_Password | |
789ebb89 | 5 | # HUAWEICLOUD_DomainName |
6 | ||
b8e5c0d8 | 7 | iam_api="https://iam.myhuaweicloud.com" |
86639dbc | 8 | dns_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 | |
20 | dns_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 | ||
71 | dns_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 EM |
100 | |
101 | # Remove all records | |
c4ddddd4 EM |
102 | # Therotically HuaweiCloud does not allow more than one record set |
103 | # But remove them recurringly to increase robusty | |
b8e5c0d8 | 104 | while [ "${record_id}" != "0" ]; do |
28ce1c12 | 105 | _debug "Removing Record" |
b8e5c0d8 EM |
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}") | |
9d2ee212 | 134 | _debug2 "$response" |
e49ece87 YM |
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 " ") | |
9d2ee212 YM |
138 | _debug2 "Return Zone ID(s):" "${zoneidlist}" |
139 | _debug2 "Return Zone Name(s):" "${zonenamelist}" | |
e49ece87 | 140 | zoneidnum=0 |
9088c874 YM |
141 | zoneidcount=$(echo "${zoneidlist}" | grep -c '^') |
142 | _debug "Retund Zone ID(s) Count:" "${zoneidcount}" | |
143 | while [ "${zoneidnum}" -lt "${zoneidcount}" ]; do | |
e49ece87 | 144 | zoneidnum=$(_math "$zoneidnum" + 1) |
9088c874 YM |
145 | _zoneid=$(echo "${zoneidlist}" | sed -n "${zoneidnum}p") |
146 | zonename=$(echo "${zonenamelist}" | sed -n "${zoneidnum}p") | |
9d2ee212 | 147 | _debug "Check Zone Name" "${zonename}" |
e49ece87 YM |
148 | if [ "${zonename}" = "${h}." ]; then |
149 | _debug "Get Zone ID Success." | |
9088c874 | 150 | _debug "ZoneID:" "${_zoneid}" |
e49ece87 YM |
151 | printf "%s" "${_zoneid}" |
152 | return 0 | |
153 | fi | |
154 | done | |
b8e5c0d8 | 155 | fi |
b8e5c0d8 EM |
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}") | |
e49ece87 | 168 | if _contains "${response}" '"id"'; then |
b8e5c0d8 EM |
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 | |
f6f6550b EM |
181 | |
182 | # Get Existing Records | |
183 | export _H1="X-Auth-Token: ${_token}" | |
5d0657c4 EM |
184 | response=$(_get "${dns_api}/v2/zones/${zoneid}/recordsets?name=${_domain}") |
185 | ||
c4ddddd4 | 186 | _debug2 "${response}" |
fd511966 | 187 | _exist_record=$(echo "${response}" | _egrep_o '"records":[^]]*' | sed 's/\"records\"\:\[//g') |
f6f6550b EM |
188 | _debug "${_exist_record}" |
189 | ||
190 | # Check if record exist | |
191 | # Generate body data | |
f6f6550b | 192 | if [ -z "${_exist_record}" ]; then |
5d0657c4 | 193 | _post_body="{ |
f6f6550b EM |
194 | \"name\": \"${_domain}.\", |
195 | \"description\": \"ACME Challenge\", | |
196 | \"type\": \"TXT\", | |
197 | \"ttl\": 1, | |
198 | \"records\": [ | |
199 | \"\\\"${_txtvalue}\\\"\" | |
200 | ] | |
201 | }" | |
c4ddddd4 EM |
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 | }" | |
f6f6550b | 213 | fi |
5d0657c4 EM |
214 | |
215 | _record_id="$(_get_recordset_id "${_token}" "${_domain}" "${zoneid}")" | |
9d2ee212 | 216 | _debug "Record Set ID is:" "${_record_id}" |
5d0657c4 EM |
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}")" | |
5d0657c4 EM |
223 | done |
224 | ||
225 | # Add brand new records with all old and new records | |
b8e5c0d8 EM |
226 | export _H2="Content-Type: application/json" |
227 | export _H1="X-Auth-Token: ${_token}" | |
228 | ||
c4ddddd4 | 229 | _debug2 "${_post_body}" |
5d0657c4 | 230 | _post "${_post_body}" "${dns_api}/v2/zones/${zoneid}/recordsets" >/dev/null |
b8e5c0d8 EM |
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 | ||
5d0657c4 EM |
239 | # _rm_record $token $zoneid $recordid |
240 | # assume ${dns_api} exist | |
241 | # no output | |
242 | # return 0 | |
b8e5c0d8 EM |
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 | ||
5d0657c4 EM |
251 | _post "" "${dns_api}/v2/zones/${_zone_id}/recordsets/${_record_id}" false "DELETE" >/dev/null |
252 | return $? | |
b8e5c0d8 EM |
253 | } |
254 | ||
255 | _get_token() { | |
256 | _username=$1 | |
257 | _password=$2 | |
789ebb89 | 258 | _domain_name=$3 |
b8e5c0d8 EM |
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\": { | |
789ebb89 | 272 | \"name\": \"${_domain_name}\" |
b8e5c0d8 EM |
273 | } |
274 | } | |
275 | } | |
276 | }, | |
277 | \"scope\": { | |
278 | \"project\": { | |
789ebb89 | 279 | \"name\": \"ap-southeast-1\" |
b8e5c0d8 EM |
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-) | |
9d2ee212 | 288 | _secure_debug "${_code}" |
b8e5c0d8 EM |
289 | printf "%s" "${_token}" |
290 | return 0 | |
291 | } |