diff options
-rwxr-xr-x | linode-ddns.sh | 31 | ||||
-rw-r--r-- | systemd/linode-ddns@.service | 2 | ||||
-rw-r--r-- | systemd/linode-ddns@home.example.org.service.d/opts.conf | 2 |
3 files changed, 20 insertions, 15 deletions
diff --git a/linode-ddns.sh b/linode-ddns.sh index d3a9923..cd0cd76 100755 --- a/linode-ddns.sh +++ b/linode-ddns.sh @@ -2,12 +2,12 @@ # # Copyright 2022 David Vazgenovich Shakaryan # -# LINODE_TOKEN=<token> linode-ddns.sh <domain> <record name> +# LINODE_TOKEN=<token> linode-ddns.sh <domain> IP_RESOLVER='https://ifconfig.co' +TARGET="${1}" -DOMAIN="${1}" -RECORD="${2}" +shopt -s extglob die() { [[ -n "${@}" ]] && echo "${@}" >&2 @@ -22,18 +22,25 @@ lincurl() { ip="$(curl -sf4 "${IP_RESOLVER}")" || die 'IP lookup failed' -res="$(lincurl)" || die 'Domains lookup failed' -domain_id="$(jq -er --arg domain "${DOMAIN}" \ - 'first(.data[] | select(.domain == $domain)) | .id' \ - <<< "${res}")" || die 'Domain not found' +dom_re="${TARGET}" +while [[ "${dom_re}" =~ ^([^\\]*)\.(.*)$ ]]; do + dom_re="(${BASH_REMATCH[1]}\\.)?${BASH_REMATCH[2]}" +done -res=$(lincurl "${domain_id}/records") || die 'Records lookup failed' -record_id="$(jq -er --arg name "${RECORD}" \ +res="$(lincurl)" || die 'Domains lookup failed' +IFS='|' read dom_id dom_name < <(jq -er --arg re "${dom_re}" \ + '[.data[] | select(.domain | test("\\A" + $re + "\\z"))] | + if . == [] then (null | halt_error) else . end | + max_by(.domain | length) | [.id, .domain] | join("|")' \ + <<< "${res}") || die 'Domain not found' +rec_name="${TARGET%%?(.)${dom_name}}" + +res=$(lincurl "${dom_id}/records") || die 'Records lookup failed' +rec_id="$(jq -er --arg name "${rec_name}" \ 'first(.data[] | select(.type == "A" and .name == $name)) | .id' \ <<< "${res}")" || die 'Record not found' -res="$(lincurl "${domain_id}/records/${record_id}")" \ - || die 'Record lookup failed' +res="$(lincurl "${dom_id}/records/${rec_id}")" || die 'Record lookup failed' old_ip="$(jq -r '.target' <<< "${res}")" if [[ "${old_ip}" == "${ip}" ]]; then @@ -41,7 +48,7 @@ if [[ "${old_ip}" == "${ip}" ]]; then exit fi -res="$(lincurl "${domain_id}/records/${record_id}" \ +res="$(lincurl "${dom_id}/records/${rec_id}" \ -H 'Content-Type: application/json' \ -X PUT -d "{\"target\":\"${ip}\"}")" || die 'Record update failed' new_ip="$(jq -r '.target' <<< "${res}")" diff --git a/systemd/linode-ddns@.service b/systemd/linode-ddns@.service index 35905b4..cc445cb 100644 --- a/systemd/linode-ddns@.service +++ b/systemd/linode-ddns@.service @@ -3,4 +3,4 @@ Description=Linode DDNS updater [Service] Type=oneshot -ExecStart=linode-ddns.sh "${DOMAIN}" "${RECORD}" +ExecStart=linode-ddns.sh %i diff --git a/systemd/linode-ddns@home.example.org.service.d/opts.conf b/systemd/linode-ddns@home.example.org.service.d/opts.conf index da136e7..cbd2bea 100644 --- a/systemd/linode-ddns@home.example.org.service.d/opts.conf +++ b/systemd/linode-ddns@home.example.org.service.d/opts.conf @@ -1,4 +1,2 @@ [Service] Environment="LINODE_TOKEN=access_token" -Environment="DOMAIN=example.org" -Environment="RECORD=home" |