2019-03-21 05:46:49 +00:00
|
|
|
import _ from 'lodash-es';
|
|
|
|
|
2018-08-19 06:05:16 +00:00
|
|
|
function ConstraintModel(op, key, value) {
|
|
|
|
this.op = op;
|
|
|
|
this.value = value;
|
|
|
|
this.key = key;
|
|
|
|
}
|
|
|
|
|
|
|
|
var patterns = {
|
|
|
|
id: {
|
|
|
|
nodeId: 'node.id',
|
|
|
|
nodeHostname: 'node.hostname',
|
|
|
|
nodeRole: 'node.role',
|
|
|
|
nodeLabels: 'node.labels.',
|
2020-04-10 21:54:53 +00:00
|
|
|
engineLabels: 'engine.labels.',
|
2018-08-19 06:05:16 +00:00
|
|
|
},
|
|
|
|
op: {
|
|
|
|
eq: '==',
|
2020-04-10 21:54:53 +00:00
|
|
|
neq: '!=',
|
|
|
|
},
|
2018-08-19 06:05:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
function matchesConstraint(value, constraint) {
|
2020-04-10 21:54:53 +00:00
|
|
|
if (!constraint || (constraint.op === patterns.op.eq && value === constraint.value) || (constraint.op === patterns.op.neq && value !== constraint.value)) {
|
2018-08-19 06:05:16 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function matchesLabel(labels, constraint) {
|
|
|
|
if (!constraint) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
var found = _.find(labels, function (label) {
|
|
|
|
return label.key === constraint.key && label.value === constraint.value;
|
|
|
|
});
|
|
|
|
return found !== undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
function extractValue(constraint, op) {
|
|
|
|
return constraint.split(op).pop().trim();
|
|
|
|
}
|
|
|
|
|
|
|
|
function extractCustomLabelKey(constraint, op, baseLabelKey) {
|
|
|
|
return constraint.split(op).shift().trim().replace(baseLabelKey, '');
|
|
|
|
}
|
|
|
|
|
2020-04-10 21:54:53 +00:00
|
|
|
angular.module('portainer.docker').factory('ConstraintsHelper', [
|
|
|
|
function ConstraintsHelperFactory() {
|
2018-08-19 06:05:16 +00:00
|
|
|
'use strict';
|
|
|
|
return {
|
|
|
|
transformConstraints: function (constraints) {
|
|
|
|
var transform = {};
|
|
|
|
for (var i = 0; i < constraints.length; i++) {
|
|
|
|
var constraint = constraints[i];
|
|
|
|
|
|
|
|
var op;
|
|
|
|
if (constraint.includes(patterns.op.eq)) {
|
|
|
|
op = patterns.op.eq;
|
|
|
|
} else if (constraint.includes(patterns.op.neq)) {
|
|
|
|
op = patterns.op.neq;
|
|
|
|
}
|
|
|
|
|
|
|
|
var value = extractValue(constraint, op);
|
|
|
|
var key = '';
|
|
|
|
switch (true) {
|
|
|
|
case constraint.includes(patterns.id.nodeId):
|
|
|
|
transform.nodeId = new ConstraintModel(op, key, value);
|
|
|
|
break;
|
|
|
|
case constraint.includes(patterns.id.nodeHostname):
|
|
|
|
transform.nodeHostname = new ConstraintModel(op, key, value);
|
|
|
|
break;
|
|
|
|
case constraint.includes(patterns.id.nodeRole):
|
|
|
|
transform.nodeRole = new ConstraintModel(op, key, value);
|
|
|
|
break;
|
|
|
|
case constraint.includes(patterns.id.nodeLabels):
|
|
|
|
key = extractCustomLabelKey(constraint, op, patterns.id.nodeLabels);
|
|
|
|
transform.nodeLabels = new ConstraintModel(op, key, value);
|
|
|
|
break;
|
|
|
|
case constraint.includes(patterns.id.engineLabels):
|
|
|
|
key = extractCustomLabelKey(constraint, op, patterns.id.engineLabels);
|
|
|
|
transform.engineLabels = new ConstraintModel(op, key, value);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return transform;
|
|
|
|
},
|
|
|
|
matchesServiceConstraints: function (service, node) {
|
|
|
|
if (service.Constraints === undefined || service.Constraints.length === 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
var constraints = this.transformConstraints(angular.copy(service.Constraints));
|
2020-04-10 21:54:53 +00:00
|
|
|
if (
|
|
|
|
matchesConstraint(node.Id, constraints.nodeId) &&
|
2018-08-19 06:05:16 +00:00
|
|
|
matchesConstraint(node.Hostname, constraints.nodeHostname) &&
|
|
|
|
matchesConstraint(node.Role, constraints.nodeRole) &&
|
|
|
|
matchesLabel(node.Labels, constraints.nodeLabels) &&
|
|
|
|
matchesLabel(node.EngineLabels, constraints.engineLabels)
|
|
|
|
) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2020-04-10 21:54:53 +00:00
|
|
|
},
|
2018-08-19 06:05:16 +00:00
|
|
|
};
|
2020-04-10 21:54:53 +00:00
|
|
|
},
|
|
|
|
]);
|