Fix crash in renewCerts()
This commit is contained in:
+70
-79
@@ -623,91 +623,85 @@ async function unconfigureApp(app) {
|
||||
await reload();
|
||||
}
|
||||
|
||||
function renewCerts(options, auditSource, progressCallback, callback) {
|
||||
async function renewCerts(options, auditSource, progressCallback) {
|
||||
assert.strictEqual(typeof options, 'object');
|
||||
assert.strictEqual(typeof auditSource, 'object');
|
||||
assert.strictEqual(typeof progressCallback, 'function');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
util.callbackify(apps.list)(function (error, allApps) {
|
||||
if (error) return callback(error);
|
||||
const allApps = await apps.list();
|
||||
|
||||
let appDomains = [];
|
||||
let appDomains = [];
|
||||
|
||||
// add webadmin and mail domain
|
||||
if (settings.mailFqdn() === settings.dashboardFqdn()) {
|
||||
appDomains.push({ domain: settings.dashboardDomain(), fqdn: settings.dashboardFqdn(), type: 'webadmin+mail', nginxConfigFilename: path.join(paths.NGINX_APPCONFIG_DIR, `${settings.dashboardFqdn()}.conf`) });
|
||||
// add webadmin and mail domain
|
||||
if (settings.mailFqdn() === settings.dashboardFqdn()) {
|
||||
appDomains.push({ domain: settings.dashboardDomain(), fqdn: settings.dashboardFqdn(), type: 'webadmin+mail', nginxConfigFilename: path.join(paths.NGINX_APPCONFIG_DIR, `${settings.dashboardFqdn()}.conf`) });
|
||||
} else {
|
||||
appDomains.push({ domain: settings.dashboardDomain(), fqdn: settings.dashboardFqdn(), type: 'webadmin', nginxConfigFilename: path.join(paths.NGINX_APPCONFIG_DIR, `${settings.dashboardFqdn()}.conf`) });
|
||||
appDomains.push({ domain: settings.mailDomain(), fqdn: settings.mailFqdn(), type: 'mail' });
|
||||
}
|
||||
|
||||
for (const app of allApps) {
|
||||
if (app.runState === apps.RSTATE_STOPPED) continue; // do not renew certs of stopped apps
|
||||
|
||||
appDomains.push({ domain: app.domain, fqdn: app.fqdn, type: 'primary', app: app, nginxConfigFilename: path.join(paths.NGINX_APPCONFIG_DIR, app.id + '.conf') });
|
||||
|
||||
app.alternateDomains.forEach(function (alternateDomain) {
|
||||
const nginxConfigFilename = path.join(paths.NGINX_APPCONFIG_DIR, `${app.id}-redirect-${alternateDomain.fqdn}.conf`);
|
||||
appDomains.push({ domain: alternateDomain.domain, fqdn: alternateDomain.fqdn, type: 'alternate', app: app, nginxConfigFilename });
|
||||
});
|
||||
|
||||
app.aliasDomains.forEach(function (aliasDomain) {
|
||||
const nginxConfigFilename = path.join(paths.NGINX_APPCONFIG_DIR, `${app.id}-alias-${aliasDomain.fqdn.replace('*', '_')}.conf`);
|
||||
appDomains.push({ domain: aliasDomain.domain, fqdn: aliasDomain.fqdn, type: 'alias', app: app, nginxConfigFilename });
|
||||
});
|
||||
}
|
||||
|
||||
if (options.domain) appDomains = appDomains.filter(function (appDomain) { return appDomain.domain === options.domain; });
|
||||
|
||||
let progress = 1, renewed = [];
|
||||
|
||||
for (const appDomain of appDomains) {
|
||||
progressCallback({ percent: progress, message: `Ensuring certs of ${appDomain.fqdn}` });
|
||||
progress += Math.round(100/appDomains.length);
|
||||
|
||||
const { bundle, renewed } = await ensureCertificate(appDomain.fqdn, appDomain.domain, auditSource);
|
||||
|
||||
if (renewed) renewed.push(appDomain.fqdn);
|
||||
|
||||
if (appDomain.type === 'mail') continue; // mail has no nginx config to check current cert
|
||||
|
||||
// hack to check if the app's cert changed or not. this doesn't handle prod/staging le change since they use same file name
|
||||
let currentNginxConfig = safe.fs.readFileSync(appDomain.nginxConfigFilename, 'utf8') || '';
|
||||
if (currentNginxConfig.includes(bundle.certFilePath)) return;
|
||||
|
||||
debug(`renewCerts: creating new nginx config since ${appDomain.nginxConfigFilename} does not have ${bundle.certFilePath}`);
|
||||
|
||||
// reconfigure since the cert changed
|
||||
if (appDomain.type === 'webadmin' || appDomain.type === 'webadmin+mail') {
|
||||
await writeDashboardNginxConfig(bundle, `${settings.dashboardFqdn()}.conf`, settings.dashboardFqdn());
|
||||
} else if (appDomain.type === 'primary') {
|
||||
await writeAppNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alternate') {
|
||||
await writeAppRedirectNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alias') {
|
||||
await writeAppNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else {
|
||||
appDomains.push({ domain: settings.dashboardDomain(), fqdn: settings.dashboardFqdn(), type: 'webadmin', nginxConfigFilename: path.join(paths.NGINX_APPCONFIG_DIR, `${settings.dashboardFqdn()}.conf`) });
|
||||
appDomains.push({ domain: settings.mailDomain(), fqdn: settings.mailFqdn(), type: 'mail' });
|
||||
throw new BoxError(BoxError.INTERNAL_ERROR, `Unknown domain type for ${appDomain.fqdn}. This should never happen`);
|
||||
}
|
||||
}
|
||||
|
||||
allApps.forEach(function (app) {
|
||||
if (app.runState === apps.RSTATE_STOPPED) return; // do not renew certs of stopped apps
|
||||
debug(`renewCerts: Renewed certs of ${JSON.stringify(renewed)}`);
|
||||
if (renewed.length === 0) return;
|
||||
|
||||
appDomains.push({ domain: app.domain, fqdn: app.fqdn, type: 'primary', app: app, nginxConfigFilename: path.join(paths.NGINX_APPCONFIG_DIR, app.id + '.conf') });
|
||||
if (renewed.includes(settings.mailFqdn())) await mail.handleCertChanged();
|
||||
|
||||
app.alternateDomains.forEach(function (alternateDomain) {
|
||||
const nginxConfigFilename = path.join(paths.NGINX_APPCONFIG_DIR, `${app.id}-redirect-${alternateDomain.fqdn}.conf`);
|
||||
appDomains.push({ domain: alternateDomain.domain, fqdn: alternateDomain.fqdn, type: 'alternate', app: app, nginxConfigFilename });
|
||||
});
|
||||
await reload(); // reload nginx if any certs were updated but the config was not rewritten
|
||||
|
||||
app.aliasDomains.forEach(function (aliasDomain) {
|
||||
const nginxConfigFilename = path.join(paths.NGINX_APPCONFIG_DIR, `${app.id}-alias-${aliasDomain.fqdn.replace('*', '_')}.conf`);
|
||||
appDomains.push({ domain: aliasDomain.domain, fqdn: aliasDomain.fqdn, type: 'alias', app: app, nginxConfigFilename });
|
||||
});
|
||||
});
|
||||
|
||||
if (options.domain) appDomains = appDomains.filter(function (appDomain) { return appDomain.domain === options.domain; });
|
||||
|
||||
let progress = 1, renewed = [];
|
||||
|
||||
async.eachSeries(appDomains, async function (appDomain) {
|
||||
progressCallback({ percent: progress, message: `Ensuring certs of ${appDomain.fqdn}` });
|
||||
progress += Math.round(100/appDomains.length);
|
||||
|
||||
const { bundle, renewed } = ensureCertificate(appDomain.fqdn, appDomain.domain, auditSource);
|
||||
|
||||
if (renewed) renewed.push(appDomain.fqdn);
|
||||
|
||||
if (appDomain.type === 'mail') return; // mail has no nginx config to check current cert
|
||||
|
||||
// hack to check if the app's cert changed or not. this doesn't handle prod/staging le change since they use same file name
|
||||
let currentNginxConfig = safe.fs.readFileSync(appDomain.nginxConfigFilename, 'utf8') || '';
|
||||
if (currentNginxConfig.includes(bundle.certFilePath)) return;
|
||||
|
||||
debug(`renewCerts: creating new nginx config since ${appDomain.nginxConfigFilename} does not have ${bundle.certFilePath}`);
|
||||
|
||||
// reconfigure since the cert changed
|
||||
if (appDomain.type === 'webadmin' || appDomain.type === 'webadmin+mail') {
|
||||
await writeDashboardNginxConfig(bundle, `${settings.dashboardFqdn()}.conf`, settings.dashboardFqdn());
|
||||
} else if (appDomain.type === 'primary') {
|
||||
await writeAppNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alternate') {
|
||||
await writeAppRedirectNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alias') {
|
||||
await writeAppNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else {
|
||||
throw new BoxError(BoxError.INTERNAL_ERROR, `Unknown domain type for ${appDomain.fqdn}. This should never happen`);
|
||||
}
|
||||
}, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
debug(`renewCerts: Renewed certs of ${JSON.stringify(renewed)}`);
|
||||
if (renewed.length === 0) return callback(null);
|
||||
|
||||
async.series([
|
||||
async () => { if (renewed.includes(settings.mailFqdn())) await mail.handleCertChanged(); }, // mail cert renewed
|
||||
reload, // reload nginx if any certs were updated but the config was not rewritten
|
||||
(next) => { // restart tls apps on cert change
|
||||
const tlsApps = allApps.filter(app => app.manifest.addons && app.manifest.addons.tls && renewed.includes(app.fqdn));
|
||||
async.eachSeries(tlsApps, function (app, iteratorDone) {
|
||||
apps.restart(app, auditSource, () => iteratorDone());
|
||||
}, next);
|
||||
}
|
||||
], callback);
|
||||
});
|
||||
});
|
||||
// restart tls apps on cert change
|
||||
const tlsApps = allApps.filter(app => app.manifest.addons && app.manifest.addons.tls && renewed.includes(app.fqdn));
|
||||
for (const app of tlsApps) {
|
||||
await apps.restart(app, auditSource);
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanupCerts() {
|
||||
@@ -735,16 +729,13 @@ async function cleanupCerts() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkCerts(options, auditSource, progressCallback, callback) {
|
||||
async function checkCerts(options, auditSource, progressCallback) {
|
||||
assert.strictEqual(typeof options, 'object');
|
||||
assert.strictEqual(typeof auditSource, 'object');
|
||||
assert.strictEqual(typeof progressCallback, 'function');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
async.series([
|
||||
renewCerts.bind(null, options, auditSource, progressCallback),
|
||||
cleanupCerts
|
||||
], callback);
|
||||
await renewCerts(options, auditSource, progressCallback);
|
||||
await cleanupCerts();
|
||||
}
|
||||
|
||||
function removeAppConfigs() {
|
||||
|
||||
Reference in New Issue
Block a user