Skip to content

Instantly share code, notes, and snippets.

@hyperfocusaurus
Created December 28, 2014 15:56
Show Gist options
  • Save hyperfocusaurus/18dce21b0b018a33e470 to your computer and use it in GitHub Desktop.
Save hyperfocusaurus/18dce21b0b018a33e470 to your computer and use it in GitHub Desktop.
Update a DNS record using the Digital Ocean REST API. Configure using the constants at the top, run using "node update-dns". NB: borrows heavily from the PHP version from @bensquire called Digital-Ocean-Dynamic-DNS-Updater
const ACCESS_TOKEN = '';
const DOMAIN = '';
const RECORD = '';
var http = require('http');
var https = require('https');
var when = require('when');
var color = require('bash-color');
var fetchExternalIp = function () {
process.stdout.write('Fetching external ip...');
return when.promise(function (resolve, reject) {
var request = http.get("http://ipecho.net/plain", function (result) {
var ip = "";
result.on('data', function (chunk) {
ip += chunk;
});
result.on('end', function () {
resolve(ip);
});
});
});
};
var verifyExternalIp = function (ip) {
return when.promise(function (resolve, reject) {
// IP address regex fetched from http://www.regular-expressions.info/examples.html
if (/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/.test(ip)) {
process.stdout.write(color.green(ip + '\n'));
resolve(ip);
} else {
process.stdout.write(color.red('[FAIL]' + '\n'));
reject('bad ip address');
}
});
};
var errorHandler = function (error) {
process.stderr.write('Error: ' + error);
};
var fetchCurrentRecord = function (newIp) {
process.stdout.write("Fetching current record...");
return when.promise(function (resolve, reject) {
// "https://api.digitalocean.com/v2/domains/" + DOMAIN + "/records"
var request = https.get({
hostname: "api.digitalocean.com",
port: 443,
path: "/v2/domains/" + DOMAIN + "/records",
headers: {
"Authorization": "Bearer " + ACCESS_TOKEN,
"Accept": "application/json"
}
}, function (result) {
var jsonResult = "";
result.on('data', function (chunk) {
jsonResult += chunk;
});
result.on('end', function () {
var records = JSON.parse(jsonResult).domain_records;
var findDomain = function (currentRecord) {
return currentRecord.name === RECORD;
};
var validRecords = records.filter(findDomain);
if (validRecords.length != 1) {
process.stdout.write(color.red("[FAIL]") + "\n");
reject('Too many or too few valid records: ', validRecords.length);
} else {
var currentIp = validRecords[0].data;
var recordId = validRecords[0].id
process.stdout.write(color.green(currentIp) + "\n");
resolve({
currentIp: currentIp,
newIp: newIp,
recordId: recordId
});
}
});
});
});
};
var verifyCurrentRecord = function (args) {
process.stdout.write("Verifying new ip is different from old ip...");
return when.promise(function (resolve, reject) {
if (args.currentIp === args.newIp) {
process.stdout.write(color.yellow("MATCH") + "\n");
resolve(false);
} else {
process.stdout.write(color.green("NO MATCH") + "\n");
resolve(args);
}
});
};
var updateRecord = function (args) {
return when.promise(function (resolve, reject) {
var requestBody = {
data: args.newIp
};
var requestBodyStr = JSON.stringify(requestBody);
var req = https.request({
hostname: "api.digitalocean.com",
port: 443,
method: 'PUT',
path: "v2/domains/" + DOMAIN + "/records/" + args.recordId,
headers: {
"Authorization": "Bearer " + ACCESS_TOKEN,
"Content-Type": "application/json",
"Content-Length": requestBodyStr.length
}
});
req.write(requestBodyStr);
req.end();
});
}
var maybeUpdateRecord = function (newIp, recordId) {
return when.promise(function (resolve, reject) {
if(newIp !== false) {
process.stdout.write("Updating record...");
updateRecord(newIp, recordId).then(resolve, reject);
} else {
process.stdout.write("Doing nothing (already up-to-date)\n");
}
});
}
var run = function () {
process.stdout.write('Updating record: ' + RECORD + '.' + DOMAIN + ' at ' + (new Date()).toISOString() + '\n');
fetchExternalIp()
.then(verifyExternalIp)
.then(fetchCurrentRecord)
.then(verifyCurrentRecord)
.then(maybeUpdateRecord)
.catch(errorHandler)
;
};
// finally, run the damn script
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment