parent
9e4af0f074
commit
6a53b307ba
@ -0,0 +1,37 @@ |
||||
module.exports = { |
||||
"ecmaFeatures": { |
||||
"modules": true, |
||||
"spread" : true, |
||||
"restParams" : true |
||||
}, |
||||
// "plugins": [
|
||||
// "unicorn"
|
||||
// ],
|
||||
"env": { |
||||
"es6": true, |
||||
"node": true, |
||||
"mocha": true |
||||
}, |
||||
"parserOptions": { |
||||
"ecmaVersion": 2017, |
||||
"sourceType": "module" |
||||
}, |
||||
"extends": "eslint:recommended", |
||||
"rules": { |
||||
"indent": [ |
||||
"error", |
||||
2 |
||||
], |
||||
// "unicorn/no-array-instanceof": "error",
|
||||
"no-console": 0, |
||||
"semi": ["error", "never"], |
||||
"linebreak-style": [ |
||||
"error", |
||||
"unix" |
||||
], |
||||
"quotes": [ |
||||
"error", |
||||
"single" |
||||
] |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
/node_modules/ |
||||
/coverage/ |
||||
*.lock |
||||
config/local* |
@ -0,0 +1,19 @@ |
||||
network: NETWORK_DESC |
||||
domain: NETWORK_DOMAIN |
||||
notify: |
||||
services: |
||||
pushsafer: |
||||
k: PS_API_KEY, |
||||
d: PS_DEVICE_ID |
||||
email: |
||||
credentials: |
||||
user: GMAIL_SMTP_USER |
||||
pass: GMAIL_SMTP_PW |
||||
aws: |
||||
# region: 'us-east-1' # explicitly set AWS region |
||||
# sslEnabled: true # override whether SSL is enabled |
||||
#maxRetries: 3 # override the number of retries for a request |
||||
# timeout: 15000 |
||||
accessKeyId: AWS_ACCESS_KEY_ID # can omit access key and secret key |
||||
secretAccessKey: AWS_ACCESS_SECRET_KEY # if relying on a profile or IAM |
||||
profile: AWS_PROFILE # name of profile from ~/.aws/credentials |
@ -0,0 +1,11 @@ |
||||
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,5 @@ |
||||
network: 'testing kebler network' |
||||
domain: 'test.kebler.net' |
||||
dev: true |
||||
announce: true |
||||
cron: 1 |
@ -0,0 +1,23 @@ |
||||
# example local.yaml file |
||||
# copy to local.yaml and add secrets, ignored by git |
||||
# aws: # comment out this key to get default profile |
||||
# region: 'us-east-1' # explicitly set AWS region |
||||
# sslEnabled: true # override whether SSL is enabled |
||||
# maxRetries: 3 # override the number of retries for a request |
||||
# timeout: 15000 |
||||
# accessKeyId: 'my iam key' # can omit access key and secret key |
||||
# secretAccessKey: 'my secret' # if relying on a profile or IAM |
||||
# profile: aprofile # name of profile from ~/.aws/credentials |
||||
# notify: |
||||
# services: |
||||
# pushsafer: |
||||
# k: akey # api key |
||||
# d: anid # network admin user or group id |
||||
# email: |
||||
# credentials: |
||||
# user: blah@gmail.com |
||||
# pass: apismtppwsuppliedbygoogle |
||||
# to: |
||||
# - jimshoe@gmail.com |
||||
# - imapsuedonym@gmail.com |
||||
# subject: 'The subject of all notifiction emails' |
@ -0,0 +1,75 @@ |
||||
import opts from 'config' |
||||
import Notifier from '@uci-utils/notify' |
||||
import Route53 from '@uci-utils/route53' |
||||
import pIp from 'public-ip' |
||||
import { lookup as clookup } from 'dns' |
||||
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') |
||||
process.exit() |
||||
} |
||||
|
||||
const interval = (opts.lookup || {}).interval * 1000 || 10000 |
||||
const timeout = (opts.lookup || {}).timeout * 1000 * 60 || 120000 |
||||
|
||||
let notify=()=>{} // noop
|
||||
const route53 = new Route53(opts.aws ? opts.aws : {profile:'default'}) |
||||
; |
||||
(async () => { |
||||
if (opts.notify){ |
||||
const notifier = await Notifier.create(opts.notify) |
||||
notify = notifier.send.bind(notifier) |
||||
} |
||||
|
||||
if (opts.cron) { |
||||
console.log('setting up check cron job every', opts.cron,'minutes') |
||||
const cronstr = `0 */${opts.cron} * * * *` |
||||
const job = new CronJob(cronstr, checkIP) |
||||
console.log('cron job starting with:',cronstr) |
||||
job.start() |
||||
} else { |
||||
console.log('running check a single time') |
||||
checkIP |
||||
} |
||||
|
||||
})().catch(err => { |
||||
console.log('FATAL: IP Updater! \n',err) |
||||
process.exitCode = 1 |
||||
process.kill(process.pid, 'SIGINT') // this will restart via systemd unit
|
||||
}) |
||||
|
||||
|
||||
async function checkIP () { |
||||
let curr = await pIp.v4() |
||||
if (opts.dev) { |
||||
let ip = curr.split('.') |
||||
ip[0] = ip[0] - Math.floor(Math.random() * 10) |
||||
curr = ip.join('.') |
||||
} |
||||
const saved = await route53.getZoneRecordValue(rname) |
||||
if (opts.announce) notify('checking for change in public ip') |
||||
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) |
||||
console.log(msg) |
||||
notify(msg) |
||||
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) |
||||
} |
||||
,(opts.lookup || {}).interval * 1000 || 10000) |
||||
// const fail = setTimeout(,timeout)
|
||||
} else console.log('Public IP has not changed, nothing to do', saved) |
||||
|
||||
} |
@ -0,0 +1,37 @@ |
||||
{ |
||||
"name": "updatePublicIp", |
||||
"version": "0.1.2", |
||||
"description": "", |
||||
"main": "src/route53.js", |
||||
"scripts": { |
||||
"start": "node -r esm index.js", |
||||
"dev": "NODE_ENV=dev nodemon -r esm index.js" |
||||
}, |
||||
"author": "David Kebler", |
||||
"license": "MIT", |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "git+https://github.com/uCOMmandIt/.git" |
||||
}, |
||||
"keywords": [ |
||||
"node.js" |
||||
], |
||||
"bugs": { |
||||
"url": "https://github.com/uCOMmandIt/uci-utils/issues" |
||||
}, |
||||
"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-pushsafer-plugin": "^0.1.2", |
||||
"@uci-utils/route53": "^0.1.2", |
||||
"config": "^3.3.2", |
||||
"cron": "^1.8.2", |
||||
"esm": "^3.2.25", |
||||
"js-yaml": "^3.14.0", |
||||
"public-ip": "^4.0.2" |
||||
}, |
||||
"devDependencies": { |
||||
"nodemon": "^1.19.4" |
||||
} |
||||
} |
@ -0,0 +1,7 @@ |
||||
### Update DNS Record with Public Ip |
||||
|
||||
Need a static IP for your network but don't want to pay for one? Run this node script which includes a cron job and your network can regularly check for changes in its public IP and update a DNS record at a AWS Route53 zone. |
||||
|
||||
Get notified when the network's public IP changes and that the DNS record has been sucessfully updated |
||||
|
||||
Setting/options in config directory |
Loading…
Reference in new issue