Skip to content

Commit f7f8ea9

Browse files
authored
Merge pull request #5110 from ionos-cloud/add_ionos_cloud_script
Feature: DNS API for IONOS cloud
2 parents 58cad98 + 74ffbb2 commit f7f8ea9

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

dnsapi/dns_ionos_cloud.sh

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#!/usr/bin/env sh
2+
3+
# Supports IONOS Cloud DNS API v1.15.4
4+
#
5+
# Usage:
6+
# Export IONOS_TOKEN before calling acme.sh:
7+
# $ export IONOS_TOKEN="..."
8+
#
9+
# $ acme.sh --issue --dns dns_ionos_cloud ...
10+
11+
IONOS_CLOUD_API="https://dns.de-fra.ionos.com"
12+
IONOS_CLOUD_ROUTE_ZONES="/zones"
13+
14+
dns_ionos_cloud_add() {
15+
fulldomain=$1
16+
txtvalue=$2
17+
18+
if ! _ionos_init; then
19+
return 1
20+
fi
21+
22+
_record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1)
23+
_body="{\"properties\":{\"name\":\"$_record_name\", \"type\":\"TXT\", \"content\":\"$txtvalue\"}}"
24+
25+
if _ionos_cloud_rest POST "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "202" ]; then
26+
_info "TXT record has been created successfully."
27+
return 0
28+
fi
29+
30+
return 1
31+
}
32+
33+
dns_ionos_cloud_rm() {
34+
fulldomain=$1
35+
txtvalue=$2
36+
37+
if ! _ionos_init; then
38+
return 1
39+
fi
40+
41+
if ! _ionos_cloud_get_record "$_zone_id" "$txtvalue" "$fulldomain"; then
42+
_err "Could not find _acme-challenge TXT record."
43+
return 1
44+
fi
45+
46+
if _ionos_cloud_rest DELETE "$IONOS_CLOUD_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "202" ]; then
47+
_info "TXT record has been deleted successfully."
48+
return 0
49+
fi
50+
51+
return 1
52+
}
53+
54+
_ionos_init() {
55+
IONOS_TOKEN="${IONOS_TOKEN:-$(_readaccountconf_mutable IONOS_TOKEN)}"
56+
57+
if [ -z "$IONOS_TOKEN" ]; then
58+
_err "You didn't specify an IONOS token yet."
59+
_err "Read https://api.ionos.com/docs/authentication/v1/#tag/tokens/operation/tokensGenerate to learn how to get a token."
60+
_err "You need to set it before calling acme.sh:"
61+
_err "\$ export IONOS_TOKEN=\"...\""
62+
_err "\$ acme.sh --issue -d ... --dns dns_ionos_cloud"
63+
return 1
64+
fi
65+
66+
_saveaccountconf_mutable IONOS_TOKEN "$IONOS_TOKEN"
67+
68+
if ! _get_cloud_zone "$fulldomain"; then
69+
_err "Cannot find zone $zone in your IONOS account."
70+
return 1
71+
fi
72+
73+
return 0
74+
}
75+
76+
_get_cloud_zone() {
77+
domain=$1
78+
zone=$(printf "%s" "$domain" | cut -d . -f 2-)
79+
80+
if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES?filter.zoneName=$zone"; then
81+
_response="$(echo "$_response" | tr -d "\n")"
82+
83+
_zone_list_items=$(echo "$_response" | _egrep_o "\"items\":.*")
84+
85+
_zone_id=$(printf "%s\n" "$_zone_list_items" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
86+
if [ "$_zone_id" ]; then
87+
return 0
88+
fi
89+
fi
90+
91+
return 1
92+
}
93+
94+
_ionos_cloud_get_record() {
95+
zone_id=$1
96+
txtrecord=$2
97+
# this is to transform the domain to lower case
98+
fulldomain=$(printf "%s" "$3" | _lower_case)
99+
# this is to transform record name to lower case
100+
# IONOS Cloud API transforms all record names to lower case
101+
_record_name=$(printf "%s" "$fulldomain" | cut -d . -f 1 | _lower_case)
102+
103+
if _ionos_cloud_rest GET "$IONOS_CLOUD_ROUTE_ZONES/$zone_id/records"; then
104+
_response="$(echo "$_response" | tr -d "\n")"
105+
106+
pattern="\{\"id\":\"[a-fA-F0-9\-]*\",\"type\":\"record\",\"href\":\"/zones/$zone_id/records/[a-fA-F0-9\-]*\",\"metadata\":\{\"createdDate\":\"[A-Z0-9\:\.\-]*\",\"lastModifiedDate\":\"[A-Z0-9\:\.\-]*\",\"fqdn\":\"$fulldomain\",\"state\":\"AVAILABLE\",\"zoneId\":\"$zone_id\"\},\"properties\":\{\"content\":\"$txtrecord\",\"enabled\":true,\"name\":\"$_record_name\",\"priority\":[0-9]*,\"ttl\":[0-9]*,\"type\":\"TXT\"\}\}"
107+
108+
_record="$(echo "$_response" | _egrep_o "$pattern")"
109+
if [ "$_record" ]; then
110+
_record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
111+
return 0
112+
fi
113+
fi
114+
115+
return 1
116+
}
117+
118+
_ionos_cloud_rest() {
119+
method="$1"
120+
route="$2"
121+
data="$3"
122+
123+
export _H1="Authorization: Bearer $IONOS_TOKEN"
124+
125+
# clear headers
126+
: >"$HTTP_HEADER"
127+
128+
if [ "$method" != "GET" ]; then
129+
_response="$(_post "$data" "$IONOS_CLOUD_API$route" "" "$method" "application/json")"
130+
else
131+
_response="$(_get "$IONOS_CLOUD_API$route")"
132+
fi
133+
134+
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
135+
136+
if [ "$?" != "0" ]; then
137+
_err "Error $route: $_response"
138+
return 1
139+
fi
140+
141+
_debug2 "_response" "$_response"
142+
_debug2 "_code" "$_code"
143+
144+
return 0
145+
}

0 commit comments

Comments
 (0)