Skip to content

Commit

Permalink
dnsapi/ionos: Add API support for IONOS DNS API
Browse files Browse the repository at this point in the history
The IONOS DNS API is in beta state, please read [1] on how to get
started.

PLEASE NOTE: The v2 wildcard certification creation [2] is not yet
supported as the IONOS API doesn't allow the creation of multiple TXT
records with the same domain name.

[1] https://beta.developer.hosting.ionos.de/docs/getstarted
[2] acmesh-official#1261
  • Loading branch information
lbrocke authored and Sp1l committed Aug 10, 2021
1 parent 488fc09 commit 1191ba4
Showing 1 changed file with 157 additions and 0 deletions.
157 changes: 157 additions & 0 deletions dnsapi/dns_ionos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#!/usr/bin/env sh

# Supports IONOS DNS API Beta v1.0.0
#
# Usage:
# Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh:
#
# $ export IONOS_PREFIX="..."
# $ export IONOS_SECRET="..."
#
# $ acme.sh --issue --dns dns_ionos ...

IONOS_API="https://api.hosting.ionos.com/dns"
IONOS_ROUTE_ZONES="/v1/zones"

IONOS_TXT_TTL=60 # minumum accepted by API
IONOS_TXT_PRIO=10

dns_ionos_add() {
fulldomain=$1
txtvalue=$2

_ionos_init

_body="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}"

if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then
_info "TXT record for _sub_domain.$_domain has been created successfully."
return 0
fi

return 1
}

dns_ionos_rm() {
fulldomain=$1
txtvalue=$2

_ionos_init

if ! _ionos_get_record "$fulldomain" "$_zone_id"; then
_err "Could not find _acme-challenge TXT record."
return 1
fi

if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then
_info "TXT record for _sub_domain.$_domain has been deleted successfully."
return 0
fi

return 1
}

_ionos_init() {
IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}"
IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}"

if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then
_err "You didn't specify an IONOS api prefix and secret yet."
_err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret."
_err ""
_err "Then set them before calling acme.sh:"
_err "\$ export IONOS_PREFIX=\"...\""
_err "\$ export IONOS_SECRET=\"...\""
_err "\$ acme.sh --issue -d ... --dns dns_ionos"
return 1
fi

_saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX"
_saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET"

if ! _get_root "$fulldomain"; then
_err "Cannot find this domain in your IONOS account."
return 1
fi
}

_get_root() {
domain=$1
i=2
p=1

if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then
response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"

while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
if [ -z "$h" ]; then
return 1
fi

_zone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")"
if [ "$_zone" ]; then
_zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"' )
if [ "$_zone_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h

return 0
fi

return 1
fi

p=$i
i=$(_math "$i" + 1)
done
fi

return 1
}

_ionos_get_record() {
fulldomain=$1
zone_id=$2

if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then
response="$(echo "$response" | tr -d "\n" )"

_record="$(echo "$response" | _egrep_o "{\"name\":\s*\"$fulldomain\".*}")"
if [ "$_record" ]; then
_record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"' )

return 0
fi
fi

return 1
}

_ionos_rest() {
method="$1"
route="$2"
data="$3"

IONOS_API_KEY="$(printf "%s.%s" "$IONOS_PREFIX" "$IONOS_SECRET")"

export _H1="X-API-Key: $IONOS_API_KEY"

if [ "$method" != "GET" ]; then
export _H2="Accept: application/json"
export _H3="Content-Type: application/json"

response="$(_post "$data" "$IONOS_API$route" "" "$method")"
else
export _H2="Accept: */*"

response="$(_get "$IONOS_API$route")"
fi

if [ "$?" != "0" ]; then
_err "Error $route"
return 1
fi

return 0
}

0 comments on commit 1191ba4

Please sign in to comment.