rework dns api to take domainObject
the DNS backends require many different params, it's just easier to pass them all together and have backends do whatever. For example, route53 API requires the fqdn. Some other backends require just the "part" to insert. * location - location in the database (where app is installed) * zoneName - the dns zone name * domain - domain in the database (where apps are installed into) * name/getName() - this returns the name to insert in the DNS based on zoneName/location * fqdn - the fully resolved location in zoneName verifyDnsConfig also takes a domain object even if it's not in db just so that we can test even existing domain objects, if required. The IP param is removed since it's not required. for caas, we also don't need the fqdn hack in dnsConfig anymore
This commit is contained in:
12
src/apps.js
12
src/apps.js
@@ -397,8 +397,8 @@ function get(appId, callback) {
|
|||||||
for (let d of domainObjects) { domainObjectMap[d.domain] = d; }
|
for (let d of domainObjects) { domainObjectMap[d.domain] = d; }
|
||||||
|
|
||||||
app.iconUrl = getIconUrlSync(app);
|
app.iconUrl = getIconUrlSync(app);
|
||||||
app.fqdn = domains.fqdn(app.location, app.domain, domainObjectMap[app.domain].config);
|
app.fqdn = domains.fqdn(app.location, domainObjectMap[app.domain]);
|
||||||
app.alternateDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, ad.domain, domainObjectMap[ad.domain].config); });
|
app.alternateDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
|
||||||
|
|
||||||
callback(null, app);
|
callback(null, app);
|
||||||
});
|
});
|
||||||
@@ -431,8 +431,8 @@ function getByIpAddress(ip, callback) {
|
|||||||
for (let d of domainObjects) { domainObjectMap[d.domain] = d; }
|
for (let d of domainObjects) { domainObjectMap[d.domain] = d; }
|
||||||
|
|
||||||
app.iconUrl = getIconUrlSync(app);
|
app.iconUrl = getIconUrlSync(app);
|
||||||
app.fqdn = domains.fqdn(app.location, app.domain, domainObjectMap[app.domain].config);
|
app.fqdn = domains.fqdn(app.location, domainObjectMap[app.domain]);
|
||||||
app.alternateDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, ad.domain, domainObjectMap[ad.domain].config); });
|
app.alternateDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
|
||||||
|
|
||||||
callback(null, app);
|
callback(null, app);
|
||||||
});
|
});
|
||||||
@@ -457,8 +457,8 @@ function getAll(callback) {
|
|||||||
|
|
||||||
async.eachSeries(apps, function (app, iteratorDone) {
|
async.eachSeries(apps, function (app, iteratorDone) {
|
||||||
app.iconUrl = getIconUrlSync(app);
|
app.iconUrl = getIconUrlSync(app);
|
||||||
app.fqdn = domains.fqdn(app.location, app.domain, domainObjectMap[app.domain].config);
|
app.fqdn = domains.fqdn(app.location, domainObjectMap[app.domain]);
|
||||||
app.alternateDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, ad.domain, domainObjectMap[ad.domain].config); });
|
app.alternateDomains.forEach(function (ad) { ad.fqdn = domains.fqdn(ad.subdomain, domainObjectMap[ad.domain]); });
|
||||||
|
|
||||||
iteratorDone(null, app);
|
iteratorDone(null, app);
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ function setDashboardDomain(domain, callback) {
|
|||||||
if (error && error.reason === DomainsError.NOT_FOUND) return callback(new CloudronError(CloudronError.BAD_FIELD, 'No such domain'));
|
if (error && error.reason === DomainsError.NOT_FOUND) return callback(new CloudronError(CloudronError.BAD_FIELD, 'No such domain'));
|
||||||
if (error) return callback(new CloudronError(CloudronError.INTERNAL_ERROR, error));
|
if (error) return callback(new CloudronError(CloudronError.INTERNAL_ERROR, error));
|
||||||
|
|
||||||
const fqdn = domains.fqdn(constants.ADMIN_LOCATION, domainObject.domain, domainObject.config);
|
const fqdn = domains.fqdn(constants.ADMIN_LOCATION, domainObject);
|
||||||
|
|
||||||
config.setAdminDomain(domain);
|
config.setAdminDomain(domain);
|
||||||
config.setAdminLocation(constants.ADMIN_LOCATION);
|
config.setAdminLocation(constants.ADMIN_LOCATION);
|
||||||
|
|||||||
@@ -4,35 +4,38 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
config = require('../config.js'),
|
config = require('../config.js'),
|
||||||
debug = require('debug')('box:dns/caas'),
|
debug = require('debug')('box:dns/caas'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
superagent = require('superagent'),
|
superagent = require('superagent'),
|
||||||
util = require('util');
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js');
|
||||||
|
|
||||||
function getFqdn(subdomain, domain) {
|
function getFqdn(location, domain) {
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof domain, 'string');
|
||||||
|
|
||||||
return (subdomain === '') ? domain : subdomain + '-' + domain;
|
return (location === '') ? domain : location + '-' + domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
var fqdn = subdomain !== '' && type === 'TXT' ? subdomain + '.' + dnsConfig.fqdn : getFqdn(subdomain, dnsConfig.fqdn);
|
const dnsConfig = domainObject.config;
|
||||||
|
|
||||||
debug('add: %s for zone %s of type %s with values %j', subdomain, dnsConfig.fqdn, type, values);
|
let fqdn = location !== '' && type === 'TXT' ? location + '.' + domainObject.domain : getFqdn(location, domainObject.domain);
|
||||||
|
|
||||||
|
debug('add: %s for zone %s of type %s with values %j', location, domainObject.domain, type, values);
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
type: type,
|
type: type,
|
||||||
@@ -54,16 +57,16 @@ function add(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
var fqdn = subdomain !== '' && type === 'TXT' ? subdomain + '.' + dnsConfig.fqdn : getFqdn(subdomain, dnsConfig.fqdn);
|
const dnsConfig = domainObject.config;
|
||||||
|
const fqdn = location !== '' && type === 'TXT' ? location + '.' + domainObject.domain : getFqdn(location, domainObject.domain);
|
||||||
|
|
||||||
debug('get: zoneName: %s subdomain: %s type: %s fqdn: %s', dnsConfig.fqdn, subdomain, type, fqdn);
|
debug('get: zoneName: %s subdomain: %s type: %s fqdn: %s', domainObject.domain, location, type, fqdn);
|
||||||
|
|
||||||
superagent
|
superagent
|
||||||
.get(config.apiServerOrigin() + '/api/v1/domains/' + fqdn)
|
.get(config.apiServerOrigin() + '/api/v1/domains/' + fqdn)
|
||||||
@@ -77,26 +80,15 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
add(dnsConfig, zoneName, subdomain, type, values, callback);
|
const dnsConfig = domainObject.config;
|
||||||
}
|
debug('del: %s for zone %s of type %s with values %j', location, domainObject.domain, type, values);
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
|
||||||
assert(util.isArray(values));
|
|
||||||
assert.strictEqual(typeof callback, 'function');
|
|
||||||
|
|
||||||
debug('del: %s for zone %s of type %s with values %j', subdomain, dnsConfig.fqdn, type, values);
|
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
type: type,
|
type: type,
|
||||||
@@ -104,7 +96,7 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
superagent
|
superagent
|
||||||
.del(config.apiServerOrigin() + '/api/v1/domains/' + getFqdn(subdomain, dnsConfig.fqdn))
|
.del(config.apiServerOrigin() + '/api/v1/domains/' + getFqdn(location, domainObject.domain))
|
||||||
.query({ token: dnsConfig.token })
|
.query({ token: dnsConfig.token })
|
||||||
.send(data)
|
.send(data)
|
||||||
.timeout(30 * 1000)
|
.timeout(30 * 1000)
|
||||||
@@ -119,29 +111,42 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, domain, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config;
|
||||||
|
|
||||||
if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string'));
|
if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string'));
|
||||||
|
|
||||||
|
const ip = '127.0.0.1';
|
||||||
|
|
||||||
var credentials = {
|
var credentials = {
|
||||||
token: dnsConfig.token,
|
token: dnsConfig.token,
|
||||||
fqdn: domain,
|
|
||||||
hyphenatedSubdomains: true // this will ensure we always use them, regardless of passed-in configs
|
hyphenatedSubdomains: true // this will ensure we always use them, regardless of passed-in configs
|
||||||
};
|
};
|
||||||
|
|
||||||
const testSubdomain = 'cloudrontestdns';
|
const location = 'cloudrontestdns';
|
||||||
|
|
||||||
upsert(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error, changeId) {
|
upsert(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record added with change id %s', changeId);
|
debug('verifyDnsConfig: Test A record added');
|
||||||
|
|
||||||
del(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error) {
|
del(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record removed again');
|
debug('verifyDnsConfig: Test A record removed again');
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -12,9 +12,11 @@ var assert = require('assert'),
|
|||||||
async = require('async'),
|
async = require('async'),
|
||||||
debug = require('debug')('box:dns/cloudflare'),
|
debug = require('debug')('box:dns/cloudflare'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
superagent = require('superagent'),
|
superagent = require('superagent'),
|
||||||
util = require('util'),
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js'),
|
||||||
_ = require('underscore');
|
_ = require('underscore');
|
||||||
|
|
||||||
// we are using latest v4 stable API https://api.cloudflare.com/#getting-started-endpoints
|
// we are using latest v4 stable API https://api.cloudflare.com/#getting-started-endpoints
|
||||||
@@ -54,16 +56,13 @@ function getZoneByName(dnsConfig, zoneName, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gets records filtered by zone, type and fqdn
|
// gets records filtered by zone, type and fqdn
|
||||||
function getDnsRecords(dnsConfig, zoneId, zoneName, subdomain, type, callback) {
|
function getDnsRecords(dnsConfig, zoneId, fqdn, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof dnsConfig, 'object');
|
||||||
assert.strictEqual(typeof zoneId, 'string');
|
assert.strictEqual(typeof zoneId, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof fqdn, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
var fqdn = subdomain === '' ? zoneName : subdomain + '.' + zoneName;
|
|
||||||
|
|
||||||
superagent.get(CLOUDFLARE_ENDPOINT + '/zones/' + zoneId + '/dns_records')
|
superagent.get(CLOUDFLARE_ENDPOINT + '/zones/' + zoneId + '/dns_records')
|
||||||
.set('X-Auth-Key',dnsConfig.token)
|
.set('X-Auth-Key',dnsConfig.token)
|
||||||
.set('X-Auth-Email',dnsConfig.email)
|
.set('X-Auth-Email',dnsConfig.email)
|
||||||
@@ -79,24 +78,25 @@ function getDnsRecords(dnsConfig, zoneId, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
var fqdn = subdomain === '' ? zoneName : subdomain + '.' + zoneName;
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
debug('upsert: %s for zone %s of type %s with values %j', subdomain, zoneName, type, values);
|
debug('upsert: %s for zone %s of type %s with values %j', fqdn, zoneName, type, values);
|
||||||
|
|
||||||
getZoneByName(dnsConfig, zoneName, function(error, result) {
|
getZoneByName(dnsConfig, zoneName, function(error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
let zoneId = result.id;
|
let zoneId = result.id;
|
||||||
|
|
||||||
getDnsRecords(dnsConfig, zoneId, zoneName, subdomain, type, function (error, dnsRecords) {
|
getDnsRecords(dnsConfig, zoneId, fqdn, type, function (error, dnsRecords) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
let i = 0; // // used to track available records to update instead of create
|
let i = 0; // // used to track available records to update instead of create
|
||||||
@@ -119,7 +119,7 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (i >= dnsRecords.length) { // create a new record
|
if (i >= dnsRecords.length) { // create a new record
|
||||||
debug(`upsert: Adding new record subdomain: ${subdomain}, zoneName: ${zoneName} proxied: false`);
|
debug(`upsert: Adding new record fqdn: ${fqdn}, zoneName: ${zoneName} proxied: false`);
|
||||||
|
|
||||||
superagent.post(CLOUDFLARE_ENDPOINT + '/zones/' + zoneId + '/dns_records')
|
superagent.post(CLOUDFLARE_ENDPOINT + '/zones/' + zoneId + '/dns_records')
|
||||||
.set('X-Auth-Key', dnsConfig.token)
|
.set('X-Auth-Key', dnsConfig.token)
|
||||||
@@ -135,7 +135,7 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
} else { // replace existing record
|
} else { // replace existing record
|
||||||
data.proxied = dnsRecords[i].proxied; // preserve proxied parameter
|
data.proxied = dnsRecords[i].proxied; // preserve proxied parameter
|
||||||
|
|
||||||
debug(`upsert: Updating existing record subdomain: ${subdomain}, zoneName: ${zoneName} proxied: ${data.proxied}`);
|
debug(`upsert: Updating existing record fqdn: ${fqdn}, zoneName: ${zoneName} proxied: ${data.proxied}`);
|
||||||
|
|
||||||
superagent.put(CLOUDFLARE_ENDPOINT + '/zones/' + zoneId + '/dns_records/' + dnsRecords[i].id)
|
superagent.put(CLOUDFLARE_ENDPOINT + '/zones/' + zoneId + '/dns_records/' + dnsRecords[i].id)
|
||||||
.set('X-Auth-Key', dnsConfig.token)
|
.set('X-Auth-Key', dnsConfig.token)
|
||||||
@@ -156,17 +156,20 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
getZoneByName(dnsConfig, zoneName, function(error, result){
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
getZoneByName(dnsConfig, zoneName, function(error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
getDnsRecords(dnsConfig, result.id, zoneName, subdomain, type, function(error, result) {
|
getDnsRecords(dnsConfig, zone.id, fqdn, type, function (error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
var tmp = result.map(function (record) { return record.content; });
|
var tmp = result.map(function (record) { return record.content; });
|
||||||
@@ -177,18 +180,21 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
getZoneByName(dnsConfig, zoneName, function(error, result){
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
getZoneByName(dnsConfig, zoneName, function(error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
getDnsRecords(dnsConfig, result.id, zoneName, subdomain, type, function(error, result) {
|
getDnsRecords(dnsConfig, zone.id, fqdn, type, function(error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
if (result.length === 0) return callback(null);
|
if (result.length === 0) return callback(null);
|
||||||
|
|
||||||
@@ -221,16 +227,31 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof fqdn, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string'));
|
if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string'));
|
||||||
if (!dnsConfig.email || typeof dnsConfig.email !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'email must be a non-empty string'));
|
if (!dnsConfig.email || typeof dnsConfig.email !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'email must be a non-empty string'));
|
||||||
|
|
||||||
|
const ip = '127.0.0.1';
|
||||||
|
|
||||||
var credentials = {
|
var credentials = {
|
||||||
token: dnsConfig.token,
|
token: dnsConfig.token,
|
||||||
email: dnsConfig.email
|
email: dnsConfig.email
|
||||||
@@ -242,22 +263,22 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain'));
|
if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain'));
|
||||||
if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers'));
|
if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers'));
|
||||||
|
|
||||||
getZoneByName(dnsConfig, zoneName, function(error, result) {
|
getZoneByName(dnsConfig, zoneName, function(error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
if (!_.isEqual(result.name_servers.sort(), nameservers.sort())) {
|
if (!_.isEqual(zone.name_servers.sort(), nameservers.sort())) {
|
||||||
debug('verifyDnsConfig: %j and %j do not match', nameservers, result.name_servers);
|
debug('verifyDnsConfig: %j and %j do not match', nameservers, zone.name_servers);
|
||||||
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Cloudflare'));
|
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Cloudflare'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const testSubdomain = 'cloudrontestdns';
|
const location = 'cloudrontestdns';
|
||||||
|
|
||||||
upsert(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error, changeId) {
|
upsert(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record added with change id %s', changeId);
|
debug('verifyDnsConfig: Test A record added');
|
||||||
|
|
||||||
del(dnsConfig, zoneName, testSubdomain, 'A', [ ip ], function (error) {
|
del(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record removed again');
|
debug('verifyDnsConfig: Test A record removed again');
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -12,10 +12,12 @@ var assert = require('assert'),
|
|||||||
async = require('async'),
|
async = require('async'),
|
||||||
debug = require('debug')('box:dns/digitalocean'),
|
debug = require('debug')('box:dns/digitalocean'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
safe = require('safetydance'),
|
safe = require('safetydance'),
|
||||||
superagent = require('superagent'),
|
superagent = require('superagent'),
|
||||||
util = require('util');
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js');
|
||||||
|
|
||||||
var DIGITALOCEAN_ENDPOINT = 'https://api.digitalocean.com';
|
var DIGITALOCEAN_ENDPOINT = 'https://api.digitalocean.com';
|
||||||
|
|
||||||
@@ -23,10 +25,10 @@ function formatError(response) {
|
|||||||
return util.format('DigitalOcean DNS error [%s] %j', response.statusCode, response.body);
|
return util.format('DigitalOcean DNS error [%s] %j', response.statusCode, response.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInternal(dnsConfig, zoneName, subdomain, type, callback) {
|
function getInternal(dnsConfig, zoneName, name, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof dnsConfig, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof zoneName, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof name, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
@@ -45,7 +47,7 @@ function getInternal(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result)));
|
if (result.statusCode !== 200) return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, formatError(result)));
|
||||||
|
|
||||||
matchingRecords = matchingRecords.concat(result.body.domain_records.filter(function (record) {
|
matchingRecords = matchingRecords.concat(result.body.domain_records.filter(function (record) {
|
||||||
return (record.type === type && record.name === subdomain);
|
return (record.type === type && record.name === name);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
nextPage = (result.body.links && result.body.links.pages) ? result.body.links.pages.next : null;
|
nextPage = (result.body.links && result.body.links.pages) ? result.body.links.pages.next : null;
|
||||||
@@ -61,19 +63,20 @@ function getInternal(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug('upsert: %s for zone %s of type %s with values %j', subdomain, zoneName, type, values);
|
debug('upsert: %s for zone %s of type %s with values %j', name, zoneName, type, values);
|
||||||
|
|
||||||
getInternal(dnsConfig, zoneName, subdomain, type, function (error, result) {
|
getInternal(dnsConfig, zoneName, name, type, function (error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
// used to track available records to update instead of create
|
// used to track available records to update instead of create
|
||||||
@@ -89,7 +92,7 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
type: type,
|
type: type,
|
||||||
name: subdomain,
|
name: name,
|
||||||
data: value,
|
data: value,
|
||||||
priority: priority,
|
priority: priority,
|
||||||
ttl: 1
|
ttl: 1
|
||||||
@@ -133,16 +136,17 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
getInternal(dnsConfig, zoneName, subdomain, type, function (error, result) {
|
getInternal(dnsConfig, zoneName, name, type, function (error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
// We only return the value string
|
// We only return the value string
|
||||||
@@ -154,17 +158,18 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
getInternal(dnsConfig, zoneName, subdomain, type, function (error, result) {
|
getInternal(dnsConfig, zoneName, name, type, function (error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
if (result.length === 0) return callback(null);
|
if (result.length === 0) return callback(null);
|
||||||
@@ -193,15 +198,30 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof fqdn, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string'));
|
if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string'));
|
||||||
|
|
||||||
|
const ip = '127.0.0.1';
|
||||||
|
|
||||||
var credentials = {
|
var credentials = {
|
||||||
token: dnsConfig.token
|
token: dnsConfig.token
|
||||||
};
|
};
|
||||||
@@ -217,14 +237,14 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Digital Ocean'));
|
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Digital Ocean'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const testSubdomain = 'cloudrontestdns';
|
const location = 'cloudrontestdns';
|
||||||
|
|
||||||
upsert(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error, changeId) {
|
upsert(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record added with change id %s', changeId);
|
debug('verifyDnsConfig: Test A record added');
|
||||||
|
|
||||||
del(dnsConfig, zoneName, testSubdomain, 'A', [ ip ], function (error) {
|
del(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record removed again');
|
debug('verifyDnsConfig: Test A record removed again');
|
||||||
|
|||||||
@@ -4,16 +4,18 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
debug = require('debug')('box:dns/gandi'),
|
debug = require('debug')('box:dns/gandi'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
superagent = require('superagent'),
|
superagent = require('superagent'),
|
||||||
util = require('util');
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js');
|
||||||
|
|
||||||
var GANDI_API = 'https://dns.api.gandi.net/api/v5';
|
var GANDI_API = 'https://dns.api.gandi.net/api/v5';
|
||||||
|
|
||||||
@@ -21,24 +23,25 @@ function formatError(response) {
|
|||||||
return util.format(`Gandi DNS error [${response.statusCode}] ${response.body.message}`);
|
return util.format(`Gandi DNS error [${response.statusCode}] ${response.body.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug(`upsert: ${subdomain} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
debug(`upsert: ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
'rrset_ttl': 300, // this is the minimum allowed
|
'rrset_ttl': 300, // this is the minimum allowed
|
||||||
'rrset_values': values // for mx records, value is already of the '<priority> <server>' format
|
'rrset_values': values // for mx records, value is already of the '<priority> <server>' format
|
||||||
};
|
};
|
||||||
|
|
||||||
superagent.put(`${GANDI_API}/domains/${zoneName}/records/${subdomain}/${type}`)
|
superagent.put(`${GANDI_API}/domains/${zoneName}/records/${name}/${type}`)
|
||||||
.set('X-Api-Key', dnsConfig.token)
|
.set('X-Api-Key', dnsConfig.token)
|
||||||
.timeout(30 * 1000)
|
.timeout(30 * 1000)
|
||||||
.send(data)
|
.send(data)
|
||||||
@@ -52,18 +55,19 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug(`get: ${subdomain} in zone ${zoneName} of type ${type}`);
|
debug(`get: ${name} in zone ${zoneName} of type ${type}`);
|
||||||
|
|
||||||
superagent.get(`${GANDI_API}/domains/${zoneName}/records/${subdomain}/${type}`)
|
superagent.get(`${GANDI_API}/domains/${zoneName}/records/${name}/${type}`)
|
||||||
.set('X-Api-Key', dnsConfig.token)
|
.set('X-Api-Key', dnsConfig.token)
|
||||||
.timeout(30 * 1000)
|
.timeout(30 * 1000)
|
||||||
.end(function (error, result) {
|
.end(function (error, result) {
|
||||||
@@ -78,19 +82,20 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug(`del: ${subdomain} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
debug(`del: ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
||||||
|
|
||||||
superagent.del(`${GANDI_API}/domains/${zoneName}/records/${subdomain}/${type}`)
|
superagent.del(`${GANDI_API}/domains/${zoneName}/records/${name}/${type}`)
|
||||||
.set('X-Api-Key', dnsConfig.token)
|
.set('X-Api-Key', dnsConfig.token)
|
||||||
.timeout(30 * 1000)
|
.timeout(30 * 1000)
|
||||||
.end(function (error, result) {
|
.end(function (error, result) {
|
||||||
@@ -105,19 +110,34 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof fqdn, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string'));
|
if (!dnsConfig.token || typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a non-empty string'));
|
||||||
|
|
||||||
var credentials = {
|
var credentials = {
|
||||||
token: dnsConfig.token
|
token: dnsConfig.token
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ip = '127.0.0.1';
|
||||||
|
|
||||||
if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here
|
if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here
|
||||||
|
|
||||||
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
||||||
@@ -129,14 +149,14 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Gandi'));
|
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Gandi'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const testSubdomain = 'cloudrontestdns';
|
const location = 'cloudrontestdns';
|
||||||
|
|
||||||
upsert(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error, changeId) {
|
upsert(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record added with change id %s', changeId);
|
debug('verifyDnsConfig: Test A record added');
|
||||||
|
|
||||||
del(dnsConfig, zoneName, testSubdomain, 'A', [ ip ], function (error) {
|
del(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record removed again');
|
debug('verifyDnsConfig: Test A record removed again');
|
||||||
|
|||||||
@@ -4,16 +4,18 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
debug = require('debug')('box:dns/gcdns'),
|
debug = require('debug')('box:dns/gcdns'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
GCDNS = require('@google-cloud/dns'),
|
GCDNS = require('@google-cloud/dns'),
|
||||||
util = require('util'),
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js'),
|
||||||
_ = require('underscore');
|
_ = require('underscore');
|
||||||
|
|
||||||
function getDnsCredentials(dnsConfig) {
|
function getDnsCredentials(dnsConfig) {
|
||||||
@@ -55,22 +57,23 @@ function getZoneByName(dnsConfig, zoneName, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug('add: %s for zone %s of type %s with values %j', subdomain, zoneName, type, values);
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
debug('add: %s for zone %s of type %s with values %j', fqdn, zoneName, type, values);
|
||||||
|
|
||||||
getZoneByName(getDnsCredentials(dnsConfig), zoneName, function (error, zone) {
|
getZoneByName(getDnsCredentials(dnsConfig), zoneName, function (error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
var domain = (subdomain ? subdomain + '.' : '') + zoneName + '.';
|
zone.getRecords({ type: type, name: fqdn + '.' }, function (error, oldRecords) {
|
||||||
|
|
||||||
zone.getRecords({ type: type, name: domain }, function (error, oldRecords) {
|
|
||||||
if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message));
|
if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message));
|
||||||
if (error) {
|
if (error) {
|
||||||
debug('upsert->zone.getRecords', error);
|
debug('upsert->zone.getRecords', error);
|
||||||
@@ -78,12 +81,12 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newRecord = zone.record(type, {
|
var newRecord = zone.record(type, {
|
||||||
name: domain,
|
name: fqdn + '.',
|
||||||
data: values,
|
data: values,
|
||||||
ttl: 1
|
ttl: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
zone.createChange({ delete: oldRecords, add: newRecord }, function(error, change) {
|
zone.createChange({ delete: oldRecords, add: newRecord }, function(error /*, change */) {
|
||||||
if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message));
|
if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message));
|
||||||
if (error && error.code === 412) return callback(new DomainsError(DomainsError.STILL_BUSY, error.message));
|
if (error && error.code === 412) return callback(new DomainsError(DomainsError.STILL_BUSY, error.message));
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -97,18 +100,21 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
getZoneByName(getDnsCredentials(dnsConfig), zoneName, function (error, zone) {
|
getZoneByName(getDnsCredentials(dnsConfig), zoneName, function (error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
name: (subdomain ? subdomain + '.' : '') + zoneName + '.',
|
name: fqdn + '.',
|
||||||
type: type
|
type: type
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -122,20 +128,21 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
getZoneByName(getDnsCredentials(dnsConfig), zoneName, function (error, zone) {
|
getZoneByName(getDnsCredentials(dnsConfig), zoneName, function (error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
var domain = (subdomain ? subdomain + '.' : '') + zoneName + '.';
|
zone.getRecords({ type: type, name: fqdn + '.' }, function(error, oldRecords) {
|
||||||
|
|
||||||
zone.getRecords({ type: type, name: domain }, function(error, oldRecords) {
|
|
||||||
if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message));
|
if (error && error.code === 403) return callback(new DomainsError(DomainsError.ACCESS_DENIED, error.message));
|
||||||
if (error) {
|
if (error) {
|
||||||
debug('del->zone.getRecords', error);
|
debug('del->zone.getRecords', error);
|
||||||
@@ -156,19 +163,35 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof fqdn, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
if (typeof dnsConfig.projectId !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'projectId must be a string'));
|
if (typeof dnsConfig.projectId !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'projectId must be a string'));
|
||||||
if (!dnsConfig.credentials || typeof dnsConfig.credentials !== 'object') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials must be an object'));
|
if (!dnsConfig.credentials || typeof dnsConfig.credentials !== 'object') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials must be an object'));
|
||||||
if (typeof dnsConfig.credentials.client_email !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials.client_email must be a string'));
|
if (typeof dnsConfig.credentials.client_email !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials.client_email must be a string'));
|
||||||
if (typeof dnsConfig.credentials.private_key !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials.private_key must be a string'));
|
if (typeof dnsConfig.credentials.private_key !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'credentials.private_key must be a string'));
|
||||||
|
|
||||||
var credentials = getDnsCredentials(dnsConfig);
|
var credentials = getDnsCredentials(dnsConfig);
|
||||||
|
|
||||||
|
const ip = '127.0.0.1';
|
||||||
|
|
||||||
if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here
|
if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here
|
||||||
|
|
||||||
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
||||||
@@ -184,14 +207,14 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Google Cloud DNS'));
|
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Google Cloud DNS'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const testSubdomain = 'cloudrontestdns';
|
const location = 'cloudrontestdns';
|
||||||
|
|
||||||
upsert(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error, changeId) {
|
upsert(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record added with change id %s', changeId);
|
debug('verifyDnsConfig: Test A record added');
|
||||||
|
|
||||||
del(dnsConfig, zoneName, testSubdomain, 'A', [ ip ], function (error) {
|
del(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record removed again');
|
debug('verifyDnsConfig: Test A record removed again');
|
||||||
|
|||||||
@@ -4,16 +4,18 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
debug = require('debug')('box:dns/godaddy'),
|
debug = require('debug')('box:dns/godaddy'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
superagent = require('superagent'),
|
superagent = require('superagent'),
|
||||||
util = require('util');
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js');
|
||||||
|
|
||||||
// const GODADDY_API_OTE = 'https://api.ote-godaddy.com/v1/domains';
|
// const GODADDY_API_OTE = 'https://api.ote-godaddy.com/v1/domains';
|
||||||
const GODADDY_API = 'https://api.godaddy.com/v1/domains';
|
const GODADDY_API = 'https://api.godaddy.com/v1/domains';
|
||||||
@@ -27,17 +29,18 @@ function formatError(response) {
|
|||||||
return util.format(`GoDaddy DNS error [${response.statusCode}] ${response.body.message}`);
|
return util.format(`GoDaddy DNS error [${response.statusCode}] ${response.body.message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug(`upsert: ${subdomain} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
debug(`upsert: ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
||||||
|
|
||||||
var records = [ ];
|
var records = [ ];
|
||||||
values.forEach(function (value) {
|
values.forEach(function (value) {
|
||||||
@@ -53,7 +56,7 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
records.push(record);
|
records.push(record);
|
||||||
});
|
});
|
||||||
|
|
||||||
superagent.put(`${GODADDY_API}/${zoneName}/records/${type}/${subdomain}`)
|
superagent.put(`${GODADDY_API}/${zoneName}/records/${type}/${name}`)
|
||||||
.set('Authorization', `sso-key ${dnsConfig.apiKey}:${dnsConfig.apiSecret}`)
|
.set('Authorization', `sso-key ${dnsConfig.apiKey}:${dnsConfig.apiSecret}`)
|
||||||
.timeout(30 * 1000)
|
.timeout(30 * 1000)
|
||||||
.send(records)
|
.send(records)
|
||||||
@@ -68,18 +71,19 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug(`get: ${subdomain} in zone ${zoneName} of type ${type}`);
|
debug(`get: ${name} in zone ${zoneName} of type ${type}`);
|
||||||
|
|
||||||
superagent.get(`${GODADDY_API}/${zoneName}/records/${type}/${subdomain}`)
|
superagent.get(`${GODADDY_API}/${zoneName}/records/${type}/${name}`)
|
||||||
.set('Authorization', `sso-key ${dnsConfig.apiKey}:${dnsConfig.apiSecret}`)
|
.set('Authorization', `sso-key ${dnsConfig.apiKey}:${dnsConfig.apiSecret}`)
|
||||||
.timeout(30 * 1000)
|
.timeout(30 * 1000)
|
||||||
.end(function (error, result) {
|
.end(function (error, result) {
|
||||||
@@ -98,22 +102,23 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug(`get: ${subdomain} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
debug(`get: ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
||||||
|
|
||||||
if (type !== 'A' && type !== 'TXT') return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, new Error('Record deletion is not supported by GoDaddy API')));
|
if (type !== 'A' && type !== 'TXT') return callback(new DomainsError(DomainsError.EXTERNAL_ERROR, new Error('Record deletion is not supported by GoDaddy API')));
|
||||||
|
|
||||||
// check if the record exists at all so that we don't insert the "Dead" record for no reason
|
// check if the record exists at all so that we don't insert the "Dead" record for no reason
|
||||||
get(dnsConfig, zoneName, subdomain, type, function (error, values) {
|
get(domainObject, location, type, function (error, values) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
if (values.length === 0) return callback();
|
if (values.length === 0) return callback();
|
||||||
|
|
||||||
@@ -123,7 +128,7 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
data: type === 'A' ? GODADDY_INVALID_IP : GODADDY_INVALID_TXT
|
data: type === 'A' ? GODADDY_INVALID_IP : GODADDY_INVALID_TXT
|
||||||
}];
|
}];
|
||||||
|
|
||||||
superagent.put(`${GODADDY_API}/${zoneName}/records/${type}/${subdomain}`)
|
superagent.put(`${GODADDY_API}/${zoneName}/records/${type}/${name}`)
|
||||||
.set('Authorization', `sso-key ${dnsConfig.apiKey}:${dnsConfig.apiSecret}`)
|
.set('Authorization', `sso-key ${dnsConfig.apiKey}:${dnsConfig.apiSecret}`)
|
||||||
.send(records)
|
.send(records)
|
||||||
.timeout(30 * 1000)
|
.timeout(30 * 1000)
|
||||||
@@ -140,16 +145,31 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof fqdn, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
if (!dnsConfig.apiKey || typeof dnsConfig.apiKey !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'apiKey must be a non-empty string'));
|
if (!dnsConfig.apiKey || typeof dnsConfig.apiKey !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'apiKey must be a non-empty string'));
|
||||||
if (!dnsConfig.apiSecret || typeof dnsConfig.apiSecret !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'apiSecret must be a non-empty string'));
|
if (!dnsConfig.apiSecret || typeof dnsConfig.apiSecret !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'apiSecret must be a non-empty string'));
|
||||||
|
|
||||||
|
const ip = '127.0.0.1';
|
||||||
|
|
||||||
var credentials = {
|
var credentials = {
|
||||||
apiKey: dnsConfig.apiKey,
|
apiKey: dnsConfig.apiKey,
|
||||||
apiSecret: dnsConfig.apiSecret
|
apiSecret: dnsConfig.apiSecret
|
||||||
@@ -166,14 +186,14 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to GoDaddy'));
|
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to GoDaddy'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const testSubdomain = 'cloudrontestdns';
|
const location = 'cloudrontestdns';
|
||||||
|
|
||||||
upsert(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error, changeId) {
|
upsert(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record added with change id %s', changeId);
|
debug('verifyDnsConfig: Test A record added');
|
||||||
|
|
||||||
del(dnsConfig, zoneName, testSubdomain, 'A', [ ip ], function (error) {
|
del(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record removed again');
|
debug('verifyDnsConfig: Test A record removed again');
|
||||||
|
|||||||
@@ -10,18 +10,16 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
|
||||||
util = require('util');
|
util = require('util');
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
@@ -31,10 +29,9 @@ function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
callback(new Error('not implemented'));
|
callback(new Error('not implemented'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
@@ -43,10 +40,9 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
callback(new Error('not implemented'));
|
callback(new Error('not implemented'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
@@ -56,11 +52,19 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
callback(new Error('not implemented'));
|
callback(new Error('not implemented'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, domain, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
// Result: dnsConfig object
|
// Result: dnsConfig object
|
||||||
|
|||||||
@@ -4,43 +4,42 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
debug = require('debug')('box:dns/manual'),
|
debug = require('debug')('box:dns/manual'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
util = require('util');
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js');
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug('upsert: %s for zone %s of type %s with values %j', subdomain, zoneName, type, values);
|
debug('upsert: %s for zone %s of type %s with values %j', location, domainObject.zoneName, type, values);
|
||||||
|
|
||||||
return callback(null);
|
return callback(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
callback(null, [ ]); // returning ip confuses apptask into thinking the entry already exists
|
callback(null, [ ]); // returning ip confuses apptask into thinking the entry already exists
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
@@ -48,13 +47,25 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, domain, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
// Very basic check if the nameservers can be fetched
|
// Very basic check if the nameservers can be fetched
|
||||||
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
||||||
if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain'));
|
if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain'));
|
||||||
|
|||||||
@@ -4,16 +4,19 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
debug = require('debug')('box:dns/namecom'),
|
debug = require('debug')('box:dns/namecom'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
safe = require('safetydance'),
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
superagent = require('superagent');
|
safe = require('safetydance'),
|
||||||
|
superagent = require('superagent'),
|
||||||
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js');
|
||||||
|
|
||||||
const NAMECOM_API = 'https://api.name.com/v4';
|
const NAMECOM_API = 'https://api.name.com/v4';
|
||||||
|
|
||||||
@@ -21,18 +24,18 @@ function formatError(response) {
|
|||||||
return `Name.com DNS error [${response.statusCode}] ${response.text}`;
|
return `Name.com DNS error [${response.statusCode}] ${response.text}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addRecord(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function addRecord(dnsConfig, zoneName, name, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof dnsConfig, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof zoneName, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof name, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(Array.isArray(values));
|
assert(Array.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug(`add: ${subdomain} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
debug(`add: ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
host: subdomain,
|
host: name,
|
||||||
type: type,
|
type: type,
|
||||||
ttl: 300 // 300 is the lowest
|
ttl: 300 // 300 is the lowest
|
||||||
};
|
};
|
||||||
@@ -57,19 +60,19 @@ function addRecord(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateRecord(dnsConfig, zoneName, recordId, subdomain, type, values, callback) {
|
function updateRecord(dnsConfig, zoneName, recordId, name, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof dnsConfig, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof zoneName, 'string');
|
||||||
assert.strictEqual(typeof recordId, 'number');
|
assert.strictEqual(typeof recordId, 'number');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof name, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(Array.isArray(values));
|
assert(Array.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug(`update:${recordId} on ${subdomain} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
debug(`update:${recordId} on ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
host: subdomain,
|
host: name,
|
||||||
type: type,
|
type: type,
|
||||||
ttl: 300 // 300 is the lowest
|
ttl: 300 // 300 is the lowest
|
||||||
};
|
};
|
||||||
@@ -94,16 +97,14 @@ function updateRecord(dnsConfig, zoneName, recordId, subdomain, type, values, ca
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInternal(dnsConfig, zoneName, subdomain, type, callback) {
|
function getInternal(dnsConfig, zoneName, name, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof dnsConfig, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof zoneName, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof name, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
debug(`getInternal: ${name} in zone ${zoneName} of type ${type}`);
|
||||||
|
|
||||||
debug(`getInternal: ${subdomain} in zone ${zoneName} of type ${type}`);
|
|
||||||
|
|
||||||
superagent.get(`${NAMECOM_API}/domains/${zoneName}/records`)
|
superagent.get(`${NAMECOM_API}/domains/${zoneName}/records`)
|
||||||
.auth(dnsConfig.username, dnsConfig.token)
|
.auth(dnsConfig.username, dnsConfig.token)
|
||||||
@@ -123,7 +124,7 @@ function getInternal(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var results = result.body.records.filter(function (r) {
|
var results = result.body.records.filter(function (r) {
|
||||||
return (r.host === subdomain && r.type === type);
|
return (r.host === name && r.type === type);
|
||||||
});
|
});
|
||||||
|
|
||||||
debug('getInternal: %j', results);
|
debug('getInternal: %j', results);
|
||||||
@@ -132,35 +133,39 @@ function getInternal(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(Array.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug(`upsert: ${subdomain} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
debug(`upsert: ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
||||||
|
|
||||||
getInternal(dnsConfig, zoneName, subdomain, type, function (error, result) {
|
getInternal(dnsConfig, zoneName, name, type, function (error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
if (result.length === 0) return addRecord(dnsConfig, zoneName, subdomain, type, values, callback);
|
if (result.length === 0) return addRecord(dnsConfig, zoneName, name, type, values, callback);
|
||||||
|
|
||||||
return updateRecord(dnsConfig, zoneName, result[0].id, subdomain, type, values, callback);
|
return updateRecord(dnsConfig, zoneName, result[0].id, name, type, values, callback);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
getInternal(dnsConfig, zoneName, subdomain, type, function (error, result) {
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
|
getInternal(dnsConfig, zoneName, name, type, function (error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
var tmp = result.map(function (record) { return record.answer; });
|
var tmp = result.map(function (record) { return record.answer; });
|
||||||
@@ -171,19 +176,20 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(Array.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
subdomain = subdomain || '@';
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
name = domains.getName(domainObject, location, type) || '@';
|
||||||
|
|
||||||
debug(`del: ${subdomain} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
debug(`del: ${name} in zone ${zoneName} of type ${type} with values ${JSON.stringify(values)}`);
|
||||||
|
|
||||||
getInternal(dnsConfig, zoneName, subdomain, type, function (error, result) {
|
getInternal(dnsConfig, zoneName, name, type, function (error, result) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
if (result.length === 0) return callback();
|
if (result.length === 0) return callback();
|
||||||
@@ -201,13 +207,26 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof fqdn, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
if (typeof dnsConfig.username !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'username must be a string'));
|
if (typeof dnsConfig.username !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'username must be a string'));
|
||||||
if (typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a string'));
|
if (typeof dnsConfig.token !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'token must be a string'));
|
||||||
|
|
||||||
@@ -216,6 +235,8 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
token: dnsConfig.token
|
token: dnsConfig.token
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ip = '127.0.0.1';
|
||||||
|
|
||||||
if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here
|
if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here
|
||||||
|
|
||||||
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
||||||
@@ -227,14 +248,14 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Name.com'));
|
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Name.com'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const testSubdomain = 'cloudrontestdns';
|
const location = 'cloudrontestdns';
|
||||||
|
|
||||||
upsert(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error, changeId) {
|
upsert(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record added with change id %s', changeId);
|
debug('verifyDnsConfig: Test A record added');
|
||||||
|
|
||||||
del(dnsConfig, zoneName, testSubdomain, 'A', [ ip ], function (error) {
|
del(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record removed again');
|
debug('verifyDnsConfig: Test A record removed again');
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: waitForDns,
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -12,33 +12,30 @@ var assert = require('assert'),
|
|||||||
debug = require('debug')('box:dns/noop'),
|
debug = require('debug')('box:dns/noop'),
|
||||||
util = require('util');
|
util = require('util');
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug('upsert: %s for zone %s of type %s with values %j', subdomain, zoneName, type, values);
|
debug('upsert: %s for zone %s of type %s with values %j', location, domainObject.zoneName, type, values);
|
||||||
|
|
||||||
return callback(null);
|
return callback(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
callback(null, [ ]); // returning ip confuses apptask into thinking the entry already exists
|
callback(null, [ ]); // returning ip confuses apptask into thinking the entry already exists
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
@@ -46,9 +43,9 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForDns(domain, zoneName, type, value, options, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof value, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
@@ -57,11 +54,8 @@ function waitForDns(domain, zoneName, type, value, options, callback) {
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, domain, zoneName, ip, callback) {
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
|
||||||
assert.strictEqual(typeof ip, 'string');
|
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
return callback(null, { });
|
return callback(null, { });
|
||||||
|
|||||||
@@ -4,19 +4,18 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig,
|
verifyDnsConfig: verifyDnsConfig
|
||||||
|
|
||||||
// not part of "dns" interface
|
|
||||||
getHostedZone: getHostedZone
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
AWS = require('aws-sdk'),
|
AWS = require('aws-sdk'),
|
||||||
debug = require('debug')('box:dns/route53'),
|
debug = require('debug')('box:dns/route53'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
util = require('util'),
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js'),
|
||||||
_ = require('underscore');
|
_ = require('underscore');
|
||||||
|
|
||||||
function getDnsCredentials(dnsConfig) {
|
function getDnsCredentials(dnsConfig) {
|
||||||
@@ -82,20 +81,22 @@ function getHostedZone(dnsConfig, zoneName, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug('add: %s for zone %s of type %s with values %j', subdomain, zoneName, type, values);
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
debug('add: %s for zone %s of type %s with values %j', fqdn, zoneName, type, values);
|
||||||
|
|
||||||
getZoneByName(dnsConfig, zoneName, function (error, zone) {
|
getZoneByName(dnsConfig, zoneName, function (error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
var fqdn = subdomain === '' ? zoneName : subdomain + '.' + zoneName;
|
|
||||||
var records = values.map(function (v) { return { Value: v }; }); // for mx records, value is already of the '<priority> <server>' format
|
var records = values.map(function (v) { return { Value: v }; }); // for mx records, value is already of the '<priority> <server>' format
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
@@ -126,31 +127,23 @@ function add(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
|
||||||
assert(util.isArray(values));
|
|
||||||
assert.strictEqual(typeof callback, 'function');
|
|
||||||
|
|
||||||
add(dnsConfig, zoneName, subdomain, type, values, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
getZoneByName(dnsConfig, zoneName, function (error, zone) {
|
getZoneByName(dnsConfig, zoneName, function (error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
var params = {
|
var params = {
|
||||||
HostedZoneId: zone.Id,
|
HostedZoneId: zone.Id,
|
||||||
MaxItems: '1',
|
MaxItems: '1',
|
||||||
StartRecordName: (subdomain ? subdomain + '.' : '') + zoneName + '.',
|
StartRecordName: fqdn + '.',
|
||||||
StartRecordType: type
|
StartRecordType: type
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -169,18 +162,20 @@ function get(dnsConfig, zoneName, subdomain, type, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName,
|
||||||
|
fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
getZoneByName(dnsConfig, zoneName, function (error, zone) {
|
getZoneByName(dnsConfig, zoneName, function (error, zone) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
var fqdn = subdomain === '' ? zoneName : subdomain + '.' + zoneName;
|
|
||||||
var records = values.map(function (v) { return { Value: v }; });
|
var records = values.map(function (v) { return { Value: v }; });
|
||||||
|
|
||||||
var resourceRecordSet = {
|
var resourceRecordSet = {
|
||||||
@@ -226,13 +221,26 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof fqdn, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const dnsConfig = domainObject.config,
|
||||||
|
zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
if (!dnsConfig.accessKeyId || typeof dnsConfig.accessKeyId !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'accessKeyId must be a non-empty string'));
|
if (!dnsConfig.accessKeyId || typeof dnsConfig.accessKeyId !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'accessKeyId must be a non-empty string'));
|
||||||
if (!dnsConfig.secretAccessKey || typeof dnsConfig.secretAccessKey !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'secretAccessKey must be a non-empty string'));
|
if (!dnsConfig.secretAccessKey || typeof dnsConfig.secretAccessKey !== 'string') return callback(new DomainsError(DomainsError.BAD_FIELD, 'secretAccessKey must be a non-empty string'));
|
||||||
|
|
||||||
@@ -244,6 +252,8 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
listHostedZonesByName: true, // new/updated creds require this perm
|
listHostedZonesByName: true, // new/updated creds require this perm
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ip = '127.0.0.1';
|
||||||
|
|
||||||
if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here
|
if (process.env.BOX_ENV === 'test') return callback(null, credentials); // this shouldn't be here
|
||||||
|
|
||||||
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
||||||
@@ -258,14 +268,14 @@ function verifyDnsConfig(dnsConfig, fqdn, zoneName, ip, callback) {
|
|||||||
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Route53'));
|
return callback(new DomainsError(DomainsError.BAD_FIELD, 'Domain nameservers are not set to Route53'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const testSubdomain = 'cloudrontestdns';
|
const location = 'cloudrontestdns';
|
||||||
|
|
||||||
upsert(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error, changeId) {
|
upsert(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record added with change id %s', changeId);
|
debug('verifyDnsConfig: Test A record added');
|
||||||
|
|
||||||
del(credentials, zoneName, testSubdomain, 'A', [ ip ], function (error) {
|
del(domainObject, location, 'A', [ ip ], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug('verifyDnsConfig: Test A record removed again');
|
debug('verifyDnsConfig: Test A record removed again');
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ function resolveIp(hostname, options, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function isChangeSynced(domain, type, value, nameserver, callback) {
|
function isChangeSynced(hostname, type, value, nameserver, callback) {
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof hostname, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof value, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
assert.strictEqual(typeof nameserver, 'string');
|
assert.strictEqual(typeof nameserver, 'string');
|
||||||
@@ -46,16 +46,16 @@ function isChangeSynced(domain, type, value, nameserver, callback) {
|
|||||||
|
|
||||||
async.every(nsIps, function (nsIp, iteratorCallback) {
|
async.every(nsIps, function (nsIp, iteratorCallback) {
|
||||||
const resolveOptions = { server: nsIp, timeout: 5000 };
|
const resolveOptions = { server: nsIp, timeout: 5000 };
|
||||||
const resolver = type === 'A' ? resolveIp.bind(null, domain) : dns.resolve.bind(null, domain, 'TXT');
|
const resolver = type === 'A' ? resolveIp.bind(null, hostname) : dns.resolve.bind(null, hostname, 'TXT');
|
||||||
|
|
||||||
resolver(resolveOptions, function (error, answer) {
|
resolver(resolveOptions, function (error, answer) {
|
||||||
if (error && error.code === 'TIMEOUT') {
|
if (error && error.code === 'TIMEOUT') {
|
||||||
debug(`isChangeSynced: NS ${nameserver} (${nsIp}) timed out when resolving ${domain} (${type})`);
|
debug(`isChangeSynced: NS ${nameserver} (${nsIp}) timed out when resolving ${hostname} (${type})`);
|
||||||
return iteratorCallback(null, true); // should be ok if dns server is down
|
return iteratorCallback(null, true); // should be ok if dns server is down
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
debug(`isChangeSynced: NS ${nameserver} (${nsIp}) errored when resolve ${domain} (${type}): ${error}`);
|
debug(`isChangeSynced: NS ${nameserver} (${nsIp}) errored when resolve ${hostname} (${type}): ${error}`);
|
||||||
return iteratorCallback(null, false);
|
return iteratorCallback(null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ function isChangeSynced(domain, type, value, nameserver, callback) {
|
|||||||
match = answer.some(function (a) { return value === a.join(''); });
|
match = answer.some(function (a) { return value === a.join(''); });
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(`isChangeSynced: ${domain} (${type}) was resolved to ${answer} at NS ${nameserver} (${nsIp}). Expecting ${value}. Match ${match}`);
|
debug(`isChangeSynced: ${hostname} (${type}) was resolved to ${answer} at NS ${nameserver} (${nsIp}). Expecting ${value}. Match ${match}`);
|
||||||
|
|
||||||
iteratorCallback(null, match);
|
iteratorCallback(null, match);
|
||||||
});
|
});
|
||||||
@@ -76,26 +76,26 @@ function isChangeSynced(domain, type, value, nameserver, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if IP change has propagated to every nameserver
|
// check if IP change has propagated to every nameserver
|
||||||
function waitForDns(domain, zoneName, type, value, options, callback) {
|
function waitForDns(hostname, zoneName, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof hostname, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof zoneName, 'string');
|
||||||
assert(type === 'A' || type === 'TXT');
|
assert(type === 'A' || type === 'TXT');
|
||||||
assert.strictEqual(typeof value, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug('waitForDns: domain %s to be %s in zone %s.', domain, value, zoneName);
|
debug('waitForDns: hostname %s to be %s in zone %s.', hostname, value, zoneName);
|
||||||
|
|
||||||
var attempt = 0;
|
var attempt = 0;
|
||||||
async.retry(options, function (retryCallback) {
|
async.retry(options, function (retryCallback) {
|
||||||
++attempt;
|
++attempt;
|
||||||
debug(`waitForDns (try ${attempt}): ${domain} to be ${value} in zone ${zoneName}`);
|
debug(`waitForDns (try ${attempt}): ${hostname} to be ${value} in zone ${zoneName}`);
|
||||||
|
|
||||||
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
||||||
if (error || !nameservers) return retryCallback(error || new DomainsError(DomainsError.EXTERNAL_ERROR, 'Unable to get nameservers'));
|
if (error || !nameservers) return retryCallback(error || new DomainsError(DomainsError.EXTERNAL_ERROR, 'Unable to get nameservers'));
|
||||||
|
|
||||||
async.every(nameservers, isChangeSynced.bind(null, domain, type, value), function (error, synced) {
|
async.every(nameservers, isChangeSynced.bind(null, hostname, type, value), function (error, synced) {
|
||||||
debug('waitForDns: %s %s ns: %j', domain, synced ? 'done' : 'not done', nameservers);
|
debug('waitForDns: %s %s ns: %j', hostname, synced ? 'done' : 'not done', nameservers);
|
||||||
|
|
||||||
retryCallback(synced ? null : new DomainsError(DomainsError.EXTERNAL_ERROR, 'ETRYAGAIN'));
|
retryCallback(synced ? null : new DomainsError(DomainsError.EXTERNAL_ERROR, 'ETRYAGAIN'));
|
||||||
});
|
});
|
||||||
@@ -103,7 +103,7 @@ function waitForDns(domain, zoneName, type, value, options, callback) {
|
|||||||
}, function retryDone(error) {
|
}, function retryDone(error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
debug(`waitForDns: ${domain} has propagated`);
|
debug(`waitForDns: ${hostname} has propagated`);
|
||||||
|
|
||||||
callback(null);
|
callback(null);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,44 +4,43 @@ exports = module.exports = {
|
|||||||
upsert: upsert,
|
upsert: upsert,
|
||||||
get: get,
|
get: get,
|
||||||
del: del,
|
del: del,
|
||||||
waitForDns: require('./waitfordns.js'),
|
wait: wait,
|
||||||
verifyDnsConfig: verifyDnsConfig
|
verifyDnsConfig: verifyDnsConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
debug = require('debug')('box:dns/manual'),
|
debug = require('debug')('box:dns/manual'),
|
||||||
dns = require('../native-dns.js'),
|
dns = require('../native-dns.js'),
|
||||||
|
domains = require('../domains.js'),
|
||||||
DomainsError = require('../domains.js').DomainsError,
|
DomainsError = require('../domains.js').DomainsError,
|
||||||
sysinfo = require('../sysinfo.js'),
|
sysinfo = require('../sysinfo.js'),
|
||||||
util = require('util');
|
util = require('util'),
|
||||||
|
waitForDns = require('./waitfordns.js');
|
||||||
|
|
||||||
function upsert(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function upsert(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug('upsert: %s for zone %s of type %s with values %j', subdomain, zoneName, type, values);
|
debug('upsert: %s for zone %s of type %s with values %j', location, domainObject.zoneName, type, values);
|
||||||
|
|
||||||
return callback(null);
|
return callback(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(dnsConfig, zoneName, subdomain, type, callback) {
|
function get(domainObject, location, type, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
callback(null, [ ]); // returning ip confuses apptask into thinking the entry already exists
|
callback(null, [ ]); // returning ip confuses apptask into thinking the entry already exists
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
function del(domainObject, location, type, values, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
@@ -49,20 +48,33 @@ function del(dnsConfig, zoneName, subdomain, type, values, callback) {
|
|||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, domain, zoneName, ip, callback) {
|
function wait(domainObject, location, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
|
assert(options && typeof options === 'object'); // { interval: 5000, times: 50000 }
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
|
waitForDns(fqdn, domainObject.zoneName, type, value, options, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyDnsConfig(domainObject, callback) {
|
||||||
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
|
const zoneName = domainObject.zoneName;
|
||||||
|
|
||||||
// Very basic check if the nameservers can be fetched
|
// Very basic check if the nameservers can be fetched
|
||||||
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
dns.resolve(zoneName, 'NS', { timeout: 5000 }, function (error, nameservers) {
|
||||||
if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain'));
|
if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, 'Unable to resolve nameservers for this domain'));
|
||||||
if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers'));
|
if (error || !nameservers) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : 'Unable to get nameservers'));
|
||||||
|
|
||||||
const separator = dnsConfig.hyphenatedSubdomains ? '-' : '.';
|
const location = 'cloudrontestdns';
|
||||||
const fqdn = `cloudrontest${separator}${domain}`;
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
dns.resolve(fqdn, 'A', { server: '127.0.0.1', timeout: 5000 }, function (error, result) {
|
dns.resolve(fqdn, 'A', { server: '127.0.0.1', timeout: 5000 }, function (error, result) {
|
||||||
if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, `Unable to resolve ${fqdn}`));
|
if (error && error.code === 'ENOTFOUND') return callback(new DomainsError(DomainsError.BAD_FIELD, `Unable to resolve ${fqdn}`));
|
||||||
if (error || !result) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : `Unable to resolve ${fqdn}`));
|
if (error || !result) return callback(new DomainsError(DomainsError.BAD_FIELD, error ? error.message : `Unable to resolve ${fqdn}`));
|
||||||
|
|||||||
127
src/domains.js
127
src/domains.js
@@ -10,6 +10,7 @@ module.exports = exports = {
|
|||||||
isLocked: isLocked,
|
isLocked: isLocked,
|
||||||
|
|
||||||
fqdn: fqdn,
|
fqdn: fqdn,
|
||||||
|
getName: getName,
|
||||||
|
|
||||||
getDnsRecords: getDnsRecords,
|
getDnsRecords: getDnsRecords,
|
||||||
upsertDnsRecords: upsertDnsRecords,
|
upsertDnsRecords: upsertDnsRecords,
|
||||||
@@ -28,10 +29,7 @@ module.exports = exports = {
|
|||||||
|
|
||||||
prepareDashboardDomain: prepareDashboardDomain,
|
prepareDashboardDomain: prepareDashboardDomain,
|
||||||
|
|
||||||
DomainsError: DomainsError,
|
DomainsError: DomainsError
|
||||||
|
|
||||||
// exported for testing
|
|
||||||
_getName: getName
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var assert = require('assert'),
|
var assert = require('assert'),
|
||||||
@@ -105,18 +103,18 @@ function parentDomain(domain) {
|
|||||||
return domain.replace(/^\S+?\./, ''); // +? means non-greedy
|
return domain.replace(/^\S+?\./, ''); // +? means non-greedy
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyDnsConfig(dnsConfig, domain, zoneName, provider, ip, callback) {
|
function verifyDnsConfig(dnsConfig, domain, zoneName, provider, callback) {
|
||||||
assert(dnsConfig && typeof dnsConfig === 'object'); // the dns config to test with
|
assert(dnsConfig && typeof dnsConfig === 'object'); // the dns config to test with
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof domain, 'string');
|
||||||
assert.strictEqual(typeof zoneName, 'string');
|
assert.strictEqual(typeof zoneName, 'string');
|
||||||
assert.strictEqual(typeof provider, 'string');
|
assert.strictEqual(typeof provider, 'string');
|
||||||
assert.strictEqual(typeof ip, 'string');
|
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
var backend = api(provider);
|
var backend = api(provider);
|
||||||
if (!backend) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid provider'));
|
if (!backend) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Invalid provider'));
|
||||||
|
|
||||||
api(provider).verifyDnsConfig(dnsConfig, domain, zoneName, ip, function (error, result) {
|
const domainObject = { config: dnsConfig, domain: domain, zoneName: zoneName };
|
||||||
|
api(provider).verifyDnsConfig(domainObject, function (error, result) {
|
||||||
if (error && error.reason === DomainsError.ACCESS_DENIED) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Incorrect configuration. Access denied'));
|
if (error && error.reason === DomainsError.ACCESS_DENIED) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Incorrect configuration. Access denied'));
|
||||||
if (error && error.reason === DomainsError.NOT_FOUND) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Zone not found'));
|
if (error && error.reason === DomainsError.NOT_FOUND) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Zone not found'));
|
||||||
if (error && error.reason === DomainsError.EXTERNAL_ERROR) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Configuration error: ' + error.message));
|
if (error && error.reason === DomainsError.EXTERNAL_ERROR) return callback(new DomainsError(DomainsError.BAD_FIELD, 'Configuration error: ' + error.message));
|
||||||
@@ -130,12 +128,8 @@ function verifyDnsConfig(dnsConfig, domain, zoneName, provider, ip, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function fqdn(location, domain, dnsConfig) {
|
function fqdn(location, domainObject) {
|
||||||
assert.strictEqual(typeof location, 'string');
|
return location + (location ? (domainObject.config.hyphenatedSubdomains ? '-' : '.') : '') + domainObject.domain;
|
||||||
assert.strictEqual(typeof domain, 'string');
|
|
||||||
assert.strictEqual(typeof dnsConfig, 'object');
|
|
||||||
|
|
||||||
return location + (location ? (dnsConfig.hyphenatedSubdomains ? '-' : '.') : '') + domain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hostname validation comes from RFC 1123 (section 2.1)
|
// Hostname validation comes from RFC 1123 (section 2.1)
|
||||||
@@ -146,7 +140,7 @@ function validateHostname(location, domainObject) {
|
|||||||
assert.strictEqual(typeof location, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof domainObject, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
|
|
||||||
const hostname = fqdn(location, domainObject.domain, domainObject.config);
|
const hostname = fqdn(location, domainObject);
|
||||||
|
|
||||||
const RESERVED_LOCATIONS = [
|
const RESERVED_LOCATIONS = [
|
||||||
constants.API_LOCATION,
|
constants.API_LOCATION,
|
||||||
@@ -231,23 +225,19 @@ function add(domain, data, auditSource, callback) {
|
|||||||
let error = validateTlsConfig(tlsConfig, provider);
|
let error = validateTlsConfig(tlsConfig, provider);
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
sysinfo.getPublicIp(function (error, ip) {
|
verifyDnsConfig(config, domain, zoneName, provider, function (error, sanitizedConfig) {
|
||||||
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, 'Error getting IP:' + error.message));
|
if (error) return callback(error);
|
||||||
|
|
||||||
verifyDnsConfig(config, domain, zoneName, provider, ip, function (error, sanitizedConfig) {
|
domaindb.add(domain, { zoneName: zoneName, provider: provider, config: sanitizedConfig, tlsConfig: tlsConfig }, function (error) {
|
||||||
if (error) return callback(error);
|
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new DomainsError(DomainsError.ALREADY_EXISTS));
|
||||||
|
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
||||||
|
|
||||||
domaindb.add(domain, { zoneName: zoneName, provider: provider, config: sanitizedConfig, tlsConfig: tlsConfig }, function (error) {
|
reverseProxy.setFallbackCertificate(domain, fallbackCertificate, function (error) {
|
||||||
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new DomainsError(DomainsError.ALREADY_EXISTS));
|
|
||||||
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
||||||
|
|
||||||
reverseProxy.setFallbackCertificate(domain, fallbackCertificate, function (error) {
|
eventlog.add(eventlog.ACTION_DOMAIN_ADD, auditSource, { domain, zoneName, provider });
|
||||||
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
|
||||||
|
|
||||||
eventlog.add(eventlog.ACTION_DOMAIN_ADD, auditSource, { domain, zoneName, provider });
|
callback();
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -325,25 +315,21 @@ function update(domain, data, auditSource, callback) {
|
|||||||
error = validateTlsConfig(tlsConfig, provider);
|
error = validateTlsConfig(tlsConfig, provider);
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
sysinfo.getPublicIp(function (error, ip) {
|
verifyDnsConfig(config, domain, zoneName, provider, function (error, sanitizedConfig) {
|
||||||
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, 'Error getting IP:' + error.message));
|
if (error) return callback(error);
|
||||||
|
|
||||||
verifyDnsConfig(config, domain, zoneName, provider, ip, function (error, sanitizedConfig) {
|
domaindb.update(domain, { zoneName: zoneName, provider: provider, config: sanitizedConfig, tlsConfig: tlsConfig }, function (error) {
|
||||||
if (error) return callback(error);
|
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new DomainsError(DomainsError.NOT_FOUND));
|
||||||
|
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
||||||
|
|
||||||
domaindb.update(domain, { zoneName: zoneName, provider: provider, config: sanitizedConfig, tlsConfig: tlsConfig }, function (error) {
|
if (!fallbackCertificate) return callback();
|
||||||
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new DomainsError(DomainsError.NOT_FOUND));
|
|
||||||
|
reverseProxy.setFallbackCertificate(domain, fallbackCertificate, function (error) {
|
||||||
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
||||||
|
|
||||||
if (!fallbackCertificate) return callback();
|
eventlog.add(eventlog.ACTION_DOMAIN_UPDATE, auditSource, { domain, zoneName, provider });
|
||||||
|
|
||||||
reverseProxy.setFallbackCertificate(domain, fallbackCertificate, function (error) {
|
callback();
|
||||||
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
|
||||||
|
|
||||||
eventlog.add(eventlog.ACTION_DOMAIN_UPDATE, auditSource, { domain, zoneName, provider });
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -379,39 +365,36 @@ function clear(callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns the 'name' that needs to be inserted into zone
|
// returns the 'name' that needs to be inserted into zone
|
||||||
function getName(domain, subdomain, type) {
|
function getName(domain, location, type) {
|
||||||
// hack for supporting special caas domains. if we want to remove this, we have to fix the appstore domain API first
|
|
||||||
if (domain.provider === 'caas') return subdomain;
|
|
||||||
|
|
||||||
const part = domain.domain.slice(0, -domain.zoneName.length - 1);
|
const part = domain.domain.slice(0, -domain.zoneName.length - 1);
|
||||||
|
|
||||||
if (subdomain === '') return part;
|
if (location === '') return part;
|
||||||
|
|
||||||
if (!domain.config.hyphenatedSubdomains) return part ? `${subdomain}.${part}` : subdomain;
|
if (!domain.config.hyphenatedSubdomains) return part ? `${location}.${part}` : location;
|
||||||
|
|
||||||
// hyphenatedSubdomains
|
// hyphenatedSubdomains
|
||||||
if (type !== 'TXT') return `${subdomain}-${part}`;
|
if (type !== 'TXT') return `${location}-${part}`;
|
||||||
|
|
||||||
if (subdomain.startsWith('_acme-challenge.')) {
|
if (location.startsWith('_acme-challenge.')) {
|
||||||
return `${subdomain}-${part}`;
|
return `${location}-${part}`;
|
||||||
} else if (subdomain === '_acme-challenge') {
|
} else if (location === '_acme-challenge') {
|
||||||
const up = part.replace(/^[^.]*\.?/, ''); // this gets the domain one level up
|
const up = part.replace(/^[^.]*\.?/, ''); // this gets the domain one level up
|
||||||
return up ? `${subdomain}.${up}` : subdomain;
|
return up ? `${location}.${up}` : location;
|
||||||
} else {
|
} else {
|
||||||
return `${subdomain}.${part}`;
|
return `${location}.${part}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDnsRecords(subdomain, domain, type, callback) {
|
function getDnsRecords(location, domain, type, callback) {
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof domain, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
get(domain, function (error, result) {
|
get(domain, function (error, domainObject) {
|
||||||
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
||||||
|
|
||||||
api(result.provider).get(result.config, result.zoneName, getName(result, subdomain, type), type, function (error, values) {
|
api(domainObject.provider).get(domainObject, location, type, function (error, values) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
callback(null, values);
|
callback(null, values);
|
||||||
@@ -420,19 +403,19 @@ function getDnsRecords(subdomain, domain, type, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// note: for TXT records the values must be quoted
|
// note: for TXT records the values must be quoted
|
||||||
function upsertDnsRecords(subdomain, domain, type, values, callback) {
|
function upsertDnsRecords(location, domain, type, values, callback) {
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof domain, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug('upsertDNSRecord: %s on %s type %s values', subdomain, domain, type, values);
|
debug('upsertDNSRecord: %s on %s type %s values', location, domain, type, values);
|
||||||
|
|
||||||
get(domain, function (error, result) {
|
get(domain, function (error, domainObject) {
|
||||||
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
if (error) return callback(new DomainsError(DomainsError.INTERNAL_ERROR, error));
|
||||||
|
|
||||||
api(result.provider).upsert(result.config, result.zoneName, getName(result, subdomain, type), type, values, function (error) {
|
api(domainObject.provider).upsert(domainObject, location, type, values, function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
callback(null);
|
callback(null);
|
||||||
@@ -440,19 +423,19 @@ function upsertDnsRecords(subdomain, domain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeDnsRecords(subdomain, domain, type, values, callback) {
|
function removeDnsRecords(location, domain, type, values, callback) {
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof domain, 'string');
|
||||||
assert.strictEqual(typeof type, 'string');
|
assert.strictEqual(typeof type, 'string');
|
||||||
assert(util.isArray(values));
|
assert(util.isArray(values));
|
||||||
assert.strictEqual(typeof callback, 'function');
|
assert.strictEqual(typeof callback, 'function');
|
||||||
|
|
||||||
debug('removeDNSRecord: %s on %s type %s values', subdomain, domain, type, values);
|
debug('removeDNSRecord: %s on %s type %s values', location, domain, type, values);
|
||||||
|
|
||||||
get(domain, function (error, result) {
|
get(domain, function (error, domainObject) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
api(result.provider).del(result.config, result.zoneName, getName(result, subdomain, type), type, values, function (error) {
|
api(domainObject.provider).del(domainObject, location, type, values, function (error) {
|
||||||
if (error && error.reason !== DomainsError.NOT_FOUND) return callback(error);
|
if (error && error.reason !== DomainsError.NOT_FOUND) return callback(error);
|
||||||
|
|
||||||
callback(null);
|
callback(null);
|
||||||
@@ -460,8 +443,8 @@ function removeDnsRecords(subdomain, domain, type, values, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForDnsRecord(subdomain, domain, type, value, options, callback) {
|
function waitForDnsRecord(location, domain, type, value, options, callback) {
|
||||||
assert.strictEqual(typeof subdomain, 'string');
|
assert.strictEqual(typeof location, 'string');
|
||||||
assert.strictEqual(typeof domain, 'string');
|
assert.strictEqual(typeof domain, 'string');
|
||||||
assert(type === 'A' || type === 'TXT');
|
assert(type === 'A' || type === 'TXT');
|
||||||
assert.strictEqual(typeof value, 'string');
|
assert.strictEqual(typeof value, 'string');
|
||||||
@@ -471,9 +454,7 @@ function waitForDnsRecord(subdomain, domain, type, value, options, callback) {
|
|||||||
get(domain, function (error, domainObject) {
|
get(domain, function (error, domainObject) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
const hostname = fqdn(subdomain, domainObject.domain, domainObject.config);
|
api(domainObject.provider).wait(domainObject, location, type, value, options, callback);
|
||||||
|
|
||||||
api(domainObject.provider).waitForDns(hostname, domainObject.zoneName, type, value, options, callback);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,7 +501,7 @@ function prepareDashboardDomain(domain, auditSource, progressCallback, callback)
|
|||||||
(done) => { progressCallback({ percent: 40, message: 'Waiting for DNS' }); done(); },
|
(done) => { progressCallback({ percent: 40, message: 'Waiting for DNS' }); done(); },
|
||||||
waitForDnsRecord.bind(null, constants.ADMIN_LOCATION, domain, 'A', ip, { interval: 30000, times: 50000 }),
|
waitForDnsRecord.bind(null, constants.ADMIN_LOCATION, domain, 'A', ip, { interval: 30000, times: 50000 }),
|
||||||
(done) => { progressCallback({ percent: 70, message: 'Getting certificate' }); done(); },
|
(done) => { progressCallback({ percent: 70, message: 'Getting certificate' }); done(); },
|
||||||
reverseProxy.ensureCertificate.bind(null, fqdn(constants.ADMIN_LOCATION, domainObject.domain, domainObject.config), domain, auditSource)
|
reverseProxy.ensureCertificate.bind(null, fqdn(constants.ADMIN_LOCATION, domainObject), domain, auditSource)
|
||||||
], function (error) {
|
], function (error) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
@@ -528,4 +509,4 @@ function prepareDashboardDomain(domain, auditSource, progressCallback, callback)
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ function validateCertificate(location, domainObject, certificate) {
|
|||||||
if (cert && !key) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, 'missing key');
|
if (cert && !key) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, 'missing key');
|
||||||
|
|
||||||
// -checkhost checks for SAN or CN exclusively. SAN takes precedence and if present, ignores the CN.
|
// -checkhost checks for SAN or CN exclusively. SAN takes precedence and if present, ignores the CN.
|
||||||
const fqdn = domains.fqdn(location, domainObject.domain, domainObject.config);
|
const fqdn = domains.fqdn(location, domainObject);
|
||||||
|
|
||||||
var result = safe.child_process.execSync(`openssl x509 -noout -checkhost "${fqdn}"`, { encoding: 'utf8', input: cert });
|
var result = safe.child_process.execSync(`openssl x509 -noout -checkhost "${fqdn}"`, { encoding: 'utf8', input: cert });
|
||||||
if (result === null) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, 'Unable to get certificate subject:' + safe.error.message);
|
if (result === null) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, 'Unable to get certificate subject:' + safe.error.message);
|
||||||
@@ -278,7 +278,7 @@ function setAppCertificateSync(location, domainObject, certificate) {
|
|||||||
assert.strictEqual(typeof domainObject, 'object');
|
assert.strictEqual(typeof domainObject, 'object');
|
||||||
assert.strictEqual(typeof certificate, 'object');
|
assert.strictEqual(typeof certificate, 'object');
|
||||||
|
|
||||||
let fqdn = domains.fqdn(location, domainObject.domain, domainObject.config);
|
let fqdn = domains.fqdn(location, domainObject);
|
||||||
if (certificate.cert && certificate.key) {
|
if (certificate.cert && certificate.key) {
|
||||||
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, `${fqdn}.user.cert`), certificate.cert)) return safe.error;
|
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, `${fqdn}.user.cert`), certificate.cert)) return safe.error;
|
||||||
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, `${fqdn}.user.key`), certificate.key)) return safe.error;
|
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, `${fqdn}.user.key`), certificate.key)) return safe.error;
|
||||||
@@ -412,7 +412,7 @@ function configureAdmin(domain, auditSource, callback) {
|
|||||||
domains.get(domain, function (error, domainObject) {
|
domains.get(domain, function (error, domainObject) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
const adminFqdn = domains.fqdn(constants.ADMIN_LOCATION, domainObject.domain, domainObject.config);
|
const adminFqdn = domains.fqdn(constants.ADMIN_LOCATION, domainObject);
|
||||||
|
|
||||||
ensureCertificate(adminFqdn, domainObject.domain, auditSource, function (error, bundle) {
|
ensureCertificate(adminFqdn, domainObject.domain, auditSource, function (error, bundle) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
@@ -429,7 +429,7 @@ function writeAdminConfig(domain, callback) {
|
|||||||
domains.get(domain, function (error, domainObject) {
|
domains.get(domain, function (error, domainObject) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|
||||||
const adminFqdn = domains.fqdn(constants.ADMIN_LOCATION, domainObject.domain, domainObject.config);
|
const adminFqdn = domains.fqdn(constants.ADMIN_LOCATION, domainObject);
|
||||||
|
|
||||||
getCertificate(adminFqdn, domainObject.domain, function (error, bundle) {
|
getCertificate(adminFqdn, domainObject.domain, function (error, bundle) {
|
||||||
if (error) return callback(error);
|
if (error) return callback(error);
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ describe('Certificates', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not allow cert without matching domain', function () {
|
it('does not allow cert without matching domain', function () {
|
||||||
expect(reverseProxy.validateCertificate('', { domain: 'cloudron.io', config: {} }, { cert: validCert0, key: validKey0 })).to.be.an(Error);
|
expect(reverseProxy.validateCertificate('', { domain: 'cloudron.io' }, { cert: validCert0, key: validKey0 })).to.be.an(Error);
|
||||||
expect(reverseProxy.validateCertificate('cloudron.io', foobarDomain, { cert: validCert0, key: validKey0 })).to.be.an(Error);
|
expect(reverseProxy.validateCertificate('cloudron.io', foobarDomain, { cert: validCert0, key: validKey0 })).to.be.an(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user