Check for portBindings with range outside the db constraint for now

This commit is contained in:
Johannes Zellner
2024-02-28 14:56:04 +01:00
parent d87460a3cd
commit dec7bc3ca3
2 changed files with 73 additions and 0 deletions
+40
View File
@@ -133,6 +133,7 @@ exports = module.exports = {
HEALTH_DEAD: 'dead',
// exported for testing
_checkForPortBindingConflict: checkForPortBindingConflict,
_validatePortBindings: validatePortBindings,
_validateAccessRestriction: validateAccessRestriction,
_validateUpstreamUri: validateUpstreamUri,
@@ -795,6 +796,39 @@ function accessLevel(app, user) {
return canAccess(app, user) ? 'user' : null;
}
async function checkForPortBindingConflict(portBindings, id = '') {
assert.strictEqual(typeof portBindings, 'object');
assert.strictEqual(typeof id, 'string');
let existingPortBindings;
if (id) existingPortBindings = await database.query('SELECT * FROM appPortBindings WHERE appId != ?', [ id ]);
else existingPortBindings = await database.query('SELECT * FROM appPortBindings', []);
if (existingPortBindings.length === 0) return;
const tcpPorts = existingPortBindings.filter((p) => p.type === 'tcp');
const udpPorts = existingPortBindings.filter((p) => p.type === 'udp');
for (let portName in portBindings) {
const p = portBindings[portName];
const testPorts = p.type === 'tcp' ? tcpPorts : udpPorts;
const found = testPorts.find((e) => {
// if one is true we dont have a conflict
// a1 <----> a2 b1 <-------> b2
// b1 <------> b2 a1 <-----> a2
const a2 = (e.hostPort + e.count - 1);
const b1 = p.hostPort;
const b2 = (p.hostPort + p.portCount -1);
const a1 = e.hostPort;
return !((a2 < b1) || (b2 < a1));
});
if (found) throw new BoxError(BoxError.CONFLICT, `Conflicting port ${p.hostPort}`);
}
}
async function add(id, appStoreId, manifest, subdomain, domain, portBindings, data) {
assert.strictEqual(typeof id, 'string');
assert.strictEqual(typeof appStoreId, 'string');
@@ -830,6 +864,8 @@ async function add(id, appStoreId, manifest, subdomain, domain, portBindings, da
enableRedis = 'enableRedis' in data ? data.enableRedis : true,
icon = data.icon || null;
await checkForPortBindingConflict(portBindings);
const queries = [];
queries.push({
@@ -914,10 +950,14 @@ async function updateWithConstraints(id, app, constraints) {
assert(!('tags' in app) || Array.isArray(app.tags));
assert(!('env' in app) || typeof app.env === 'object');
const queries = [ ];
if ('portBindings' in app) {
const portBindings = app.portBindings || { };
await checkForPortBindingConflict(portBindings, id);
// replace entries by app id
queries.push({ query: 'DELETE FROM appPortBindings WHERE appId = ?', args: [ id ] });
Object.keys(portBindings).forEach(function (env) {