reverseproxy: simplify certificate renewal

An issue was that mail container was not getting refreshed with the up to
date certs. The root cause is that it is refreshed only in the renewCerts()
cron job. If cert renewal was caused by an app task, then the cron job will
skip the restart (since cert is fresh).

The other issue is that we keep hitting 0 length certs when we run out of disk
space. The root cause is that when out of disk space, a cert renewal will
cause cert to be written but since it has no space it is 0 length. Then, when
the user tries to restart the server, the box code does not write the cert again.

This change fixes the above two including:
* To simplify, we use the fallback cert only if we failed to get a LE cert. Expired LE certs
  will continue to be used. nginx is fine with this.

* restart directory as well on renewal
This commit is contained in:
Girish Ramakrishnan
2022-11-11 18:09:10 +01:00
parent f917eb8f13
commit 9c8f78a059
8 changed files with 216 additions and 162 deletions
+4 -11
View File
@@ -1067,13 +1067,6 @@ async function clear() {
await database.query('DELETE FROM apps');
}
async function getDomainObjectMap() {
const domainObjects = await domains.list();
let domainObjectMap = {};
for (let d of domainObjects) { domainObjectMap[d.domain] = d; }
return domainObjectMap;
}
// each query simply join apps table with another table by id. we then join the full result together
const PB_QUERY = 'SELECT id, GROUP_CONCAT(CAST(appPortBindings.hostPort AS CHAR(6))) AS hostPorts, GROUP_CONCAT(appPortBindings.environmentVariable) AS environmentVariables, GROUP_CONCAT(appPortBindings.type) AS portTypes FROM apps LEFT JOIN appPortBindings ON apps.id = appPortBindings.appId GROUP BY apps.id';
const ENV_QUERY = 'SELECT id, JSON_ARRAYAGG(appEnvVars.name) AS envNames, JSON_ARRAYAGG(appEnvVars.value) AS envValues FROM apps LEFT JOIN appEnvVars ON apps.id = appEnvVars.appId GROUP BY apps.id';
@@ -1088,7 +1081,7 @@ const APPS_QUERY = `SELECT ${APPS_FIELDS_PREFIXED}, hostPorts, environmentVariab
async function get(id) {
assert.strictEqual(typeof id, 'string');
const domainObjectMap = await getDomainObjectMap();
const domainObjectMap = await domains.getDomainObjectMap();
const result = await database.query(`${APPS_QUERY} WHERE apps.id = ?`, [ id ]);
if (result.length === 0) return null;
@@ -1103,7 +1096,7 @@ async function get(id) {
async function getByIpAddress(ip) {
assert.strictEqual(typeof ip, 'string');
const domainObjectMap = await getDomainObjectMap();
const domainObjectMap = await domains.getDomainObjectMap();
const result = await database.query(`${APPS_QUERY} WHERE apps.containerIp = ?`, [ ip ]);
if (result.length === 0) return null;
@@ -1114,7 +1107,7 @@ async function getByIpAddress(ip) {
}
async function list() {
const domainObjectMap = await getDomainObjectMap();
const domainObjectMap = await domains.getDomainObjectMap();
const results = await database.query(`${APPS_QUERY} ORDER BY apps.id`, [ ]);
results.forEach(postProcess);
@@ -1290,7 +1283,7 @@ function checkAppState(app, state) {
async function validateLocations(locations) {
assert(Array.isArray(locations));
const domainObjectMap = await getDomainObjectMap();
const domainObjectMap = await domains.getDomainObjectMap();
for (let location of locations) {
if (!(location.domain in domainObjectMap)) throw new BoxError(BoxError.BAD_FIELD, `No such domain in ${location.type} location`);