Skip to content

Instantly share code, notes, and snippets.

@alexshpilkin
Last active April 29, 2018 21:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexshpilkin/bdb47d6c30027e133c2ac463ea4c7ffc to your computer and use it in GitHub Desktop.
Save alexshpilkin/bdb47d6c30027e133c2ac463ea4c7ffc to your computer and use it in GitHub Desktop.
HTTP API for local DNS records in unbound(8)
#!/bin/sh -eu
DOMAIN=lointa.in
JOURNAL=/srv/dns/$DOMAIN
fail() { echo "Status: $1"; echo "Content-Type: text/plain"; echo; echo "$REQUEST_METHOD"; exit; }
if [ -z "$PATH_INFO" ]; then
echo "Status: 308 Permanent Redirect"
echo "Content-Length: 0";
echo "Location: $SCRIPT_NAME/"
echo
exit
elif [ "x$PATH_INFO" = x/ ]; then
if [ "x$REQUEST_METHOD" != xGET ]; then fail 405; fi
echo 'Content-Type: text/json'
echo 'Link: </dns.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="text/ld+json"'
echo
sep=[
for file in "$JOURNAL"/*; do
printf '%s "%s"\n' "$sep" "$(basename "$file")"; sep=,
done
echo ]
exit
elif echo "$PATH_INFO" | grep -Eq '^/[a-zA-Z0-9-]{1,63}'; then :; else
fail 404
fi
name=$(echo "$PATH_INFO" | cut -c 2- | tr A-Z a-z)
if [ "x$REQUEST_METHOD" = xGET ]; then
echo "Content-Type: text/json; charset=utf-8"
echo
cat "$JOURNAL/$name"
elif [ "x$REQUEST_METHOD" = xPUT ]; then
if [ x"$CONTENT_TYPE" = xtext/json ] \
|| [ x"$CONTENT_TYPE" = xapplication/json ]; then :; else fail 415; fi
data=$(mktemp); trap "rm -f '$data'" EXIT
if jq -c . >"$data" 2>&1; then :; else fail 400; fi
if
unbound-control local_data \
"$name.$DOMAIN. 300 A $(cat "$data" | jq -r .address)" \
>/dev/null
then :; else fail 400; fi
mv "$data" "$JOURNAL/$name"
echo "Status: 200"
echo "Content-Length: 0"
echo
elif [ "x$REQUEST_METHOD" = xDELETE ]; then
if [ -f "$JOURNAL/$name" ]; then :; else fail 404; fi
if [ -w "$JOURNAL/$name" ]; then :; else fail 403; fi
rm "$JOURNAL/$name"
unbound-control local_data_remove "$name.$DOMAIN" >/dev/null
echo "Status: 200"
echo "Content-Length: 0"
echo
else
fail 405
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment