diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..341a3ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +DIGITALOCEAN_TOKEN +DIGITALOCEAN_DOMAIN diff --git a/dyndns.bash b/dyndns.bash new file mode 100755 index 0000000..91261ec --- /dev/null +++ b/dyndns.bash @@ -0,0 +1,89 @@ +#! /bin/bash + +# Work with DigitalOcean api to update "A" record for a domain. +# Store DigitalOcean API token in file : DIGITALOCEAN_TOKEN +# Store domain to be updated in file : DIGITALOCEAN_DOMAIN + +SCRIPT="${BASH_SOURCE[0]}" +SCRIPT_DIR=$(builtin cd "${SCRIPT%/*}" && pwd ) +SCRIPT_NAME=${SCRIPT##*/} + +REPEAT_CHECK_DIR=$HOME/repeat_check +REPEAT_CHECK=$REPEAT_CHECK_DIR/$SCRIPT_NAME # file to save argument in if successful + +DIGITALOCEAN_DOMAIN=`cat $SCRIPT_DIR/DIGITALOCEAN_DOMAIN` +DIGITALOCEAN_TOKEN=`cat $SCRIPT_DIR/DIGITALOCEAN_TOKEN` + +# Get IP from command line if available. Otherwise use curl to get public IP. +IP="" +if [ "$#" == "1" ]; then + IP=$1 +else + IP=`curl -4 icanhazip.com 2> /dev/null` +fi + +# If $IP does not look like a valid address then complain and exit. +# For regular expression, thank you to : https://tecadmin.net/shell-script-validate-ipv4-addresses/ +if ! [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + echo Invalid IP address format: $IP + exit +fi + +get_a_record_ids() { + curl -X GET \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v2/domains/$DIGITALOCEAN_DOMAIN/records" 2> /dev/null | jq '.domain_records | map(select(.type == "A" and .name == "@")) | map(.id) | .[]' +} + +add_a_record() { + echo adding new A record for $DIGITALOCEAN_DOMAIN with value : $IP + curl -X POST \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + -d "{\"type\":\"A\" \ + ,\"name\":\"@\" \ + ,\"data\":\"$IP\" \ + ,\"priority\":null \ + ,\"port\":null \ + ,\"ttl\":1800 \ + ,\"weight\":null \ + ,\"flags\":null \ + ,\"tag\":null \ + }" \ + "https://api.digitalocean.com/v2/domains/$DIGITALOCEAN_DOMAIN/records" > /dev/null 2>&1 +} + +delete_record_by_id() { + echo deleting existing A record for $DIGITALOCEAN_DOMAIN + curl -X DELETE \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ + "https://api.digitalocean.com/v2/domains/$DIGITALOCEAN_DOMAIN/records/$1" > /dev/null 2>&1 +} + +replace_a_record() { + for id in `get_a_record_ids`; do + delete_record_by_id $id + done + + add_a_record +} + + +# exit if previous successful call was with same argument +if [[ -e $REPEAT_CHECK ]]; then + PREVIOUS_IP=`cat $REPEAT_CHECK` + if [[ "$IP" == "$PREVIOUS_IP" ]]; then + echo previous update was also with argument: \"$IP\" so exiting now to avoid duplicate work. + exit + fi +fi + +# attempt to replace A record and, if successful, save arguments to check against next time +if replace_a_record $IP; then + # if successful then save arguments. + echo update worked so saving arguments \"$IP\" in $REPEAT_CHECK + mkdir -p $REPEAT_CHECK_DIR + echo "$IP" > $REPEAT_CHECK +fi diff --git a/set_digitalocean_dns_a_record.bash b/set_digitalocean_dns_a_record.bash deleted file mode 100755 index f795894..0000000 --- a/set_digitalocean_dns_a_record.bash +++ /dev/null @@ -1,47 +0,0 @@ -#! /bin/bash -SCRIPT="${BASH_SOURCE[0]}" -SCRIPT_DIR=${SCRIPT%/*} - -DIGITALOCEAN_DOMAIN=$1 -IP=$2 - -DIGITALOCEAN_TOKEN=`cat $SCRIPT_DIR/DO_TOKEN` - -get_a_record_ids() { - curl -X GET \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ - "https://api.digitalocean.com/v2/domains/$DIGITALOCEAN_DOMAIN/records" 2> /dev/null | jq '.domain_records | map(select(.type == "A" and .name == "@")) | map(.id) | .[]' -} - -add_a_record() { - echo adding new A record for $DIGITALOCEAN_DOMAIN with value : $IP - curl -X POST \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ - -d "{\"type\":\"A\" \ - ,\"name\":\"@\" \ - ,\"data\":\"$IP\" \ - ,\"priority\":null \ - ,\"port\":null \ - ,\"ttl\":1800 \ - ,\"weight\":null \ - ,\"flags\":null \ - ,\"tag\":null \ - }" \ - "https://api.digitalocean.com/v2/domains/$DIGITALOCEAN_DOMAIN/records" > /dev/null 2>&1 -} - -delete_record_by_id() { - echo deleting existing A record for $DIGITALOCEAN_DOMAIN - curl -X DELETE \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \ - "https://api.digitalocean.com/v2/domains/$DIGITALOCEAN_DOMAIN/records/$1" > /dev/null 2>&1 -} - -for s in `get_a_record_ids`; do - delete_record_by_id $s -done - -add_a_record diff --git a/update_digitalocean_dns_a_record.bash b/update_digitalocean_dns_a_record.bash deleted file mode 100755 index 3dc3edf..0000000 --- a/update_digitalocean_dns_a_record.bash +++ /dev/null @@ -1,30 +0,0 @@ -#! /bin/bash - -# set an A record but first check to make sure we didn't just do this. - -DIGITALOCEAN_DOMAIN=$1 -IP=$2 - -SCRIPT="${BASH_SOURCE[0]}" -SCRIPT_DIR=${SCRIPT%/*} -SCRIPT_NAME=${SCRIPT##*/} - -REPEAT_CHECK_DIR=$HOME/repeat_check -REPEAT_CHECK=$REPEAT_CHECK_DIR/$SCRIPT_NAME # file to save argument in if successful - -# exit if previous successful call was with same argument -if [[ -e $REPEAT_CHECK ]]; then - PREVIOUS_ARGUMENTS=`cat $REPEAT_CHECK` - if [[ "$*" == "$PREVIOUS_ARGUMENTS" ]]; then - echo previous call to $SCRIPT was also with arguments: \"$*\" so exiting now to avoid duplicate work. - exit - fi -fi - -if $SCRIPT_DIR/set_digitalocean_dns_a_record.bash $@; then - # if successful then save arguments. - echo call to $SCRIPT worked so saving arguments \"$*\" in $REPEAT_CHECK - mkdir -p $REPEAT_CHECK_DIR - echo "$*" > $REPEAT_CHECK -fi - diff --git a/update_digitalocean_dns_a_record_to_myip.bash b/update_digitalocean_dns_a_record_to_myip.bash deleted file mode 100755 index 178b269..0000000 --- a/update_digitalocean_dns_a_record_to_myip.bash +++ /dev/null @@ -1,14 +0,0 @@ -#! /bin/bash -SCRIPT="${BASH_SOURCE[0]}" -SCRIPT_DIR=${SCRIPT%/*} - -DIGITALOCEAN_DOMAIN=$1 -IP=`curl -4 icanhazip.com 2> /dev/null` - -# thank you for regular expression to : https://tecadmin.net/shell-script-validate-ipv4-addresses/ -if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then - $SCRIPT_DIR/update_digitalocean_dns_a_record.bash $DIGITALOCEAN_DOMAIN $IP -fi - - -