4 # Custom servercow.de DNS API v1 for use with [acme.sh](https://github.com/acmesh-official/acme.sh)
7 # export SERVERCOW_API_Username=username
8 # export SERVERCOW_API_Password=password
9 # acme.sh --issue -d example.com --dns dns_servercow
12 # Any issues / questions / suggestions can be posted here:
13 # https://github.com/jhartlep/servercow-dns-api/issues
15 # Author: Jens Hartlep
18 SERVERCOW_API
="https://api.servercow.de/dns/v1/domains"
20 # Usage dns_servercow_add _acme-challenge.www.domain.com "abcdefghijklmnopqrstuvwxyz"
25 _info
"Using servercow"
26 _debug fulldomain
"$fulldomain"
27 _debug txtvalue
"$txtvalue"
29 SERVERCOW_API_Username
="${SERVERCOW_API_Username:-$(_readaccountconf_mutable SERVERCOW_API_Username)}"
30 SERVERCOW_API_Password
="${SERVERCOW_API_Password:-$(_readaccountconf_mutable SERVERCOW_API_Password)}"
31 if [ -z "$SERVERCOW_API_Username" ] ||
[ -z "$SERVERCOW_API_Password" ]; then
32 SERVERCOW_API_Username
=""
33 SERVERCOW_API_Password
=""
34 _err
"You don't specify servercow api username and password yet."
35 _err
"Please create your username and password and try again."
39 # save the credentials to the account conf file
40 _saveaccountconf_mutable SERVERCOW_API_Username
"$SERVERCOW_API_Username"
41 _saveaccountconf_mutable SERVERCOW_API_Password
"$SERVERCOW_API_Password"
43 _debug
"First detect the root zone"
44 if ! _get_root
"$fulldomain"; then
49 _debug _sub_domain
"$_sub_domain"
50 _debug _domain
"$_domain"
52 if _servercow_api POST
"$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":20}"; then
53 if printf -- "%s" "$response" |
grep "ok" >/dev
/null
; then
57 _err
"add txt record error."
61 _err
"add txt record error."
66 # Usage fulldomain txtvalue
67 # Remove the txt record after validation
72 _info
"Using servercow"
73 _debug fulldomain
"$fulldomain"
74 _debug txtvalue
"$fulldomain"
76 SERVERCOW_API_Username
="${SERVERCOW_API_Username:-$(_readaccountconf_mutable SERVERCOW_API_Username)}"
77 SERVERCOW_API_Password
="${SERVERCOW_API_Password:-$(_readaccountconf_mutable SERVERCOW_API_Password)}"
78 if [ -z "$SERVERCOW_API_Username" ] ||
[ -z "$SERVERCOW_API_Password" ]; then
79 SERVERCOW_API_Username
=""
80 SERVERCOW_API_Password
=""
81 _err
"You don't specify servercow api username and password yet."
82 _err
"Please create your username and password and try again."
86 _debug
"First detect the root zone"
87 if ! _get_root
"$fulldomain"; then
92 _debug _sub_domain
"$_sub_domain"
93 _debug _domain
"$_domain"
95 if _servercow_api DELETE
"$_domain" "{\"type\":\"TXT\",\"name\":\"$fulldomain\"}"; then
96 if printf -- "%s" "$response" |
grep "ok" >/dev
/null
; then
98 _contains
"$response" '"message":"ok"'
100 _err
"delete txt record error."
107 #################### Private functions below ##################################
109 # _acme-challenge.www.domain.com
111 # _sub_domain=_acme-challenge.www
119 _domain
=$
(printf "%s" "$fulldomain" | cut
-d .
-f $i-100)
121 _debug _domain
"$_domain"
122 if [ -z "$_domain" ]; then
127 if ! _servercow_api GET
"$_domain"; then
131 if ! _contains
"$response" '"error":"no such domain in user context"' >/dev
/null
; then
132 _sub_domain
=$
(printf "%s" "$fulldomain" | cut
-d .
-f 1-$p)
133 if [ -z "$_sub_domain" ]; then
153 export _H1
="Content-Type: application/json"
154 export _H2
="X-Auth-Username: $SERVERCOW_API_Username"
155 export _H3
="X-Auth-Password: $SERVERCOW_API_Password"
157 if [ "$method" != "GET" ]; then
159 response
="$(_post "$data" "$SERVERCOW_API/$domain" "" "$method")"
161 response
="$(_get "$SERVERCOW_API/$domain")"
164 if [ "$?" != "0" ]; then
168 _debug2 response
"$response"