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