added in systemd unit and scripts
added in APP_INSTANCE for custom start includine debug first basic working version that has been deployedmaster
parent
6a53b307ba
commit
ba0f05436c
|
@ -1,11 +1,3 @@
|
|||
notify:
|
||||
services:
|
||||
pushsafer:
|
||||
module: "@uci-utils/notify-pushsafer-plugin"
|
||||
email:
|
||||
module: "@uci-utils/notify-email-plugin"
|
||||
subject: 'A Public IP Address has changed'
|
||||
cron: 10 # interval in minutes to check to see if public ip has changed, comment to run just once or set to falsey
|
||||
lookup:
|
||||
interval: 10 # seconds to keep trying lookup of changed value
|
||||
timeout: 2 # minutes before giving up - failed set
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
debug: true
|
||||
verbose: vv
|
|
@ -1,5 +1,5 @@
|
|||
network: 'testing kebler network'
|
||||
domain: 'test.kebler.net'
|
||||
dev: true
|
||||
announce: true
|
||||
verbose: v
|
||||
cron: 1
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
announce: false
|
||||
pro: true
|
||||
cron: 30 # interval in minutes to check to see if public ip has changed, comment to run just once or set to falsey
|
||||
lookup:
|
||||
interval: 10 # seconds to keep trying lookup of changed value
|
||||
timeout: 2 # minutes before giving up - failed set
|
53
index.js
53
index.js
|
@ -7,15 +7,18 @@ import { promisify } from 'util'
|
|||
const lookup = promisify(clookup)
|
||||
import { CronJob } from 'cron'
|
||||
|
||||
console.log(JSON.stringify(opts, null, 3))
|
||||
const rname = process.argv[2] || opts.domain
|
||||
if (!rname) {
|
||||
console.log('exiting, must supply subdomain record name to check')
|
||||
console.log('exiting, must supply (sub)domain record name to check')
|
||||
console.log(JSON.stringify(opts, null, 3))
|
||||
process.exit()
|
||||
}
|
||||
|
||||
const interval = (opts.lookup || {}).interval * 1000 || 10000
|
||||
const timeout = (opts.lookup || {}).timeout * 1000 * 60 || 120000
|
||||
const verbose = (opts.verbose ||'').length
|
||||
const interval = (opts.lookup || {}).interval || 10 // seconds
|
||||
const timeout = (opts.lookup || {}).timeout || 5 // minutes
|
||||
|
||||
if (verbose) console.log(JSON.stringify(opts, null, 3))
|
||||
|
||||
let notify=()=>{} // noop
|
||||
const route53 = new Route53(opts.aws ? opts.aws : {profile:'default'})
|
||||
|
@ -25,8 +28,7 @@ const route53 = new Route53(opts.aws ? opts.aws : {profile:'default'})
|
|||
const notifier = await Notifier.create(opts.notify)
|
||||
notify = notifier.send.bind(notifier)
|
||||
}
|
||||
|
||||
if (opts.cron) {
|
||||
if (opts.cron && !opts.debug) {
|
||||
console.log('setting up check cron job every', opts.cron,'minutes')
|
||||
const cronstr = `0 */${opts.cron} * * * *`
|
||||
const job = new CronJob(cronstr, checkIP)
|
||||
|
@ -34,7 +36,7 @@ const route53 = new Route53(opts.aws ? opts.aws : {profile:'default'})
|
|||
job.start()
|
||||
} else {
|
||||
console.log('running check a single time')
|
||||
checkIP
|
||||
checkIP()
|
||||
}
|
||||
|
||||
})().catch(err => {
|
||||
|
@ -52,24 +54,41 @@ async function checkIP () {
|
|||
curr = ip.join('.')
|
||||
}
|
||||
const saved = await route53.getZoneRecordValue(rname)
|
||||
if (opts.announce) notify('checking for change in public ip')
|
||||
if (opts.debug) notify('checking for change in public ip',timestamp())
|
||||
if (curr !== saved) {
|
||||
let msg=`For Network:${opts.network}, a new public ip has been detected for ${rname} from ${saved} to ${curr}`
|
||||
console.log(msg)
|
||||
notify(msg)
|
||||
msg=JSON.stringify(await route53.updateZoneRecordValue(rname,curr),null,3)
|
||||
let msg=`${timestamp()} Network:${opts.network}, a new public ip has been detected for ${rname} from ${saved} to ${curr}`
|
||||
console.log(msg)
|
||||
notify(msg)
|
||||
const res=JSON.stringify(await route53.updateZoneRecordValue(rname,curr),null,3)
|
||||
console.log(res)
|
||||
notify(res)
|
||||
const fail = setTimeout(()=>{
|
||||
clearInterval(check)
|
||||
msg=`${timestamp()}, ${opts.network}: FATAL the pending change of ip address was not realized in ${timeout*(opts.debug ? 10 : 60)} seconds. Human attention required`
|
||||
console.log(msg)
|
||||
notify(msg)
|
||||
},timeout*1000*(opts.debug ? 10 : 60))
|
||||
const check = setInterval(async ()=>{
|
||||
if (curr === (await lookup(rname)).address) {
|
||||
msg=`Update Succeeded, lookup of ${rname} is now ${curr}`
|
||||
clearInterval(check)
|
||||
} else msg=`Update Pending, will check again in ${(opts.lookup || {}).interval || 10 } seconds`
|
||||
console.log(msg)
|
||||
notify(msg)
|
||||
clearTimeout(fail)
|
||||
console.log(msg)
|
||||
notify(msg)
|
||||
} else {
|
||||
msg=`Update Pending, will check again in ${interval} seconds`
|
||||
if (verbose || opts.debug ) {
|
||||
notify(msg)
|
||||
console.log(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
,(opts.lookup || {}).interval * 1000 || 10000)
|
||||
// const fail = setTimeout(,timeout)
|
||||
,interval*1000)
|
||||
|
||||
} else console.log('Public IP has not changed, nothing to do', saved)
|
||||
|
||||
}
|
||||
|
||||
function timestamp() {
|
||||
return new Date().toLocaleString().replace('T', ' ').substring(0, 19)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"ignoreRoot": [".git"],
|
||||
"watch": ["config/","node_modules/@uci/","node_modules/@uci-utils/","src/","index.js"],
|
||||
"ignore": [".git"],
|
||||
"ext" : "yaml, js"
|
||||
}
|
|
@ -5,7 +5,8 @@
|
|||
"main": "src/route53.js",
|
||||
"scripts": {
|
||||
"start": "node -r esm index.js",
|
||||
"dev": "NODE_ENV=dev nodemon -r esm index.js"
|
||||
"dev": "NODE_ENV=dev nodemon -r esm index.js",
|
||||
"dev:debug": "NODE_APP_INSTANCE=debug npm run dev"
|
||||
},
|
||||
"author": "David Kebler",
|
||||
"license": "MIT",
|
||||
|
@ -22,7 +23,7 @@
|
|||
"homepage": "https://github.com/uCOMmandIt/uci-utils#readme",
|
||||
"dependencies": {
|
||||
"@uci-utils/notify": "^0.1.5",
|
||||
"@uci-utils/notify-email-plugin": "^0.1.5",
|
||||
"@uci-utils/notify-email-plugin": "^0.1.6",
|
||||
"@uci-utils/notify-pushsafer-plugin": "^0.1.2",
|
||||
"@uci-utils/route53": "^0.1.2",
|
||||
"config": "^3.3.2",
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
CONF=$1
|
||||
if [ -z "$CONF" ];
|
||||
then
|
||||
echo missing configuration argument, aborting
|
||||
exit 1
|
||||
fi
|
||||
DIR="$(dirname "$(readlink -f "$0")")"
|
||||
# echo $DIR
|
||||
cd $DIR || exit
|
||||
NODE=$(which node)
|
||||
export NODE_ENV=production
|
||||
export NODE_APP_INSTANCE=$CONF
|
||||
export NODE_ENV=$2
|
||||
# echo $NODE
|
||||
$NODE -r esm $DIR/index.js
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
# install template system space
|
||||
DIR="$(dirname "$(readlink -f "$0")")"
|
||||
sudo \cp -f $DIR/update-public-ip@.service /etc/systemd/system
|
||||
echo "update-public-ip@.service copied to systemd"
|
||||
. start
|
||||
. persist
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
CONF=$1
|
||||
sudo journalctl --unit=update-public-ip@$CONF.service -n 50 --no-pager
|
||||
exit 1
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
CONF=$1
|
||||
sudo systemctl enable update-public-ip@$CONF
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
CONF=$1
|
||||
if [ -z "$CONF" ];
|
||||
then
|
||||
echo missing configuration argument, aborting
|
||||
exit 1
|
||||
fi
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl stop update-public-ip@$CONF
|
||||
sudo systemctl start update-public-ip@$CONF
|
||||
sudo systemctl status update-public-ip@$CONF
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
CONF=$1
|
||||
if [ -z "$CONF" ];
|
||||
then
|
||||
echo missing configuration argument, aborting
|
||||
exit 1
|
||||
fi
|
||||
sudo systemctl status update-public-ip@$CONF
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
CONF=$1
|
||||
if [ -z "$CONF" ];
|
||||
then
|
||||
echo missing configuration argument, aborting
|
||||
exit 1
|
||||
fi
|
||||
sudo systemctl stop update-public-ip@$CONF
|
||||
sudo systemctl status update-public-ip@$CONF
|
||||
sudo journalctl --unit=update-public-ip@$CONF.service -n 100 --no-pager
|
|
@ -0,0 +1,17 @@
|
|||
[Unit]
|
||||
Description=Update DNS record at Route53 with LAN public IP
|
||||
After=network-online.target
|
||||
[Service]
|
||||
# if using aws profile files must be in .aws under user home given below.
|
||||
User=sysadmin
|
||||
Group=sysadmin
|
||||
# NODE_ENV and NODE_INSTANCE will determine configuration file. see config directory in repo
|
||||
Environment=NODE_ENV=production
|
||||
Environment=NODE_APP_INSTANCE=%i
|
||||
WorkingDirectory=/opt/update-public-ip
|
||||
ExecStart=/usr/bin/node -r esm /opt/update-public-ip/index.js
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
Loading…
Reference in New Issue