Remove usage of config.appFqdn()

This commit is contained in:
Girish Ramakrishnan
2018-01-09 21:03:59 -08:00
parent c108cd2d5f
commit efc0a3b68d
15 changed files with 176 additions and 138 deletions
+3 -3
View File
@@ -114,7 +114,7 @@ var RMAPPDIR_CMD = path.join(__dirname, 'scripts/rmappdir.sh');
function debugApp(app, args) {
assert(!app || typeof app === 'object');
var prefix = app ? config.appFqdn(app) : '(no app)';
var prefix = app ? app.intrinsicFqdn : '(no app)';
debug(prefix + ' ' + util.format.apply(util, Array.prototype.slice.call(arguments, 1)));
}
@@ -250,7 +250,7 @@ function setupOauth(app, options, callback) {
if (!app.sso) return callback(null);
var appId = app.id;
var redirectURI = 'https://' + (app.altDomain || config.appFqdn(app));
var redirectURI = 'https://' + (app.altDomain || app.intrinsicFqdn);
var scope = 'profile';
clients.delByAppIdAndType(appId, clients.TYPE_OAUTH, function (error) { // remove existing creds
@@ -647,7 +647,7 @@ function setupRedis(app, options, callback) {
}
const tag = infra.images.redis.tag, redisName = 'redis-' + app.id;
const label = config.appFqdn(app);
const label = app.intrinsicFqdn;
// note that we do not add appId label because this interferes with the stop/start app logic
const cmd = `docker run --restart=always -d --name=${redisName} \
--label=location=${label} \
+1 -1
View File
@@ -26,7 +26,7 @@ var gDockerEventStream = null;
function debugApp(app) {
assert(!app || typeof app === 'object');
var prefix = app ? config.appFqdn(app) : '(no app)';
var prefix = app ? app.intrinsicFqdn : '(no app)';
var manifestAppId = app ? app.manifest.id : '';
var id = app ? app.id : '';
+127 -91
View File
@@ -60,6 +60,9 @@ var addons = require('./addons.js'),
DatabaseError = require('./databaseerror.js'),
debug = require('debug')('box:apps'),
docker = require('./docker.js'),
domaindb = require('./domaindb.js'),
domains = require('./domains.js'),
DomainError = require('./domains.js').DomainError,
eventlog = require('./eventlog.js'),
fs = require('fs'),
groups = require('./groups.js'),
@@ -119,22 +122,18 @@ AppsError.BAD_CERTIFICATE = 'Invalid certificate';
// Domain name validation comes from RFC 2181 (Name syntax)
// https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
// We are validating the validity of the location-fqdn as host name (and not dns name)
function validateHostname(location, domain) {
function validateHostname(location, domain, hostname) {
assert.strictEqual(typeof location, 'string');
assert.strictEqual(typeof domain, 'string');
var hostname = config.appFqdn({ location: location, domain: domain });
if (!hostname) return new AppsError(AppsError.BAD_FIELD, 'hostname cannot be empty');
const RESERVED_LOCATIONS = [
config.adminFqdn(),
config.appFqdn({ location: constants.API_LOCATION, domain: config.fqdn() }),
config.appFqdn({ location: constants.SMTP_LOCATION, domain: config.fqdn() }),
config.appFqdn({ location: constants.IMAP_LOCATION, domain: config.fqdn() }),
config.mailFqdn(),
config.appFqdn({ location: constants.POSTMAN_LOCATION, domain: config.fqdn() })
config.adminLocation(), // FIXME: this shouldn't be here
constants.API_LOCATION,
constants.SMTP_LOCATION,
constants.IMAP_LOCATION,
constants.POSTMAN_LOCATION
];
if (RESERVED_LOCATIONS.indexOf(hostname) !== -1) return new AppsError(AppsError.BAD_FIELD, hostname + ' is reserved');
if (RESERVED_LOCATIONS.indexOf(location) !== -1) return new AppsError(AppsError.BAD_FIELD, location + ' is reserved');
// workaround https://github.com/oncletom/tld.js/issues/73
var tmp = hostname.replace('_', '-');
@@ -311,6 +310,7 @@ function getAppConfig(app) {
manifest: app.manifest,
location: app.location,
domain: app.domain,
intrinsicFqdn: app.intrinsicFqdn,
accessRestriction: app.accessRestriction,
portBindings: app.portBindings,
memoryLimit: app.memoryLimit,
@@ -358,11 +358,16 @@ function get(appId, callback) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such app'));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
app.iconUrl = getIconUrlSync(app);
app.fqdn = app.altDomain || config.appFqdn(app);
app.cnameTarget = app.altDomain ? config.appFqdn(app) : null;
domaindb.get(app.domain, function (error, result) {
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
callback(null, app);
app.intrinsicFqdn = app.location + (result.provider === 'caas' ? '-' : '.') + app.domain;
app.iconUrl = getIconUrlSync(app);
app.fqdn = app.altDomain || app.intrinsicFqdn;
app.cnameTarget = app.altDomain ? app.intrinsicFqdn : null;
callback(null, app);
});
});
}
@@ -377,11 +382,16 @@ function getByIpAddress(ip, callback) {
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such app'));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
app.iconUrl = getIconUrlSync(app);
app.fqdn = app.altDomain || config.appFqdn(app);
app.cnameTarget = app.altDomain ? config.appFqdn(app) : null;
domaindb.get(app.domain, function (error, result) {
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
callback(null, app);
app.intrinsicFqdn = app.location + (result.provider === 'caas' ? '-' : '.') + app.domain;
app.iconUrl = getIconUrlSync(app);
app.fqdn = app.altDomain || app.intrinsicFqdn;
app.cnameTarget = app.altDomain ? app.intrinsicFqdn : null;
callback(null, app);
});
});
});
}
@@ -392,13 +402,22 @@ function getAll(callback) {
appdb.getAll(function (error, apps) {
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
apps.forEach(function (app) {
app.iconUrl = getIconUrlSync(app);
app.fqdn = app.altDomain || config.appFqdn(app);
app.cnameTarget = app.altDomain ? config.appFqdn(app) : null;
});
async.eachSeries(apps, function (app, iteratorDone) {
domaindb.get(app.domain, function (error, result) {
if (error) return iteratorDone(new AppsError(AppsError.INTERNAL_ERROR, error));
callback(null, apps);
app.intrinsicFqdn = app.location + (result.provider === 'caas' ? '-' : '.') + app.domain;
app.iconUrl = getIconUrlSync(app);
app.fqdn = app.altDomain || app.intrinsicFqdn;
app.cnameTarget = app.altDomain ? app.intrinsicFqdn : null;
iteratorDone();
});
}, function (error) {
if (error) return callback(error);
callback(null, apps);
});
});
}
@@ -468,9 +487,6 @@ function install(data, auditSource, callback) {
error = checkManifestConstraints(manifest);
if (error) return callback(error);
error = validateHostname(location, domain);
if (error) return callback(error);
error = validatePortBindings(portBindings, manifest.tcpPorts);
if (error) return callback(error);
@@ -508,45 +524,56 @@ function install(data, auditSource, callback) {
}
}
error = certificates.validateCertificate(cert, key, config.appFqdn({ domain: domain, location: location }));
if (error) return callback(new AppsError(AppsError.BAD_CERTIFICATE, error.message));
domains.get(domain, function (error, domainObject) {
if (error && error.reason === DomainError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such domain'));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Could not get domain info:' + error.message));
debug('Will install app with id : ' + appId);
var intrinsicFqdn = location + (domainObject.provider === 'caas' ? '-' : '.') + domain;
appstore.purchase(appId, appStoreId, function (error) {
if (error && error.reason === AppstoreError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND));
if (error && error.reason === AppstoreError.BILLING_REQUIRED) return callback(new AppsError(AppsError.BILLING_REQUIRED, error.message));
if (error && error.reason === AppstoreError.EXTERNAL_ERROR) return callback(new AppsError(AppsError.EXTERNAL_ERROR, error.message));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
error = validateHostname(location, domain, intrinsicFqdn);
if (error) return callback(error);
var data = {
accessRestriction: accessRestriction,
memoryLimit: memoryLimit,
altDomain: altDomain,
xFrameOptions: xFrameOptions,
sso: sso,
debugMode: debugMode,
mailboxName: (location ? location : manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app',
restoreConfig: backupId ? { backupId: backupId, backupFormat: backupFormat } : null,
enableBackup: enableBackup,
robotsTxt: robotsTxt
};
error = certificates.validateCertificate(cert, key, intrinsicFqdn);
if (error) return callback(new AppsError(AppsError.BAD_CERTIFICATE, error.message));
appdb.add(appId, appStoreId, manifest, location, domain, portBindings, data, function (error) {
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(getDuplicateErrorDetails(location, portBindings, error));
debug('Will install app with id : ' + appId);
appstore.purchase(appId, appStoreId, function (error) {
if (error && error.reason === AppstoreError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND));
if (error && error.reason === AppstoreError.BILLING_REQUIRED) return callback(new AppsError(AppsError.BILLING_REQUIRED, error.message));
if (error && error.reason === AppstoreError.EXTERNAL_ERROR) return callback(new AppsError(AppsError.EXTERNAL_ERROR, error.message));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
// save cert to boxdata/certs
if (cert && key) {
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, config.appFqdn({ domain: domain, location: location }) + '.user.cert'), cert)) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving cert: ' + safe.error.message));
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, config.appFqdn({ domain: domain, location: location }) + '.user.key'), key)) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving key: ' + safe.error.message));
}
var data = {
accessRestriction: accessRestriction,
memoryLimit: memoryLimit,
altDomain: altDomain,
xFrameOptions: xFrameOptions,
sso: sso,
debugMode: debugMode,
mailboxName: (location ? location : manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app',
restoreConfig: backupId ? { backupId: backupId, backupFormat: backupFormat } : null,
enableBackup: enableBackup,
robotsTxt: robotsTxt,
intrinsicFqdn: intrinsicFqdn
};
taskmanager.restartAppTask(appId);
appdb.add(appId, appStoreId, manifest, location, domain, portBindings, data, function (error) {
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(getDuplicateErrorDetails(location, portBindings, error));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
eventlog.add(eventlog.ACTION_APP_INSTALL, auditSource, { appId: appId, location: location, domain: domain, manifest: manifest, backupId: backupId });
// save cert to boxdata/certs
if (cert && key) {
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, intrinsicFqdn + '.user.cert'), cert)) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving cert: ' + safe.error.message));
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, intrinsicFqdn + '.user.key'), key)) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving key: ' + safe.error.message));
}
callback(null, { id : appId });
taskmanager.restartAppTask(appId);
eventlog.add(eventlog.ACTION_APP_INSTALL, auditSource, { appId: appId, location: location, domain: domain, manifest: manifest, backupId: backupId });
callback(null, { id : appId });
});
});
});
});
@@ -569,9 +596,6 @@ function configure(appId, data, auditSource, callback) {
if ('domain' in data) domain = values.domain = data.domain.toLowerCase();
else domain = app.domain;
error = validateHostname(location, domain);
if (error) return callback(error);
if ('accessRestriction' in data) {
values.accessRestriction = data.accessRestriction;
error = validateAccessRestriction(values.accessRestriction);
@@ -615,43 +639,55 @@ function configure(appId, data, auditSource, callback) {
if (error) return callback(error);
}
// save cert to boxdata/certs. TODO: move this to apptask when we have a real task queue
if ('cert' in data && 'key' in data) {
if (data.cert && data.key) {
error = certificates.validateCertificate(data.cert, data.key, config.appFqdn({ domain: domain, location: location }));
if (error) return callback(new AppsError(AppsError.BAD_CERTIFICATE, error.message));
domains.get(domain, function (error, domainObject) {
if (error && error.reason === DomainError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such domain'));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Could not get domain info:' + error.message));
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, config.appFqdn({ domain: domain, location: location }) + '.user.cert'), data.cert)) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving cert: ' + safe.error.message));
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, config.appFqdn({ domain: domain, location: location }) + '.user.key'), data.key)) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving key: ' + safe.error.message));
} else { // remove existing cert/key
if (!safe.fs.unlinkSync(path.join(paths.APP_CERTS_DIR, config.appFqdn({ domain: domain, location: location }) + '.user.cert'))) debug('Error removing cert: ' + safe.error.message);
if (!safe.fs.unlinkSync(path.join(paths.APP_CERTS_DIR, config.appFqdn({ domain: domain, location: location }) + '.user.key'))) debug('Error removing key: ' + safe.error.message);
var intrinsicFqdn = location + (domainObject.provider === 'caas' ? '-' : '.') + domain;
values.intrinsicFqdn = intrinsicFqdn;
error = validateHostname(location, domain, intrinsicFqdn);
if (error) return callback(error);
// save cert to boxdata/certs. TODO: move this to apptask when we have a real task queue
if ('cert' in data && 'key' in data) {
if (data.cert && data.key) {
error = certificates.validateCertificate(data.cert, data.key, intrinsicFqdn);
if (error) return callback(new AppsError(AppsError.BAD_CERTIFICATE, error.message));
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, intrinsicFqdn + '.user.cert'), data.cert)) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving cert: ' + safe.error.message));
if (!safe.fs.writeFileSync(path.join(paths.APP_CERTS_DIR, intrinsicFqdn + '.user.key'), data.key)) return callback(new AppsError(AppsError.INTERNAL_ERROR, 'Error saving key: ' + safe.error.message));
} else { // remove existing cert/key
if (!safe.fs.unlinkSync(path.join(paths.APP_CERTS_DIR, intrinsicFqdn + '.user.cert'))) debug('Error removing cert: ' + safe.error.message);
if (!safe.fs.unlinkSync(path.join(paths.APP_CERTS_DIR, intrinsicFqdn + '.user.key'))) debug('Error removing key: ' + safe.error.message);
}
}
}
if ('enableBackup' in data) values.enableBackup = data.enableBackup;
if ('enableBackup' in data) values.enableBackup = data.enableBackup;
values.oldConfig = getAppConfig(app);
values.oldConfig = getAppConfig(app);
debug('Will configure app with id:%s values:%j', appId, values);
debug('Will configure app with id:%s values:%j', appId, values);
var oldName = (app.location ? app.location : app.manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app';
var newName = (location ? location : app.manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app';
mailboxdb.updateName(oldName, values.oldConfig.domain, newName, domain, function (error) {
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new AppsError(AppsError.ALREADY_EXISTS, 'This mailbox is already taken'));
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.BAD_STATE));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
appdb.setInstallationCommand(appId, appdb.ISTATE_PENDING_CONFIGURE, values, function (error) {
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(getDuplicateErrorDetails(location, portBindings, error));
var oldName = (app.location ? app.location : app.manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app';
var newName = (location ? location : app.manifest.title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app';
mailboxdb.updateName(oldName, values.oldConfig.domain, newName, domain, function (error) {
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(new AppsError(AppsError.ALREADY_EXISTS, 'This mailbox is already taken'));
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.BAD_STATE));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
taskmanager.restartAppTask(appId);
appdb.setInstallationCommand(appId, appdb.ISTATE_PENDING_CONFIGURE, values, function (error) {
if (error && error.reason === DatabaseError.ALREADY_EXISTS) return callback(getDuplicateErrorDetails(location, portBindings, error));
if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.BAD_STATE));
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId });
taskmanager.restartAppTask(appId);
callback(null);
eventlog.add(eventlog.ACTION_APP_CONFIGURE, auditSource, { appId: appId });
callback(null);
});
});
});
});
@@ -1130,13 +1166,13 @@ function restoreInstalledApps(callback) {
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
async.map(apps, function (app, iteratorDone) {
debug('marking %s for restore', config.appFqdn(app));
debug('marking %s for restore', app.intrinsicFqdn);
backups.getByAppIdPaged(1, 1, app.id, function (error, results) {
var restoreConfig = !error && results.length ? { backupId: results[0].id, backupFormat: results[0].format } : null;
appdb.setInstallationCommand(app.id, appdb.ISTATE_PENDING_RESTORE, { restoreConfig: restoreConfig, oldConfig: null }, function (error) {
if (error) debug('did not mark %s for restore', config.appFqdn(app), error);
if (error) debug('did not mark %s for restore', app.intrinsicFqdn, error);
iteratorDone(); // always succeed
});
@@ -1152,10 +1188,10 @@ function configureInstalledApps(callback) {
if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error));
async.map(apps, function (app, iteratorDone) {
debug('marking %s for reconfigure', config.appFqdn(app));
debug('marking %s for reconfigure', app.intrinsicFqdn);
appdb.setInstallationCommand(app.id, appdb.ISTATE_PENDING_CONFIGURE, { oldConfig: null }, function (error) {
if (error) debug('did not mark %s for reconfigure', config.appFqdn(app), error);
if (error) debug('did not mark %s for reconfigure', app.intrinsicFqdn, error);
iteratorDone(); // always succeed
});
+7 -7
View File
@@ -72,7 +72,7 @@ function initialize(callback) {
function debugApp(app) {
assert.strictEqual(typeof app, 'object');
var prefix = app ? (config.appFqdn(app) || '(bare)') : '(no app)';
var prefix = app ? (app.intrinsicFqdn || '(bare)') : '(no app)';
debug(prefix + ' ' + util.format.apply(util, Array.prototype.slice.call(arguments, 1)));
}
@@ -271,7 +271,7 @@ function registerSubdomain(app, overwrite, callback) {
if (error) return callback(error);
async.retry({ times: 200, interval: 5000 }, function (retryCallback) {
debugApp(app, 'Registering subdomain location [%s] overwrite: %s', config.appFqdn(app), overwrite);
debugApp(app, 'Registering subdomain location [%s] overwrite: %s', app.intrinsicFqdn, overwrite);
// get the current record before updating it
domains.getDNSRecords(app.location, app.domain, 'A', function (error, values) {
@@ -320,7 +320,7 @@ function unregisterSubdomain(app, location, domain, callback) {
if (error) return callback(error);
async.retry({ times: 30, interval: 5000 }, function (retryCallback) {
debugApp(app, 'Unregistering subdomain: %s', config.appFqdn({ domain: domain, location: location }));
debugApp(app, 'Unregistering subdomain: %s', app.intrinsicFqdn);
domains.removeDNSRecords(location, domain, 'A', [ ip ], function (error) {
if (error && (error.reason === DomainError.STILL_BUSY || error.reason === DomainError.EXTERNAL_ERROR)) return retryCallback(error); // try again
@@ -357,7 +357,7 @@ function waitForDnsPropagation(app, callback) {
sysinfo.getPublicIp(function (error, ip) {
if (error) return callback(error);
domains.waitForDNSRecord(config.appFqdn(app), app.domain, ip, 'A', { interval: 5000, times: 120 }, callback);
domains.waitForDNSRecord(app.intrinsicFqdn, app.domain, ip, 'A', { interval: 5000, times: 120 }, callback);
});
}
@@ -374,7 +374,7 @@ function waitForAltDomainDnsPropagation(app, callback) {
domains.waitForDNSRecord(app.altDomain, tld.getDomain(app.altDomain), ip, 'A', { interval: 10000, times: 60 }, callback);
});
} else {
domains.waitForDNSRecord(app.altDomain, tld.getDomain(app.altDomain), config.appFqdn(app) + '.', 'CNAME', { interval: 10000, times: 60 }, callback);
domains.waitForDNSRecord(app.altDomain, tld.getDomain(app.altDomain), app.intrinsicFqdn + '.', 'CNAME', { interval: 10000, times: 60 }, callback);
}
}
@@ -508,7 +508,7 @@ function configure(app, callback) {
assert.strictEqual(typeof callback, 'function');
// oldConfig can be null during an infra update
var locationChanged = app.oldConfig && (config.appFqdn(app.oldConfig) !== config.appFqdn(app));
var locationChanged = app.oldConfig && (app.oldConfig.intrinsicFqdn !== app.intrinsicFqdn);
async.series([
updateApp.bind(null, app, { installationProgress: '10, Cleaning up old install' }),
@@ -776,7 +776,7 @@ function startTask(appId, callback) {
assert.strictEqual(typeof callback, 'function');
// determine what to do
appdb.get(appId, function (error, app) {
apps.get(appId, function (error, app) {
if (error) return callback(error);
debugApp(app, 'startTask installationState: %s runState: %s', app.installationState, app.runState);
+5 -5
View File
@@ -70,7 +70,7 @@ var BACKUPTASK_CMD = path.join(__dirname, 'backuptask.js');
function debugApp(app) {
assert(!app || typeof app === 'object');
var prefix = app ? config.appFqdn(app) : '(no app)';
var prefix = app ? app.intrinsicFqdn : '(no app)';
debug(prefix + ' ' + util.format.apply(util, Array.prototype.slice.call(arguments, 1)));
}
@@ -720,7 +720,7 @@ function backupApp(app, callback) {
const timestamp = (new Date()).toISOString().replace(/[T.]/g, '-').replace(/[:Z]/g,'');
safe.fs.unlinkSync(paths.BACKUP_LOG_FILE); // start fresh log file
progress.set(progress.BACKUP, 10, 'Backing up ' + (app.altDomain || config.appFqdn(app)));
progress.set(progress.BACKUP, 10, 'Backing up ' + (app.altDomain || app.intrinsicFqdn));
backupAppWithTimestamp(app, timestamp, function (error) {
progress.set(progress.BACKUP, 100, error ? error.message : '');
@@ -747,12 +747,12 @@ function backupBoxAndApps(auditSource, callback) {
var step = 100/(allApps.length+2);
async.mapSeries(allApps, function iterator(app, iteratorCallback) {
progress.set(progress.BACKUP, step * processed, 'Backing up ' + (app.altDomain || config.appFqdn(app)));
progress.set(progress.BACKUP, step * processed, 'Backing up ' + (app.altDomain || app.intrinsicFqdn));
++processed;
if (!app.enableBackup) {
progress.set(progress.BACKUP, step * processed, 'Skipped backup ' + (app.altDomain || config.appFqdn(app)));
progress.set(progress.BACKUP, step * processed, 'Skipped backup ' + (app.altDomain || app.intrinsicFqdn));
return iteratorCallback(null, null); // nothing to backup
}
@@ -762,7 +762,7 @@ function backupBoxAndApps(auditSource, callback) {
return iteratorCallback(error);
}
progress.set(progress.BACKUP, step * processed, 'Backed up ' + (app.altDomain || config.appFqdn(app)));
progress.set(progress.BACKUP, step * processed, 'Backed up ' + (app.altDomain || app.intrinsicFqdn));
iteratorCallback(null, backupId || null); // clear backupId if is in BAD_STATE and never backed up
});
+6 -6
View File
@@ -174,11 +174,11 @@ function renewAll(auditSource, callback) {
apps.getAll(function (error, allApps) {
if (error) return callback(error);
allApps.push({ location: config.adminLocation(), domain: config.fqdn() }); // inject fake webadmin app
allApps.push({ intrinsicFqdn: config.adminFqdn() }); // inject fake webadmin app
var expiringApps = [ ];
for (var i = 0; i < allApps.length; i++) {
var appDomain = allApps[i].altDomain || config.appFqdn(allApps[i]);
var appDomain = allApps[i].altDomain || allApps[i].instrincFqdn;
var certFilePath = path.join(paths.APP_CERTS_DIR, appDomain + '.user.cert');
var keyFilePath = path.join(paths.APP_CERTS_DIR, appDomain + '.user.key');
@@ -202,10 +202,10 @@ function renewAll(auditSource, callback) {
}
}
debug('renewAll: %j needs to be renewed', expiringApps.map(function (app) { return app.altDomain || config.appFqdn(app); }));
debug('renewAll: %j needs to be renewed', expiringApps.map(function (app) { return app.altDomain || app.intrinsicFqdn; }));
async.eachSeries(expiringApps, function iterator(app, iteratorCallback) {
var domain = app.altDomain || config.appFqdn(app);
var domain = app.altDomain || app.intrinsicFqdn;
getApi(app, function (error, api, apiOptions) {
if (error) return callback(error);
@@ -240,7 +240,7 @@ function renewAll(auditSource, callback) {
}
// reconfigure and reload nginx. this is required for the case where we got a renewed cert after fallback
var configureFunc = config.appFqdn(app) === config.adminFqdn() ?
var configureFunc = app.intrinsicFqdn === config.adminFqdn() ?
nginx.configureAdmin.bind(null, certFilePath, keyFilePath, constants.NGINX_ADMIN_CONFIG_FILE_NAME, config.adminFqdn())
: nginx.configureApp.bind(null, app, certFilePath, keyFilePath);
@@ -402,7 +402,7 @@ function ensureCertificate(app, callback) {
assert.strictEqual(typeof app, 'object');
assert.strictEqual(typeof callback, 'function');
var domain = app.altDomain || config.appFqdn(app);
var domain = app.altDomain || app.intrinsicFqdn;
var certFilePath = path.join(paths.APP_CERTS_DIR, domain + '.user.cert');
var keyFilePath = path.join(paths.APP_CERTS_DIR, domain + '.user.key');
+1 -1
View File
@@ -279,7 +279,7 @@ function configureWebadmin(callback) {
function configureNginx(error) {
debug('configureNginx: dns update: %j', error || {});
certificates.ensureCertificate({ domain: config.fqdn(), location: config.adminLocation() }, function (error, certFilePath, keyFilePath) {
certificates.ensureCertificate({ domain: config.fqdn(), location: config.adminLocation(), intrinsicFqdn: config.adminFqdn() }, function (error, certFilePath, keyFilePath) {
if (error) return done(error);
gWebadminStatus.tls = true;
-1
View File
@@ -33,7 +33,6 @@ exports = module.exports = {
adminFqdn: adminFqdn,
mailLocation: mailLocation,
mailFqdn: mailFqdn,
appFqdn: appFqdn,
setZoneName: setZoneName,
hasIPv6: hasIPv6,
dkimSelector: dkimSelector,
+3 -3
View File
@@ -51,7 +51,7 @@ var addons = require('./addons.js'),
function debugApp(app, args) {
assert(!app || typeof app === 'object');
var prefix = app ? config.appFqdn(app) : '(no app)';
var prefix = app ? app.intrinsicFqdn : '(no app)';
debug(prefix + ' ' + util.format.apply(util, Array.prototype.slice.call(arguments, 1)));
}
@@ -129,7 +129,7 @@ function createSubcontainer(app, name, cmd, options, callback) {
var manifest = app.manifest;
var exposedPorts = {}, dockerPortBindings = { };
var domain = app.altDomain || config.appFqdn(app);
var domain = app.altDomain || app.intrinsicFqdn;
var stdEnv = [
'CLOUDRON=1',
'WEBADMIN_ORIGIN=' + config.adminOrigin(),
@@ -186,7 +186,7 @@ function createSubcontainer(app, name, cmd, options, callback) {
'/run': {}
},
Labels: {
'fqdn': config.appFqdn(app),
'fqdn': app.intrinsicFqdn,
'appId': app.id,
'isSubcontainer': String(!isAppContainer)
},
+2 -2
View File
@@ -55,7 +55,7 @@ function configureApp(app, certFilePath, keyFilePath, callback) {
var sourceDir = path.resolve(__dirname, '..');
var endpoint = 'app';
var vhost = app.altDomain || config.appFqdn(app);
var vhost = app.altDomain || app.intrinsicFqdn;
var data = {
sourceDir: sourceDir,
@@ -86,7 +86,7 @@ function unconfigureApp(app, callback) {
assert.strictEqual(typeof app, 'object');
assert.strictEqual(typeof callback, 'function');
var vhost = app.altDomain || config.appFqdn(app);
var vhost = app.altDomain || app.intrinsicFqdn;
var nginxConfigFilename = path.join(paths.NGINX_APPCONFIG_DIR, app.id + '.conf');
if (!safe.fs.unlinkSync(nginxConfigFilename)) {
+5 -3
View File
@@ -47,7 +47,9 @@ var TEST_IMAGE = TEST_IMAGE_REPO + ':' + TEST_IMAGE_TAG;
var APP_STORE_ID = 'test', APP_ID;
var APP_LOCATION = 'appslocation';
var APP_DOMAIN = 'example-apps-test.com';
var APP_LOCATION_2 = 'appslocationtwo';
var APP_DOMAIN_2 = 'example-apps-test.com';
var APP_LOCATION_NEW = 'appslocationnew';
var APP_MANIFEST = JSON.parse(fs.readFileSync(__dirname + '/../../../../test-app/CloudronManifest.json', 'utf8'));
@@ -149,7 +151,7 @@ function startBox(done) {
safe.fs.unlinkSync(paths.INFRA_VERSION_FILE);
child_process.execSync('docker ps -qa | xargs --no-run-if-empty docker rm -f');
config.setFqdn('example-apps-test.com');
config.setFqdn(APP_DOMAIN);
config.setZoneName('foobar.com');
awsHostedZones = {
@@ -722,8 +724,8 @@ describe('App installation', function () {
expect(data.Config.Env).to.contain('WEBADMIN_ORIGIN=' + config.adminOrigin());
expect(data.Config.Env).to.contain('API_ORIGIN=' + config.adminOrigin());
expect(data.Config.Env).to.contain('CLOUDRON=1');
expect(data.Config.Env).to.contain('APP_ORIGIN=https://' + config.appFqdn(APP_LOCATION));
expect(data.Config.Env).to.contain('APP_DOMAIN=' + config.appFqdn(APP_LOCATION));
expect(data.Config.Env).to.contain('APP_ORIGIN=https://' + APP_LOCATION + '.' + APP_DOMAIN);
expect(data.Config.Env).to.contain('APP_DOMAIN=' + APP_LOCATION + '.' + APP_DOMAIN);
// Hostname must not be set of app fqdn or app location!
expect(data.Config.Hostname).to.not.contain(APP_LOCATION);
expect(data.Config.Env).to.contain('ECHO_SERVER_PORT=7171');
+1 -1
View File
@@ -48,7 +48,7 @@ function resumeTasks(callback) {
if (app.installationState === appdb.ISTATE_ERROR) return;
debug('Creating process for %s (%s) with state %s', config.appFqdn(app), app.id, app.installationState);
debug('Creating process for %s (%s) with state %s', app.intrinsicFqdn, app.id, app.installationState);
restartAppTask(app.id, NOOP_CALLBACK); // restart because the auto-installer could have queued up tasks already
});
+12 -12
View File
@@ -161,35 +161,35 @@ describe('Apps', function () {
describe('validateHostname', function () {
it('does not allow admin subdomain', function () {
expect(apps._validateHostname('my', 'example.com')).to.be.an(Error);
expect(apps._validateHostname('my', 'example.com', 'my.example.com')).to.be.an(Error);
});
it('cannot have >63 length subdomains', function () {
var s = '';
for (var i = 0; i < 64; i++) s += 's';
expect(apps._validateHostname(s, 'example.com')).to.be.an(Error);
expect(apps._validateHostname(s, 'example.com', s + '.example.com')).to.be.an(Error);
});
it('allows only alphanumerics and hypen', function () {
expect(apps._validateHostname('#2r', 'example.com')).to.be.an(Error);
expect(apps._validateHostname('a%b', 'example.com')).to.be.an(Error);
expect(apps._validateHostname('ab_', 'example.com')).to.be.an(Error);
expect(apps._validateHostname('a.b', 'example.com')).to.be.an(Error);
expect(apps._validateHostname('-ab', 'example.com')).to.be.an(Error);
expect(apps._validateHostname('ab-', 'example.com')).to.be.an(Error);
expect(apps._validateHostname('#2r', 'example.com', '#2r.example.com')).to.be.an(Error);
expect(apps._validateHostname('a%b', 'example.com', 'a%b.example.com')).to.be.an(Error);
expect(apps._validateHostname('ab_', 'example.com', 'ab_.example.com')).to.be.an(Error);
expect(apps._validateHostname('a.b', 'example.com', 'a.b.example.com')).to.be.an(Error);
expect(apps._validateHostname('-ab', 'example.com', '-ab.example.com')).to.be.an(Error);
expect(apps._validateHostname('ab-', 'example.com', 'ab-.example.com')).to.be.an(Error);
});
it('total length cannot exceed 255', function () {
var s = '';
for (var i = 0; i < (255 - 'example.com'.length); i++) s += 's';
expect(apps._validateHostname(s, 'example.com')).to.be.an(Error);
expect(apps._validateHostname(s, 'example.com', s + '.example.com')).to.be.an(Error);
});
it('allow valid domains', function () {
expect(apps._validateHostname('a', 'example.com')).to.be(null);
expect(apps._validateHostname('a0-x', 'example.com')).to.be(null);
expect(apps._validateHostname('01', 'example.com')).to.be(null);
expect(apps._validateHostname('a', 'example.com', 'a.example.com')).to.be(null);
expect(apps._validateHostname('a0-x', 'example.com', 'a0-x.example.com')).to.be(null);
expect(apps._validateHostname('01', 'example.com', '01.example.com')).to.be(null);
});
});
+3
View File
@@ -67,6 +67,8 @@ var APP = {
runState: null,
location: 'applocation',
domain: DOMAIN_0.domain,
intrinsicFqdn: DOMAIN_0.domain + '.' + 'applocation',
fqdn: DOMAIN_0.domain + '.' + 'applocation',
manifest: MANIFEST,
containerId: null,
httpPort: 4567,
@@ -101,6 +103,7 @@ describe('apptask', function () {
async.series([
database.initialize,
database._clear,
domains.update.bind(null, DOMAIN_0.domain, DOMAIN_0.provider, DOMAIN_0.config, null),
appdb.add.bind(null, APP.id, APP.appStoreId, APP.manifest, APP.location, APP.domain, APP.portBindings, APP),
settings.initialize,
-2
View File
@@ -68,7 +68,6 @@ describe('config', function () {
expect(config.isCustomDomain()).to.equal(true);
expect(config.fqdn()).to.equal('example.com');
expect(config.adminOrigin()).to.equal('https://my.example.com');
expect(config.appFqdn({ location: 'app', domain: config.fqdn() })).to.equal('app.example.com');
expect(config.zoneName()).to.equal('example.com');
});
@@ -79,7 +78,6 @@ describe('config', function () {
expect(config.isCustomDomain()).to.equal(false);
expect(config.fqdn()).to.equal('test.example.com');
expect(config.adminOrigin()).to.equal('https://my-test.example.com');
expect(config.appFqdn({ location: 'app', domain: config.fqdn() })).to.equal('app-test.example.com');
expect(config.zoneName()).to.equal('example.com');
});