Check for portBindings with range outside the db constraint for now
This commit is contained in:
+40
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user