]> git.proxmox.com Git - mirror_acme.sh.git/blob - dnsapi/dns_ionos.sh
Merge pull request #3430 from lbrocke/dns-api-ionos
[mirror_acme.sh.git] / dnsapi / dns_ionos.sh
1 #!/usr/bin/env sh
2
3 # Supports IONOS DNS API Beta v1.0.0
4 #
5 # Usage:
6 # Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh:
7 #
8 # $ export IONOS_PREFIX="..."
9 # $ export IONOS_SECRET="..."
10 #
11 # $ acme.sh --issue --dns dns_ionos ...
12
13 IONOS_API="https://api.hosting.ionos.com/dns"
14 IONOS_ROUTE_ZONES="/v1/zones"
15
16 IONOS_TXT_TTL=60 # minimum accepted by API
17 IONOS_TXT_PRIO=10
18
19 dns_ionos_add() {
20 fulldomain=$1
21 txtvalue=$2
22
23 if ! _ionos_init; then
24 return 1
25 fi
26
27 _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]"
28
29 if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ -z "$response" ]; then
30 _info "TXT record has been created successfully."
31 return 0
32 fi
33
34 return 1
35 }
36
37 dns_ionos_rm() {
38 fulldomain=$1
39 txtvalue=$2
40
41 if ! _ionos_init; then
42 return 1
43 fi
44
45 if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then
46 _err "Could not find _acme-challenge TXT record."
47 return 1
48 fi
49
50 if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then
51 _info "TXT record has been deleted successfully."
52 return 0
53 fi
54
55 return 1
56 }
57
58 _ionos_init() {
59 IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}"
60 IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}"
61
62 if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then
63 _err "You didn't specify an IONOS api prefix and secret yet."
64 _err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret."
65 _err ""
66 _err "Then set them before calling acme.sh:"
67 _err "\$ export IONOS_PREFIX=\"...\""
68 _err "\$ export IONOS_SECRET=\"...\""
69 _err "\$ acme.sh --issue -d ... --dns dns_ionos"
70 return 1
71 fi
72
73 _saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX"
74 _saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET"
75
76 if ! _get_root "$fulldomain"; then
77 _err "Cannot find this domain in your IONOS account."
78 return 1
79 fi
80 }
81
82 _get_root() {
83 domain=$1
84 i=1
85 p=1
86
87 if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then
88 response="$(echo "$response" | tr -d "\n")"
89
90 while true; do
91 h=$(printf "%s" "$domain" | cut -d . -f $i-100)
92 if [ -z "$h" ]; then
93 return 1
94 fi
95
96 _zone="$(echo "$response" | _egrep_o "\"name\":\"$h\".*\}")"
97 if [ "$_zone" ]; then
98 _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
99 if [ "$_zone_id" ]; then
100 _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
101 _domain=$h
102
103 return 0
104 fi
105
106 return 1
107 fi
108
109 p=$i
110 i=$(_math "$i" + 1)
111 done
112 fi
113
114 return 1
115 }
116
117 _ionos_get_record() {
118 fulldomain=$1
119 zone_id=$2
120 txtrecord=$3
121
122 if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then
123 response="$(echo "$response" | tr -d "\n")"
124
125 _record="$(echo "$response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")"
126 if [ "$_record" ]; then
127 _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
128
129 return 0
130 fi
131 fi
132
133 return 1
134 }
135
136 _ionos_rest() {
137 method="$1"
138 route="$2"
139 data="$3"
140
141 IONOS_API_KEY="$(printf "%s.%s" "$IONOS_PREFIX" "$IONOS_SECRET")"
142
143 export _H1="X-API-Key: $IONOS_API_KEY"
144
145 if [ "$method" != "GET" ]; then
146 export _H2="Accept: application/json"
147 export _H3="Content-Type: application/json"
148
149 response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")"
150 else
151 export _H2="Accept: */*"
152
153 response="$(_get "$IONOS_API$route")"
154 fi
155
156 if [ "$?" != "0" ]; then
157 _err "Error $route"
158 return 1
159 fi
160
161 return 0
162 }