make sysinfo provider a setting

This commit is contained in:
Girish Ramakrishnan
2019-10-29 15:46:33 -07:00
parent 7a25187bee
commit 7d987d7c79
19 changed files with 132 additions and 56 deletions
+2 -2
View File
@@ -38,7 +38,6 @@ var apps = require('./apps.js'),
semver = require('semver'),
settings = require('./settings.js'),
superagent = require('superagent'),
sysinfo = require('./sysinfo.js'),
users = require('./users.js'),
util = require('util');
@@ -246,12 +245,13 @@ function sendAliveStatus(callback) {
appAutoupdatePattern: allSettings[settings.APP_AUTOUPDATE_PATTERN_KEY],
boxAutoupdatePattern: allSettings[settings.BOX_AUTOUPDATE_PATTERN_KEY],
timeZone: allSettings[settings.TIME_ZONE_KEY],
sysinfoProvider: allSettings[settings.SYSINFO_CONFIG_KEY].provider
};
var data = {
version: constants.VERSION,
adminFqdn: settings.adminFqdn(),
provider: sysinfo.provider(),
provider: settings.provider(),
backendSettings: backendSettings,
machine: {
cpus: os.cpus(),
+3 -3
View File
@@ -350,7 +350,7 @@ function registerSubdomains(app, overwrite, callback) {
assert.strictEqual(typeof overwrite, 'boolean');
assert.strictEqual(typeof callback, 'function');
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(error);
const allDomains = [ { subdomain: app.location, domain: app.domain }].concat(app.alternateDomains);
@@ -396,7 +396,7 @@ function unregisterSubdomains(app, allDomains, callback) {
assert(Array.isArray(allDomains));
assert.strictEqual(typeof callback, 'function');
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(error);
async.eachSeries(allDomains, function (domain, iteratorDone) {
@@ -430,7 +430,7 @@ function waitForDnsPropagation(app, callback) {
return callback(null);
}
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(new BoxError(BoxError.NETWORK_ERROR, `Error getting public IP: ${error.message}`));
domains.waitForDnsRecord(app.location, app.domain, 'A', ip, { interval: 5000, times: 240 }, function (error) {
+1 -2
View File
@@ -47,7 +47,6 @@ var apps = require('./apps.js'),
shell = require('./shell.js'),
spawn = require('child_process').spawn,
split = require('split'),
sysinfo = require('./sysinfo.js'),
tasks = require('./tasks.js'),
users = require('./users.js');
@@ -136,7 +135,7 @@ function getConfig(callback) {
version: constants.VERSION,
isDemo: settings.isDemo(),
memory: os.totalmem(),
provider: sysinfo.provider(),
provider: settings.provider(),
cloudronName: allSettings[settings.CLOUDRON_NAME_KEY],
uiSpec: custom.uiSpec()
});
+1 -1
View File
@@ -37,7 +37,7 @@ function getQuery(dnsConfig, callback) {
assert.strictEqual(typeof dnsConfig, 'object');
assert.strictEqual(typeof callback, 'function');
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(error);
callback(null, {
+1 -1
View File
@@ -89,7 +89,7 @@ function verifyDnsConfig(domainObject, callback) {
if (error && error.code === 'ENOTFOUND') return callback(new BoxError(BoxError.BAD_FIELD, `Unable to resolve ${fqdn}`, { field: 'nameservers' }));
if (error || !result) return callback(new BoxError(BoxError.BAD_FIELD, error ? error.message : `Unable to resolve ${fqdn}`, { field: 'nameservers' }));
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Failed to detect IP of this server: ${error.message}`));
if (result.length !== 1 || ip !== result[0]) return callback(new BoxError(BoxError.EXTERNAL_ERROR, `Domain resolves to ${JSON.stringify(result)} instead of ${ip}`));
+2 -2
View File
@@ -371,7 +371,7 @@ function checkDnsRecords(location, domain, callback) {
getDnsRecords(location, domain, 'A', function (error, values) {
if (error) return callback(error);
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(error);
if (values.length === 0) return callback(null, { needsOverwrite: false }); // does not exist
@@ -473,7 +473,7 @@ function prepareDashboardDomain(domain, auditSource, progressCallback, callback)
const adminFqdn = fqdn(constants.ADMIN_LOCATION, domainObject);
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(error);
async.series([
+1 -1
View File
@@ -21,7 +21,7 @@ function sync(auditSource, callback) {
assert.strictEqual(typeof auditSource, 'object');
assert.strictEqual(typeof callback, 'function');
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(error);
let info = safe.JSON.parse(safe.fs.readFileSync(paths.DYNDNS_INFO_FILE, 'utf8')) || { ip: null };
+3 -3
View File
@@ -275,7 +275,7 @@ function checkMx(domain, mailFqdn, callback) {
dns.resolve(mxRecords[0].exchange, 'A', DNS_OPTIONS, function (error, mxIps) {
if (error || mxIps.length !== 1) return callback(null, mx);
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(null, mx);
mx.status = mxIps[0] === ip;
@@ -332,7 +332,7 @@ function checkPtr(mailFqdn, callback) {
status: false
};
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(error, ptr);
ptr.domain = ip.split('.').reverse().join('.') + '.in-addr.arpa';
@@ -415,7 +415,7 @@ const RBL_LIST = [
function checkRblStatus(domain, callback) {
assert.strictEqual(typeof callback, 'function');
sysinfo.getPublicIp(function (error, ip) {
sysinfo.getServerIp(function (error, ip) {
if (error) return callback(error, ip);
var flippedIp = ip.split('.').reverse().join('.');
+1 -2
View File
@@ -27,7 +27,6 @@ var appstore = require('./appstore.js'),
semver = require('semver'),
settings = require('./settings.js'),
superagent = require('superagent'),
sysinfo = require('./sysinfo.js'),
users = require('./users.js'),
tld = require('tldjs'),
_ = require('underscore');
@@ -264,7 +263,7 @@ function getStatus(callback) {
callback(null, _.extend({
version: constants.VERSION,
apiServerOrigin: settings.apiServerOrigin(), // used by CaaS tool
provider: sysinfo.provider(),
provider: settings.provider(),
cloudronName: cloudronName,
adminFqdn: settings.adminDomain() ? settings.adminFqdn() : null,
activated: activated,
+2 -2
View File
@@ -15,13 +15,13 @@ var assert = require('assert'),
HttpError = require('connect-lastmile').HttpError,
HttpSuccess = require('connect-lastmile').HttpSuccess,
provision = require('../provision.js'),
sysinfo = require('../sysinfo.js'),
settings = require('../settings.js'),
superagent = require('superagent');
function providerTokenAuth(req, res, next) {
assert.strictEqual(typeof req.body, 'object');
if (sysinfo.provider() === 'ami') {
if (settings.provider() === 'ami') {
if (typeof req.body.providerToken !== 'string' || !req.body.providerToken) return next(new HttpError(400, 'providerToken must be a non empty string'));
superagent.get('http://169.254.169.254/latest/meta-data/instance-id').timeout(30 * 1000).end(function (error, result) {
+39 -2
View File
@@ -43,6 +43,11 @@ exports = module.exports = {
getCloudronToken: getCloudronToken,
setCloudronToken: setCloudronToken,
getSysinfoConfig: getSysinfoConfig,
setSysinfoConfig: setSysinfoConfig,
provider: provider,
getAll: getAll,
initCache: initCache,
@@ -69,6 +74,7 @@ exports = module.exports = {
PLATFORM_CONFIG_KEY: 'platform_config',
EXTERNAL_LDAP_KEY: 'external_ldap_config',
REGISTRY_CONFIG_KEY: 'registry_config',
SYSINFO_CONFIG_KEY: 'sysinfo_config',
// strings
APP_AUTOUPDATE_PATTERN_KEY: 'app_autoupdate_pattern',
@@ -133,6 +139,9 @@ let gDefaults = (function () {
provider: 'noop'
};
result[exports.REGISTRY_CONFIG_KEY] = {};
result[exports.SYSINFO_CONFIG_KEY] = {
provider: 'generic'
};
result[exports.ADMIN_DOMAIN_KEY] = '';
result[exports.ADMIN_FQDN_KEY] = '';
result[exports.API_SERVER_ORIGIN_KEY] = 'https://api.cloudron.io';
@@ -467,6 +476,30 @@ function setRegistryConfig(registryConfig, callback) {
});
}
function getSysinfoConfig(callback) {
assert.strictEqual(typeof callback, 'function');
settingsdb.get(exports.SYSINFO_CONFIG_KEY, function (error, value) {
if (error && error.reason === BoxError.NOT_FOUND) return callback(null, gDefaults[exports.SYSINFO_CONFIG_KEY]);
if (error) return callback(error);
callback(null, JSON.parse(value));
});
}
function setSysinfoConfig(sysinfoConfig, callback) {
assert.strictEqual(typeof sysinfoConfig, 'object');
assert.strictEqual(typeof callback, 'function');
settingsdb.set(exports.SYSINFO_CONFIG_KEY, JSON.stringify(sysinfoConfig), function (error) {
if (error) return callback(error);
notifyChange(exports.REGISTRY_CONFIG_KEY, sysinfoConfig);
callback(null);
});
}
function getLicenseKey(callback) {
assert.strictEqual(typeof callback, 'function');
@@ -554,7 +587,7 @@ function getAll(callback) {
result[exports.DEMO_KEY] = !!result[exports.DEMO_KEY];
// convert JSON objects
[exports.BACKUP_CONFIG_KEY, exports.PLATFORM_CONFIG_KEY, exports.EXTERNAL_LDAP_KEY, exports.REGISTRY_CONFIG_KEY ].forEach(function (key) {
[exports.BACKUP_CONFIG_KEY, exports.PLATFORM_CONFIG_KEY, exports.EXTERNAL_LDAP_KEY, exports.REGISTRY_CONFIG_KEY, exports.SYSINFO_CONFIG_KEY ].forEach(function (key) {
result[key] = typeof result[key] === 'object' ? result[key] : safe.JSON.parse(result[key]);
});
@@ -568,12 +601,15 @@ function initCache(callback) {
getAll(function (error, allSettings) {
if (error) return callback(error);
const provider = safe.fs.readFileSync(paths.PROVIDER_FILE, 'utf8');
gCache = {
apiServerOrigin: allSettings[exports.API_SERVER_ORIGIN_KEY],
webServerOrigin: allSettings[exports.WEB_SERVER_ORIGIN_KEY],
adminDomain: allSettings[exports.ADMIN_DOMAIN_KEY],
adminFqdn: allSettings[exports.ADMIN_FQDN_KEY],
isDemo: allSettings[exports.DEMO_KEY]
isDemo: allSettings[exports.DEMO_KEY],
provider: provider ? provider.trim() : 'generic'
};
callback();
@@ -614,6 +650,7 @@ function setApiServerOrigin(origin, callback) {
});
}
function provider() { return gCache.provider; }
function apiServerOrigin() { return gCache.apiServerOrigin; }
function webServerOrigin() { return gCache.webServerOrigin; }
function adminDomain() { return gCache.adminDomain; }
+22 -6
View File
@@ -12,12 +12,27 @@ let assert = require('assert'),
once = require('once'),
path = require('path'),
paths = require('./paths.js'),
sysinfo = require('./sysinfo.js');
settings = require('./settings.js');
// the logic here is also used in the cloudron-support tool
const AUTHORIZED_KEYS_FILEPATH = constants.TEST ? path.join(paths.baseDir(), 'authorized_keys') : ((sysinfo.provider() === 'ec2' || sysinfo.provider() === 'lightsail' || sysinfo.provider() === 'ami') ? '/home/ubuntu/.ssh/authorized_keys' : '/root/.ssh/authorized_keys'),
AUTHORIZED_KEYS_USER = constants.TEST ? process.getuid() : ((sysinfo.provider() === 'ec2' || sysinfo.provider() === 'lightsail' || sysinfo.provider() === 'ami') ? 'ubuntu' : 'root'),
AUTHORIZED_KEYS_CMD = path.join(__dirname, 'scripts/remotesupport.sh');
const AUTHORIZED_KEYS_CMD = path.join(__dirname, 'scripts/remotesupport.sh');
function sshInfo() {
let filePath, user;
if (constants.TEST) {
filePath = path.join(paths.baseDir(), 'authorized_keys');
user = process.getuid();
} else if (settings.provider() === 'ec2' || settings.provider() === 'lightsail' || settings.provider() === 'ami') {
filePath = '/home/ubuntu/.ssh/authorized_keys';
user = 'ubuntu';
} else {
filePath = '/root/.ssh/authorized_keys';
user = 'root';
}
return { filePath, user };
}
function getRemoteSupport(callback) {
assert.strictEqual(typeof callback, 'function');
@@ -25,7 +40,7 @@ function getRemoteSupport(callback) {
callback = once(callback); // exit may or may not be called after an 'error'
let result = '';
let cp = shell.sudo('support', [ AUTHORIZED_KEYS_CMD, 'is-enabled', AUTHORIZED_KEYS_FILEPATH ], {}, function (error) {
let cp = shell.sudo('support', [ AUTHORIZED_KEYS_CMD, 'is-enabled', sshInfo().filePath ], {}, function (error) {
if (error) callback(new BoxError(BoxError.FS_ERROR, error));
callback(null, { enabled: result.trim() === 'true' });
@@ -36,7 +51,8 @@ function getRemoteSupport(callback) {
function enableRemoteSupport(enable, callback) {
assert.strictEqual(typeof callback, 'function');
shell.sudo('support', [ AUTHORIZED_KEYS_CMD, enable ? 'enable' : 'disable', AUTHORIZED_KEYS_FILEPATH, AUTHORIZED_KEYS_USER ], {}, function (error) {
let si = sshInfo();
shell.sudo('support', [ AUTHORIZED_KEYS_CMD, enable ? 'enable' : 'disable', si.filePath, si.user ], {}, function (error) {
if (error) callback(new BoxError(BoxError.FS_ERROR, error));
callback();
+15 -21
View File
@@ -1,35 +1,25 @@
'use strict';
exports = module.exports = {
getPublicIp: getPublicIp,
getServerIp: getServerIp,
hasIPv6: hasIPv6,
provider: provider
hasIPv6: hasIPv6
};
var assert = require('assert'),
ec2 = require('./sysinfo/ec2.js'),
fs = require('fs'),
generic = require('./sysinfo/generic.js'),
paths = require('./paths.js'),
scaleway = require('./sysinfo/scaleway.js'),
safe = require('safetydance');
settings = require('./settings.js');
let gProvider = null;
function provider() {
if (gProvider) return gProvider;
gProvider = safe.fs.readFileSync(paths.PROVIDER_FILE, 'utf8');
if (!gProvider) return gProvider = 'generic';
return gProvider.trim();
}
function getApi(callback) {
function getApi(config, callback) {
assert.strictEqual(typeof config, 'object');
assert.strictEqual(typeof callback, 'function');
switch (provider()) {
const provider = config.provider || 'generic';
switch (provider) {
case 'ec2': return callback(null, ec2);
case 'lightsail': return callback(null, ec2);
case 'ami': return callback(null, ec2);
@@ -38,13 +28,17 @@ function getApi(callback) {
}
}
function getPublicIp(callback) {
function getServerIp(callback) {
assert.strictEqual(typeof callback, 'function');
getApi(function (error, api) {
settings.getSysinfoConfig(function (error, config) {
if (error) return callback(error);
api.getPublicIp(callback);
getApi(config, function (error, api) {
if (error) return callback(error);
api.getServerIp(config, callback);
});
});
}
+3 -2
View File
@@ -1,7 +1,7 @@
'use strict';
exports = module.exports = {
getPublicIp: getPublicIp
getServerIp: getServerIp
};
var assert = require('assert'),
@@ -9,7 +9,8 @@ var assert = require('assert'),
superagent = require('superagent'),
util = require('util');
function getPublicIp(callback) {
function getServerIp(config, callback) {
assert.strictEqual(typeof config, 'object');
assert.strictEqual(typeof callback, 'function');
superagent.get('http://169.254.169.254/latest/meta-data/public-ipv4').timeout(30 * 1000).end(function (error, result) {
+3 -2
View File
@@ -1,7 +1,7 @@
'use strict';
exports = module.exports = {
getPublicIp: getPublicIp
getServerIp: getServerIp
};
var assert = require('assert'),
@@ -9,7 +9,8 @@ var assert = require('assert'),
BoxError = require('../boxerror.js'),
superagent = require('superagent');
function getPublicIp(callback) {
function getServerIp(config, callback) {
assert.strictEqual(typeof config, 'object');
assert.strictEqual(typeof callback, 'function');
if (process.env.BOX_ENV === 'test') return callback(null, '127.0.0.1');
+3 -2
View File
@@ -7,12 +7,13 @@
// -------------------------------------------
exports = module.exports = {
getPublicIp: getPublicIp
getServerIp: getServerIp
};
var assert = require('assert');
function getPublicIp(callback) {
function getServerIp(config, callback) {
assert.strictEqual(typeo config, 'object');
assert.strictEqual(typeof callback, 'function');
callback(new Error('not implemented'));
+3 -2
View File
@@ -1,7 +1,7 @@
'use strict';
exports = module.exports = {
getPublicIp: getPublicIp
getServerIp: getServerIp
};
var assert = require('assert'),
@@ -9,7 +9,8 @@ var assert = require('assert'),
superagent = require('superagent'),
util = require('util');
function getPublicIp(callback) {
function getServerIp(config, callback) {
assert.strictEqual(typeof config, 'object');
assert.strictEqual(typeof callback, 'function');
superagent.get('http://169.254.42.42/conf').timeout(30 * 1000).end(function (error, result) {
+2
View File
@@ -31,6 +31,7 @@ function setup(done) {
database._clear,
settings._setApiServerOrigin.bind(null, MOCK_API_SERVER_ORIGIN),
settings.setAdmin.bind(null, ADMIN_DOMAIN, 'my.' + ADMIN_DOMAIN),
settings.initCache
], done);
}
@@ -81,6 +82,7 @@ describe('Appstore', function () {
expect(body.backendSettings.mailConfig.relayProviders).to.be.an('array');
expect(body.backendSettings.appAutoupdatePattern).to.be.a('string');
expect(body.backendSettings.boxAutoupdatePattern).to.be.a('string');
expect(body.backendSettings.sysinfoProvider).to.be.a('string');
expect(body.backendSettings.timeZone).to.be.a('string');
expect(body.machine).to.be.an('object');
expect(body.machine.cpus).to.be.an('array');