]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_gandi_livedns.sh
Merge pull request #4542 from alexleigh/master
[mirror_acme.sh.git] / dnsapi / dns_gandi_livedns.sh
1 #!/usr/bin/env sh
2
3 # Gandi LiveDNS v5 API
4 # https://doc.livedns.gandi.net/
5 # currently under beta
6 #
7 # Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
8 #
9 #Author: Frédéric Crozat <fcrozat@suse.com>
10 # Dominik Röttsches <drott@google.com>
11 #Report Bugs here: https://github.com/fcrozat/acme.sh
12 #
13 ######## Public functions #####################
14
15 GANDI_LIVEDNS_API="https://dns.api.gandi.net/api/v5"
16
17 #Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
18 dns_gandi_livedns_add() {
19 fulldomain=$1
20 txtvalue=$2
21
22 if [ -z "$GANDI_LIVEDNS_KEY" ]; then
23 _err "No API key specified for Gandi LiveDNS."
24 _err "Create your key and export it as GANDI_LIVEDNS_KEY"
25 return 1
26 fi
27
28 _saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY"
29
30 _debug "First detect the root zone"
31 if ! _get_root "$fulldomain"; then
32 _err "invalid domain"
33 return 1
34 fi
35 _debug fulldomain "$fulldomain"
36 _debug txtvalue "$txtvalue"
37 _debug domain "$_domain"
38 _debug sub_domain "$_sub_domain"
39
40 _dns_gandi_append_record "$_domain" "$_sub_domain" "$txtvalue"
41 }
42
43 #Usage: fulldomain txtvalue
44 #Remove the txt record after validation.
45 dns_gandi_livedns_rm() {
46 fulldomain=$1
47 txtvalue=$2
48
49 _debug "First detect the root zone"
50 if ! _get_root "$fulldomain"; then
51 _err "invalid domain"
52 return 1
53 fi
54
55 _debug fulldomain "$fulldomain"
56 _debug domain "$_domain"
57 _debug sub_domain "$_sub_domain"
58 _debug txtvalue "$txtvalue"
59
60 if ! _dns_gandi_existing_rrset_values "$_domain" "$_sub_domain"; then
61 return 1
62 fi
63 _new_rrset_values=$(echo "$_rrset_values" | sed "s/...$txtvalue...//g")
64 # Cleanup dangling commata.
65 _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, ,/ ,/g")
66 _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/, *\]/\]/g")
67 _new_rrset_values=$(echo "$_new_rrset_values" | sed "s/\[ *,/\[/g")
68 _debug "New rrset_values" "$_new_rrset_values"
69
70 _gandi_livedns_rest PUT \
71 "domains/$_domain/records/$_sub_domain/TXT" \
72 "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" &&
73 _contains "$response" '{"message": "DNS Record Created"}' &&
74 _info "Removing record $(__green "success")"
75 }
76
77 #################### Private functions below ##################################
78 #_acme-challenge.www.domain.com
79 #returns
80 # _sub_domain=_acme-challenge.www
81 # _domain=domain.com
82 _get_root() {
83 domain=$1
84 i=2
85 p=1
86 while true; do
87 h=$(printf "%s" "$domain" | cut -d . -f $i-100)
88 _debug h "$h"
89 if [ -z "$h" ]; then
90 #not valid
91 return 1
92 fi
93
94 if ! _gandi_livedns_rest GET "domains/$h"; then
95 return 1
96 fi
97
98 if _contains "$response" '"code": 401'; then
99 _err "$response"
100 return 1
101 elif _contains "$response" '"code": 404'; then
102 _debug "$h not found"
103 else
104 _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
105 _domain="$h"
106 return 0
107 fi
108 p="$i"
109 i=$(_math "$i" + 1)
110 done
111 return 1
112 }
113
114 _dns_gandi_append_record() {
115 domain=$1
116 sub_domain=$2
117 txtvalue=$3
118
119 if _dns_gandi_existing_rrset_values "$domain" "$sub_domain"; then
120 _debug "Appending new value"
121 _rrset_values=$(echo "$_rrset_values" | sed "s/\"]/\",\"$txtvalue\"]/")
122 else
123 _debug "Creating new record" "$_rrset_values"
124 _rrset_values="[\"$txtvalue\"]"
125 fi
126 _debug new_rrset_values "$_rrset_values"
127 _gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \
128 "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" &&
129 _contains "$response" '{"message": "DNS Record Created"}' &&
130 _info "Adding record $(__green "success")"
131 }
132
133 _dns_gandi_existing_rrset_values() {
134 domain=$1
135 sub_domain=$2
136 if ! _gandi_livedns_rest GET "domains/$domain/records/$sub_domain"; then
137 return 1
138 fi
139 if ! _contains "$response" '"rrset_type": "TXT"'; then
140 _debug "Does not have a _acme-challenge TXT record yet."
141 return 1
142 fi
143 if _contains "$response" '"rrset_values": \[\]'; then
144 _debug "Empty rrset_values for TXT record, no previous TXT record."
145 return 1
146 fi
147 _debug "Already has TXT record."
148 _rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' |
149 _egrep_o '\[".*\"]')
150 return 0
151 }
152
153 _gandi_livedns_rest() {
154 m=$1
155 ep="$2"
156 data="$3"
157 _debug "$ep"
158
159 export _H1="Content-Type: application/json"
160 export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY"
161
162 if [ "$m" = "GET" ]; then
163 response="$(_get "$GANDI_LIVEDNS_API/$ep")"
164 else
165 _debug data "$data"
166 response="$(_post "$data" "$GANDI_LIVEDNS_API/$ep" "" "$m")"
167 fi
168
169 if [ "$?" != "0" ]; then
170 _err "error $ep"
171 return 1
172 fi
173 _debug2 response "$response"
174 return 0
175 }