]>
Commit | Line | Data |
---|---|---|
d30b441e TC |
1 | #!/usr/bin/env sh |
2 | # | |
3 | # | |
4 | #RACKSPACE_Username="" | |
5 | # | |
6 | #RACKSPACE_Apikey="" | |
7 | ||
8 | RACKSPACE_Endpoint="https://dns.api.rackspacecloud.com/v1.0" | |
9 | ||
8d3ad3a8 | 10 | # 20210923 - RS changed the fields in the API response; fix sed |
d30b441e TC |
11 | # 20190213 - The name & id fields swapped in the API response; fix sed |
12 | # 20190101 - Duplicating file for new pull request to dev branch | |
d795fac3 | 13 | # Original - tcocca:rackspace_dnsapi https://github.com/acmesh-official/acme.sh/pull/1297 |
d30b441e TC |
14 | |
15 | ######## Public functions ##################### | |
16 | #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" | |
17 | dns_rackspace_add() { | |
18 | fulldomain="$1" | |
19 | _debug fulldomain="$fulldomain" | |
20 | txtvalue="$2" | |
21 | _debug txtvalue="$txtvalue" | |
22 | _rackspace_check_auth || return 1 | |
23 | _rackspace_check_rootzone || return 1 | |
24 | _info "Creating TXT record." | |
25 | if ! _rackspace_rest POST "$RACKSPACE_Tenant/domains/$_domain_id/records" "{\"records\":[{\"name\":\"$fulldomain\",\"type\":\"TXT\",\"data\":\"$txtvalue\",\"ttl\":300}]}"; then | |
26 | return 1 | |
27 | fi | |
28 | _debug2 response "$response" | |
29 | if ! _contains "$response" "$txtvalue" >/dev/null; then | |
30 | _err "Could not add TXT record." | |
31 | return 1 | |
32 | fi | |
33 | return 0 | |
34 | } | |
35 | ||
36 | #fulldomain txtvalue | |
37 | dns_rackspace_rm() { | |
38 | fulldomain=$1 | |
39 | _debug fulldomain="$fulldomain" | |
40 | txtvalue=$2 | |
41 | _debug txtvalue="$txtvalue" | |
42 | _rackspace_check_auth || return 1 | |
43 | _rackspace_check_rootzone || return 1 | |
44 | _info "Checking for TXT record." | |
45 | if ! _get_recordid "$_domain_id" "$fulldomain" "$txtvalue"; then | |
46 | _err "Could not get TXT record id." | |
47 | return 1 | |
48 | fi | |
49 | if [ "$_dns_record_id" = "" ]; then | |
50 | _err "TXT record not found." | |
51 | return 1 | |
52 | fi | |
53 | _info "Removing TXT record." | |
54 | if ! _delete_txt_record "$_domain_id" "$_dns_record_id"; then | |
55 | _err "Could not remove TXT record $_dns_record_id." | |
56 | fi | |
57 | return 0 | |
58 | } | |
59 | ||
60 | #################### Private functions below ################################## | |
61 | #_acme-challenge.www.domain.com | |
62 | #returns | |
63 | # _sub_domain=_acme-challenge.www | |
64 | # _domain=domain.com | |
65 | # _domain_id=sdjkglgdfewsdfg | |
66 | _get_root_zone() { | |
67 | domain="$1" | |
68 | i=2 | |
69 | p=1 | |
70 | while true; do | |
71 | h=$(printf "%s" "$domain" | cut -d . -f $i-100) | |
72 | _debug h "$h" | |
73 | if [ -z "$h" ]; then | |
74 | #not valid | |
75 | return 1 | |
76 | fi | |
8b3d792b | 77 | if ! _rackspace_rest GET "$RACKSPACE_Tenant/domains/search?name=$h"; then |
d30b441e TC |
78 | return 1 |
79 | fi | |
80 | _debug2 response "$response" | |
81 | if _contains "$response" "\"name\":\"$h\"" >/dev/null; then | |
82 | # Response looks like: | |
16d0416f | 83 | # {"id":"12345","accountId":"1111111","name": "example.com","ttl":3600,"emailAddress": ... <and so on> |
8d3ad3a8 | 84 | _domain_id=$(echo "$response" | sed -n "s/^.*\"id\":\"\([^,]*\)\",\"accountId\":\"[0-9]*\",\"name\":\"$h\",.*/\1/p") |
d30b441e TC |
85 | _debug2 domain_id "$_domain_id" |
86 | if [ -n "$_domain_id" ]; then | |
87 | _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) | |
88 | _domain=$h | |
89 | return 0 | |
90 | fi | |
91 | return 1 | |
92 | fi | |
93 | p=$i | |
94 | i=$(_math "$i" + 1) | |
95 | done | |
96 | return 1 | |
97 | } | |
98 | ||
99 | _get_recordid() { | |
100 | domainid="$1" | |
101 | fulldomain="$2" | |
102 | txtvalue="$3" | |
103 | if ! _rackspace_rest GET "$RACKSPACE_Tenant/domains/$domainid/records?name=$fulldomain&type=TXT"; then | |
104 | return 1 | |
105 | fi | |
106 | _debug response "$response" | |
107 | if ! _contains "$response" "$txtvalue"; then | |
108 | _dns_record_id=0 | |
109 | return 0 | |
110 | fi | |
111 | _dns_record_id=$(echo "$response" | tr '{' "\n" | grep "\"data\":\"$txtvalue\"" | sed -n 's/^.*"id":"\([^"]*\)".*/\1/p') | |
112 | _debug _dns_record_id "$_dns_record_id" | |
113 | return 0 | |
114 | } | |
115 | ||
116 | _delete_txt_record() { | |
117 | domainid="$1" | |
118 | _dns_record_id="$2" | |
119 | if ! _rackspace_rest DELETE "$RACKSPACE_Tenant/domains/$domainid/records?id=$_dns_record_id"; then | |
120 | return 1 | |
121 | fi | |
122 | _debug response "$response" | |
123 | if ! _contains "$response" "RUNNING"; then | |
124 | return 1 | |
125 | fi | |
126 | return 0 | |
127 | } | |
128 | ||
129 | _rackspace_rest() { | |
130 | m="$1" | |
131 | ep="$2" | |
132 | data="$3" | |
133 | _debug ep "$ep" | |
134 | export _H1="Accept: application/json" | |
135 | export _H2="X-Auth-Token: $RACKSPACE_Token" | |
136 | export _H3="X-Project-Id: $RACKSPACE_Tenant" | |
137 | export _H4="Content-Type: application/json" | |
138 | if [ "$m" != "GET" ]; then | |
139 | _debug data "$data" | |
140 | response="$(_post "$data" "$RACKSPACE_Endpoint/$ep" "" "$m")" | |
141 | retcode=$? | |
142 | else | |
143 | _info "Getting $RACKSPACE_Endpoint/$ep" | |
144 | response="$(_get "$RACKSPACE_Endpoint/$ep")" | |
145 | retcode=$? | |
146 | fi | |
147 | ||
148 | if [ "$retcode" != "0" ]; then | |
149 | _err "error $ep" | |
150 | return 1 | |
151 | fi | |
152 | _debug2 response "$response" | |
153 | return 0 | |
154 | } | |
155 | ||
156 | _rackspace_authorization() { | |
157 | export _H1="Content-Type: application/json" | |
158 | data="{\"auth\":{\"RAX-KSKEY:apiKeyCredentials\":{\"username\":\"$RACKSPACE_Username\",\"apiKey\":\"$RACKSPACE_Apikey\"}}}" | |
159 | _debug data "$data" | |
160 | response="$(_post "$data" "https://identity.api.rackspacecloud.com/v2.0/tokens" "" "POST")" | |
161 | retcode=$? | |
162 | _debug2 response "$response" | |
163 | if [ "$retcode" != "0" ]; then | |
164 | _err "Authentication failed." | |
165 | return 1 | |
166 | fi | |
167 | if _contains "$response" "token"; then | |
168 | RACKSPACE_Token="$(echo "$response" | _normalizeJson | sed -n 's/^.*"token":{.*,"id":"\([^"]*\)",".*/\1/p')" | |
169 | RACKSPACE_Tenant="$(echo "$response" | _normalizeJson | sed -n 's/^.*"token":{.*,"id":"\([^"]*\)"}.*/\1/p')" | |
170 | _debug RACKSPACE_Token "$RACKSPACE_Token" | |
171 | _debug RACKSPACE_Tenant "$RACKSPACE_Tenant" | |
172 | fi | |
173 | return 0 | |
174 | } | |
175 | ||
176 | _rackspace_check_auth() { | |
177 | # retrieve the rackspace creds | |
178 | RACKSPACE_Username="${RACKSPACE_Username:-$(_readaccountconf_mutable RACKSPACE_Username)}" | |
179 | RACKSPACE_Apikey="${RACKSPACE_Apikey:-$(_readaccountconf_mutable RACKSPACE_Apikey)}" | |
180 | # check their vals for null | |
181 | if [ -z "$RACKSPACE_Username" ] || [ -z "$RACKSPACE_Apikey" ]; then | |
182 | RACKSPACE_Username="" | |
183 | RACKSPACE_Apikey="" | |
184 | _err "You didn't specify a Rackspace username and api key." | |
185 | _err "Please set those values and try again." | |
186 | return 1 | |
187 | fi | |
188 | # save the username and api key to the account conf file. | |
189 | _saveaccountconf_mutable RACKSPACE_Username "$RACKSPACE_Username" | |
190 | _saveaccountconf_mutable RACKSPACE_Apikey "$RACKSPACE_Apikey" | |
191 | if [ -z "$RACKSPACE_Token" ]; then | |
192 | _info "Getting authorization token." | |
193 | if ! _rackspace_authorization; then | |
194 | _err "Can not get token." | |
195 | fi | |
196 | fi | |
197 | } | |
198 | ||
199 | _rackspace_check_rootzone() { | |
200 | _debug "First detect the root zone" | |
201 | if ! _get_root_zone "$fulldomain"; then | |
202 | _err "invalid domain" | |
203 | return 1 | |
204 | fi | |
205 | _debug _domain_id "$_domain_id" | |
206 | _debug _sub_domain "$_sub_domain" | |
207 | _debug _domain "$_domain" | |
208 | } |