-
-
Save Marak/3297582 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node_modules | |
secrets.js |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "node-nat-ddns-cron", | |
"private": true, | |
"version": "0.0.0", | |
"dependencies": { | |
"nat-pmp": "0.0.1" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var natpmp = require('nat-pmp'); | |
var https = require('https'); | |
var encode = require('querystring').encode; | |
// This is my linode API key, not stored in this file for obvious reasons. | |
var apiKey = require('./secrets').apiKey; | |
var client = natpmp.connect('10.0.1.1'); | |
console.log("Looking up external IP address..."); | |
client.externalIp(function (err, data) { | |
if (err) throw err; | |
// console.log("external ip", data); | |
var ip = data.ip.join("."); | |
console.log("Updating dns for home.creationix.com to point to %s...", ip); | |
setHost("creationix.com", "home", ip, function (err, result) { | |
if (err) throw err; | |
console.log("Mapping 22 on the local machine to 2222 on the nat...") | |
client.portMapping({ private:22, public: 2222, ttl: 3600}, function (err, result) { | |
if (err) throw err; | |
console.log("Done"); | |
process.exit(); | |
}); | |
}); | |
}); | |
/////////////////////////////////////////////////////////////////////////////// | |
function request(query, callback) { | |
query.api_key = "..."; | |
var path = "/?" + encode(query); | |
// console.log("GET https://api.linode.com" + path); | |
query.api_key = apiKey; | |
var path = "/?" + encode(query); | |
https.request({ | |
host: "api.linode.com", | |
path: path | |
}, function (res) { | |
var parts = []; | |
var length = 0; | |
res.on("data", function (chunk) { | |
parts.push(chunk); | |
length += chunk.length; | |
}); | |
res.on("end", function () { | |
res.rawBody = Buffer.concat(parts, length); | |
try { | |
res.body = JSON.parse(res.rawBody.toString('utf8')); | |
} | |
catch (err) { | |
return callback(err); | |
} | |
var errors = res.body.ERRORARRAY; | |
if (errors.length) { | |
var error = errors[0]; | |
var err = new Error(error.ERRORMESSAGE); | |
err.linodeCode = error.ERRORCODE; | |
return callback(err, res); | |
} | |
return callback(null, res, res.body.DATA); | |
}); | |
}).end(); | |
} | |
function filter(data, query) { | |
var queryKeys = Object.keys(query); | |
var queryKeysLength = queryKeys.length; | |
return data.filter(function (item) { | |
for (var j = 0; j < queryKeysLength; j++) { | |
var key = queryKeys[j]; | |
if (item[key] !== query[key]) { | |
return false; | |
} | |
} | |
return true; | |
}); | |
} | |
function getDomains(query, callback) { | |
request({api_action: "domain.list"}, function (err, res, data) { | |
if (err) return callback(err); | |
var domains = filter(data, query); | |
callback(null, domains); | |
}); | |
} | |
function getDomain(query, callback) { | |
getDomains(query, function (err, domains) { | |
if (domains.length) { | |
return callback(null, domains[0]); | |
} | |
var err = new Error("No domain found using query " + JSON.stringify(query)); | |
callback(err); | |
}); | |
} | |
function getDomainResources(domainId, query, callback) { | |
request({ | |
api_action: "domain.resource.list", | |
DomainID: domainId | |
}, function (err, res, data) { | |
if (err) return callback(err); | |
var resources = filter(data, query); | |
callback(null, resources); | |
}); | |
} | |
function getDomainResource(domainId, query, callback) { | |
getDomainResources(domainId, query, function (err, resources) { | |
if (resources.length) { | |
return callback(null, resources[0]); | |
} | |
var err = new Error("No resource found on domain " + domainId + " using query " + JSON.stringify(query)); | |
callback(err); | |
}); | |
} | |
function updateDomainResource(domainId, resourceId, values, callback) { | |
var query = { | |
api_action: "domain.resource.update", | |
DomainID: domainId, | |
ResourceID: resourceId | |
}; | |
for (var key in values) { | |
query[key] = values[key]; | |
} | |
request(query, function (err, res, data) { | |
if (err) return callback(err); | |
callback(null, data); | |
}); | |
} | |
function setHost(domainName, subdomain, ip, callback) { | |
getDomain({DOMAIN: domainName}, function (err, domain) { | |
if (err) return callback(err); | |
// console.log("domain", domain); | |
var domainId = domain.DOMAINID; | |
getDomainResource(domainId, {TYPE: "a", NAME: subdomain}, function (err, resource) { | |
if (err) return callback(err); | |
// console.log("resource", resource); | |
var resourceId = resource.RESOURCEID; | |
updateDomainResource(domainId, resourceId, { Target: ip }, callback); | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment