diff --git a/src/apps.js b/src/apps.js index 7e4683e10..2da7c5db3 100644 --- a/src/apps.js +++ b/src/apps.js @@ -1145,7 +1145,11 @@ function setLocation(appId, data, auditSource, callback) { error = domains.validateHostname(values.location, domainObject); if (error) return callback(new AppsError(AppsError.BAD_FIELD, 'Bad location: ' + error.message, { field: 'location' })); - scheduleTask(appId, { oldConfig: getAppConfig(app) }, values, function (error, result) { + const args = { + oldConfig: _.pick(app, 'location', 'domain', 'fqdn', 'alternateDomains', 'portBindings'), + overwriteDns: !!data.overwriteDns + }; + scheduleTask(appId, args, values, function (error, result) { if (error && error.reason === AppsError.ALREADY_EXISTS) error = getDuplicateErrorDetails(error.message, values.location, domainObject, data.portBindings, app.alternateDomains); if (error) return callback(error); diff --git a/src/apptask.js b/src/apptask.js index 272f20520..383a249bb 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -360,6 +360,8 @@ function registerSubdomains(app, overwrite, callback) { if (error && error.reason === DomainsError.NOT_FOUND) return retryCallback(null, new BoxError(BoxError.NOT_FOUND, error.message, domain)); if (error) return retryCallback(null, new BoxError(BoxError.EXTERNAL_ERROR, error.message, domain)); // give up for access and other errors + if (values.length !== 0 && values[0] === ip) return retryCallback(null); // up-to-date + // refuse to update any existing DNS record for custom domains that we did not create if (values.length !== 0 && !overwrite) return retryCallback(null, new BoxError(BoxError.ALREADY_EXISTS, 'DNS Record already exists', domain)); @@ -638,12 +640,13 @@ function create(app, progressCallback, callback) { }); } -function changeLocation(app, oldConfig, progressCallback, callback) { +function changeLocation(app, args, progressCallback, callback) { assert.strictEqual(typeof app, 'object'); - assert.strictEqual(typeof oldConfig, 'object'); + assert.strictEqual(typeof args, 'object'); assert.strictEqual(typeof progressCallback, 'function'); assert.strictEqual(typeof callback, 'function'); + const oldConfig = args.oldConfig; const locationChanged = oldConfig.fqdn !== app.fqdn; async.series([ @@ -664,7 +667,7 @@ function changeLocation(app, oldConfig, progressCallback, callback) { }, progressCallback.bind(null, { percent: 30, message: 'Registering subdomains' }), - registerSubdomains.bind(null, app, !locationChanged /* overwrite */), // if location changed, do not overwrite to detect conflicts + registerSubdomains.bind(null, app, args.overwriteDns), // re-setup addons since they rely on the app's fqdn (e.g oauth) progressCallback.bind(null, { percent: 50, message: 'Setting up addons' }), @@ -771,7 +774,7 @@ function configure(app, oldConfig, progressCallback, callback) { downloadIcon.bind(null, app), progressCallback.bind(null, { percent: 30, message: 'Registering subdomains' }), - registerSubdomains.bind(null, app, !locationChanged /* overwrite */), // if location changed, do not overwrite to detect conflicts + registerSubdomains.bind(null, app, false /* overwrite */), // if location changed, do not overwrite to detect conflicts progressCallback.bind(null, { percent: 40, message: 'Downloading image' }), downloadImage.bind(null, app.manifest), @@ -1027,7 +1030,7 @@ function run(appId, args, progressCallback, callback) { case apps.ISTATE_PENDING_RESIZE: case apps.ISTATE_PENDING_DEBUG: return create(app, progressCallback, callback); - case apps.ISTATE_PENDING_LOCATION_CHANGE: return changeLocation(app, args.oldConfig, progressCallback, callback); + case apps.ISTATE_PENDING_LOCATION_CHANGE: return changeLocation(app, args, progressCallback, callback); case apps.ISTATE_PENDING_DATA_DIR_MIGRATION: return migrateDataDir(app, args.oldDataDir, progressCallback, callback); case apps.ISTATE_PENDING_UNINSTALL: return uninstall(app, progressCallback, callback); case apps.ISTATE_PENDING_CLONE: return install(app, args.restoreConfig || {}, progressCallback, callback); diff --git a/src/routes/apps.js b/src/routes/apps.js index 14da00f9e..b21384a4a 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -337,6 +337,8 @@ function setLocation(req, res, next) { if (req.body.alternateDomains.some(function (d) { return (typeof d.domain !== 'string' || typeof d.subdomain !== 'string'); })) return next(new HttpError(400, 'alternateDomains array must contain objects with domain and subdomain strings')); } + if ('overwriteDns' in req.body && typeof req.body.overwriteDns !== 'boolean') return next(new HttpError(400, 'overwriteDns must be boolean')); + apps.setLocation(req.params.id, req.body, auditSource.fromRequest(req), function (error, result) { if (error) return next(toHttpError(error));