]>
Commit | Line | Data |
---|---|---|
fab2d9dc FC |
1 | #!/usr/bin/env sh |
2 | ||
3 | # Gandi LiveDNS v5 API | |
3c933158 | 4 | # https://doc.livedns.gandi.net/ |
fab2d9dc FC |
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> | |
29a5311a | 10 | # Dominik Röttsches <drott@google.com> |
fab2d9dc FC |
11 | #Report Bugs here: https://github.com/fcrozat/acme.sh |
12 | # | |
13 | ######## Public functions ##################### | |
14 | ||
856811bd | 15 | GANDI_LIVEDNS_API="https://dns.api.gandi.net/api/v5" |
fab2d9dc FC |
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 | |
f3c98428 | 23 | _err "No API key specified for Gandi LiveDNS." |
fab2d9dc FC |
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 | ||
29a5311a | 40 | _dns_gandi_append_record "$_domain" "$_sub_domain" "$txtvalue" |
fab2d9dc FC |
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" | |
29a5311a | 58 | _debug txtvalue "$txtvalue" |
fab2d9dc | 59 | |
29a5311a DR |
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" \ | |
19c43451 | 72 | "{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" && |
73 | _contains "$response" '{"message": "DNS Record Created"}' && | |
74 | _info "Removing record $(__green "success")" | |
fab2d9dc FC |
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) | |
d24a87ca | 88 | _debug h "$h" |
fab2d9dc FC |
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 | ||
9683ffe1 | 98 | if _contains "$response" '"code": 401'; then |
99 | _err "$response" | |
100 | return 1 | |
101 | elif _contains "$response" '"code": 404'; then | |
fab2d9dc FC |
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 | ||
29a5311a DR |
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" \ | |
19c43451 | 128 | "{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" && |
129 | _contains "$response" '{"message": "DNS Record Created"}' && | |
130 | _info "Adding record $(__green "success")" | |
29a5311a DR |
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." | |
19c43451 | 148 | _rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' | |
149 | _egrep_o '\[".*\"]') | |
29a5311a DR |
150 | return 0 |
151 | } | |
152 | ||
fab2d9dc FC |
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 | ||
9683ffe1 | 162 | if [ "$m" = "GET" ]; then |
163 | response="$(_get "$GANDI_LIVEDNS_API/$ep")" | |
164 | else | |
fab2d9dc FC |
165 | _debug data "$data" |
166 | response="$(_post "$data" "$GANDI_LIVEDNS_API/$ep" "" "$m")" | |
fab2d9dc FC |
167 | fi |
168 | ||
169 | if [ "$?" != "0" ]; then | |
170 | _err "error $ep" | |
171 | return 1 | |
172 | fi | |
173 | _debug2 response "$response" | |
174 | return 0 | |
175 | } |