]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_constellix.sh
Merge pull request #3734 from acmesh-official/dev
[mirror_acme.sh.git] / dnsapi / dns_constellix.sh
1 #!/usr/bin/env sh
2
3 # Author: Wout Decre <wout@canodus.be>
4
5 CONSTELLIX_Api="https://api.dns.constellix.com/v1"
6 #CONSTELLIX_Key="XXX"
7 #CONSTELLIX_Secret="XXX"
8
9 ######## Public functions #####################
10
11 # Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
12 # Used to add txt record
13 dns_constellix_add() {
14 fulldomain=$1
15 txtvalue=$2
16
17 CONSTELLIX_Key="${CONSTELLIX_Key:-$(_readaccountconf_mutable CONSTELLIX_Key)}"
18 CONSTELLIX_Secret="${CONSTELLIX_Secret:-$(_readaccountconf_mutable CONSTELLIX_Secret)}"
19
20 if [ -z "$CONSTELLIX_Key" ] || [ -z "$CONSTELLIX_Secret" ]; then
21 _err "You did not specify the Contellix API key and secret yet."
22 return 1
23 fi
24
25 _saveaccountconf_mutable CONSTELLIX_Key "$CONSTELLIX_Key"
26 _saveaccountconf_mutable CONSTELLIX_Secret "$CONSTELLIX_Secret"
27
28 if ! _get_root "$fulldomain"; then
29 _err "Invalid domain"
30 return 1
31 fi
32
33 # The TXT record might already exist when working with wildcard certificates. In that case, update the record by adding the new value.
34 _debug "Search TXT record"
35 if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then
36 if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then
37 _info "Adding TXT record"
38 if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"add\":true,\"set\":{\"name\":\"${_sub_domain}\",\"ttl\":60,\"roundRobin\":[{\"value\":\"${txtvalue}\"}]}}]"; then
39 if printf -- "%s" "$response" | grep "{\"success\":\"1 record(s) added, 0 record(s) updated, 0 record(s) deleted\"}" >/dev/null; then
40 _info "Added"
41 return 0
42 else
43 _err "Error adding TXT record"
44 fi
45 fi
46 else
47 _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
48 if _constellix_rest GET "domains/${_domain_id}/records/TXT/${_record_id}"; then
49 _new_rr_values=$(printf "%s\n" "$response" | _egrep_o '"roundRobin":\[[^]]*\]' | sed "s/\]$/,{\"value\":\"${txtvalue}\"}]/")
50 _debug _new_rr_values "$_new_rr_values"
51 _info "Updating TXT record"
52 if _constellix_rest PUT "domains/${_domain_id}/records/TXT/${_record_id}" "{\"name\":\"${_sub_domain}\",\"ttl\":60,${_new_rr_values}}"; then
53 if printf -- "%s" "$response" | grep "{\"success\":\"Record.*updated successfully\"}" >/dev/null; then
54 _info "Updated"
55 return 0
56 elif printf -- "%s" "$response" | grep "{\"errors\":\[\"Contents are identical\"\]}" >/dev/null; then
57 _info "Already exists, no need to update"
58 return 0
59 else
60 _err "Error updating TXT record"
61 fi
62 fi
63 fi
64 fi
65 fi
66
67 return 1
68 }
69
70 # Usage: fulldomain txtvalue
71 # Used to remove the txt record after validation
72 dns_constellix_rm() {
73 fulldomain=$1
74 txtvalue=$2
75
76 CONSTELLIX_Key="${CONSTELLIX_Key:-$(_readaccountconf_mutable CONSTELLIX_Key)}"
77 CONSTELLIX_Secret="${CONSTELLIX_Secret:-$(_readaccountconf_mutable CONSTELLIX_Secret)}"
78
79 if [ -z "$CONSTELLIX_Key" ] || [ -z "$CONSTELLIX_Secret" ]; then
80 _err "You did not specify the Contellix API key and secret yet."
81 return 1
82 fi
83
84 if ! _get_root "$fulldomain"; then
85 _err "Invalid domain"
86 return 1
87 fi
88
89 # The TXT record might have been removed already when working with some wildcard certificates.
90 _debug "Search TXT record"
91 if _constellix_rest GET "domains/${_domain_id}/records/TXT/search?exact=${_sub_domain}"; then
92 if printf -- "%s" "$response" | grep "{\"errors\":\[\"Requested record was not found\"\]}" >/dev/null; then
93 _info "Removed"
94 return 0
95 else
96 _info "Removing TXT record"
97 if _constellix_rest POST "domains/${_domain_id}/records" "[{\"type\":\"txt\",\"delete\":true,\"filter\":{\"field\":\"name\",\"op\":\"eq\",\"value\":\"${_sub_domain}\"}}]"; then
98 if printf -- "%s" "$response" | grep "{\"success\":\"0 record(s) added, 0 record(s) updated, 1 record(s) deleted\"}" >/dev/null; then
99 _info "Removed"
100 return 0
101 else
102 _err "Error removing TXT record"
103 fi
104 fi
105 fi
106 fi
107
108 return 1
109 }
110
111 #################### Private functions below ##################################
112
113 _get_root() {
114 domain=$1
115 i=2
116 p=1
117 _debug "Detecting root zone"
118 while true; do
119 h=$(printf "%s" "$domain" | cut -d . -f $i-100)
120 if [ -z "$h" ]; then
121 return 1
122 fi
123
124 if ! _constellix_rest GET "domains/search?exact=$h"; then
125 return 1
126 fi
127
128 if _contains "$response" "\"name\":\"$h\""; then
129 _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]*" | cut -d ':' -f 2)
130 if [ "$_domain_id" ]; then
131 _sub_domain=$(printf "%s" "$domain" | cut -d '.' -f 1-$p)
132 _domain="$h"
133
134 _debug _domain_id "$_domain_id"
135 _debug _sub_domain "$_sub_domain"
136 _debug _domain "$_domain"
137 return 0
138 fi
139 return 1
140 fi
141 p=$i
142 i=$(_math "$i" + 1)
143 done
144 return 1
145 }
146
147 _constellix_rest() {
148 m=$1
149 ep="$2"
150 data="$3"
151 _debug "$ep"
152
153 rdate=$(date +"%s")"000"
154 hmac=$(printf "%s" "$rdate" | _hmac sha1 "$(printf "%s" "$CONSTELLIX_Secret" | _hex_dump | tr -d ' ')" | _base64)
155
156 export _H1="x-cnsdns-apiKey: $CONSTELLIX_Key"
157 export _H2="x-cnsdns-requestDate: $rdate"
158 export _H3="x-cnsdns-hmac: $hmac"
159 export _H4="Accept: application/json"
160 export _H5="Content-Type: application/json"
161
162 if [ "$m" != "GET" ]; then
163 _debug data "$data"
164 response="$(_post "$data" "$CONSTELLIX_Api/$ep" "" "$m")"
165 else
166 response="$(_get "$CONSTELLIX_Api/$ep")"
167 fi
168
169 if [ "$?" != "0" ]; then
170 _err "Error $ep"
171 return 1
172 fi
173
174 _debug response "$response"
175 return 0
176 }