Force eslint one-var rule
Implements: blueprint converge-to-eslint-config-openstack Change-Id: I17ef229b9e31e56e77027a08e6a01a3aa7041699
This commit is contained in:
parent
bcddfcac9c
commit
a44a36118b
|
@ -17,7 +17,6 @@
|
|||
complexity: 0
|
||||
eqeqeq: 0
|
||||
no-script-url: 0
|
||||
one-var: [0, {uninitialized: always, initialized: never}]
|
||||
max-len: [0, 120]
|
||||
|
||||
# extra rules
|
||||
|
|
136
static/models.js
136
static/models.js
|
@ -58,8 +58,8 @@ var collectionMethods = [
|
|||
|
||||
_.each(collectionMethods, (method) => {
|
||||
collectionMixin[method] = function() {
|
||||
var args = _.toArray(arguments),
|
||||
source = args[0];
|
||||
var args = _.toArray(arguments);
|
||||
var source = args[0];
|
||||
|
||||
if (_.isPlainObject(source)) {
|
||||
args[0] = (model) => _.isMatch(model.attributes, source);
|
||||
|
@ -147,22 +147,21 @@ var restrictionMixin = models.restrictionMixin = {
|
|||
return ret;
|
||||
};
|
||||
|
||||
var checkedLimitTypes = {},
|
||||
name = this.get('name'),
|
||||
limits = this.expandedLimits[name] || {},
|
||||
overrides = limits.overrides || [],
|
||||
limitValues = {
|
||||
max: evaluateExpressionHelper(limits.max, models).value,
|
||||
min: evaluateExpressionHelper(limits.min, models).value,
|
||||
recommended: evaluateExpressionHelper(limits.recommended, models).value
|
||||
},
|
||||
count = nodes.nodesAfterDeploymentWithRole(name).length,
|
||||
messages,
|
||||
label = this.get('label');
|
||||
var checkedLimitTypes = {};
|
||||
var name = this.get('name');
|
||||
var limits = this.expandedLimits[name] || {};
|
||||
var overrides = limits.overrides || [];
|
||||
var limitValues = {
|
||||
max: evaluateExpressionHelper(limits.max, models).value,
|
||||
min: evaluateExpressionHelper(limits.min, models).value,
|
||||
recommended: evaluateExpressionHelper(limits.recommended, models).value
|
||||
};
|
||||
var count = nodes.nodesAfterDeploymentWithRole(name).length;
|
||||
var messages;
|
||||
var label = this.get('label');
|
||||
|
||||
var checkOneLimit = (obj, limitType) => {
|
||||
var limitValue,
|
||||
comparator;
|
||||
var limitValue, comparator;
|
||||
|
||||
if (_.isUndefined(obj[limitType])) {
|
||||
return;
|
||||
|
@ -277,8 +276,8 @@ models.Roles = BaseCollection.extend(restrictionMixin).extend({
|
|||
this.each((role) => {
|
||||
role.expandLimits(role.get('limits'));
|
||||
|
||||
var roleConflicts = role.get('conflicts'),
|
||||
roleName = role.get('name');
|
||||
var roleConflicts = role.get('conflicts');
|
||||
var roleName = role.get('name');
|
||||
|
||||
if (roleConflicts == '*') {
|
||||
role.conflicts = _.map(this.reject({name: roleName}), (role) => role.get('name'));
|
||||
|
@ -503,8 +502,8 @@ models.Nodes = BaseCollection.extend({
|
|||
},
|
||||
areDisksConfigurable() {
|
||||
if (!this.length) return false;
|
||||
var roles = _.union(this.at(0).get('roles'), this.at(0).get('pending_roles')),
|
||||
disks = this.at(0).resource('disks');
|
||||
var roles = _.union(this.at(0).get('roles'), this.at(0).get('pending_roles'));
|
||||
var disks = this.at(0).resource('disks');
|
||||
return !this.any((node) => {
|
||||
var roleConflict = _.difference(roles, _.union(node.get('roles'), node.get('pending_roles'))).length;
|
||||
return roleConflict || !_.isEqual(disks, node.resource('disks'));
|
||||
|
@ -543,9 +542,9 @@ models.Task = BaseModel.extend({
|
|||
return _.intersection(names, _.flatten(_.values(_.pick(this.groups, groups))));
|
||||
},
|
||||
extendStatuses(filters) {
|
||||
var activeTaskStatuses = ['running', 'pending'],
|
||||
completedTaskStatuses = ['ready', 'error'],
|
||||
statuses = utils.composeList(filters.status);
|
||||
var activeTaskStatuses = ['running', 'pending'];
|
||||
var completedTaskStatuses = ['ready', 'error'];
|
||||
var statuses = utils.composeList(filters.status);
|
||||
if (_.isEmpty(statuses)) {
|
||||
statuses = _.union(activeTaskStatuses, completedTaskStatuses);
|
||||
}
|
||||
|
@ -659,9 +658,9 @@ models.Settings = Backbone.DeepModel.extend(superMixin).extend(cacheMixin).exten
|
|||
this.once('change', this.mergePluginSettings, this);
|
||||
},
|
||||
validate(attrs, options) {
|
||||
var errors = {},
|
||||
models = options ? options.models : {},
|
||||
checkRestrictions = (setting) => this.checkRestrictions(models, null, setting);
|
||||
var errors = {};
|
||||
var models = options ? options.models : {};
|
||||
var checkRestrictions = (setting) => this.checkRestrictions(models, null, setting);
|
||||
_.each(attrs, (group, groupName) => {
|
||||
if ((group.metadata || {}).enabled === false || checkRestrictions(group.metadata).result) return;
|
||||
_.each(group, (setting, settingName) => {
|
||||
|
@ -689,8 +688,8 @@ models.Settings = Backbone.DeepModel.extend(superMixin).extend(cacheMixin).exten
|
|||
},
|
||||
hasChanges(initialAttributes, models) {
|
||||
return _.any(this.attributes, (section, sectionName) => {
|
||||
var metadata = section.metadata,
|
||||
result = false;
|
||||
var metadata = section.metadata;
|
||||
var result = false;
|
||||
if (metadata) {
|
||||
if (this.checkRestrictions(models, null, metadata).result) return result;
|
||||
if (!_.isUndefined(metadata.enabled)) {
|
||||
|
@ -773,8 +772,8 @@ models.Volume = BaseModel.extend({
|
|||
constructorName: 'Volume',
|
||||
urlRoot: '/api/volumes/',
|
||||
getMinimalSize(minimum) {
|
||||
var currentDisk = this.collection.disk,
|
||||
groupAllocatedSpace = 0;
|
||||
var currentDisk = this.collection.disk;
|
||||
var groupAllocatedSpace = 0;
|
||||
if (currentDisk && currentDisk.collection)
|
||||
groupAllocatedSpace = currentDisk.collection.reduce((sum, disk) => {
|
||||
return disk.id == currentDisk.id ? sum : sum + disk.get('volumes').findWhere({name: this.get('name')}).get('size');
|
||||
|
@ -782,10 +781,10 @@ models.Volume = BaseModel.extend({
|
|||
return minimum - groupAllocatedSpace;
|
||||
},
|
||||
getMaxSize() {
|
||||
var volumes = this.collection.disk.get('volumes'),
|
||||
diskAllocatedSpace = volumes.reduce((total, volume) => {
|
||||
return this.get('name') == volume.get('name') ? total : total + volume.get('size');
|
||||
}, 0);
|
||||
var volumes = this.collection.disk.get('volumes');
|
||||
var diskAllocatedSpace = volumes.reduce((total, volume) => {
|
||||
return this.get('name') == volume.get('name') ? total : total + volume.get('size');
|
||||
}, 0);
|
||||
return this.collection.disk.get('size') - diskAllocatedSpace;
|
||||
},
|
||||
validate(attrs, options) {
|
||||
|
@ -937,15 +936,15 @@ models.NetworkConfiguration = BaseModel.extend(cacheMixin).extend({
|
|||
return false;
|
||||
},
|
||||
validate(attrs) {
|
||||
var errors = {},
|
||||
networkingParametersErrors = {},
|
||||
ns = 'cluster_page.network_tab.validation.',
|
||||
networks = attrs.networks,
|
||||
networkParameters = attrs.networking_parameters,
|
||||
nodeNetworkGroupsErrors = {},
|
||||
nodeNetworkGroups = app.nodeNetworkGroups,
|
||||
novaNetManager = networkParameters.get('net_manager'),
|
||||
floatingRangesErrors;
|
||||
var errors = {};
|
||||
var networkingParametersErrors = {};
|
||||
var ns = 'cluster_page.network_tab.validation.';
|
||||
var networks = attrs.networks;
|
||||
var networkParameters = attrs.networking_parameters;
|
||||
var nodeNetworkGroupsErrors = {};
|
||||
var nodeNetworkGroups = app.nodeNetworkGroups;
|
||||
var novaNetManager = networkParameters.get('net_manager');
|
||||
var floatingRangesErrors;
|
||||
|
||||
nodeNetworkGroups.map((nodeNetworkGroup) => {
|
||||
var currentNetworks = new models.Networks(networks.where({group_id: nodeNetworkGroup.id}));
|
||||
|
@ -982,8 +981,8 @@ models.NetworkConfiguration = BaseModel.extend(cacheMixin).extend({
|
|||
nodeNetworkGroupErrors[network.id] = networkErrors;
|
||||
}
|
||||
if (network.get('name') == 'baremetal') {
|
||||
var baremetalCidrError = _.has(nodeNetworkGroupErrors[network.id], 'cidr'),
|
||||
baremetalGateway = networkParameters.get('baremetal_gateway');
|
||||
var baremetalCidrError = _.has(nodeNetworkGroupErrors[network.id], 'cidr');
|
||||
var baremetalGateway = networkParameters.get('baremetal_gateway');
|
||||
if (!utils.validateIP(baremetalGateway)) {
|
||||
networkingParametersErrors.baremetal_gateway = i18n(ns + 'invalid_gateway');
|
||||
} else if (!baremetalCidrError && !utils.validateIpCorrespondsToCIDR(cidr, baremetalGateway)) {
|
||||
|
@ -1040,7 +1039,8 @@ models.NetworkConfiguration = BaseModel.extend(cacheMixin).extend({
|
|||
var idRangeAttr = segmentation == 'vlan' ? 'vlan_range' : 'gre_id_range';
|
||||
var maxId = segmentation == 'vlan' ? 4094 : 65535;
|
||||
var idRange = networkParameters.get(idRangeAttr);
|
||||
var idStart = Number(idRange[0]), idEnd = Number(idRange[1]);
|
||||
var idStart = Number(idRange[0]);
|
||||
var idEnd = Number(idRange[1]);
|
||||
if (!utils.isNaturalNumber(idStart) || idStart < 2 || idStart > maxId) {
|
||||
idRangeErrors[0] = i18n(ns + 'invalid_id_start');
|
||||
} else if (!utils.isNaturalNumber(idEnd) || idEnd < 2 || idEnd > maxId) {
|
||||
|
@ -1078,30 +1078,30 @@ models.NetworkConfiguration = BaseModel.extend(cacheMixin).extend({
|
|||
}
|
||||
});
|
||||
|
||||
var floatingRanges = networkParameters.get('floating_ranges'),
|
||||
networkToCheckFloatingRange = networks.find((network) => {
|
||||
if (!network.get('meta').floating_range_var) return false;
|
||||
var cidrError = false;
|
||||
try {
|
||||
cidrError = !!errors.networks[network.get('group_id')][network.id].cidr;
|
||||
} catch (error) {}
|
||||
if (cidrError) return false;
|
||||
return utils.validateIpCorrespondsToCIDR(network.get('cidr'), floatingRanges[0][0]) &&
|
||||
utils.validateIpCorrespondsToCIDR(network.get('cidr'), floatingRanges[0][1]);
|
||||
});
|
||||
var floatingRanges = networkParameters.get('floating_ranges');
|
||||
var networkToCheckFloatingRange = networks.find((network) => {
|
||||
if (!network.get('meta').floating_range_var) return false;
|
||||
var cidrError = false;
|
||||
try {
|
||||
cidrError = !!errors.networks[network.get('group_id')][network.id].cidr;
|
||||
} catch (error) {}
|
||||
if (cidrError) return false;
|
||||
return utils.validateIpCorrespondsToCIDR(network.get('cidr'), floatingRanges[0][0]) &&
|
||||
utils.validateIpCorrespondsToCIDR(network.get('cidr'), floatingRanges[0][1]);
|
||||
});
|
||||
|
||||
var networkToCheckFloatingRangeData = networkToCheckFloatingRange ? {
|
||||
cidr: networkToCheckFloatingRange.get('cidr'),
|
||||
network: _.capitalize(networkToCheckFloatingRange.get('name')),
|
||||
nodeNetworkGroup: nodeNetworkGroups.get(networkToCheckFloatingRange.get('group_id')).get('name')
|
||||
} : {},
|
||||
networkToCheckFloatingRangeIPRanges = networkToCheckFloatingRange ? _.filter(networkToCheckFloatingRange.get('ip_ranges'), (range, index) => {
|
||||
var ipRangeError = false;
|
||||
try {
|
||||
ipRangeError = !_.all(range) || !!_.find(errors.networks[networkToCheckFloatingRange.get('group_id')][networkToCheckFloatingRange.id].ip_ranges, {index: index});
|
||||
} catch (error) {}
|
||||
return !ipRangeError;
|
||||
}) : [];
|
||||
cidr: networkToCheckFloatingRange.get('cidr'),
|
||||
network: _.capitalize(networkToCheckFloatingRange.get('name')),
|
||||
nodeNetworkGroup: nodeNetworkGroups.get(networkToCheckFloatingRange.get('group_id')).get('name')
|
||||
} : {};
|
||||
var networkToCheckFloatingRangeIPRanges = networkToCheckFloatingRange ? _.filter(networkToCheckFloatingRange.get('ip_ranges'), (range, index) => {
|
||||
var ipRangeError = false;
|
||||
try {
|
||||
ipRangeError = !_.all(range) || !!_.find(errors.networks[networkToCheckFloatingRange.get('group_id')][networkToCheckFloatingRange.id].ip_ranges, {index: index});
|
||||
} catch (error) {}
|
||||
return !ipRangeError;
|
||||
}) : [];
|
||||
|
||||
floatingRangesErrors = utils.validateIPRanges(
|
||||
floatingRanges,
|
||||
|
|
|
@ -215,8 +215,8 @@ VmWareModels.VCenter = BaseModel.extend({
|
|||
if (!response.editable || !response.editable.metadata || !response.editable.value) {
|
||||
return;
|
||||
}
|
||||
var metadata = response.editable.metadata || [],
|
||||
value = response.editable.value || {};
|
||||
var metadata = response.editable.metadata || [];
|
||||
var value = response.editable.value || {};
|
||||
|
||||
// Availability Zone(s)
|
||||
var azMetadata = _.find(metadata, {name: 'availability_zones'});
|
||||
|
|
|
@ -36,8 +36,8 @@ var Field = React.createClass({
|
|||
_.defer(() => dispatcher.trigger('vcenter_model_update'));
|
||||
},
|
||||
render() {
|
||||
var metadata = this.props.metadata,
|
||||
value = this.props.model.get(metadata.name);
|
||||
var metadata = this.props.metadata;
|
||||
var value = this.props.model.get(metadata.name);
|
||||
return (
|
||||
<Input
|
||||
{... _.pick(metadata, 'name', 'type', 'label', 'description')}
|
||||
|
@ -156,9 +156,9 @@ var NovaCompute = React.createClass({
|
|||
|
||||
var AvailabilityZone = React.createClass({
|
||||
addNovaCompute(current) {
|
||||
var collection = this.props.model.get('nova_computes'),
|
||||
index = collection.indexOf(current),
|
||||
newItem = current.clone();
|
||||
var collection = this.props.model.get('nova_computes');
|
||||
var index = collection.indexOf(current);
|
||||
var newItem = current.clone();
|
||||
var targetNode = _.cloneDeep(newItem.get('target_node'));
|
||||
if (this.props.isLocked) {
|
||||
targetNode.current = {id: 'invalid'};
|
||||
|
@ -175,18 +175,18 @@ var AvailabilityZone = React.createClass({
|
|||
_.defer(() => dispatcher.trigger('vcenter_model_update'));
|
||||
},
|
||||
renderFields() {
|
||||
var model = this.props.model,
|
||||
meta = model.get('metadata');
|
||||
var model = this.props.model;
|
||||
var meta = model.get('metadata');
|
||||
meta = _.filter(meta, VmWareModels.isRegularField);
|
||||
return (
|
||||
<FieldGroup model={model} disabled={this.props.isLocked || this.props.disabled}/>
|
||||
);
|
||||
},
|
||||
renderComputes(actions) {
|
||||
var novaComputes = this.props.model.get('nova_computes'),
|
||||
isSingleInstance = novaComputes.length == 1,
|
||||
disabled = actions.disable.nova_computes,
|
||||
cluster = this.props.cluster;
|
||||
var novaComputes = this.props.model.get('nova_computes');
|
||||
var isSingleInstance = novaComputes.length == 1;
|
||||
var disabled = actions.disable.nova_computes;
|
||||
var cluster = this.props.cluster;
|
||||
|
||||
return (
|
||||
<div className='col-xs-offset-1'>
|
||||
|
@ -375,17 +375,17 @@ var VmWareTab = React.createClass({
|
|||
return null;
|
||||
}
|
||||
|
||||
var model = this.state.model,
|
||||
currentJson = JSON.stringify(this.model.toJSON()),
|
||||
editable = this.props.cluster.isAvailableForSettingsChanges(),
|
||||
hide = this.actions.hide || {},
|
||||
disable = this.actions.disable || {};
|
||||
var model = this.state.model;
|
||||
var currentJson = JSON.stringify(this.model.toJSON());
|
||||
var editable = this.props.cluster.isAvailableForSettingsChanges();
|
||||
var hide = this.actions.hide || {};
|
||||
var disable = this.actions.disable || {};
|
||||
|
||||
model.isValid();
|
||||
var hasChanges = this.detectChanges(this.json, currentJson);
|
||||
var hasDefaultsChanges = this.detectChanges(this.defaultsJson, currentJson);
|
||||
var saveDisabled = !hasChanges || !this.isSavingPossible(),
|
||||
defaultsDisabled = !hasDefaultsChanges;
|
||||
var saveDisabled = !hasChanges || !this.isSavingPossible();
|
||||
var defaultsDisabled = !hasDefaultsChanges;
|
||||
|
||||
return (
|
||||
<div className='row'>
|
||||
|
|
|
@ -55,7 +55,8 @@ define([
|
|||
},
|
||||
waitForCssSelector: function(cssSelector, timeout) {
|
||||
return new this.constructor(this, function() {
|
||||
var self = this, currentTimeout;
|
||||
var self = this;
|
||||
var currentTimeout;
|
||||
return this.parent
|
||||
.getFindTimeout()
|
||||
.then(function(value) {
|
||||
|
@ -75,7 +76,8 @@ define([
|
|||
},
|
||||
waitForElementDeletion: function(cssSelector, timeout) {
|
||||
return new this.constructor(this, function() {
|
||||
var self = this, currentTimeout;
|
||||
var self = this;
|
||||
var currentTimeout;
|
||||
return this.parent
|
||||
.getFindTimeout()
|
||||
.then(function(value) {
|
||||
|
@ -137,8 +139,7 @@ define([
|
|||
|
||||
return this.parent.executeAsync(function(dragFrom, dragTo, done) {
|
||||
var dragAndDrop = (function() {
|
||||
var dispatchEvent;
|
||||
var createEvent;
|
||||
var dispatchEvent, createEvent;
|
||||
|
||||
// Setup methods to call the proper event creation and dispatch functions for the current platform.
|
||||
if (document.createEvent) {
|
||||
|
@ -494,11 +495,11 @@ define([
|
|||
}
|
||||
});
|
||||
|
||||
var serverHost = '127.0.0.1',
|
||||
serverPort = process.env.NAILGUN_PORT || 5544,
|
||||
serverUrl = 'http://' + serverHost + ':' + serverPort,
|
||||
username = 'admin',
|
||||
password = 'admin';
|
||||
var serverHost = '127.0.0.1';
|
||||
var serverPort = process.env.NAILGUN_PORT || 5544;
|
||||
var serverUrl = 'http://' + serverHost + ':' + serverPort;
|
||||
var username = 'admin';
|
||||
var password = 'admin';
|
||||
|
||||
return {
|
||||
username: username,
|
||||
|
|
|
@ -28,10 +28,10 @@ define([
|
|||
ClustersPage.prototype = {
|
||||
constructor: ClustersPage,
|
||||
createCluster: function(clusterName, stepsMethods) {
|
||||
var self = this,
|
||||
stepMethod = function(stepName) {
|
||||
return _.bind(_.get(stepsMethods, stepName, _.noop), self);
|
||||
};
|
||||
var self = this;
|
||||
var stepMethod = function(stepName) {
|
||||
return _.bind(_.get(stepsMethods, stepName, _.noop), self);
|
||||
};
|
||||
return this.remote
|
||||
.clickByCssSelector('.create-cluster')
|
||||
.then(function() {
|
||||
|
|
|
@ -41,8 +41,8 @@ define([
|
|||
.waitForCssSelector('.node-popover', 1000);
|
||||
},
|
||||
openNodePopup: function(fromExtendedView) {
|
||||
var self = this,
|
||||
cssSelector = fromExtendedView ? '.node-popover' : '.node';
|
||||
var self = this;
|
||||
var cssSelector = fromExtendedView ? '.node-popover' : '.node';
|
||||
return this.remote
|
||||
.findByCssSelector(cssSelector)
|
||||
.clickByCssSelector('.node-settings')
|
||||
|
@ -52,8 +52,8 @@ define([
|
|||
});
|
||||
},
|
||||
discardNode: function(fromExtendedView) {
|
||||
var self = this,
|
||||
cssSelector = fromExtendedView ? '.node-popover' : '.node';
|
||||
var self = this;
|
||||
var cssSelector = fromExtendedView ? '.node-popover' : '.node';
|
||||
return this.remote
|
||||
.findByCssSelector(cssSelector)
|
||||
.clickByCssSelector('.btn-discard')
|
||||
|
|
|
@ -55,10 +55,10 @@ define([
|
|||
});
|
||||
},
|
||||
'Renaming cluster works': function() {
|
||||
var initialName = clusterName,
|
||||
newName = clusterName + '!!!',
|
||||
renameInputSelector = '.rename-block input[type=text]',
|
||||
nameSelector = '.cluster-info-value.name .btn-link';
|
||||
var initialName = clusterName;
|
||||
var newName = clusterName + '!!!';
|
||||
var renameInputSelector = '.rename-block input[type=text]';
|
||||
var nameSelector = '.cluster-info-value.name .btn-link';
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return dashboardPage.startClusterRenaming();
|
||||
|
@ -172,13 +172,13 @@ define([
|
|||
},
|
||||
'Test statistics update': function() {
|
||||
this.timeout = 120000;
|
||||
var controllerNodes = 3,
|
||||
storageCinderNodes = 1,
|
||||
computeNodes = 2,
|
||||
operatingSystemNodes = 1,
|
||||
virtualNodes = 1,
|
||||
valueSelector = '.statistics-block .cluster-info-value',
|
||||
total = controllerNodes + storageCinderNodes + computeNodes + operatingSystemNodes + virtualNodes;
|
||||
var controllerNodes = 3;
|
||||
var storageCinderNodes = 1;
|
||||
var computeNodes = 2;
|
||||
var operatingSystemNodes = 1;
|
||||
var virtualNodes = 1;
|
||||
var valueSelector = '.statistics-block .cluster-info-value';
|
||||
var total = controllerNodes + storageCinderNodes + computeNodes + operatingSystemNodes + virtualNodes;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(controllerNodes, ['Controller']);
|
||||
|
|
|
@ -25,11 +25,9 @@ define([
|
|||
'use strict';
|
||||
|
||||
registerSuite(function() {
|
||||
var common,
|
||||
clusterPage,
|
||||
clusterName,
|
||||
nodesAmount = 3,
|
||||
applyButtonSelector = 'button.btn-apply';
|
||||
var common, clusterPage, clusterName;
|
||||
var nodesAmount = 3;
|
||||
var applyButtonSelector = 'button.btn-apply';
|
||||
|
||||
return {
|
||||
name: 'Cluster page',
|
||||
|
|
|
@ -136,8 +136,8 @@ define([
|
|||
.assertElementNotExists('.settings-tab .nav-pills > li.active i.glyphicon-danger-sign', 'Subgroup menu has default layout after resetting changes');
|
||||
},
|
||||
'Test repositories custom control': function() {
|
||||
var repoAmount,
|
||||
self = this;
|
||||
var repoAmount;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.clickLinkByText('General')
|
||||
// get amount of default repositories
|
||||
|
|
|
@ -25,13 +25,10 @@ define([
|
|||
'use strict';
|
||||
|
||||
registerSuite(function() {
|
||||
var common,
|
||||
clusterPage,
|
||||
dashboardPage,
|
||||
clusterName,
|
||||
searchButtonSelector = '.node-management-panel .btn-search',
|
||||
sortingButtonSelector = '.node-management-panel .btn-sorters',
|
||||
filtersButtonSelector = '.node-management-panel .btn-filters';
|
||||
var common, clusterPage, dashboardPage, clusterName;
|
||||
var searchButtonSelector = '.node-management-panel .btn-search';
|
||||
var sortingButtonSelector = '.node-management-panel .btn-sorters';
|
||||
var filtersButtonSelector = '.node-management-panel .btn-filters';
|
||||
|
||||
return {
|
||||
name: 'Node management panel on cluster nodes page: search, sorting, filtering',
|
||||
|
@ -98,10 +95,10 @@ define([
|
|||
.assertElementExists(searchButtonSelector, 'Empty search control is closed when clicking outside the input');
|
||||
},
|
||||
'Test node list sorting': function() {
|
||||
var activeSortersPanelSelector = '.active-sorters',
|
||||
moreControlSelector = '.sorters .more-control',
|
||||
firstNodeName,
|
||||
self = this;
|
||||
var activeSortersPanelSelector = '.active-sorters';
|
||||
var moreControlSelector = '.sorters .more-control';
|
||||
var firstNodeName;
|
||||
var self = this;
|
||||
return this.remote
|
||||
.assertElementExists(activeSortersPanelSelector, 'Active sorters panel is shown if there are nodes in cluster')
|
||||
.assertElementNotExists(activeSortersPanelSelector + '.btn-reset-sorting', 'Default sorting can not be reset from active sorters panel')
|
||||
|
@ -144,8 +141,8 @@ define([
|
|||
.end();
|
||||
},
|
||||
'Test node list filtering': function() {
|
||||
var activeFiltersPanelSelector = '.active-filters',
|
||||
moreControlSelector = '.filters .more-control';
|
||||
var activeFiltersPanelSelector = '.active-filters';
|
||||
var moreControlSelector = '.filters .more-control';
|
||||
return this.remote
|
||||
.assertElementNotExists(activeFiltersPanelSelector, 'Environment has no active filters by default')
|
||||
.clickByCssSelector(filtersButtonSelector)
|
||||
|
|
|
@ -26,12 +26,8 @@ define([
|
|||
'use strict';
|
||||
|
||||
registerSuite(function() {
|
||||
var common,
|
||||
node,
|
||||
modal,
|
||||
clusterPage,
|
||||
clusterName,
|
||||
nodeNewName = 'Node new name';
|
||||
var common, node, modal, clusterPage, clusterName;
|
||||
var nodeNewName = 'Node new name';
|
||||
|
||||
return {
|
||||
name: 'Node view tests',
|
||||
|
|
|
@ -25,12 +25,9 @@ define([
|
|||
'use strict';
|
||||
|
||||
registerSuite(function() {
|
||||
var common,
|
||||
clusterPage,
|
||||
settingsPage,
|
||||
dashboardPage,
|
||||
clusterName = 'Plugin UI tests',
|
||||
zabbixSectionSelector = '.setting-section-zabbix_monitoring ';
|
||||
var common, clusterPage, settingsPage, dashboardPage;
|
||||
var clusterName = 'Plugin UI tests';
|
||||
var zabbixSectionSelector = '.setting-section-zabbix_monitoring ';
|
||||
|
||||
return {
|
||||
name: 'Plugin UI tests',
|
||||
|
@ -62,9 +59,8 @@ define([
|
|||
});
|
||||
},
|
||||
'Check plugin in not deployed environment': function() {
|
||||
var self = this,
|
||||
zabbixInitialVersion,
|
||||
zabbixTextInputValue;
|
||||
var self = this;
|
||||
var zabbixInitialVersion, zabbixTextInputValue;
|
||||
return this.remote
|
||||
.assertElementEnabled(zabbixSectionSelector + 'h3 input[type=checkbox]', 'Plugin is changeable')
|
||||
.assertElementNotSelected(zabbixSectionSelector + 'h3 input[type=checkbox]', 'Plugin is not actvated')
|
||||
|
@ -104,8 +100,8 @@ define([
|
|||
},
|
||||
'Check plugin in deployed environment': function() {
|
||||
this.timeout = 100000;
|
||||
var self = this,
|
||||
zabbixInitialVersion;
|
||||
var self = this;
|
||||
var zabbixInitialVersion;
|
||||
return this.remote
|
||||
.then(function() {
|
||||
return common.addNodesToCluster(1, ['Controller']);
|
||||
|
|
|
@ -52,12 +52,12 @@ suite('File Control', () => {
|
|||
});
|
||||
|
||||
test('File fetching', () => {
|
||||
var readMethod = sinon.mock(),
|
||||
readerObject = {
|
||||
readAsBinaryString: readMethod,
|
||||
result: 'File contents'
|
||||
},
|
||||
saveMethod = sinon.spy(input, 'saveFile');
|
||||
var readMethod = sinon.mock();
|
||||
var readerObject = {
|
||||
readAsBinaryString: readMethod,
|
||||
result: 'File contents'
|
||||
};
|
||||
var saveMethod = sinon.spy(input, 'saveFile');
|
||||
|
||||
window.FileReader = () => readerObject;
|
||||
|
||||
|
@ -77,9 +77,9 @@ suite('File Control', () => {
|
|||
});
|
||||
|
||||
test('File saving', () => {
|
||||
var setState = sinon.spy(input, 'setState'),
|
||||
dummyName = 'dummy.ext',
|
||||
dummyContent = 'Lorem ipsum dolores';
|
||||
var setState = sinon.spy(input, 'setState');
|
||||
var dummyName = 'dummy.ext';
|
||||
var dummyContent = 'Lorem ipsum dolores';
|
||||
input.saveFile(dummyName, dummyContent);
|
||||
|
||||
assert.deepEqual(setState.args[0][0], {
|
||||
|
|
|
@ -19,8 +19,8 @@ import models from 'models';
|
|||
suite('Test models', () => {
|
||||
suite('Test Task model', () => {
|
||||
test('Test extendStatuses method', () => {
|
||||
var task = new models.Task(),
|
||||
filters, result;
|
||||
var task = new models.Task();
|
||||
var filters, result;
|
||||
|
||||
filters = {status: []};
|
||||
result = ['running', 'pending', 'ready', 'error'];
|
||||
|
@ -60,9 +60,9 @@ suite('Test models', () => {
|
|||
});
|
||||
|
||||
test('Test extendGroups method', () => {
|
||||
var task = new models.Task(),
|
||||
allTaskNames = _.flatten(_.values(task.groups)),
|
||||
filters, result;
|
||||
var task = new models.Task();
|
||||
var allTaskNames = _.flatten(_.values(task.groups));
|
||||
var filters, result;
|
||||
|
||||
filters = {name: []};
|
||||
result = allTaskNames;
|
||||
|
|
|
@ -15,21 +15,18 @@
|
|||
**/
|
||||
import OffloadingModes from 'views/cluster_page_tabs/nodes_tab_screens/offloading_modes_control';
|
||||
|
||||
var offloadingModesConrol,
|
||||
TestMode22,
|
||||
TestMode31,
|
||||
fakeOffloadingModes,
|
||||
fakeInterface = {
|
||||
offloading_modes: fakeOffloadingModes,
|
||||
get(key) {
|
||||
assert.equal(key, 'offloading_modes', '"offloading_modes" interface property should be used to get data');
|
||||
return fakeOffloadingModes;
|
||||
},
|
||||
set(key, value) {
|
||||
assert.equal(key, 'offloading_modes', '"offloading_modes" interface property should be used to set data');
|
||||
fakeOffloadingModes = value;
|
||||
}
|
||||
};
|
||||
var offloadingModesConrol, TestMode22, TestMode31, fakeOffloadingModes;
|
||||
var fakeInterface = {
|
||||
offloading_modes: fakeOffloadingModes,
|
||||
get(key) {
|
||||
assert.equal(key, 'offloading_modes', '"offloading_modes" interface property should be used to get data');
|
||||
return fakeOffloadingModes;
|
||||
},
|
||||
set(key, value) {
|
||||
assert.equal(key, 'offloading_modes', '"offloading_modes" interface property should be used to set data');
|
||||
fakeOffloadingModes = value;
|
||||
}
|
||||
};
|
||||
|
||||
suite('Offloadning Modes control', () => {
|
||||
setup(() => {
|
||||
|
|
|
@ -39,9 +39,9 @@ var utils = {
|
|||
return _.object(_.map((serializedOptions || '').split(';'), (option) => option.split(':')));
|
||||
},
|
||||
getNodeListFromTabOptions(options) {
|
||||
var nodeIds = utils.deserializeTabOptions(options.screenOptions[0]).nodes,
|
||||
ids = nodeIds ? nodeIds.split(',').map((id) => parseInt(id, 10)) : [],
|
||||
nodes = new models.Nodes(options.cluster.get('nodes').getByIds(ids));
|
||||
var nodeIds = utils.deserializeTabOptions(options.screenOptions[0]).nodes;
|
||||
var ids = nodeIds ? nodeIds.split(',').map((id) => parseInt(id, 10)) : [];
|
||||
var nodes = new models.Nodes(options.cluster.get('nodes').getByIds(ids));
|
||||
if (nodes.length == ids.length) return nodes;
|
||||
},
|
||||
renderMultilineText(text) {
|
||||
|
@ -71,8 +71,8 @@ var utils = {
|
|||
return modelPath;
|
||||
},
|
||||
evaluateExpression(expression, models, options) {
|
||||
var compiledExpression = new Expression(expression, models, options),
|
||||
value = compiledExpression.evaluate();
|
||||
var compiledExpression = new Expression(expression, models, options);
|
||||
var value = compiledExpression.evaluate();
|
||||
return {
|
||||
value: value,
|
||||
modelPaths: compiledExpression.modelPaths
|
||||
|
@ -120,7 +120,8 @@ var utils = {
|
|||
var base = 1024;
|
||||
treshold = treshold || 256;
|
||||
var units = ['byte', 'kb', 'mb', 'gb', 'tb'];
|
||||
var i, result, unit = 'tb';
|
||||
var i, result;
|
||||
var unit = 'tb';
|
||||
for (i = 0; i < units.length; i += 1) {
|
||||
result = bytes / Math.pow(base, i);
|
||||
if (result < treshold) {
|
||||
|
@ -162,7 +163,8 @@ var utils = {
|
|||
},
|
||||
validateCidr(cidr, field) {
|
||||
field = field || 'cidr';
|
||||
var error = {}, match;
|
||||
var error = {};
|
||||
var match;
|
||||
if (_.isString(cidr)) {
|
||||
match = cidr.match(utils.regexes.cidr);
|
||||
if (match) {
|
||||
|
@ -184,8 +186,8 @@ var utils = {
|
|||
return _.isString(ip) && !!ip.match(utils.regexes.ip);
|
||||
},
|
||||
validateIPRanges(ranges, cidr, existingRanges = [], warnings = {}) {
|
||||
var ipRangesErrors = [],
|
||||
ns = 'cluster_page.network_tab.validation.';
|
||||
var ipRangesErrors = [];
|
||||
var ns = 'cluster_page.network_tab.validation.';
|
||||
_.defaults(warnings, {
|
||||
INVALID_IP: i18n(ns + 'invalid_ip'),
|
||||
DOES_NOT_MATCH_CIDR: i18n(ns + 'ip_does_not_match_cidr'),
|
||||
|
@ -239,14 +241,14 @@ var utils = {
|
|||
return ipRangesErrors;
|
||||
},
|
||||
checkIPRangesIntersection([startIP, endIP], existingRanges) {
|
||||
var startIPInt = IP.toLong(startIP),
|
||||
endIPInt = IP.toLong(endIP);
|
||||
var startIPInt = IP.toLong(startIP);
|
||||
var endIPInt = IP.toLong(endIP);
|
||||
return _.find(existingRanges, ([ip1, ip2]) => IP.toLong(ip2) >= startIPInt && IP.toLong(ip1) <= endIPInt);
|
||||
},
|
||||
validateIpCorrespondsToCIDR(cidr, ip) {
|
||||
if (!cidr) return true;
|
||||
var networkData = IP.cidrSubnet(cidr),
|
||||
ipInt = IP.toLong(ip);
|
||||
var networkData = IP.cidrSubnet(cidr);
|
||||
var ipInt = IP.toLong(ip);
|
||||
return ipInt >= IP.toLong(networkData.firstAddress) && ipInt <= IP.toLong(networkData.lastAddress);
|
||||
},
|
||||
validateVlanRange(vlanStart, vlanEnd, vlan) {
|
||||
|
@ -309,8 +311,8 @@ var utils = {
|
|||
var attr = options.attr;
|
||||
return _.isFunction(model[attr]) ? model[attr]() : model.get(attr);
|
||||
};
|
||||
var value1 = getValue(model1),
|
||||
value2 = getValue(model2);
|
||||
var value1 = getValue(model1);
|
||||
var value2 = getValue(model2);
|
||||
if (_.isString(value1) && _.isString(value2)) {
|
||||
return utils.natsort(value1, value2, options);
|
||||
}
|
||||
|
@ -323,9 +325,9 @@ var utils = {
|
|||
return options.desc ? -result : result;
|
||||
},
|
||||
composeDocumentationLink(link) {
|
||||
var isMirantisIso = _.contains(app.version.get('feature_groups'), 'mirantis'),
|
||||
release = app.version.get('release'),
|
||||
linkStart = isMirantisIso ? 'https://docs.mirantis.com/openstack/fuel/fuel-' :
|
||||
var isMirantisIso = _.contains(app.version.get('feature_groups'), 'mirantis');
|
||||
var release = app.version.get('release');
|
||||
var linkStart = isMirantisIso ? 'https://docs.mirantis.com/openstack/fuel/fuel-' :
|
||||
'https://docs.fuel-infra.org/openstack/fuel/fuel-';
|
||||
return linkStart + release + '/' + link;
|
||||
}
|
||||
|
|
|
@ -63,9 +63,9 @@ var CapacityPage = React.createClass({
|
|||
|
||||
var LicenseUsage = React.createClass({
|
||||
render() {
|
||||
var capacityReport = this.props.capacityLog.get('report'),
|
||||
tableClassName = 'capacity-audit-table',
|
||||
headClassName = 'name';
|
||||
var capacityReport = this.props.capacityLog.get('report');
|
||||
var tableClassName = 'capacity-audit-table';
|
||||
var headClassName = 'name';
|
||||
return (
|
||||
<div>
|
||||
<h3>{i18n('capacity_page.license_usage')}</h3>
|
||||
|
|
|
@ -55,15 +55,15 @@ var ClusterPage = React.createClass({
|
|||
statics: {
|
||||
navbarActiveElement: 'clusters',
|
||||
breadcrumbsPath(pageOptions) {
|
||||
var cluster = pageOptions.cluster,
|
||||
tabOptions = pageOptions.tabOptions[0],
|
||||
addScreenBreadcrumb = tabOptions && tabOptions.match(/^(?!list$)\w+$/),
|
||||
breadcrumbs = [
|
||||
['home', '#'],
|
||||
['environments', '#clusters'],
|
||||
[cluster.get('name'), '#cluster/' + cluster.get('id'), {skipTranslation: true}],
|
||||
[i18n('cluster_page.tabs.' + pageOptions.activeTab), '#cluster/' + cluster.get('id') + '/' + pageOptions.activeTab, {active: !addScreenBreadcrumb}]
|
||||
];
|
||||
var cluster = pageOptions.cluster;
|
||||
var tabOptions = pageOptions.tabOptions[0];
|
||||
var addScreenBreadcrumb = tabOptions && tabOptions.match(/^(?!list$)\w+$/);
|
||||
var breadcrumbs = [
|
||||
['home', '#'],
|
||||
['environments', '#clusters'],
|
||||
[cluster.get('name'), '#cluster/' + cluster.get('id'), {skipTranslation: true}],
|
||||
[i18n('cluster_page.tabs.' + pageOptions.activeTab), '#cluster/' + cluster.get('id') + '/' + pageOptions.activeTab, {active: !addScreenBreadcrumb}]
|
||||
];
|
||||
if (addScreenBreadcrumb) {
|
||||
breadcrumbs.push([i18n('cluster_page.nodes_tab.breadcrumbs.' + tabOptions), null, {active: true}]);
|
||||
}
|
||||
|
@ -271,10 +271,10 @@ var ClusterPage = React.createClass({
|
|||
}
|
||||
},
|
||||
render() {
|
||||
var cluster = this.props.cluster,
|
||||
availableTabs = this.getAvailableTabs(cluster),
|
||||
tabUrls = _.pluck(availableTabs, 'url'),
|
||||
tab = _.find(availableTabs, {url: this.props.activeTab});
|
||||
var cluster = this.props.cluster;
|
||||
var availableTabs = this.getAvailableTabs(cluster);
|
||||
var tabUrls = _.pluck(availableTabs, 'url');
|
||||
var tab = _.find(availableTabs, {url: this.props.activeTab});
|
||||
if (!tab) return null;
|
||||
var Tab = tab.tab;
|
||||
|
||||
|
|
|
@ -48,10 +48,10 @@ var DashboardTab = React.createClass({
|
|||
return this.props.cluster.get('nodes').fetch();
|
||||
},
|
||||
render() {
|
||||
var cluster = this.props.cluster,
|
||||
nodes = cluster.get('nodes'),
|
||||
release = cluster.get('release'),
|
||||
runningDeploymentTask = cluster.task({group: 'deployment', active: true});
|
||||
var cluster = this.props.cluster;
|
||||
var nodes = cluster.get('nodes');
|
||||
var release = cluster.get('release');
|
||||
var runningDeploymentTask = cluster.task({group: 'deployment', active: true});
|
||||
|
||||
var dashboardLinks = [{
|
||||
url: '/',
|
||||
|
@ -156,9 +156,9 @@ var DashboardLink = React.createClass({
|
|||
return 'http://' + this.props.cluster.get('networkConfiguration').get('public_vip') + url;
|
||||
},
|
||||
render() {
|
||||
var isSSLEnabled = this.props.cluster.get('settings').get('public_ssl.horizon.value'),
|
||||
isURLRelative = !(/^(?:https?:)?\/\//.test(this.props.url)),
|
||||
url = isURLRelative ? this.processRelativeURL(this.props.url) : this.props.url;
|
||||
var isSSLEnabled = this.props.cluster.get('settings').get('public_ssl.horizon.value');
|
||||
var isURLRelative = !(/^(?:https?:)?\/\//.test(this.props.url));
|
||||
var url = isURLRelative ? this.processRelativeURL(this.props.url) : this.props.url;
|
||||
return (
|
||||
<div className={'link-block ' + this.props.className}>
|
||||
<div className='title'>
|
||||
|
@ -180,11 +180,11 @@ var DeploymentInProgressControl = React.createClass({
|
|||
Dialog.show({cluster: this.props.cluster});
|
||||
},
|
||||
render() {
|
||||
var task = this.props.task,
|
||||
taskName = task.get('name'),
|
||||
isInfiniteTask = task.isInfinite(),
|
||||
taskProgress = task.get('progress'),
|
||||
showStopButton = task.match({name: 'deploy'});
|
||||
var task = this.props.task;
|
||||
var taskName = task.get('name');
|
||||
var isInfiniteTask = task.isInfinite();
|
||||
var taskProgress = task.get('progress');
|
||||
var showStopButton = task.match({name: 'deploy'});
|
||||
return (
|
||||
<div className='row'>
|
||||
<div className='dashboard-block clearfix'>
|
||||
|
@ -236,17 +236,17 @@ var DeploymentResult = React.createClass({
|
|||
render() {
|
||||
var task = this.props.cluster.task({group: 'deployment', active: false});
|
||||
if (!task) return null;
|
||||
var error = task.match({status: 'error'}),
|
||||
delimited = task.escape('message').split('\n\n'),
|
||||
summary = delimited.shift(),
|
||||
details = delimited.join('\n\n'),
|
||||
warning = task.match({name: ['reset_environment', 'stop_deployment']}),
|
||||
classes = {
|
||||
alert: true,
|
||||
'alert-warning': warning,
|
||||
'alert-danger': !warning && error,
|
||||
'alert-success': !warning && !error
|
||||
};
|
||||
var error = task.match({status: 'error'});
|
||||
var delimited = task.escape('message').split('\n\n');
|
||||
var summary = delimited.shift();
|
||||
var details = delimited.join('\n\n');
|
||||
var warning = task.match({name: ['reset_environment', 'stop_deployment']});
|
||||
var classes = {
|
||||
alert: true,
|
||||
'alert-warning': warning,
|
||||
'alert-danger': !warning && error,
|
||||
'alert-success': !warning && !error
|
||||
};
|
||||
return (
|
||||
<div className={utils.classNames(classes)}>
|
||||
<button className='close' onClick={this.dismissTaskResult}>×</button>
|
||||
|
@ -381,8 +381,8 @@ var DeployReadinessBlock = React.createClass({
|
|||
},
|
||||
// check cluster settings
|
||||
function(cluster) {
|
||||
var configModels = this.getConfigModels(),
|
||||
areSettingsInvalid = !cluster.get('settings').isValid({models: configModels});
|
||||
var configModels = this.getConfigModels();
|
||||
var areSettingsInvalid = !cluster.get('settings').isValid({models: configModels});
|
||||
return areSettingsInvalid &&
|
||||
{blocker: [
|
||||
<span key='invalid_settings'>
|
||||
|
@ -396,20 +396,20 @@ var DeployReadinessBlock = React.createClass({
|
|||
},
|
||||
// check node amount restrictions according to their roles
|
||||
function(cluster) {
|
||||
var configModels = this.getConfigModels(),
|
||||
roleModels = cluster.get('roles'),
|
||||
validRoleModels = roleModels.filter((role) => !role.checkRestrictions(configModels).result),
|
||||
limitValidations = _.zipObject(validRoleModels.map((role) => [role.get('name'), role.checkLimits(configModels, cluster.get('nodes'))])),
|
||||
limitRecommendations = _.zipObject(validRoleModels.map((role) => [role.get('name'), role.checkLimits(configModels, cluster.get('nodes'), true, ['recommended'])]));
|
||||
var configModels = this.getConfigModels();
|
||||
var roleModels = cluster.get('roles');
|
||||
var validRoleModels = roleModels.filter((role) => !role.checkRestrictions(configModels).result);
|
||||
var limitValidations = _.zipObject(validRoleModels.map((role) => [role.get('name'), role.checkLimits(configModels, cluster.get('nodes'))]));
|
||||
var limitRecommendations = _.zipObject(validRoleModels.map((role) => [role.get('name'), role.checkLimits(configModels, cluster.get('nodes'), true, ['recommended'])]));
|
||||
return {
|
||||
blocker: roleModels.map((role) => {
|
||||
var name = role.get('name'),
|
||||
limits = limitValidations[name];
|
||||
var name = role.get('name');
|
||||
var limits = limitValidations[name];
|
||||
return limits && !limits.valid && limits.message;
|
||||
}),
|
||||
warning: roleModels.map((role) => {
|
||||
var name = role.get('name'),
|
||||
recommendation = limitRecommendations[name];
|
||||
var name = role.get('name');
|
||||
var recommendation = limitRecommendations[name];
|
||||
return recommendation && !recommendation.valid && recommendation.message;
|
||||
})
|
||||
};
|
||||
|
@ -417,19 +417,19 @@ var DeployReadinessBlock = React.createClass({
|
|||
// check cluster network configuration
|
||||
function(cluster) {
|
||||
if (this.props.nodeNetworkGroups.where({cluster_id: cluster.id}).length > 1) return null;
|
||||
var networkVerificationTask = cluster.task('verify_networks'),
|
||||
makeComponent = (text, isError) => {
|
||||
var span = (
|
||||
<span key='invalid_networks'>
|
||||
{text}
|
||||
{' ' + i18n(this.ns + 'get_more_info') + ' '}
|
||||
<a href={'#cluster/' + this.props.cluster.id + '/network'}>
|
||||
{i18n(this.ns + 'networks_link')}
|
||||
</a>.
|
||||
</span>
|
||||
);
|
||||
return isError ? {error: [span]} : {warning: [span]};
|
||||
};
|
||||
var networkVerificationTask = cluster.task('verify_networks');
|
||||
var makeComponent = (text, isError) => {
|
||||
var span = (
|
||||
<span key='invalid_networks'>
|
||||
{text}
|
||||
{' ' + i18n(this.ns + 'get_more_info') + ' '}
|
||||
<a href={'#cluster/' + this.props.cluster.id + '/network'}>
|
||||
{i18n(this.ns + 'networks_link')}
|
||||
</a>.
|
||||
</span>
|
||||
);
|
||||
return isError ? {error: [span]} : {warning: [span]};
|
||||
};
|
||||
if (_.isUndefined(networkVerificationTask)) {
|
||||
return makeComponent(i18n(this.ns + 'verification_not_performed'));
|
||||
} else if (networkVerificationTask.match({status: 'error'})) {
|
||||
|
@ -457,11 +457,11 @@ var DeployReadinessBlock = React.createClass({
|
|||
);
|
||||
},
|
||||
render() {
|
||||
var cluster = this.props.cluster,
|
||||
nodes = cluster.get('nodes'),
|
||||
alerts = this.validate(cluster),
|
||||
isDeploymentPossible = cluster.isDeploymentPossible() && !alerts.blocker.length,
|
||||
isVMsProvisioningAvailable = nodes.any((node) => node.get('pending_addition') && node.hasRole('virt'));
|
||||
var cluster = this.props.cluster;
|
||||
var nodes = cluster.get('nodes');
|
||||
var alerts = this.validate(cluster);
|
||||
var isDeploymentPossible = cluster.isDeploymentPossible() && !alerts.blocker.length;
|
||||
var isVMsProvisioningAvailable = nodes.any((node) => node.get('pending_addition') && node.hasRole('virt'));
|
||||
|
||||
return (
|
||||
<div className='row'>
|
||||
|
@ -543,16 +543,16 @@ var WarningsBlock = React.createClass({
|
|||
var ClusterInfo = React.createClass({
|
||||
mixins: [renamingMixin('clustername')],
|
||||
getClusterValue(fieldName) {
|
||||
var cluster = this.props.cluster,
|
||||
settings = cluster.get('settings');
|
||||
var cluster = this.props.cluster;
|
||||
var settings = cluster.get('settings');
|
||||
switch (fieldName) {
|
||||
case 'status':
|
||||
return i18n('cluster.status.' + cluster.get('status'));
|
||||
case 'openstack_release':
|
||||
return cluster.get('release').get('name');
|
||||
case 'compute':
|
||||
var libvirtSettings = settings.get('common').libvirt_type,
|
||||
computeLabel = _.find(libvirtSettings.values, {data: libvirtSettings.value}).label;
|
||||
var libvirtSettings = settings.get('common').libvirt_type;
|
||||
var computeLabel = _.find(libvirtSettings.values, {data: libvirtSettings.value}).label;
|
||||
if (settings.get('common').use_vcenter.value) {
|
||||
return computeLabel + ' ' + i18n(namespace + 'and_vcenter');
|
||||
}
|
||||
|
@ -596,10 +596,10 @@ var ClusterInfo = React.createClass({
|
|||
);
|
||||
},
|
||||
renderClusterCapacity() {
|
||||
var cores = 0,
|
||||
hdds = 0,
|
||||
ram = 0,
|
||||
ns = namespace + 'cluster_info_fields.';
|
||||
var cores = 0;
|
||||
var hdds = 0;
|
||||
var ram = 0;
|
||||
var ns = namespace + 'cluster_info_fields.';
|
||||
|
||||
this.props.cluster.get('nodes').each((node) => {
|
||||
cores += node.resource('ht_cores');
|
||||
|
@ -681,10 +681,10 @@ var ClusterInfo = React.createClass({
|
|||
return result;
|
||||
},
|
||||
renderStatistics() {
|
||||
var hasNodes = !!this.props.cluster.get('nodes').length,
|
||||
fieldRoles = _.union(['total'], this.props.cluster.get('roles').pluck('name')),
|
||||
fieldStatuses = ['offline', 'error', 'pending_addition', 'pending_deletion', 'ready', 'provisioned',
|
||||
'provisioning', 'deploying', 'removing'];
|
||||
var hasNodes = !!this.props.cluster.get('nodes').length;
|
||||
var fieldRoles = _.union(['total'], this.props.cluster.get('roles').pluck('name'));
|
||||
var fieldStatuses = ['offline', 'error', 'pending_addition', 'pending_deletion', 'ready', 'provisioned',
|
||||
'provisioning', 'deploying', 'removing'];
|
||||
return (
|
||||
<div className='row statistics-block'>
|
||||
<div className='title'>{i18n(namespace + 'cluster_info_fields.statistics')}</div>
|
||||
|
@ -791,8 +791,8 @@ var AddNodesButton = React.createClass({
|
|||
var RenameEnvironmentAction = React.createClass({
|
||||
applyAction(e) {
|
||||
e.preventDefault();
|
||||
var cluster = this.props.cluster,
|
||||
name = this.state.name;
|
||||
var cluster = this.props.cluster;
|
||||
var name = this.state.name;
|
||||
if (name != cluster.get('name')) {
|
||||
var deferred = cluster.save({name: name}, {patch: true, wait: true});
|
||||
if (deferred) {
|
||||
|
@ -942,10 +942,10 @@ var DeleteEnvironmentAction = React.createClass({
|
|||
|
||||
var InstructionElement = React.createClass({
|
||||
render() {
|
||||
var link = utils.composeDocumentationLink(this.props.link),
|
||||
classes = {
|
||||
instruction: true
|
||||
};
|
||||
var link = utils.composeDocumentationLink(this.props.link);
|
||||
var classes = {
|
||||
instruction: true
|
||||
};
|
||||
classes[this.props.wrapperClass] = !!this.props.wrapperClass;
|
||||
return (
|
||||
<div className={utils.classNames(classes)}>
|
||||
|
|
|
@ -34,8 +34,8 @@ var HealthCheckTab = React.createClass({
|
|||
statics: {
|
||||
fetchData(options) {
|
||||
if (!options.cluster.get('ostf')) {
|
||||
var ostf = {},
|
||||
clusterId = options.cluster.id;
|
||||
var ostf = {};
|
||||
var clusterId = options.cluster.id;
|
||||
ostf.testsets = new models.TestSets();
|
||||
ostf.testsets.url = _.result(ostf.testsets, 'url') + '/' + clusterId;
|
||||
ostf.tests = new models.Tests();
|
||||
|
@ -119,9 +119,9 @@ var HealthcheckTabContent = React.createClass({
|
|||
this.setState({credentials: credentials});
|
||||
},
|
||||
runTests() {
|
||||
var testruns = new models.TestRuns(),
|
||||
oldTestruns = new models.TestRuns(),
|
||||
testsetIds = this.props.testsets.pluck('id');
|
||||
var testruns = new models.TestRuns();
|
||||
var oldTestruns = new models.TestRuns();
|
||||
var testsetIds = this.props.testsets.pluck('id');
|
||||
this.setState({actionInProgress: true});
|
||||
_.each(testsetIds, (testsetId) => {
|
||||
var testsToRun = _.pluck(this.props.tests.where({
|
||||
|
@ -129,15 +129,15 @@ var HealthcheckTabContent = React.createClass({
|
|||
checked: true
|
||||
}), 'id');
|
||||
if (testsToRun.length) {
|
||||
var testrunConfig = {tests: testsToRun},
|
||||
addCredentials = (obj) => {
|
||||
obj.ostf_os_access_creds = {
|
||||
ostf_os_username: this.state.credentials.user,
|
||||
ostf_os_tenant_name: this.state.credentials.tenant,
|
||||
ostf_os_password: this.state.credentials.password
|
||||
};
|
||||
return obj;
|
||||
var testrunConfig = {tests: testsToRun};
|
||||
var addCredentials = (obj) => {
|
||||
obj.ostf_os_access_creds = {
|
||||
ostf_os_username: this.state.credentials.user,
|
||||
ostf_os_tenant_name: this.state.credentials.tenant,
|
||||
ostf_os_password: this.state.credentials.password
|
||||
};
|
||||
return obj;
|
||||
};
|
||||
|
||||
if (this.props.testruns.where({testset: testsetId}).length) {
|
||||
_.each(this.props.testruns.where({testset: testsetId}), (testrun) => {
|
||||
|
@ -198,8 +198,8 @@ var HealthcheckTabContent = React.createClass({
|
|||
}
|
||||
},
|
||||
render() {
|
||||
var disabledState = this.isLocked(),
|
||||
hasRunningTests = !!this.props.testruns.where({status: 'running'}).length;
|
||||
var disabledState = this.isLocked();
|
||||
var hasRunningTests = !!this.props.testruns.where({status: 'running'}).length;
|
||||
return (
|
||||
<div>
|
||||
{!disabledState &&
|
||||
|
@ -376,18 +376,18 @@ var Test = React.createClass({
|
|||
this.props.test.set('checked', value);
|
||||
},
|
||||
render() {
|
||||
var test = this.props.test,
|
||||
result = this.props.result,
|
||||
description = _.escape(_.trim(test.get('description'))),
|
||||
status = this.props.status,
|
||||
currentStatusClassName = 'text-center healthcheck-status healthcheck-status-' + status,
|
||||
iconClasses = {
|
||||
success: 'glyphicon glyphicon-ok text-success',
|
||||
failure: 'glyphicon glyphicon-remove text-danger',
|
||||
error: 'glyphicon glyphicon-remove text-danger',
|
||||
running: 'glyphicon glyphicon-refresh animate-spin',
|
||||
wait_running: 'glyphicon glyphicon-time'
|
||||
};
|
||||
var test = this.props.test;
|
||||
var result = this.props.result;
|
||||
var description = _.escape(_.trim(test.get('description')));
|
||||
var status = this.props.status;
|
||||
var currentStatusClassName = 'text-center healthcheck-status healthcheck-status-' + status;
|
||||
var iconClasses = {
|
||||
success: 'glyphicon glyphicon-ok text-success',
|
||||
failure: 'glyphicon glyphicon-remove text-danger',
|
||||
error: 'glyphicon glyphicon-remove text-danger',
|
||||
running: 'glyphicon glyphicon-refresh animate-spin',
|
||||
wait_running: 'glyphicon glyphicon-time'
|
||||
};
|
||||
|
||||
return (
|
||||
<tr>
|
||||
|
|
|
@ -32,10 +32,10 @@ var LogsTab = React.createClass({
|
|||
return this.state.to && this.state.logsEntries;
|
||||
},
|
||||
fetchData() {
|
||||
var request,
|
||||
logsEntries = this.state.logsEntries,
|
||||
from = this.state.from,
|
||||
to = this.state.to;
|
||||
var request;
|
||||
var logsEntries = this.state.logsEntries;
|
||||
var from = this.state.from;
|
||||
var to = this.state.to;
|
||||
request = this.fetchLogs({from: from, to: to})
|
||||
.done((data) => {
|
||||
this.setState({
|
||||
|
@ -142,17 +142,17 @@ var LogFilterBar = React.createClass({
|
|||
});
|
||||
},
|
||||
fetchSources(type, nodeId) {
|
||||
var nodes = this.props.nodes,
|
||||
chosenNodeId = nodeId || (nodes.length ? nodes.first().id : null);
|
||||
var nodes = this.props.nodes;
|
||||
var chosenNodeId = nodeId || (nodes.length ? nodes.first().id : null);
|
||||
this.sources = new models.LogSources();
|
||||
this.sources.deferred = (type == 'remote' && chosenNodeId) ?
|
||||
this.sources.fetch({url: '/api/logs/sources/nodes/' + chosenNodeId})
|
||||
:
|
||||
this.sources.fetch();
|
||||
this.sources.deferred.done(() => {
|
||||
var filteredSources = this.sources.filter((source) => source.get('remote') == (type != 'local')),
|
||||
chosenSource = _.findWhere(filteredSources, {id: this.state.source}) || _.first(filteredSources),
|
||||
chosenLevelId = chosenSource ? _.contains(chosenSource.get('levels'), this.state.level) ? this.state.level : _.first(chosenSource.get('levels')) : null;
|
||||
var filteredSources = this.sources.filter((source) => source.get('remote') == (type != 'local'));
|
||||
var chosenSource = _.findWhere(filteredSources, {id: this.state.source}) || _.first(filteredSources);
|
||||
var chosenLevelId = chosenSource ? _.contains(chosenSource.get('levels'), this.state.level) ? this.state.level : _.first(chosenSource.get('levels')) : null;
|
||||
this.setState({
|
||||
type: type,
|
||||
sources: this.sources,
|
||||
|
@ -194,8 +194,8 @@ var LogFilterBar = React.createClass({
|
|||
});
|
||||
},
|
||||
onSourceChange(name, value) {
|
||||
var levels = this.state.sources.get(value).get('levels'),
|
||||
data = {locked: false, source: value};
|
||||
var levels = this.state.sources.get(value).get('levels');
|
||||
var data = {locked: false, source: value};
|
||||
if (!_.contains(levels, this.state.level)) data.level = _.first(levels);
|
||||
this.setState(data);
|
||||
},
|
||||
|
@ -207,10 +207,10 @@ var LogFilterBar = React.createClass({
|
|||
}, this);
|
||||
},
|
||||
getRemoteSources() {
|
||||
var options = {},
|
||||
groups = [''],
|
||||
sourcesByGroup = {'': []},
|
||||
sources = this.state.sources;
|
||||
var options = {};
|
||||
var groups = [''];
|
||||
var sourcesByGroup = {'': []};
|
||||
var sources = this.state.sources;
|
||||
if (sources.length) {
|
||||
sources.each((source) => {
|
||||
var group = source.get('group') || '';
|
||||
|
@ -292,10 +292,10 @@ var LogFilterBar = React.createClass({
|
|||
</div>;
|
||||
},
|
||||
renderNodeSelect() {
|
||||
var sortedNodes = this.props.nodes.models.sort(_.partialRight(utils.compare, {attr: 'name'})),
|
||||
nodeOptions = sortedNodes.map((node) => {
|
||||
return <option value={node.id} key={node.id}>{node.get('name') || node.get('mac')}</option>;
|
||||
});
|
||||
var sortedNodes = this.props.nodes.models.sort(_.partialRight(utils.compare, {attr: 'name'}));
|
||||
var nodeOptions = sortedNodes.map((node) => {
|
||||
return <option value={node.id} key={node.id}>{node.get('name') || node.get('mac')}</option>;
|
||||
});
|
||||
|
||||
return <div className='col-md-2 col-sm-3'>
|
||||
<Input
|
||||
|
@ -365,8 +365,8 @@ var LogsTable = React.createClass({
|
|||
}[level];
|
||||
},
|
||||
render() {
|
||||
var tabRows = [],
|
||||
logsEntries = this.props.logsEntries;
|
||||
var tabRows = [];
|
||||
var logsEntries = this.props.logsEntries;
|
||||
if (logsEntries && logsEntries.length) {
|
||||
tabRows = _.map(logsEntries, (entry, index) => {
|
||||
var key = logsEntries.length - index;
|
||||
|
|
|
@ -28,9 +28,9 @@ import {Input, RadioGroup, Table} from 'views/controls';
|
|||
import SettingSection from 'views/cluster_page_tabs/setting_section';
|
||||
import CSSTransitionGroup from 'react-addons-transition-group';
|
||||
|
||||
var parametersNS = 'cluster_page.network_tab.networking_parameters.',
|
||||
networkTabNS = 'cluster_page.network_tab.',
|
||||
defaultNetworkSubtabs = ['neutron_l2', 'neutron_l3', 'network_settings', 'network_verification', 'nova_configuration'];
|
||||
var parametersNS = 'cluster_page.network_tab.networking_parameters.';
|
||||
var networkTabNS = 'cluster_page.network_tab.';
|
||||
var defaultNetworkSubtabs = ['neutron_l2', 'neutron_l3', 'network_settings', 'network_verification', 'nova_configuration'];
|
||||
|
||||
var NetworkModelManipulationMixin = {
|
||||
setValue(attribute, value, options) {
|
||||
|
@ -59,9 +59,9 @@ var NetworkModelManipulationMixin = {
|
|||
|
||||
var NetworkInputsMixin = {
|
||||
composeProps(attribute, isRange, isInteger) {
|
||||
var network = this.props.network,
|
||||
ns = network ? networkTabNS + 'network.' : parametersNS,
|
||||
error = this.getError(attribute) || null;
|
||||
var network = this.props.network;
|
||||
var ns = network ? networkTabNS + 'network.' : parametersNS;
|
||||
var error = this.getError(attribute) || null;
|
||||
|
||||
// in case of verification error we need to pass an empty string to highlight the field only
|
||||
// but not overwriting validation error
|
||||
|
@ -149,15 +149,15 @@ var Range = React.createClass({
|
|||
if (input.value) return;
|
||||
if (_.isUndefined(error)) input.value = rangeStart;
|
||||
if (input.setSelectionRange) {
|
||||
var startPos = _.lastIndexOf(rangeStart, '.') + 1,
|
||||
endPos = rangeStart.length;
|
||||
var startPos = _.lastIndexOf(rangeStart, '.') + 1;
|
||||
var endPos = rangeStart.length;
|
||||
input.setSelectionRange(startPos, endPos);
|
||||
}
|
||||
},
|
||||
onRangeChange(name, newValue, attribute, rowIndex) {
|
||||
var model = this.getModel(),
|
||||
valuesToSet = _.cloneDeep(model.get(attribute)),
|
||||
valuesToModify = this.props.extendable ? valuesToSet[rowIndex] : valuesToSet;
|
||||
var model = this.getModel();
|
||||
var valuesToSet = _.cloneDeep(model.get(attribute));
|
||||
var valuesToModify = this.props.extendable ? valuesToSet[rowIndex] : valuesToSet;
|
||||
|
||||
if (this.props.autoIncreaseWith) {
|
||||
valuesToSet = newValue;
|
||||
|
@ -188,8 +188,8 @@ var Range = React.createClass({
|
|||
});
|
||||
},
|
||||
getRangeProps(isRangeEnd) {
|
||||
var error = this.props.error || null,
|
||||
attributeName = this.props.name;
|
||||
var error = this.props.error || null;
|
||||
var attributeName = this.props.name;
|
||||
return {
|
||||
type: 'text',
|
||||
placeholder: error ? '' : this.props.placeholder,
|
||||
|
@ -222,19 +222,19 @@ var Range = React.createClass({
|
|||
);
|
||||
},
|
||||
render() {
|
||||
var error = this.props.error || null,
|
||||
attributeName = this.props.name,
|
||||
attribute = this.getModel().get(attributeName),
|
||||
ranges = this.props.autoIncreaseWith ?
|
||||
[attribute || 0, (attribute + this.props.autoIncreaseWith - 1 || 0)] :
|
||||
attribute,
|
||||
wrapperClasses = {
|
||||
'form-group range row': true,
|
||||
mini: this.props.mini,
|
||||
[this.props.wrapperClassName]: this.props.wrapperClassName
|
||||
},
|
||||
verificationError = this.props.verificationError || null,
|
||||
[startInputError, endInputError] = error || [];
|
||||
var error = this.props.error || null;
|
||||
var attributeName = this.props.name;
|
||||
var attribute = this.getModel().get(attributeName);
|
||||
var ranges = this.props.autoIncreaseWith ?
|
||||
[attribute || 0, (attribute + this.props.autoIncreaseWith - 1 || 0)] :
|
||||
attribute;
|
||||
var wrapperClasses = {
|
||||
'form-group range row': true,
|
||||
mini: this.props.mini,
|
||||
[this.props.wrapperClassName]: this.props.wrapperClassName
|
||||
};
|
||||
var verificationError = this.props.verificationError || null;
|
||||
var [startInputError, endInputError] = error || [];
|
||||
|
||||
wrapperClasses[this.props.wrapperClassName] = this.props.wrapperClassName;
|
||||
return (
|
||||
|
@ -406,8 +406,8 @@ var MultipleValuesInput = React.createClass({
|
|||
}
|
||||
},
|
||||
onChange(attribute, value, index) {
|
||||
var model = this.getModel(),
|
||||
valueToSet = _.cloneDeep(model.get(attribute));
|
||||
var model = this.getModel();
|
||||
var valueToSet = _.cloneDeep(model.get(attribute));
|
||||
valueToSet[index] = value;
|
||||
this.setValue(attribute, valueToSet);
|
||||
},
|
||||
|
@ -450,8 +450,8 @@ var MultipleValuesInput = React.createClass({
|
|||
);
|
||||
},
|
||||
render() {
|
||||
var attributeName = this.props.name,
|
||||
values = this.props.value;
|
||||
var attributeName = this.props.name;
|
||||
var values = this.props.value;
|
||||
return (
|
||||
<div className={'form-group row multiple-values ' + attributeName}>
|
||||
<div className='col-xs-12'>
|
||||
|
@ -607,9 +607,9 @@ var NetworkTab = React.createClass({
|
|||
},
|
||||
prepareIpRanges() {
|
||||
var removeEmptyRanges = (ranges) => {
|
||||
return _.filter(ranges, (range) => _.compact(range).length);
|
||||
},
|
||||
networkConfiguration = this.props.cluster.get('networkConfiguration');
|
||||
return _.filter(ranges, (range) => _.compact(range).length);
|
||||
};
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration');
|
||||
networkConfiguration.get('networks').each((network) => {
|
||||
if (network.get('meta').notation == 'ip_ranges') {
|
||||
network.set({ip_ranges: removeEmptyRanges(network.get('ip_ranges'))});
|
||||
|
@ -621,9 +621,9 @@ var NetworkTab = React.createClass({
|
|||
}
|
||||
},
|
||||
onManagerChange(name, value) {
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration'),
|
||||
networkingParameters = networkConfiguration.get('networking_parameters'),
|
||||
fixedAmount = networkConfiguration.get('networking_parameters').get('fixed_networks_amount') || 1;
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration');
|
||||
var networkingParameters = networkConfiguration.get('networking_parameters');
|
||||
var fixedAmount = networkConfiguration.get('networking_parameters').get('fixed_networks_amount') || 1;
|
||||
networkingParameters.set({
|
||||
net_manager: value,
|
||||
fixed_networks_amount: value == 'FlatDHCPManager' ? 1 : fixedAmount
|
||||
|
@ -637,14 +637,14 @@ var NetworkTab = React.createClass({
|
|||
dispatcher.trigger('networkConfigurationUpdated', this.startVerification);
|
||||
},
|
||||
startVerification() {
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration'),
|
||||
task = new models.Task(),
|
||||
options = {
|
||||
method: 'PUT',
|
||||
url: _.result(networkConfiguration, 'url') + '/verify',
|
||||
data: JSON.stringify(networkConfiguration)
|
||||
},
|
||||
ns = networkTabNS + 'verify_networks.verification_error.';
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration');
|
||||
var task = new models.Task();
|
||||
var options = {
|
||||
method: 'PUT',
|
||||
url: _.result(networkConfiguration, 'url') + '/verify',
|
||||
data: JSON.stringify(networkConfiguration)
|
||||
};
|
||||
var ns = networkTabNS + 'verify_networks.verification_error.';
|
||||
|
||||
task.save({}, options)
|
||||
.fail((response) => {
|
||||
|
@ -679,8 +679,8 @@ var NetworkTab = React.createClass({
|
|||
this.setState({actionInProgress: true});
|
||||
this.prepareIpRanges();
|
||||
|
||||
var requests = [],
|
||||
result = $.Deferred();
|
||||
var requests = [];
|
||||
var result = $.Deferred();
|
||||
|
||||
dispatcher.trigger('networkConfigurationUpdated', () => {
|
||||
return Backbone.sync('update', this.props.cluster.get('networkConfiguration'))
|
||||
|
@ -718,12 +718,12 @@ var NetworkTab = React.createClass({
|
|||
|
||||
if (this.isNetworkSettingsChanged()) {
|
||||
// collecting data to save
|
||||
var settings = this.props.cluster.get('settings'),
|
||||
dataToSave = this.props.cluster.isAvailableForSettingsChanges() ? settings.attributes :
|
||||
_.pick(settings.attributes, (group) => (group.metadata || {}).always_editable);
|
||||
var settings = this.props.cluster.get('settings');
|
||||
var dataToSave = this.props.cluster.isAvailableForSettingsChanges() ? settings.attributes :
|
||||
_.pick(settings.attributes, (group) => (group.metadata || {}).always_editable);
|
||||
|
||||
var options = {url: settings.url, patch: true, wait: true, validate: false},
|
||||
deferred = new models.Settings(_.cloneDeep(dataToSave)).save(null, options);
|
||||
var options = {url: settings.url, patch: true, wait: true, validate: false};
|
||||
var deferred = new models.Settings(_.cloneDeep(dataToSave)).save(null, options);
|
||||
if (deferred) {
|
||||
this.setState({actionInProgress: true});
|
||||
deferred
|
||||
|
@ -782,8 +782,8 @@ var NetworkTab = React.createClass({
|
|||
);
|
||||
},
|
||||
getVerificationErrors() {
|
||||
var task = this.state.hideVerificationResult ? null : this.props.cluster.task({group: 'network', status: 'error'}),
|
||||
fieldsWithVerificationErrors = [];
|
||||
var task = this.state.hideVerificationResult ? null : this.props.cluster.task({group: 'network', status: 'error'});
|
||||
var fieldsWithVerificationErrors = [];
|
||||
// @TODO(morale): soon response format will be changed and this part should be rewritten
|
||||
if (task && task.get('result').length) {
|
||||
_.each(task.get('result'), (verificationError) => {
|
||||
|
@ -842,53 +842,53 @@ var NetworkTab = React.createClass({
|
|||
});
|
||||
},
|
||||
render() {
|
||||
var isLocked = this.isLocked(),
|
||||
hasChanges = this.hasChanges(),
|
||||
{activeNetworkSectionName, cluster} = this.props,
|
||||
networkConfiguration = this.props.cluster.get('networkConfiguration'),
|
||||
networkingParameters = networkConfiguration.get('networking_parameters'),
|
||||
manager = networkingParameters.get('net_manager'),
|
||||
managers = [
|
||||
{
|
||||
label: i18n(networkTabNS + 'flatdhcp_manager'),
|
||||
data: 'FlatDHCPManager',
|
||||
checked: manager == 'FlatDHCPManager',
|
||||
disabled: isLocked
|
||||
},
|
||||
{
|
||||
label: i18n(networkTabNS + 'vlan_manager'),
|
||||
data: 'VlanManager',
|
||||
checked: manager == 'VlanManager',
|
||||
disabled: isLocked
|
||||
}
|
||||
],
|
||||
classes = {
|
||||
row: true,
|
||||
'changes-locked': isLocked
|
||||
var isLocked = this.isLocked();
|
||||
var hasChanges = this.hasChanges();
|
||||
var {activeNetworkSectionName, cluster} = this.props;
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration');
|
||||
var networkingParameters = networkConfiguration.get('networking_parameters');
|
||||
var manager = networkingParameters.get('net_manager');
|
||||
var managers = [
|
||||
{
|
||||
label: i18n(networkTabNS + 'flatdhcp_manager'),
|
||||
data: 'FlatDHCPManager',
|
||||
checked: manager == 'FlatDHCPManager',
|
||||
disabled: isLocked
|
||||
},
|
||||
nodeNetworkGroups = this.nodeNetworkGroups = new models.NodeNetworkGroups(this.props.nodeNetworkGroups.where({cluster_id: cluster.id})),
|
||||
isNovaEnvironment = cluster.get('net_provider') == 'nova_network',
|
||||
networks = networkConfiguration.get('networks'),
|
||||
isMultiRack = nodeNetworkGroups.length > 1,
|
||||
networkVerifyTask = cluster.task('verify_networks'),
|
||||
networkCheckTask = cluster.task('check_networks');
|
||||
{
|
||||
label: i18n(networkTabNS + 'vlan_manager'),
|
||||
data: 'VlanManager',
|
||||
checked: manager == 'VlanManager',
|
||||
disabled: isLocked
|
||||
}
|
||||
];
|
||||
var classes = {
|
||||
row: true,
|
||||
'changes-locked': isLocked
|
||||
};
|
||||
var nodeNetworkGroups = this.nodeNetworkGroups = new models.NodeNetworkGroups(this.props.nodeNetworkGroups.where({cluster_id: cluster.id}));
|
||||
var isNovaEnvironment = cluster.get('net_provider') == 'nova_network';
|
||||
var networks = networkConfiguration.get('networks');
|
||||
var isMultiRack = nodeNetworkGroups.length > 1;
|
||||
var networkVerifyTask = cluster.task('verify_networks');
|
||||
var networkCheckTask = cluster.task('check_networks');
|
||||
|
||||
var {validationError} = networkConfiguration,
|
||||
notEnoughOnlineNodesForVerification = cluster.get('nodes').where({online: true}).length < 2,
|
||||
isVerificationDisabled = validationError ||
|
||||
this.state.actionInProgress ||
|
||||
!!cluster.task({group: ['deployment', 'network'], active: true}) ||
|
||||
isMultiRack ||
|
||||
notEnoughOnlineNodesForVerification;
|
||||
var {validationError} = networkConfiguration;
|
||||
var notEnoughOnlineNodesForVerification = cluster.get('nodes').where({online: true}).length < 2;
|
||||
var isVerificationDisabled = validationError ||
|
||||
this.state.actionInProgress ||
|
||||
!!cluster.task({group: ['deployment', 'network'], active: true}) ||
|
||||
isMultiRack ||
|
||||
notEnoughOnlineNodesForVerification;
|
||||
|
||||
var currentNodeNetworkGroup = nodeNetworkGroups.findWhere({name: activeNetworkSectionName}),
|
||||
nodeNetworkGroupProps = {
|
||||
cluster: cluster,
|
||||
locked: isLocked,
|
||||
actionInProgress: this.state.actionInProgress,
|
||||
verificationErrors: this.getVerificationErrors(),
|
||||
validationError: validationError
|
||||
};
|
||||
var currentNodeNetworkGroup = nodeNetworkGroups.findWhere({name: activeNetworkSectionName});
|
||||
var nodeNetworkGroupProps = {
|
||||
cluster: cluster,
|
||||
locked: isLocked,
|
||||
actionInProgress: this.state.actionInProgress,
|
||||
verificationErrors: this.getVerificationErrors(),
|
||||
validationError: validationError
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={utils.classNames(classes)}>
|
||||
|
@ -1043,16 +1043,16 @@ var NodeNetworkGroup = React.createClass({
|
|||
|
||||
var NetworkSubtabs = React.createClass({
|
||||
renderClickablePills(sections, isNetworkGroupPill) {
|
||||
var {cluster, nodeNetworkGroups, validationError} = this.props,
|
||||
isNovaEnvironment = cluster.get('net_provider') == 'nova_network';
|
||||
var {cluster, nodeNetworkGroups, validationError} = this.props;
|
||||
var isNovaEnvironment = cluster.get('net_provider') == 'nova_network';
|
||||
|
||||
var networkParametersErrors = (validationError || {}).networking_parameters,
|
||||
networksErrors = (validationError || {}).networks;
|
||||
var networkParametersErrors = (validationError || {}).networking_parameters;
|
||||
var networksErrors = (validationError || {}).networks;
|
||||
|
||||
return (sections.map((groupName) => {
|
||||
var tabLabel = groupName,
|
||||
isActive = groupName == this.props.activeGroupName,
|
||||
isInvalid;
|
||||
var tabLabel = groupName;
|
||||
var isActive = groupName == this.props.activeGroupName;
|
||||
var isInvalid;
|
||||
|
||||
// is one of predefined sections selected (networking_parameters)
|
||||
if (groupName == 'neutron_l2') {
|
||||
|
@ -1103,9 +1103,9 @@ var NetworkSubtabs = React.createClass({
|
|||
}));
|
||||
},
|
||||
render() {
|
||||
var {nodeNetworkGroups} = this.props,
|
||||
settingsSections = [],
|
||||
nodeGroupSections = nodeNetworkGroups.pluck('name');
|
||||
var {nodeNetworkGroups} = this.props;
|
||||
var settingsSections = [];
|
||||
var nodeGroupSections = nodeNetworkGroups.pluck('name');
|
||||
|
||||
if (this.props.cluster.get('net_provider') == 'nova_network') {
|
||||
settingsSections.push('nova_configuration');
|
||||
|
@ -1151,9 +1151,9 @@ var NodeNetworkGroupTitle = React.createClass({
|
|||
this.setState({nodeNetworkGroupNameChangingError: null});
|
||||
if (e.key == 'Enter') {
|
||||
this.setState({actionInProgress: true});
|
||||
var element = this.refs['node-group-title-input'].getInputDOMNode(),
|
||||
newName = _.trim(element.value),
|
||||
currentNodeNetworkGroup = this.props.currentNodeNetworkGroup;
|
||||
var element = this.refs['node-group-title-input'].getInputDOMNode();
|
||||
var newName = _.trim(element.value);
|
||||
var currentNodeNetworkGroup = this.props.currentNodeNetworkGroup;
|
||||
|
||||
if (newName != currentNodeNetworkGroup.get('name')) {
|
||||
var validationError = currentNodeNetworkGroup.validate({name: newName});
|
||||
|
@ -1191,11 +1191,11 @@ var NodeNetworkGroupTitle = React.createClass({
|
|||
this.startRenaming(e);
|
||||
},
|
||||
render() {
|
||||
var {currentNodeNetworkGroup, isRenamingPossible, isDeletionPossible} = this.props,
|
||||
classes = {
|
||||
'network-group-name': true,
|
||||
'no-rename': !isRenamingPossible
|
||||
};
|
||||
var {currentNodeNetworkGroup, isRenamingPossible, isDeletionPossible} = this.props;
|
||||
var classes = {
|
||||
'network-group-name': true,
|
||||
'no-rename': !isRenamingPossible
|
||||
};
|
||||
return (
|
||||
<div className={utils.classNames(classes)} key={currentNodeNetworkGroup.id}>
|
||||
{this.state.isRenaming ?
|
||||
|
@ -1252,8 +1252,8 @@ var Network = React.createClass({
|
|||
|
||||
var networkName = this.props.network.get('name');
|
||||
|
||||
var ipRangeProps = this.composeProps('ip_ranges', true),
|
||||
gatewayProps = this.composeProps('gateway');
|
||||
var ipRangeProps = this.composeProps('ip_ranges', true);
|
||||
var gatewayProps = this.composeProps('gateway');
|
||||
return (
|
||||
<div className={'forms-box ' + networkName}>
|
||||
<h3 className='networks'>{i18n('network.' + networkName)}</h3>
|
||||
|
@ -1298,10 +1298,10 @@ var NovaParameters = React.createClass({
|
|||
]
|
||||
},
|
||||
render() {
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration'),
|
||||
networkingParameters = networkConfiguration.get('networking_parameters'),
|
||||
manager = networkingParameters.get('net_manager'),
|
||||
fixedNetworkSizeValues = _.map(_.range(3, 12), _.partial(Math.pow, 2));
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration');
|
||||
var networkingParameters = networkConfiguration.get('networking_parameters');
|
||||
var manager = networkingParameters.get('net_manager');
|
||||
var fixedNetworkSizeValues = _.map(_.range(3, 12), _.partial(Math.pow, 2));
|
||||
return (
|
||||
<div className='forms-box nova-config' key='nova-config'>
|
||||
<h3 className='networks'>{i18n(parametersNS + 'nova_configuration')}</h3>
|
||||
|
@ -1355,8 +1355,8 @@ var NetworkingL2Parameters = React.createClass({
|
|||
]
|
||||
},
|
||||
render() {
|
||||
var networkParameters = this.props.cluster.get('networkConfiguration').get('networking_parameters'),
|
||||
idRangePrefix = networkParameters.get('segmentation_type') == 'vlan' ? 'vlan' : 'gre_id';
|
||||
var networkParameters = this.props.cluster.get('networkConfiguration').get('networking_parameters');
|
||||
var idRangePrefix = networkParameters.get('segmentation_type') == 'vlan' ? 'vlan' : 'gre_id';
|
||||
return (
|
||||
<div className='forms-box' key='neutron-l2'>
|
||||
<h3 className='networks'>{i18n(parametersNS + 'l2_configuration')}</h3>
|
||||
|
@ -1442,8 +1442,8 @@ var NetworkingL3Parameters = React.createClass({
|
|||
|
||||
var NetworkSettings = React.createClass({
|
||||
onChange(groupName, settingName, value) {
|
||||
var settings = this.props.cluster.get('settings'),
|
||||
name = settings.makePath(groupName, settingName, settings.getValueAttribute(settingName));
|
||||
var settings = this.props.cluster.get('settings');
|
||||
var name = settings.makePath(groupName, settingName, settings.getValueAttribute(settingName));
|
||||
this.props.settingsForChecks.set(name, value);
|
||||
// FIXME: the following hacks cause we can't pass {validate: true} option to set method
|
||||
// this form of validation isn't supported in Backbone DeepModel
|
||||
|
@ -1455,11 +1455,11 @@ var NetworkSettings = React.createClass({
|
|||
return this.props.cluster.get('settings').checkRestrictions(this.props.configModels, action, setting);
|
||||
},
|
||||
render() {
|
||||
var cluster = this.props.cluster,
|
||||
settings = cluster.get('settings'),
|
||||
locked = this.props.locked || !!cluster.task({group: ['deployment', 'network'], active: true}),
|
||||
lockedCluster = !cluster.isAvailableForSettingsChanges(),
|
||||
allocatedRoles = _.uniq(_.flatten(_.union(cluster.get('nodes').pluck('roles'), cluster.get('nodes').pluck('pending_roles'))));
|
||||
var cluster = this.props.cluster;
|
||||
var settings = cluster.get('settings');
|
||||
var locked = this.props.locked || !!cluster.task({group: ['deployment', 'network'], active: true});
|
||||
var lockedCluster = !cluster.isAvailableForSettingsChanges();
|
||||
var allocatedRoles = _.uniq(_.flatten(_.union(cluster.get('nodes').pluck('roles'), cluster.get('nodes').pluck('pending_roles'))));
|
||||
return (
|
||||
<div className='forms-box network'>
|
||||
{
|
||||
|
@ -1477,15 +1477,15 @@ var NetworkSettings = React.createClass({
|
|||
)
|
||||
.map(
|
||||
(sectionName) => {
|
||||
var section = settings.get(sectionName),
|
||||
settingsToDisplay = _.compact(_.map(section, (setting, settingName) => {
|
||||
if (
|
||||
(section.metadata.group || setting.group == 'network') &&
|
||||
settingName != 'metadata' &&
|
||||
setting.type != 'hidden' &&
|
||||
!this.checkRestrictions('hide', setting).result
|
||||
) return settingName;
|
||||
}));
|
||||
var section = settings.get(sectionName);
|
||||
var settingsToDisplay = _.compact(_.map(section, (setting, settingName) => {
|
||||
if (
|
||||
(section.metadata.group || setting.group == 'network') &&
|
||||
settingName != 'metadata' &&
|
||||
setting.type != 'hidden' &&
|
||||
!this.checkRestrictions('hide', setting).result
|
||||
) return settingName;
|
||||
}));
|
||||
if (_.isEmpty(settingsToDisplay) && !settings.isPlugin(section)) return null;
|
||||
return <SettingSection
|
||||
{... _.pick(this.props, 'cluster', 'initialAttributes', 'settingsForChecks', 'configModels')}
|
||||
|
@ -1518,8 +1518,8 @@ var NetworkVerificationResult = React.createClass({
|
|||
return 'success';
|
||||
},
|
||||
render() {
|
||||
var task = this.props.task,
|
||||
ns = networkTabNS + 'verify_networks.';
|
||||
var task = this.props.task;
|
||||
var ns = networkTabNS + 'verify_networks.';
|
||||
|
||||
if (this.props.hideVerificationResult) task = null;
|
||||
return (
|
||||
|
|
|
@ -83,12 +83,12 @@ var NodesTab = React.createClass({
|
|||
componentWillReceiveProps(newProps) {
|
||||
var screen = this.getScreen(newProps);
|
||||
if (this.state.screen != screen && this.checkScreenExists(screen)) {
|
||||
var screenOptions = this.getScreenOptions(newProps),
|
||||
newState = {
|
||||
screen: screen,
|
||||
screenOptions: screenOptions,
|
||||
screenData: {}
|
||||
};
|
||||
var screenOptions = this.getScreenOptions(newProps);
|
||||
var newState = {
|
||||
screen: screen,
|
||||
screenOptions: screenOptions,
|
||||
screenData: {}
|
||||
};
|
||||
if (this.shouldScreenDataBeLoaded(screen)) {
|
||||
this.setState(_.extend(newState, {loading: true}));
|
||||
this.loadScreenData(screen, screenOptions);
|
||||
|
|
|
@ -111,8 +111,8 @@ var EditNodeDisksScreen = React.createClass({
|
|||
});
|
||||
},
|
||||
getDiskMetaData(disk) {
|
||||
var result,
|
||||
disksMetaData = this.props.nodes.at(0).get('meta').disks;
|
||||
var result;
|
||||
var disksMetaData = this.props.nodes.at(0).get('meta').disks;
|
||||
// try to find disk metadata by matching "extra" field
|
||||
// if at least one entry presents both in disk and metadata entry,
|
||||
// this metadata entry is for our disk
|
||||
|
@ -127,12 +127,12 @@ var EditNodeDisksScreen = React.createClass({
|
|||
return result;
|
||||
},
|
||||
getVolumesInfo(disk) {
|
||||
var volumes = {},
|
||||
unallocatedWidth = 100;
|
||||
var volumes = {};
|
||||
var unallocatedWidth = 100;
|
||||
disk.get('volumes').each((volume) => {
|
||||
var size = volume.get('size') || 0,
|
||||
width = this.getVolumeWidth(disk, size),
|
||||
name = volume.get('name');
|
||||
var size = volume.get('size') || 0;
|
||||
var width = this.getVolumeWidth(disk, size);
|
||||
var name = volume.get('name');
|
||||
unallocatedWidth -= width;
|
||||
volumes[name] = {
|
||||
size: size,
|
||||
|
@ -160,10 +160,10 @@ var EditNodeDisksScreen = React.createClass({
|
|||
return !this.state.actionInProgress && this.hasChanges() && !this.hasErrors();
|
||||
},
|
||||
render() {
|
||||
var hasChanges = this.hasChanges(),
|
||||
locked = this.isLocked(),
|
||||
loadDefaultsDisabled = !!this.state.actionInProgress,
|
||||
revertChangesDisabled = !!this.state.actionInProgress || !hasChanges;
|
||||
var hasChanges = this.hasChanges();
|
||||
var locked = this.isLocked();
|
||||
var loadDefaultsDisabled = !!this.state.actionInProgress;
|
||||
var revertChangesDisabled = !!this.state.actionInProgress || !hasChanges;
|
||||
return (
|
||||
<div className='edit-node-disks-screen'>
|
||||
<div className='row'>
|
||||
|
@ -220,8 +220,8 @@ var NodeDisk = React.createClass({
|
|||
.on('hide.bs.collapse', this.setState.bind(this, {collapsed: false}, null));
|
||||
},
|
||||
updateDisk(name, value) {
|
||||
var size = parseInt(value, 10) || 0,
|
||||
volumeInfo = this.props.volumesInfo[name];
|
||||
var size = parseInt(value, 10) || 0;
|
||||
var volumeInfo = this.props.volumesInfo[name];
|
||||
if (size > volumeInfo.max) {
|
||||
size = volumeInfo.max;
|
||||
}
|
||||
|
@ -232,15 +232,15 @@ var NodeDisk = React.createClass({
|
|||
$(ReactDOM.findDOMNode(this.refs[name])).collapse('toggle');
|
||||
},
|
||||
render() {
|
||||
var disk = this.props.disk,
|
||||
volumesInfo = this.props.volumesInfo,
|
||||
diskMetaData = this.props.diskMetaData,
|
||||
requiredDiskSize = _.sum(disk.get('volumes').map((volume) => {
|
||||
return volume.getMinimalSize(this.props.volumes.findWhere({name: volume.get('name')}).get('min_size'));
|
||||
})),
|
||||
diskError = disk.get('size') < requiredDiskSize,
|
||||
sortOrder = ['name', 'model', 'size'],
|
||||
ns = 'cluster_page.nodes_tab.configure_disks.';
|
||||
var disk = this.props.disk;
|
||||
var volumesInfo = this.props.volumesInfo;
|
||||
var diskMetaData = this.props.diskMetaData;
|
||||
var requiredDiskSize = _.sum(disk.get('volumes').map((volume) => {
|
||||
return volume.getMinimalSize(this.props.volumes.findWhere({name: volume.get('name')}).get('min_size'));
|
||||
}));
|
||||
var diskError = disk.get('size') < requiredDiskSize;
|
||||
var sortOrder = ['name', 'model', 'size'];
|
||||
var ns = 'cluster_page.nodes_tab.configure_disks.';
|
||||
|
||||
return (
|
||||
<div className='col-xs-12 disk-box' data-disk={disk.id} key={this.props.key}>
|
||||
|
@ -308,11 +308,11 @@ var NodeDisk = React.createClass({
|
|||
<h5>{i18n(ns + 'volume_groups')}</h5>
|
||||
<div className='form-horizontal disk-utility-box'>
|
||||
{this.props.volumes.map((volume, index) => {
|
||||
var volumeName = volume.get('name'),
|
||||
value = volumesInfo[volumeName].size,
|
||||
currentMaxSize = volumesInfo[volumeName].max,
|
||||
currentMinSize = _.max([volumesInfo[volumeName].min, 0]),
|
||||
validationError = volumesInfo[volumeName].error;
|
||||
var volumeName = volume.get('name');
|
||||
var value = volumesInfo[volumeName].size;
|
||||
var currentMaxSize = volumesInfo[volumeName].max;
|
||||
var currentMinSize = _.max([volumesInfo[volumeName].min, 0]);
|
||||
var validationError = volumesInfo[volumeName].error;
|
||||
|
||||
var props = {
|
||||
name: volumeName,
|
||||
|
|
|
@ -37,15 +37,15 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
],
|
||||
statics: {
|
||||
fetchData(options) {
|
||||
var cluster = options.cluster,
|
||||
nodes = utils.getNodeListFromTabOptions(options);
|
||||
var cluster = options.cluster;
|
||||
var nodes = utils.getNodeListFromTabOptions(options);
|
||||
|
||||
if (!nodes || !nodes.areInterfacesConfigurable()) {
|
||||
return $.Deferred().reject();
|
||||
}
|
||||
|
||||
var networkConfiguration = cluster.get('networkConfiguration'),
|
||||
networksMetadata = new models.ReleaseNetworkProperties();
|
||||
var networkConfiguration = cluster.get('networkConfiguration');
|
||||
var networksMetadata = new models.ReleaseNetworkProperties();
|
||||
|
||||
return $.when(...nodes.map((node) => {
|
||||
node.interfaces = new models.Interfaces();
|
||||
|
@ -143,13 +143,13 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
applyChanges() {
|
||||
if (!this.isSavingPossible()) return $.Deferred().reject();
|
||||
|
||||
var nodes = this.props.nodes,
|
||||
interfaces = this.props.interfaces,
|
||||
bonds = interfaces.filter((ifc) => ifc.isBond()),
|
||||
bondsByName = bonds.reduce((result, bond) => {
|
||||
result[bond.get('name')] = bond;
|
||||
return result;
|
||||
}, {});
|
||||
var nodes = this.props.nodes;
|
||||
var interfaces = this.props.interfaces;
|
||||
var bonds = interfaces.filter((ifc) => ifc.isBond());
|
||||
var bondsByName = bonds.reduce((result, bond) => {
|
||||
result[bond.get('name')] = bond;
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
// bonding map contains indexes of slave interfaces
|
||||
// it is needed to build the same configuration for all the nodes
|
||||
|
@ -170,8 +170,8 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
node.interfaces.add(nodeBonds);
|
||||
// determining slaves using bonding map
|
||||
_.each(nodeBonds, (bond, bondIndex) => {
|
||||
var slaveIndexes = bondingMap[bondIndex],
|
||||
slaveInterfaces = _.map(slaveIndexes, node.interfaces.at, node.interfaces);
|
||||
var slaveIndexes = bondingMap[bondIndex];
|
||||
var slaveInterfaces = _.map(slaveIndexes, node.interfaces.at, node.interfaces);
|
||||
bond.set({slaves: _.invoke(slaveInterfaces, 'pick', 'name')});
|
||||
});
|
||||
|
||||
|
@ -252,9 +252,9 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
},
|
||||
bondInterfaces() {
|
||||
this.setState({actionInProgress: true});
|
||||
var interfaces = this.props.interfaces.filter((ifc) => ifc.get('checked') && !ifc.isBond()),
|
||||
bonds = this.props.interfaces.find((ifc) => ifc.get('checked') && ifc.isBond()),
|
||||
bondingProperties = this.props.bondingConfig.properties;
|
||||
var interfaces = this.props.interfaces.filter((ifc) => ifc.get('checked') && !ifc.isBond());
|
||||
var bonds = this.props.interfaces.find((ifc) => ifc.get('checked') && ifc.isBond());
|
||||
var bondingProperties = this.props.bondingConfig.properties;
|
||||
|
||||
if (!bonds) {
|
||||
// if no bond selected - create new one
|
||||
|
@ -297,14 +297,14 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
this.setState({actionInProgress: false});
|
||||
},
|
||||
removeInterfaceFromBond(bondName, slaveInterfaceName) {
|
||||
var networks = this.props.cluster.get('networkConfiguration').get('networks'),
|
||||
bond = this.props.interfaces.find({name: bondName}),
|
||||
slaves = bond.get('slaves'),
|
||||
bondHasUnmovableNetwork = bond.get('assigned_networks').any((interfaceNetwork) => {
|
||||
return interfaceNetwork.getFullNetwork(networks).get('meta').unmovable;
|
||||
}),
|
||||
slaveInterfaceNames = _.pluck(slaves, 'name'),
|
||||
targetInterface = bond;
|
||||
var networks = this.props.cluster.get('networkConfiguration').get('networks');
|
||||
var bond = this.props.interfaces.find({name: bondName});
|
||||
var slaves = bond.get('slaves');
|
||||
var bondHasUnmovableNetwork = bond.get('assigned_networks').any((interfaceNetwork) => {
|
||||
return interfaceNetwork.getFullNetwork(networks).get('meta').unmovable;
|
||||
});
|
||||
var slaveInterfaceNames = _.pluck(slaves, 'name');
|
||||
var targetInterface = bond;
|
||||
|
||||
// if PXE interface is being removed - place networks there
|
||||
if (bondHasUnmovableNetwork) {
|
||||
|
@ -318,9 +318,9 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
|
||||
// if slaveInterfaceName is set - remove it from slaves, otherwise remove all
|
||||
if (slaveInterfaceName) {
|
||||
var slavesUpdated = _.reject(slaves, {name: slaveInterfaceName}),
|
||||
names = _.pluck(slavesUpdated, 'name'),
|
||||
bondSlaveInterfaces = this.props.interfaces.filter((ifc) => _.contains(names, ifc.get('name')));
|
||||
var slavesUpdated = _.reject(slaves, {name: slaveInterfaceName});
|
||||
var names = _.pluck(slavesUpdated, 'name');
|
||||
var bondSlaveInterfaces = this.props.interfaces.filter((ifc) => _.contains(names, ifc.get('name')));
|
||||
|
||||
bond.set({
|
||||
slaves: slavesUpdated,
|
||||
|
@ -349,11 +349,11 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
}
|
||||
},
|
||||
validate() {
|
||||
var interfaceErrors = {},
|
||||
validationResult,
|
||||
networkConfiguration = this.props.cluster.get('networkConfiguration'),
|
||||
networkingParameters = networkConfiguration.get('networking_parameters'),
|
||||
networks = networkConfiguration.get('networks');
|
||||
var interfaceErrors = {};
|
||||
var validationResult;
|
||||
var networkConfiguration = this.props.cluster.get('networkConfiguration');
|
||||
var networkingParameters = networkConfiguration.get('networking_parameters');
|
||||
var networks = networkConfiguration.get('networks');
|
||||
if (!this.props.interfaces) {
|
||||
return;
|
||||
}
|
||||
|
@ -380,16 +380,16 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
return !_.chain(this.state.interfaceErrors).values().some().value() && !this.state.actionInProgress && this.hasChanges();
|
||||
},
|
||||
getIfcProperty(property) {
|
||||
var {interfaces, nodes} = this.props,
|
||||
bondsCount = interfaces.filter((ifc) => ifc.isBond()).length,
|
||||
getPropertyValues = (ifcIndex) => {
|
||||
return _.uniq(nodes.map((node) => {
|
||||
var nodeBondsCount = node.interfaces.filter((ifc) => ifc.isBond()).length,
|
||||
nodeInterface = node.interfaces.at(ifcIndex + nodeBondsCount);
|
||||
if (property == 'current_speed') return utils.showBandwidth(nodeInterface.get(property));
|
||||
return nodeInterface.get(property);
|
||||
}));
|
||||
};
|
||||
var {interfaces, nodes} = this.props;
|
||||
var bondsCount = interfaces.filter((ifc) => ifc.isBond()).length;
|
||||
var getPropertyValues = (ifcIndex) => {
|
||||
return _.uniq(nodes.map((node) => {
|
||||
var nodeBondsCount = node.interfaces.filter((ifc) => ifc.isBond()).length;
|
||||
var nodeInterface = node.interfaces.at(ifcIndex + nodeBondsCount);
|
||||
if (property == 'current_speed') return utils.showBandwidth(nodeInterface.get(property));
|
||||
return nodeInterface.get(property);
|
||||
}));
|
||||
};
|
||||
return interfaces.map((ifc, index) => {
|
||||
if (ifc.isBond()) {
|
||||
return _.map(ifc.get('slaves'),
|
||||
|
@ -400,28 +400,28 @@ var EditNodeInterfacesScreen = React.createClass({
|
|||
});
|
||||
},
|
||||
render() {
|
||||
var nodes = this.props.nodes,
|
||||
nodeNames = nodes.pluck('name'),
|
||||
interfaces = this.props.interfaces,
|
||||
locked = this.isLocked(),
|
||||
bondingAvailable = this.bondingAvailable(),
|
||||
configurationTemplateExists = this.configurationTemplateExists(),
|
||||
checkedInterfaces = interfaces.filter((ifc) => ifc.get('checked') && !ifc.isBond()),
|
||||
checkedBonds = interfaces.filter((ifc) => ifc.get('checked') && ifc.isBond()),
|
||||
creatingNewBond = checkedInterfaces.length >= 2 && !checkedBonds.length,
|
||||
addingInterfacesToExistingBond = !!checkedInterfaces.length && checkedBonds.length == 1,
|
||||
bondingPossible = creatingNewBond || addingInterfacesToExistingBond,
|
||||
unbondingPossible = !checkedInterfaces.length && !!checkedBonds.length,
|
||||
hasChanges = this.hasChanges(),
|
||||
slaveInterfaceNames = _.pluck(_.flatten(_.filter(interfaces.pluck('slaves'))), 'name'),
|
||||
loadDefaultsEnabled = !this.state.actionInProgress,
|
||||
revertChangesEnabled = !this.state.actionInProgress && hasChanges,
|
||||
invalidSpeedsForBonding = bondingPossible && this.validateSpeedsForBonding(checkedBonds.concat(checkedInterfaces)) || interfaces.any((ifc) => {
|
||||
return ifc.isBond() && this.validateSpeedsForBonding([ifc]);
|
||||
});
|
||||
var nodes = this.props.nodes;
|
||||
var nodeNames = nodes.pluck('name');
|
||||
var interfaces = this.props.interfaces;
|
||||
var locked = this.isLocked();
|
||||
var bondingAvailable = this.bondingAvailable();
|
||||
var configurationTemplateExists = this.configurationTemplateExists();
|
||||
var checkedInterfaces = interfaces.filter((ifc) => ifc.get('checked') && !ifc.isBond());
|
||||
var checkedBonds = interfaces.filter((ifc) => ifc.get('checked') && ifc.isBond());
|
||||
var creatingNewBond = checkedInterfaces.length >= 2 && !checkedBonds.length;
|
||||
var addingInterfacesToExistingBond = !!checkedInterfaces.length && checkedBonds.length == 1;
|
||||
var bondingPossible = creatingNewBond || addingInterfacesToExistingBond;
|
||||
var unbondingPossible = !checkedInterfaces.length && !!checkedBonds.length;
|
||||
var hasChanges = this.hasChanges();
|
||||
var slaveInterfaceNames = _.pluck(_.flatten(_.filter(interfaces.pluck('slaves'))), 'name');
|
||||
var loadDefaultsEnabled = !this.state.actionInProgress;
|
||||
var revertChangesEnabled = !this.state.actionInProgress && hasChanges;
|
||||
var invalidSpeedsForBonding = bondingPossible && this.validateSpeedsForBonding(checkedBonds.concat(checkedInterfaces)) || interfaces.any((ifc) => {
|
||||
return ifc.isBond() && this.validateSpeedsForBonding([ifc]);
|
||||
});
|
||||
|
||||
var interfaceSpeeds = this.getIfcProperty('current_speed'),
|
||||
interfaceNames = this.getIfcProperty('name');
|
||||
var interfaceSpeeds = this.getIfcProperty('current_speed');
|
||||
var interfaceNames = this.getIfcProperty('name');
|
||||
return (
|
||||
<div className='row'>
|
||||
<div className='title'>
|
||||
|
@ -605,8 +605,8 @@ var NodeInterface = React.createClass({
|
|||
});
|
||||
},
|
||||
toggleOffloading() {
|
||||
var interfaceProperties = this.props.interface.get('interface_properties'),
|
||||
name = 'disable_offloading';
|
||||
var interfaceProperties = this.props.interface.get('interface_properties');
|
||||
var name = 'disable_offloading';
|
||||
this.onInterfacePropertiesChange(name, !interfaceProperties[name]);
|
||||
},
|
||||
onInterfacePropertiesChange(name, value) {
|
||||
|
@ -622,27 +622,27 @@ var NodeInterface = React.createClass({
|
|||
this.props.interface.set('interface_properties', interfaceProperties);
|
||||
},
|
||||
render() {
|
||||
var ifc = this.props.interface,
|
||||
cluster = this.props.cluster,
|
||||
locked = this.props.locked,
|
||||
availableBondingModes = ifc.isBond() ? this.getAvailableBondingModes() : [],
|
||||
networkConfiguration = cluster.get('networkConfiguration'),
|
||||
networks = networkConfiguration.get('networks'),
|
||||
networkingParameters = networkConfiguration.get('networking_parameters'),
|
||||
slaveInterfaces = ifc.getSlaveInterfaces(),
|
||||
assignedNetworks = ifc.get('assigned_networks'),
|
||||
connectionStatusClasses = (slave) => {
|
||||
var slaveDown = slave.get('state') == 'down';
|
||||
return {
|
||||
'ifc-connection-status': true,
|
||||
'ifc-online': !slaveDown,
|
||||
'ifc-offline': slaveDown
|
||||
};
|
||||
},
|
||||
bondProperties = ifc.get('bond_properties'),
|
||||
interfaceProperties = ifc.get('interface_properties') || null,
|
||||
offloadingModes = ifc.get('offloading_modes') || [],
|
||||
bondingPossible = this.props.bondingAvailable && !locked;
|
||||
var ifc = this.props.interface;
|
||||
var cluster = this.props.cluster;
|
||||
var locked = this.props.locked;
|
||||
var availableBondingModes = ifc.isBond() ? this.getAvailableBondingModes() : [];
|
||||
var networkConfiguration = cluster.get('networkConfiguration');
|
||||
var networks = networkConfiguration.get('networks');
|
||||
var networkingParameters = networkConfiguration.get('networking_parameters');
|
||||
var slaveInterfaces = ifc.getSlaveInterfaces();
|
||||
var assignedNetworks = ifc.get('assigned_networks');
|
||||
var connectionStatusClasses = (slave) => {
|
||||
var slaveDown = slave.get('state') == 'down';
|
||||
return {
|
||||
'ifc-connection-status': true,
|
||||
'ifc-online': !slaveDown,
|
||||
'ifc-offline': slaveDown
|
||||
};
|
||||
};
|
||||
var bondProperties = ifc.get('bond_properties');
|
||||
var interfaceProperties = ifc.get('interface_properties') || null;
|
||||
var offloadingModes = ifc.get('offloading_modes') || [];
|
||||
var bondingPossible = this.props.bondingAvailable && !locked;
|
||||
|
||||
return this.props.connectDropTarget(
|
||||
<div className='ifc-container'>
|
||||
|
@ -823,15 +823,15 @@ var Network = React.createClass({
|
|||
}
|
||||
},
|
||||
render() {
|
||||
var network = this.props.network,
|
||||
interfaceNetwork = this.props.interfaceNetwork,
|
||||
networkingParameters = this.props.networkingParameters,
|
||||
classes = {
|
||||
'network-block pull-left': true,
|
||||
disabled: !this.constructor.source.canDrag(this.props),
|
||||
dragging: this.props.isDragging
|
||||
},
|
||||
vlanRange = network.getVlanRange(networkingParameters);
|
||||
var network = this.props.network;
|
||||
var interfaceNetwork = this.props.interfaceNetwork;
|
||||
var networkingParameters = this.props.networkingParameters;
|
||||
var classes = {
|
||||
'network-block pull-left': true,
|
||||
disabled: !this.constructor.source.canDrag(this.props),
|
||||
dragging: this.props.isDragging
|
||||
};
|
||||
var vlanRange = network.getVlanRange(networkingParameters);
|
||||
|
||||
return this.props.connectDragSource(
|
||||
<div className={utils.classNames(classes)}>
|
||||
|
|
|
@ -22,8 +22,8 @@ import NodeListScreen from 'views/cluster_page_tabs/nodes_tab_screens/node_list_
|
|||
var EditNodesScreen = React.createClass({
|
||||
statics: {
|
||||
fetchData(options) {
|
||||
var cluster = options.cluster,
|
||||
nodes = utils.getNodeListFromTabOptions(options);
|
||||
var cluster = options.cluster;
|
||||
var nodes = utils.getNodeListFromTabOptions(options);
|
||||
|
||||
if (!nodes) {
|
||||
return $.Deferred().reject();
|
||||
|
|
|
@ -39,9 +39,9 @@ var Node = React.createClass({
|
|||
}
|
||||
},
|
||||
getNodeLogsLink() {
|
||||
var status = this.props.node.get('status'),
|
||||
error = this.props.node.get('error_type'),
|
||||
options = {type: 'remote', node: this.props.node.id};
|
||||
var status = this.props.node.get('status');
|
||||
var error = this.props.node.get('error_type');
|
||||
var options = {type: 'remote', node: this.props.node.id};
|
||||
if (status == 'discover') {
|
||||
options.source = 'bootstrap/messages';
|
||||
} else if (status == 'provisioning' || status == 'provisioned' || (status == 'error' && error == 'provision')) {
|
||||
|
@ -70,8 +70,8 @@ var Node = React.createClass({
|
|||
e.preventDefault();
|
||||
if (this.state.actionInProgress) return;
|
||||
this.setState({actionInProgress: true});
|
||||
var node = new models.Node(this.props.node.attributes),
|
||||
data = {pending_deletion: false};
|
||||
var node = new models.Node(this.props.node.attributes);
|
||||
var data = {pending_deletion: false};
|
||||
node.save(data, {patch: true})
|
||||
.done(() => {
|
||||
this.props.cluster.fetchRelated('nodes').done(() => {
|
||||
|
@ -179,9 +179,9 @@ var Node = React.createClass({
|
|||
);
|
||||
},
|
||||
renderNodeHardwareSummary() {
|
||||
var htCores = this.props.node.resource('ht_cores'),
|
||||
hdd = this.props.node.resource('hdd'),
|
||||
ram = this.props.node.resource('ram');
|
||||
var htCores = this.props.node.resource('ht_cores');
|
||||
var hdd = this.props.node.resource('hdd');
|
||||
var ram = this.props.node.resource('ram');
|
||||
return (
|
||||
<div className='node-hardware'>
|
||||
<span>{i18n('node_details.cpu')}: {this.props.node.resource('cores') || '0'} ({_.isUndefined(htCores) ? '?' : htCores})</span>
|
||||
|
@ -266,11 +266,11 @@ var Node = React.createClass({
|
|||
});
|
||||
},
|
||||
render() {
|
||||
var ns = 'cluster_page.nodes_tab.node.',
|
||||
node = this.props.node,
|
||||
isSelectable = node.isSelectable() && !this.props.locked && this.props.mode != 'edit',
|
||||
status = node.getStatusSummary(),
|
||||
roles = this.props.cluster ? node.sortedRoles(this.props.cluster.get('roles').pluck('name')) : [];
|
||||
var ns = 'cluster_page.nodes_tab.node.';
|
||||
var node = this.props.node;
|
||||
var isSelectable = node.isSelectable() && !this.props.locked && this.props.mode != 'edit';
|
||||
var status = node.getStatusSummary();
|
||||
var roles = this.props.cluster ? node.sortedRoles(this.props.cluster.get('roles').pluck('name')) : [];
|
||||
|
||||
// compose classes
|
||||
var nodePanelClasses = {
|
||||
|
@ -281,24 +281,24 @@ var Node = React.createClass({
|
|||
};
|
||||
nodePanelClasses[status] = status;
|
||||
|
||||
var manufacturer = node.get('manufacturer') || '',
|
||||
logoClasses = {
|
||||
'manufacturer-logo': true
|
||||
};
|
||||
var manufacturer = node.get('manufacturer') || '';
|
||||
var logoClasses = {
|
||||
'manufacturer-logo': true
|
||||
};
|
||||
logoClasses[manufacturer.toLowerCase()] = manufacturer;
|
||||
|
||||
var statusClasses = {
|
||||
'node-status': true
|
||||
},
|
||||
statusClass = {
|
||||
pending_addition: 'text-success',
|
||||
pending_deletion: 'text-warning',
|
||||
error: 'text-danger',
|
||||
ready: 'text-info',
|
||||
provisioning: 'text-info',
|
||||
deploying: 'text-success',
|
||||
provisioned: 'text-info'
|
||||
}[status];
|
||||
'node-status': true
|
||||
};
|
||||
var statusClass = {
|
||||
pending_addition: 'text-success',
|
||||
pending_deletion: 'text-warning',
|
||||
error: 'text-danger',
|
||||
ready: 'text-info',
|
||||
provisioning: 'text-info',
|
||||
deploying: 'text-success',
|
||||
provisioned: 'text-info'
|
||||
}[status];
|
||||
statusClasses[statusClass] = true;
|
||||
|
||||
if (this.props.viewMode == 'compact') return (
|
||||
|
|
|
@ -103,16 +103,15 @@ NodeListScreen = React.createClass({
|
|||
};
|
||||
},
|
||||
getInitialState() {
|
||||
var cluster = this.props.cluster,
|
||||
nodes = this.props.nodes,
|
||||
uiSettings = (cluster || this.props.fuelSettings).get('ui_settings');
|
||||
var {cluster, nodes} = this.props;
|
||||
var uiSettings = (cluster || this.props.fuelSettings).get('ui_settings');
|
||||
|
||||
var availableFilters = this.props.filters.map((name) => {
|
||||
var filter = new Filter(name, [], false);
|
||||
filter.updateLimits(nodes, true);
|
||||
return filter;
|
||||
}),
|
||||
activeFilters = cluster && this.props.mode == 'add' ?
|
||||
var filter = new Filter(name, [], false);
|
||||
filter.updateLimits(nodes, true);
|
||||
return filter;
|
||||
});
|
||||
var activeFilters = cluster && this.props.mode == 'add' ?
|
||||
Filter.fromObject(this.props.defaultFilters, false)
|
||||
:
|
||||
_.union(
|
||||
|
@ -121,18 +120,18 @@ NodeListScreen = React.createClass({
|
|||
);
|
||||
_.invoke(activeFilters, 'updateLimits', nodes, false);
|
||||
|
||||
var availableSorters = this.props.sorters.map((name) => new Sorter(name, 'asc', false)),
|
||||
activeSorters = cluster && this.props.mode == 'add' ?
|
||||
_.map(this.props.defaultSorting, _.partial(Sorter.fromObject, _, false))
|
||||
:
|
||||
_.union(
|
||||
_.map(uiSettings.sort, _.partial(Sorter.fromObject, _, false)),
|
||||
_.map(uiSettings.sort_by_labels, _.partial(Sorter.fromObject, _, true))
|
||||
);
|
||||
var availableSorters = this.props.sorters.map((name) => new Sorter(name, 'asc', false));
|
||||
var activeSorters = cluster && this.props.mode == 'add' ?
|
||||
_.map(this.props.defaultSorting, _.partial(Sorter.fromObject, _, false))
|
||||
:
|
||||
_.union(
|
||||
_.map(uiSettings.sort, _.partial(Sorter.fromObject, _, false)),
|
||||
_.map(uiSettings.sort_by_labels, _.partial(Sorter.fromObject, _, true))
|
||||
);
|
||||
|
||||
var search = cluster && this.props.mode == 'add' ? '' : uiSettings.search,
|
||||
viewMode = uiSettings.view_mode,
|
||||
isLabelsPanelOpen = false;
|
||||
var search = cluster && this.props.mode == 'add' ? '' : uiSettings.search;
|
||||
var viewMode = uiSettings.view_mode;
|
||||
var isLabelsPanelOpen = false;
|
||||
|
||||
var states = {search, activeSorters, activeFilters, availableSorters, availableFilters, viewMode, isLabelsPanelOpen};
|
||||
|
||||
|
@ -140,9 +139,9 @@ NodeListScreen = React.createClass({
|
|||
if (!cluster) return states;
|
||||
|
||||
// additonal Nodes tab states (Cluster page)
|
||||
var roles = cluster.get('roles').pluck('name'),
|
||||
selectedRoles = nodes.length ? _.filter(roles, (role) => !nodes.any((node) => !node.hasRole(role))) : [],
|
||||
indeterminateRoles = nodes.length ? _.filter(roles, (role) => !_.contains(selectedRoles, role) && nodes.any((node) => node.hasRole(role))) : [];
|
||||
var roles = cluster.get('roles').pluck('name');
|
||||
var selectedRoles = nodes.length ? _.filter(roles, (role) => !nodes.any((node) => !node.hasRole(role))) : [];
|
||||
var indeterminateRoles = nodes.length ? _.filter(roles, (role) => !_.contains(selectedRoles, role) && nodes.any((node) => node.hasRole(role))) : [];
|
||||
|
||||
var configModels = {
|
||||
cluster: cluster,
|
||||
|
@ -214,18 +213,18 @@ NodeListScreen = React.createClass({
|
|||
this.props.nodes.off('change:pending_roles', this.checkRoleAssignment, this);
|
||||
},
|
||||
processRoleLimits() {
|
||||
var cluster = this.props.cluster,
|
||||
maxNumberOfNodes = [],
|
||||
processedRoleLimits = {};
|
||||
var cluster = this.props.cluster;
|
||||
var maxNumberOfNodes = [];
|
||||
var processedRoleLimits = {};
|
||||
|
||||
var selectedNodes = this.props.nodes.filter((node) => this.props.selectedNodeIds[node.id]),
|
||||
clusterNodes = this.props.cluster.get('nodes').filter((node) => !_.contains(this.props.selectedNodeIds, node.id)),
|
||||
nodesForLimitCheck = new models.Nodes(_.union(selectedNodes, clusterNodes));
|
||||
var selectedNodes = this.props.nodes.filter((node) => this.props.selectedNodeIds[node.id]);
|
||||
var clusterNodes = this.props.cluster.get('nodes').filter((node) => !_.contains(this.props.selectedNodeIds, node.id));
|
||||
var nodesForLimitCheck = new models.Nodes(_.union(selectedNodes, clusterNodes));
|
||||
|
||||
cluster.get('roles').each((role) => {
|
||||
if ((role.get('limits') || {}).max) {
|
||||
var roleName = role.get('name'),
|
||||
isRoleAlreadyAssigned = nodesForLimitCheck.any((node) => node.hasRole(roleName));
|
||||
var roleName = role.get('name');
|
||||
var isRoleAlreadyAssigned = nodesForLimitCheck.any((node) => node.hasRole(roleName));
|
||||
processedRoleLimits[roleName] = role.checkLimits(this.state.configModels, nodesForLimitCheck, !isRoleAlreadyAssigned, ['max']);
|
||||
}
|
||||
});
|
||||
|
@ -305,8 +304,8 @@ NodeListScreen = React.createClass({
|
|||
},
|
||||
getFilterOptions(filter) {
|
||||
if (filter.isLabel) {
|
||||
var values = _.uniq(this.props.nodes.getLabelValues(filter.name)),
|
||||
ns = 'cluster_page.nodes_tab.node_management_panel.';
|
||||
var values = _.uniq(this.props.nodes.getLabelValues(filter.name));
|
||||
var ns = 'cluster_page.nodes_tab.node_management_panel.';
|
||||
return values.map((value) => {
|
||||
return {
|
||||
name: value,
|
||||
|
@ -395,8 +394,8 @@ NodeListScreen = React.createClass({
|
|||
}
|
||||
},
|
||||
changeUISettings(newSettings) {
|
||||
var uiSettings = (this.props.cluster || this.props.fuelSettings).get('ui_settings'),
|
||||
options = {patch: true, wait: true, validate: false};
|
||||
var uiSettings = (this.props.cluster || this.props.fuelSettings).get('ui_settings');
|
||||
var options = {patch: true, wait: true, validate: false};
|
||||
_.extend(uiSettings, newSettings);
|
||||
if (this.props.cluster) {
|
||||
this.props.cluster.save({ui_settings: uiSettings}, options);
|
||||
|
@ -418,14 +417,14 @@ NodeListScreen = React.createClass({
|
|||
return _.chain(this.props.nodes.pluck('labels')).flatten().map(_.keys).flatten().uniq().value();
|
||||
},
|
||||
render() {
|
||||
var cluster = this.props.cluster,
|
||||
locked = !!cluster && !!cluster.task({group: 'deployment', active: true}),
|
||||
nodes = this.props.nodes,
|
||||
processedRoleData = cluster ? this.processRoleLimits() : {};
|
||||
var cluster = this.props.cluster;
|
||||
var locked = !!cluster && !!cluster.task({group: 'deployment', active: true});
|
||||
var nodes = this.props.nodes;
|
||||
var processedRoleData = cluster ? this.processRoleLimits() : {};
|
||||
|
||||
// labels to manage in labels panel
|
||||
var selectedNodes = new models.Nodes(this.props.nodes.filter((node) => this.props.selectedNodeIds[node.id])),
|
||||
selectedNodeLabels = _.chain(selectedNodes.pluck('labels')).flatten().map(_.keys).flatten().uniq().value();
|
||||
var selectedNodes = new models.Nodes(this.props.nodes.filter((node) => this.props.selectedNodeIds[node.id]));
|
||||
var selectedNodeLabels = _.chain(selectedNodes.pluck('labels')).flatten().map(_.keys).flatten().uniq().value();
|
||||
|
||||
// filter nodes
|
||||
var filteredNodes = nodes.filter((node) => {
|
||||
|
@ -906,7 +905,8 @@ ManagementPanel = React.createClass({
|
|||
render() {
|
||||
var ns = 'cluster_page.nodes_tab.node_management_panel.';
|
||||
|
||||
var disksConflict, interfaceConflict;
|
||||
var disksConflict, interfaceConflict, inactiveSorters, canResetSorters,
|
||||
inactiveFilters, appliedFilters;
|
||||
if (this.props.mode == 'list' && this.props.nodes.length) {
|
||||
disksConflict = !this.props.nodes.areDisksConfigurable();
|
||||
interfaceConflict = !this.props.nodes.areInterfacesConfigurable();
|
||||
|
@ -921,8 +921,6 @@ ManagementPanel = React.createClass({
|
|||
return classes;
|
||||
};
|
||||
|
||||
var inactiveSorters, canResetSorters;
|
||||
var inactiveFilters, appliedFilters;
|
||||
if (this.props.mode != 'edit') {
|
||||
var checkSorter = (sorter, isLabel) => !_.any(this.props.activeSorters, {name: sorter.name, isLabel: isLabel});
|
||||
inactiveSorters = _.union(_.filter(this.props.availableSorters, _.partial(checkSorter, _, false)), _.filter(this.props.labelSorters, _.partial(checkSorter, _, true)))
|
||||
|
@ -1277,8 +1275,8 @@ NodeLabelsPanel = React.createClass({
|
|||
mixins: [unsavedChangesMixin],
|
||||
getInitialState() {
|
||||
var labels = _.map(this.props.labels, (label) => {
|
||||
var labelValues = this.props.nodes.getLabelValues(label),
|
||||
definedLabelValues = _.reject(labelValues, _.isUndefined);
|
||||
var labelValues = this.props.nodes.getLabelValues(label);
|
||||
var definedLabelValues = _.reject(labelValues, _.isUndefined);
|
||||
return {
|
||||
key: label,
|
||||
values: _.uniq(definedLabelValues),
|
||||
|
@ -1312,24 +1310,24 @@ NodeLabelsPanel = React.createClass({
|
|||
this.setState({labels: labels});
|
||||
},
|
||||
changeLabelKey(index, oldKey, newKey) {
|
||||
var labels = this.state.labels,
|
||||
labelData = labels[index];
|
||||
var labels = this.state.labels;
|
||||
var labelData = labels[index];
|
||||
labelData.key = newKey;
|
||||
if (!labelData.indeterminate) labelData.checked = true;
|
||||
this.validateLabels(labels);
|
||||
this.setState({labels: labels});
|
||||
},
|
||||
changeLabelState(index, key, checked) {
|
||||
var labels = this.state.labels,
|
||||
labelData = labels[index];
|
||||
var labels = this.state.labels;
|
||||
var labelData = labels[index];
|
||||
labelData.checked = checked;
|
||||
labelData.indeterminate = false;
|
||||
this.validateLabels(labels);
|
||||
this.setState({labels: labels});
|
||||
},
|
||||
changeLabelValue(index, key, value) {
|
||||
var labels = this.state.labels,
|
||||
labelData = labels[index];
|
||||
var labels = this.state.labels;
|
||||
var labelData = labels[index];
|
||||
labelData.values = [value || null];
|
||||
if (!labelData.indeterminate) labelData.checked = true;
|
||||
this.validateLabels(labels);
|
||||
|
@ -1376,8 +1374,8 @@ NodeLabelsPanel = React.createClass({
|
|||
delete nodeLabels[oldLabel];
|
||||
}
|
||||
|
||||
var nodeHasLabel = !_.isUndefined(nodeLabels[oldLabel]),
|
||||
label = labelData.key;
|
||||
var nodeHasLabel = !_.isUndefined(nodeLabels[oldLabel]);
|
||||
var label = labelData.key;
|
||||
// rename label
|
||||
if ((labelData.checked || labelData.indeterminate) && nodeHasLabel) {
|
||||
var labelValue = nodeLabels[oldLabel];
|
||||
|
@ -1534,17 +1532,17 @@ RolePanel = React.createClass({
|
|||
});
|
||||
},
|
||||
processRestrictions(role, models) {
|
||||
var name = role.get('name'),
|
||||
restrictionsCheck = role.checkRestrictions(models, 'disable'),
|
||||
roleLimitsCheckResults = this.props.processedRoleLimits[name],
|
||||
roles = this.props.cluster.get('roles'),
|
||||
conflicts = _.chain(this.props.selectedRoles)
|
||||
.union(this.props.indeterminateRoles)
|
||||
.map((role) => roles.find({name: role}).conflicts)
|
||||
.flatten()
|
||||
.uniq()
|
||||
.value(),
|
||||
messages = [];
|
||||
var name = role.get('name');
|
||||
var restrictionsCheck = role.checkRestrictions(models, 'disable');
|
||||
var roleLimitsCheckResults = this.props.processedRoleLimits[name];
|
||||
var roles = this.props.cluster.get('roles');
|
||||
var conflicts = _.chain(this.props.selectedRoles)
|
||||
.union(this.props.indeterminateRoles)
|
||||
.map((role) => roles.find({name: role}).conflicts)
|
||||
.flatten()
|
||||
.uniq()
|
||||
.value();
|
||||
var messages = [];
|
||||
|
||||
if (restrictionsCheck.result && restrictionsCheck.message) messages.push(restrictionsCheck.message);
|
||||
if (roleLimitsCheckResults && !roleLimitsCheckResults.valid && roleLimitsCheckResults.message) messages.push(roleLimitsCheckResults.message);
|
||||
|
@ -1561,8 +1559,8 @@ RolePanel = React.createClass({
|
|||
<h4>{i18n('cluster_page.nodes_tab.assign_roles')}</h4>
|
||||
{this.props.cluster.get('roles').map((role) => {
|
||||
if (!role.checkRestrictions(this.props.configModels, 'hide').result) {
|
||||
var name = role.get('name'),
|
||||
processedRestrictions = this.props.nodes.length ? this.processRestrictions(role, this.props.configModels) : {};
|
||||
var name = role.get('name');
|
||||
var processedRestrictions = this.props.nodes.length ? this.processRestrictions(role, this.props.configModels) : {};
|
||||
return (
|
||||
<Input
|
||||
key={name}
|
||||
|
@ -1625,17 +1623,17 @@ NodeList = React.createClass({
|
|||
});
|
||||
};
|
||||
|
||||
var labelNs = 'cluster_page.nodes_tab.node_management_panel.labels.',
|
||||
getLabelValue = (node, label) => {
|
||||
var labelValue = node.getLabel(label);
|
||||
return labelValue === false ?
|
||||
i18n(labelNs + 'not_assigned_label', {label: label})
|
||||
var labelNs = 'cluster_page.nodes_tab.node_management_panel.labels.';
|
||||
var getLabelValue = (node, label) => {
|
||||
var labelValue = node.getLabel(label);
|
||||
return labelValue === false ?
|
||||
i18n(labelNs + 'not_assigned_label', {label: label})
|
||||
:
|
||||
_.isNull(labelValue) ?
|
||||
i18n(labelNs + 'not_specified_label', {label: label})
|
||||
:
|
||||
_.isNull(labelValue) ?
|
||||
i18n(labelNs + 'not_specified_label', {label: label})
|
||||
:
|
||||
label + ' "' + labelValue + '"';
|
||||
};
|
||||
label + ' "' + labelValue + '"';
|
||||
};
|
||||
|
||||
var groupingMethod = (node) => {
|
||||
return _.compact(_.map(this.props.activeSorters, (sorter) => {
|
||||
|
@ -1643,9 +1641,9 @@ NodeList = React.createClass({
|
|||
|
||||
if (sorter.isLabel) return getLabelValue(node, sorter.name);
|
||||
|
||||
var result,
|
||||
ns = 'cluster_page.nodes_tab.node.',
|
||||
cluster = this.props.cluster || this.props.clusters.get(node.get('cluster'));
|
||||
var result;
|
||||
var ns = 'cluster_page.nodes_tab.node.';
|
||||
var cluster = this.props.cluster || this.props.clusters.get(node.get('cluster'));
|
||||
switch (sorter.name) {
|
||||
case 'roles':
|
||||
result = node.getRolesSummary(this.props.roles) || i18n(ns + 'no_roles');
|
||||
|
@ -1707,11 +1705,12 @@ NodeList = React.createClass({
|
|||
return groups.sort((group1, group2) => {
|
||||
var result;
|
||||
_.each(this.props.activeSorters, (sorter) => {
|
||||
var node1 = group1[1][0], node2 = group2[1][0];
|
||||
var node1 = group1[1][0];
|
||||
var node2 = group2[1][0];
|
||||
|
||||
if (sorter.isLabel) {
|
||||
var node1Label = node1.getLabel(sorter.name),
|
||||
node2Label = node2.getLabel(sorter.name);
|
||||
var node1Label = node1.getLabel(sorter.name);
|
||||
var node2Label = node2.getLabel(sorter.name);
|
||||
if (node1Label && node2Label) {
|
||||
result = utils.natsort(node1Label, node2Label, {insensitive: true});
|
||||
} else {
|
||||
|
@ -1720,9 +1719,9 @@ NodeList = React.createClass({
|
|||
} else {
|
||||
switch (sorter.name) {
|
||||
case 'roles':
|
||||
var roles1 = node1.sortedRoles(preferredRolesOrder),
|
||||
roles2 = node2.sortedRoles(preferredRolesOrder),
|
||||
order;
|
||||
var roles1 = node1.sortedRoles(preferredRolesOrder);
|
||||
var roles2 = node2.sortedRoles(preferredRolesOrder);
|
||||
var order;
|
||||
if (!roles1.length && !roles2.length) result = 0;
|
||||
else if (!roles1.length) result = 1;
|
||||
else if (!roles2.length) result = -1;
|
||||
|
@ -1743,14 +1742,14 @@ NodeList = React.createClass({
|
|||
result = utils.natsort(composeNodeDiskSizesLabel(node1), composeNodeDiskSizesLabel(node2));
|
||||
break;
|
||||
case 'group_id':
|
||||
var nodeGroup1 = node1.get('group_id'),
|
||||
nodeGroup2 = node2.get('group_id');
|
||||
var nodeGroup1 = node1.get('group_id');
|
||||
var nodeGroup2 = node2.get('group_id');
|
||||
result = nodeGroup1 == nodeGroup2 ? 0 :
|
||||
!nodeGroup1 ? 1 : !nodeGroup2 ? -1 : nodeGroup1 - nodeGroup2;
|
||||
break;
|
||||
case 'cluster':
|
||||
var cluster1 = node1.get('cluster'),
|
||||
cluster2 = node2.get('cluster');
|
||||
var cluster1 = node1.get('cluster');
|
||||
var cluster2 = node2.get('cluster');
|
||||
result = cluster1 == cluster2 ? 0 :
|
||||
!cluster1 ? 1 : !cluster2 ? -1 : utils.natsort(this.props.clusters.get(cluster1).get('name'), this.props.clusters.get(cluster2).get('name'));
|
||||
break;
|
||||
|
@ -1769,10 +1768,10 @@ NodeList = React.createClass({
|
|||
});
|
||||
},
|
||||
render() {
|
||||
var groups = this.groupNodes(),
|
||||
rolesWithLimitReached = _.keys(_.omit(this.props.processedRoleLimits, (roleLimit, roleName) => {
|
||||
return roleLimit.valid || !_.contains(this.props.selectedRoles, roleName);
|
||||
}));
|
||||
var groups = this.groupNodes();
|
||||
var rolesWithLimitReached = _.keys(_.omit(this.props.processedRoleLimits, (roleLimit, roleName) => {
|
||||
return roleLimit.valid || !_.contains(this.props.selectedRoles, roleName);
|
||||
}));
|
||||
return (
|
||||
<div className={utils.classNames({'node-list row': true, compact: this.props.viewMode == 'compact'})}>
|
||||
{groups.length > 1 &&
|
||||
|
@ -1812,10 +1811,10 @@ NodeList = React.createClass({
|
|||
NodeGroup = React.createClass({
|
||||
mixins: [SelectAllMixin],
|
||||
render() {
|
||||
var availableNodes = this.props.nodes.filter((node) => node.isSelectable()),
|
||||
nodesWithRestrictionsIds = _.pluck(_.filter(availableNodes, (node) => {
|
||||
return _.any(this.props.rolesWithLimitReached, (role) => !node.hasRole(role));
|
||||
}), 'id');
|
||||
var availableNodes = this.props.nodes.filter((node) => node.isSelectable());
|
||||
var nodesWithRestrictionsIds = _.pluck(_.filter(availableNodes, (node) => {
|
||||
return _.any(this.props.rolesWithLimitReached, (role) => !node.hasRole(role));
|
||||
}), 'id');
|
||||
return (
|
||||
<div className='nodes-group'>
|
||||
<div className='row node-group-header'>
|
||||
|
|
|
@ -38,14 +38,14 @@ var OffloadingModesControl = React.createClass({
|
|||
},
|
||||
checkModes(mode, sub) {
|
||||
var changedState = sub.reduce((state, childMode) => {
|
||||
if (!_.isEmpty(childMode.sub)) {
|
||||
this.checkModes(childMode, childMode.sub);
|
||||
}
|
||||
return (state === 0 || state === childMode.state) ? childMode.state : -1;
|
||||
},
|
||||
0
|
||||
),
|
||||
oldState;
|
||||
if (!_.isEmpty(childMode.sub)) {
|
||||
this.checkModes(childMode, childMode.sub);
|
||||
}
|
||||
return (state === 0 || state === childMode.state) ? childMode.state : -1;
|
||||
},
|
||||
0
|
||||
);
|
||||
var oldState;
|
||||
|
||||
if (mode && mode.state != changedState) {
|
||||
oldState = mode.state;
|
||||
|
@ -53,10 +53,9 @@ var OffloadingModesControl = React.createClass({
|
|||
}
|
||||
},
|
||||
findMode(name, modes) {
|
||||
var result,
|
||||
mode,
|
||||
index = 0,
|
||||
modesLength = modes.length;
|
||||
var result, mode;
|
||||
var index = 0;
|
||||
var modesLength = modes.length;
|
||||
for (; index < modesLength; index++) {
|
||||
mode = modes[index];
|
||||
if (mode.name == name) {
|
||||
|
@ -71,8 +70,8 @@ var OffloadingModesControl = React.createClass({
|
|||
return result;
|
||||
},
|
||||
onModeStateChange(name, state) {
|
||||
var modes = _.cloneDeep(this.props.interface.get('offloading_modes') || []),
|
||||
mode = this.findMode(name, modes);
|
||||
var modes = _.cloneDeep(this.props.interface.get('offloading_modes') || []);
|
||||
var mode = this.findMode(name, modes);
|
||||
|
||||
return () => {
|
||||
if (mode) {
|
||||
|
@ -87,19 +86,19 @@ var OffloadingModesControl = React.createClass({
|
|||
},
|
||||
makeOffloadingModesExcerpt() {
|
||||
var states = {
|
||||
true: i18n(ns + 'offloading_enabled'),
|
||||
false: i18n(ns + 'offloading_disabled'),
|
||||
null: i18n(ns + 'offloading_default')
|
||||
},
|
||||
ifcModes = this.props.interface.get('offloading_modes');
|
||||
true: i18n(ns + 'offloading_enabled'),
|
||||
false: i18n(ns + 'offloading_disabled'),
|
||||
null: i18n(ns + 'offloading_default')
|
||||
};
|
||||
var ifcModes = this.props.interface.get('offloading_modes');
|
||||
|
||||
if (_.uniq(_.pluck(ifcModes, 'state')).length == 1) {
|
||||
return states[ifcModes[0].state];
|
||||
}
|
||||
|
||||
var lastState,
|
||||
added = 0,
|
||||
excerpt = [];
|
||||
var lastState;
|
||||
var added = 0;
|
||||
var excerpt = [];
|
||||
_.each(ifcModes,
|
||||
(mode) => {
|
||||
if (!_.isNull(mode.state) && mode.state !== lastState) {
|
||||
|
@ -144,8 +143,8 @@ var OffloadingModesControl = React.createClass({
|
|||
});
|
||||
},
|
||||
render() {
|
||||
var modes = [],
|
||||
ifcModes = this.props.interface.get('offloading_modes');
|
||||
var modes = [];
|
||||
var ifcModes = this.props.interface.get('offloading_modes');
|
||||
if (ifcModes) {
|
||||
modes.push({
|
||||
name: i18n(ns + 'all_modes'),
|
||||
|
|
|
@ -23,10 +23,10 @@ import customControls from 'views/custom_controls';
|
|||
|
||||
var SettingSection = React.createClass({
|
||||
processRestrictions(setting, settingName) {
|
||||
var result = false,
|
||||
restrictionsCheck = this.props.checkRestrictions('disable', setting),
|
||||
messagesCheck = this.props.checkRestrictions('none', setting),
|
||||
messages = _.compact([restrictionsCheck.message, messagesCheck.message]);
|
||||
var result = false;
|
||||
var restrictionsCheck = this.props.checkRestrictions('disable', setting);
|
||||
var messagesCheck = this.props.checkRestrictions('none', setting);
|
||||
var messages = _.compact([restrictionsCheck.message, messagesCheck.message]);
|
||||
|
||||
// FIXME: hack for #1442475 to lock images_ceph in env with controllers
|
||||
if (settingName == 'images_ceph') {
|
||||
|
@ -42,9 +42,9 @@ var SettingSection = React.createClass({
|
|||
};
|
||||
},
|
||||
checkDependencies(sectionName, settingName) {
|
||||
var messages = [],
|
||||
dependentRoles = this.checkDependentRoles(sectionName, settingName),
|
||||
dependentSettings = this.checkDependentSettings(sectionName, settingName);
|
||||
var messages = [];
|
||||
var dependentRoles = this.checkDependentRoles(sectionName, settingName);
|
||||
var dependentSettings = this.checkDependentSettings(sectionName, settingName);
|
||||
|
||||
if (dependentRoles.length) messages.push(i18n('cluster_page.settings_tab.dependent_role_warning', {roles: dependentRoles.join(', '), count: dependentRoles.length}));
|
||||
if (dependentSettings.length) messages.push(i18n('cluster_page.settings_tab.dependent_settings_warning', {settings: dependentSettings.join(', '), count: dependentSettings.length}));
|
||||
|
@ -71,13 +71,13 @@ var SettingSection = React.createClass({
|
|||
},
|
||||
checkDependentRoles(sectionName, settingName) {
|
||||
if (!this.props.allocatedRoles.length) return [];
|
||||
var path = this.props.makePath(sectionName, settingName),
|
||||
setting = this.props.settings.get(path);
|
||||
var path = this.props.makePath(sectionName, settingName);
|
||||
var setting = this.props.settings.get(path);
|
||||
if (!this.areCalculationsPossible(setting)) return [];
|
||||
var valueAttribute = this.props.getValueAttribute(settingName),
|
||||
valuesToCheck = this.getValuesToCheck(setting, valueAttribute),
|
||||
pathToCheck = this.props.makePath(path, valueAttribute),
|
||||
roles = this.props.cluster.get('roles');
|
||||
var valueAttribute = this.props.getValueAttribute(settingName);
|
||||
var valuesToCheck = this.getValuesToCheck(setting, valueAttribute);
|
||||
var pathToCheck = this.props.makePath(path, valueAttribute);
|
||||
var roles = this.props.cluster.get('roles');
|
||||
return _.compact(this.props.allocatedRoles.map((roleName) => {
|
||||
var role = roles.findWhere({name: roleName});
|
||||
if (_.any(role.get('restrictions'), (restriction) => {
|
||||
|
@ -89,8 +89,8 @@ var SettingSection = React.createClass({
|
|||
}));
|
||||
},
|
||||
checkDependentSettings(sectionName, settingName) {
|
||||
var path = this.props.makePath(sectionName, settingName),
|
||||
currentSetting = this.props.settings.get(path);
|
||||
var path = this.props.makePath(sectionName, settingName);
|
||||
var currentSetting = this.props.settings.get(path);
|
||||
if (!this.areCalculationsPossible(currentSetting)) return [];
|
||||
var dependentRestrictions = {};
|
||||
var addDependentRestrictions = (setting, label) => {
|
||||
|
@ -121,10 +121,10 @@ var SettingSection = React.createClass({
|
|||
});
|
||||
// evaluate dependencies
|
||||
if (!_.isEmpty(dependentRestrictions)) {
|
||||
var valueAttribute = this.props.getValueAttribute(settingName),
|
||||
pathToCheck = this.props.makePath(path, valueAttribute),
|
||||
valuesToCheck = this.getValuesToCheck(currentSetting, valueAttribute),
|
||||
checkValues = _.partial(this.checkValues, valuesToCheck, pathToCheck, currentSetting[valueAttribute]);
|
||||
var valueAttribute = this.props.getValueAttribute(settingName);
|
||||
var pathToCheck = this.props.makePath(path, valueAttribute);
|
||||
var valuesToCheck = this.getValuesToCheck(currentSetting, valueAttribute);
|
||||
var checkValues = _.partial(this.checkValues, valuesToCheck, pathToCheck, currentSetting[valueAttribute]);
|
||||
return _.compact(_.map(dependentRestrictions, (restrictions, label) => {
|
||||
if (_.any(restrictions, checkValues)) return label;
|
||||
}));
|
||||
|
@ -166,17 +166,17 @@ var SettingSection = React.createClass({
|
|||
}
|
||||
},
|
||||
render() {
|
||||
var {settings, sectionName} = this.props,
|
||||
section = settings.get(sectionName),
|
||||
isPlugin = settings.isPlugin(section),
|
||||
metadata = section.metadata,
|
||||
sortedSettings = _.sortBy(this.props.settingsToDisplay, (settingName) => section[settingName].weight),
|
||||
processedGroupRestrictions = this.processRestrictions(metadata),
|
||||
processedGroupDependencies = this.checkDependencies(sectionName, 'metadata'),
|
||||
isGroupAlwaysEditable = isPlugin ? _.any(metadata.versions, (version) => version.metadata.always_editable) : metadata.always_editable,
|
||||
isGroupDisabled = this.props.locked || (this.props.lockedCluster && !isGroupAlwaysEditable) || processedGroupRestrictions.result,
|
||||
showSettingGroupWarning = !this.props.lockedCluster || metadata.always_editable,
|
||||
groupWarning = _.compact([processedGroupRestrictions.message, processedGroupDependencies.message]).join(' ');
|
||||
var {settings, sectionName} = this.props;
|
||||
var section = settings.get(sectionName);
|
||||
var isPlugin = settings.isPlugin(section);
|
||||
var metadata = section.metadata;
|
||||
var sortedSettings = _.sortBy(this.props.settingsToDisplay, (settingName) => section[settingName].weight);
|
||||
var processedGroupRestrictions = this.processRestrictions(metadata);
|
||||
var processedGroupDependencies = this.checkDependencies(sectionName, 'metadata');
|
||||
var isGroupAlwaysEditable = isPlugin ? _.any(metadata.versions, (version) => version.metadata.always_editable) : metadata.always_editable;
|
||||
var isGroupDisabled = this.props.locked || (this.props.lockedCluster && !isGroupAlwaysEditable) || processedGroupRestrictions.result;
|
||||
var showSettingGroupWarning = !this.props.lockedCluster || metadata.always_editable;
|
||||
var groupWarning = _.compact([processedGroupRestrictions.message, processedGroupDependencies.message]).join(' ');
|
||||
|
||||
return (
|
||||
<div className={'setting-section setting-section-' + sectionName}>
|
||||
|
@ -215,15 +215,15 @@ var SettingSection = React.createClass({
|
|||
</div>
|
||||
}
|
||||
{_.map(sortedSettings, (settingName) => {
|
||||
var setting = section[settingName],
|
||||
settingKey = settingName + (isPlugin ? '-' + metadata.chosen_id : ''),
|
||||
path = this.props.makePath(sectionName, settingName),
|
||||
error = (settings.validationError || {})[path],
|
||||
processedSettingRestrictions = this.processRestrictions(setting, settingName),
|
||||
processedSettingDependencies = this.checkDependencies(sectionName, settingName),
|
||||
isSettingDisabled = isGroupDisabled || (metadata.toggleable && !metadata.enabled) || processedSettingRestrictions.result || processedSettingDependencies.result,
|
||||
showSettingWarning = showSettingGroupWarning && !isGroupDisabled && (!metadata.toggleable || metadata.enabled),
|
||||
settingWarning = _.compact([processedSettingRestrictions.message, processedSettingDependencies.message]).join(' ');
|
||||
var setting = section[settingName];
|
||||
var settingKey = settingName + (isPlugin ? '-' + metadata.chosen_id : '');
|
||||
var path = this.props.makePath(sectionName, settingName);
|
||||
var error = (settings.validationError || {})[path];
|
||||
var processedSettingRestrictions = this.processRestrictions(setting, settingName);
|
||||
var processedSettingDependencies = this.checkDependencies(sectionName, settingName);
|
||||
var isSettingDisabled = isGroupDisabled || (metadata.toggleable && !metadata.enabled) || processedSettingRestrictions.result || processedSettingDependencies.result;
|
||||
var showSettingWarning = showSettingGroupWarning && !isGroupDisabled && (!metadata.toggleable || metadata.enabled);
|
||||
var settingWarning = _.compact([processedSettingRestrictions.message, processedSettingDependencies.message]).join(' ');
|
||||
|
||||
// support of custom controls
|
||||
var CustomControl = customControls[setting.type];
|
||||
|
|
|
@ -75,11 +75,11 @@ var SettingsTab = React.createClass({
|
|||
if (!this.isSavingPossible()) return $.Deferred().reject();
|
||||
|
||||
// collecting data to save
|
||||
var settings = this.props.cluster.get('settings'),
|
||||
dataToSave = this.props.cluster.isAvailableForSettingsChanges() ? settings.attributes :
|
||||
_.pick(settings.attributes, (group) => (group.metadata || {}).always_editable);
|
||||
var options = {url: settings.url, patch: true, wait: true, validate: false},
|
||||
deferred = new models.Settings(_.cloneDeep(dataToSave)).save(null, options);
|
||||
var settings = this.props.cluster.get('settings');
|
||||
var dataToSave = this.props.cluster.isAvailableForSettingsChanges() ? settings.attributes :
|
||||
_.pick(settings.attributes, (group) => (group.metadata || {}).always_editable);
|
||||
var options = {url: settings.url, patch: true, wait: true, validate: false};
|
||||
var deferred = new models.Settings(_.cloneDeep(dataToSave)).save(null, options);
|
||||
if (deferred) {
|
||||
this.setState({actionInProgress: true});
|
||||
deferred
|
||||
|
@ -107,10 +107,10 @@ var SettingsTab = React.createClass({
|
|||
return deferred;
|
||||
},
|
||||
loadDefaults() {
|
||||
var settings = this.props.cluster.get('settings'),
|
||||
lockedCluster = !this.props.cluster.isAvailableForSettingsChanges(),
|
||||
defaultSettings = new models.Settings(),
|
||||
deferred = defaultSettings.fetch({url: _.result(this.props.cluster, 'url') + '/attributes/defaults'});
|
||||
var settings = this.props.cluster.get('settings');
|
||||
var lockedCluster = !this.props.cluster.isAvailableForSettingsChanges();
|
||||
var defaultSettings = new models.Settings();
|
||||
var deferred = defaultSettings.fetch({url: _.result(this.props.cluster, 'url') + '/attributes/defaults'});
|
||||
|
||||
if (deferred) {
|
||||
this.setState({actionInProgress: true});
|
||||
|
@ -154,8 +154,8 @@ var SettingsTab = React.createClass({
|
|||
settings.isValid({models: this.state.configModels});
|
||||
},
|
||||
onChange(groupName, settingName, value) {
|
||||
var settings = this.props.cluster.get('settings'),
|
||||
name = settings.makePath(groupName, settingName, settings.getValueAttribute(settingName));
|
||||
var settings = this.props.cluster.get('settings');
|
||||
var name = settings.makePath(groupName, settingName, settings.getValueAttribute(settingName));
|
||||
this.state.settingsForChecks.set(name, value);
|
||||
// FIXME: the following hacks cause we can't pass {validate: true} option to set method
|
||||
// this form of validation isn't supported in Backbone DeepModel
|
||||
|
@ -167,30 +167,30 @@ var SettingsTab = React.createClass({
|
|||
return this.props.cluster.get('settings').checkRestrictions(this.state.configModels, action, setting);
|
||||
},
|
||||
isSavingPossible() {
|
||||
var settings = this.props.cluster.get('settings'),
|
||||
locked = this.state.actionInProgress || !!this.props.cluster.task({group: 'deployment', active: true}),
|
||||
// network settings are shown on Networks tab, so they should not block
|
||||
// saving of changes on Settings tab
|
||||
areSettingsValid = !_.any(_.keys(settings.validationError), (settingPath) => {
|
||||
var settingSection = settingPath.split('.')[0];
|
||||
return settings.get(settingSection).metadata.group != 'network' &&
|
||||
settings.get(settingPath).group != 'network';
|
||||
});
|
||||
var settings = this.props.cluster.get('settings');
|
||||
var locked = this.state.actionInProgress || !!this.props.cluster.task({group: 'deployment', active: true});
|
||||
// network settings are shown on Networks tab, so they should not block
|
||||
// saving of changes on Settings tab
|
||||
var areSettingsValid = !_.any(_.keys(settings.validationError), (settingPath) => {
|
||||
var settingSection = settingPath.split('.')[0];
|
||||
return settings.get(settingSection).metadata.group != 'network' &&
|
||||
settings.get(settingPath).group != 'network';
|
||||
});
|
||||
return !locked && this.hasChanges() && areSettingsValid;
|
||||
},
|
||||
render() {
|
||||
var cluster = this.props.cluster,
|
||||
settings = cluster.get('settings'),
|
||||
settingsGroupList = settings.getGroupList(),
|
||||
locked = this.state.actionInProgress || !!cluster.task({group: 'deployment', active: true}),
|
||||
lockedCluster = !cluster.isAvailableForSettingsChanges(),
|
||||
someSettingsEditable = _.any(settings.attributes, (group) => group.metadata.always_editable),
|
||||
hasChanges = this.hasChanges(),
|
||||
allocatedRoles = _.uniq(_.flatten(_.union(cluster.get('nodes').pluck('roles'), cluster.get('nodes').pluck('pending_roles')))),
|
||||
classes = {
|
||||
row: true,
|
||||
'changes-locked': lockedCluster
|
||||
};
|
||||
var cluster = this.props.cluster;
|
||||
var settings = cluster.get('settings');
|
||||
var settingsGroupList = settings.getGroupList();
|
||||
var locked = this.state.actionInProgress || !!cluster.task({group: 'deployment', active: true});
|
||||
var lockedCluster = !cluster.isAvailableForSettingsChanges();
|
||||
var someSettingsEditable = _.any(settings.attributes, (group) => group.metadata.always_editable);
|
||||
var hasChanges = this.hasChanges();
|
||||
var allocatedRoles = _.uniq(_.flatten(_.union(cluster.get('nodes').pluck('roles'), cluster.get('nodes').pluck('pending_roles'))));
|
||||
var classes = {
|
||||
row: true,
|
||||
'changes-locked': lockedCluster
|
||||
};
|
||||
|
||||
var invalidSections = {};
|
||||
_.each(settings.validationError, (error, key) => {
|
||||
|
@ -203,8 +203,8 @@ var SettingsTab = React.createClass({
|
|||
_.each(settings.attributes, (section, sectionName) => {
|
||||
var isHidden = this.checkRestrictions('hide', section.metadata).result;
|
||||
if (!isHidden) {
|
||||
var group = section.metadata.group,
|
||||
hasErrors = invalidSections[sectionName];
|
||||
var group = section.metadata.group;
|
||||
var hasErrors = invalidSections[sectionName];
|
||||
if (group) {
|
||||
if (group != 'network') {
|
||||
groupedSettings[settings.sanitizeGroup(group)][sectionName] = {invalid: hasErrors};
|
||||
|
@ -224,18 +224,18 @@ var SettingsTab = React.createClass({
|
|||
}
|
||||
|
||||
_.each(settingGroups, (settingGroup) => {
|
||||
var calculatedGroup = settings.sanitizeGroup(settingGroup),
|
||||
pickedSettings = _.compact(_.map(section, (setting, settingName) => {
|
||||
if (
|
||||
settingName != 'metadata' &&
|
||||
setting.type != 'hidden' &&
|
||||
settings.sanitizeGroup(setting.group) == calculatedGroup &&
|
||||
!this.checkRestrictions('hide', setting).result
|
||||
) return settingName;
|
||||
})),
|
||||
hasErrors = _.any(pickedSettings, (settingName) => {
|
||||
return (settings.validationError || {})[settings.makePath(sectionName, settingName)];
|
||||
});
|
||||
var calculatedGroup = settings.sanitizeGroup(settingGroup);
|
||||
var pickedSettings = _.compact(_.map(section, (setting, settingName) => {
|
||||
if (
|
||||
settingName != 'metadata' &&
|
||||
setting.type != 'hidden' &&
|
||||
settings.sanitizeGroup(setting.group) == calculatedGroup &&
|
||||
!this.checkRestrictions('hide', setting).result
|
||||
) return settingName;
|
||||
}));
|
||||
var hasErrors = _.any(pickedSettings, (settingName) => {
|
||||
return (settings.validationError || {})[settings.makePath(sectionName, settingName)];
|
||||
});
|
||||
if (!_.isEmpty(pickedSettings)) {
|
||||
groupedSettings[calculatedGroup][sectionName] = {settings: pickedSettings, invalid: hasErrors};
|
||||
}
|
||||
|
|
|
@ -96,7 +96,8 @@ Cluster = React.createClass({
|
|||
this.props.cluster.task({name: 'cluster_deletion', status: 'ready'});
|
||||
},
|
||||
fetchData() {
|
||||
var request, requests = [];
|
||||
var request;
|
||||
var requests = [];
|
||||
var deletionTask = this.props.cluster.task('cluster_deletion');
|
||||
if (deletionTask) {
|
||||
request = deletionTask.fetch();
|
||||
|
|
|
@ -92,8 +92,8 @@ export var Input = React.createClass({
|
|||
}
|
||||
},
|
||||
readFile() {
|
||||
var reader = new FileReader(),
|
||||
input = this.getInputDOMNode();
|
||||
var reader = new FileReader();
|
||||
var input = this.getInputDOMNode();
|
||||
|
||||
if (input.files.length) {
|
||||
reader.onload = () => this.saveFile(input.value.replace(/^.*[\\\/]/g, ''), reader.result);
|
||||
|
@ -127,14 +127,14 @@ export var Input = React.createClass({
|
|||
} else {
|
||||
props.onChange = this.props.debounce ? this.debouncedChange : this.onChange;
|
||||
}
|
||||
var Tag = _.contains(['select', 'textarea'], this.props.type) ? this.props.type : 'input',
|
||||
input = <Tag {...this.props} {...props}>{this.props.children}</Tag>,
|
||||
isCheckboxOrRadio = this.isCheckboxOrRadio(),
|
||||
inputWrapperClasses = {
|
||||
'input-group': this.props.toggleable,
|
||||
'custom-tumbler': isCheckboxOrRadio,
|
||||
textarea: this.props.type == 'textarea'
|
||||
};
|
||||
var Tag = _.contains(['select', 'textarea'], this.props.type) ? this.props.type : 'input';
|
||||
var input = <Tag {...this.props} {...props}>{this.props.children}</Tag>;
|
||||
var isCheckboxOrRadio = this.isCheckboxOrRadio();
|
||||
var inputWrapperClasses = {
|
||||
'input-group': this.props.toggleable,
|
||||
'custom-tumbler': isCheckboxOrRadio,
|
||||
textarea: this.props.type == 'textarea'
|
||||
};
|
||||
if (this.props.type == 'file') {
|
||||
input = <form ref='form'>{input}</form>;
|
||||
}
|
||||
|
@ -186,13 +186,13 @@ export var Input = React.createClass({
|
|||
return <span key='description' className='help-block'>{text}</span>;
|
||||
},
|
||||
renderWrapper(children) {
|
||||
var isCheckboxOrRadio = this.isCheckboxOrRadio(),
|
||||
classes = {
|
||||
'form-group': !isCheckboxOrRadio,
|
||||
'checkbox-group': isCheckboxOrRadio,
|
||||
'has-error': !_.isUndefined(this.props.error) && !_.isNull(this.props.error),
|
||||
disabled: this.props.disabled
|
||||
};
|
||||
var isCheckboxOrRadio = this.isCheckboxOrRadio();
|
||||
var classes = {
|
||||
'form-group': !isCheckboxOrRadio,
|
||||
'checkbox-group': isCheckboxOrRadio,
|
||||
'has-error': !_.isUndefined(this.props.error) && !_.isNull(this.props.error),
|
||||
disabled: this.props.disabled
|
||||
};
|
||||
classes[this.props.wrapperClassName] = this.props.wrapperClassName;
|
||||
return (<div className={utils.classNames(classes)}>{children}</div>);
|
||||
},
|
||||
|
|
|
@ -25,12 +25,12 @@ customControls.custom_repo_configuration = React.createClass({
|
|||
statics: {
|
||||
// validate method represented as static method to support cluster settings validation
|
||||
validate(setting, models) {
|
||||
var ns = 'cluster_page.settings_tab.custom_repo_configuration.errors.',
|
||||
nameRegexp = /^[\w-.]+$/,
|
||||
os = models.release.get('operating_system');
|
||||
var ns = 'cluster_page.settings_tab.custom_repo_configuration.errors.';
|
||||
var nameRegexp = /^[\w-.]+$/;
|
||||
var os = models.release.get('operating_system');
|
||||
var errors = setting.value.map((repo) => {
|
||||
var error = {},
|
||||
value = this.repoToString(repo, os);
|
||||
var error = {};
|
||||
var value = this.repoToString(repo, os);
|
||||
if (!repo.name) {
|
||||
error.name = i18n(ns + 'empty_name');
|
||||
} else if (!repo.name.match(nameRegexp)) {
|
||||
|
@ -70,8 +70,8 @@ customControls.custom_repo_configuration = React.createClass({
|
|||
},
|
||||
changeRepos(method, index, value) {
|
||||
value = _.trim(value).replace(/\s+/g, ' ');
|
||||
var repos = _.cloneDeep(this.props.value),
|
||||
os = this.props.cluster.get('release').get('operating_system');
|
||||
var repos = _.cloneDeep(this.props.value);
|
||||
var os = this.props.cluster.get('release').get('operating_system');
|
||||
switch (method) {
|
||||
case 'add':
|
||||
var data = {
|
||||
|
@ -99,8 +99,8 @@ customControls.custom_repo_configuration = React.createClass({
|
|||
repos[index].priority = value == '' ? null : Number(value);
|
||||
break;
|
||||
default:
|
||||
var repo = repos[index],
|
||||
match = value.match(this.props.repoRegexes[os]);
|
||||
var repo = repos[index];
|
||||
var match = value.match(this.props.repoRegexes[os]);
|
||||
if (match) {
|
||||
_.each(this.props.repoAttributes[os], (attribute, index) => {
|
||||
repo[attribute] = match[index + 1] || '';
|
||||
|
@ -125,20 +125,20 @@ customControls.custom_repo_configuration = React.createClass({
|
|||
);
|
||||
},
|
||||
render() {
|
||||
var ns = 'cluster_page.settings_tab.custom_repo_configuration.',
|
||||
os = this.props.cluster.get('release').get('operating_system');
|
||||
var ns = 'cluster_page.settings_tab.custom_repo_configuration.';
|
||||
var os = this.props.cluster.get('release').get('operating_system');
|
||||
return (
|
||||
<div className='repos' key={this.state.key}>
|
||||
{this.props.description &&
|
||||
<span className='help-block' dangerouslySetInnerHTML={{__html: utils.urlify(utils.linebreaks(_.escape(this.props.description)))}} />
|
||||
}
|
||||
{this.props.value.map((repo, index) => {
|
||||
var error = (this.props.error || {})[index],
|
||||
props = {
|
||||
name: index,
|
||||
type: 'text',
|
||||
disabled: this.props.disabled
|
||||
};
|
||||
var error = (this.props.error || {})[index];
|
||||
var props = {
|
||||
name: index,
|
||||
type: 'text',
|
||||
disabled: this.props.disabled
|
||||
};
|
||||
return (
|
||||
<div className='form-inline' key={'repo-' + index}>
|
||||
<Input
|
||||
|
|
|
@ -171,8 +171,8 @@ export var dialogMixin = {
|
|||
|
||||
var registrationResponseErrorMixin = {
|
||||
showResponseErrors(response, form) {
|
||||
var jsonObj,
|
||||
error = '';
|
||||
var jsonObj;
|
||||
var error = '';
|
||||
try {
|
||||
jsonObj = JSON.parse(response.responseText);
|
||||
error = jsonObj.message;
|
||||
|
@ -499,8 +499,8 @@ export var RemoveClusterDialog = React.createClass({
|
|||
this.setState({confirmation: true});
|
||||
},
|
||||
getText() {
|
||||
var ns = 'dialog.remove_cluster.',
|
||||
runningTask = this.props.cluster.task({active: true});
|
||||
var ns = 'dialog.remove_cluster.';
|
||||
var runningTask = this.props.cluster.task({active: true});
|
||||
if (runningTask) {
|
||||
if (runningTask.match({name: 'stop_deployment'})) {
|
||||
return i18n(ns + 'stop_deployment_is_running');
|
||||
|
@ -770,15 +770,15 @@ export var ShowNodeInfoDialog = React.createClass({
|
|||
}
|
||||
},
|
||||
renderBody() {
|
||||
var node = this.props.node,
|
||||
meta = node.get('meta');
|
||||
var node = this.props.node;
|
||||
var meta = node.get('meta');
|
||||
if (!meta) return <ProgressBar />;
|
||||
var groupOrder = ['system', 'cpu', 'memory', 'disks', 'interfaces'],
|
||||
groups = _.sortBy(_.keys(meta), (group) => _.indexOf(groupOrder, group)),
|
||||
sortOrder = {
|
||||
disks: ['name', 'model', 'size'],
|
||||
interfaces: ['name', 'mac', 'state', 'ip', 'netmask', 'current_speed', 'max_speed', 'driver', 'bus_info']
|
||||
};
|
||||
var groupOrder = ['system', 'cpu', 'memory', 'disks', 'interfaces'];
|
||||
var groups = _.sortBy(_.keys(meta), (group) => _.indexOf(groupOrder, group));
|
||||
var sortOrder = {
|
||||
disks: ['name', 'model', 'size'],
|
||||
interfaces: ['name', 'mac', 'state', 'ip', 'netmask', 'current_speed', 'max_speed', 'driver', 'bus_info']
|
||||
};
|
||||
if (this.state.VMsConf) groups.push('config');
|
||||
|
||||
return (
|
||||
|
@ -830,8 +830,8 @@ export var ShowNodeInfoDialog = React.createClass({
|
|||
</div>
|
||||
<div className='panel-group' id='accordion' role='tablist' aria-multiselectable='true'>
|
||||
{_.map(groups, (group, groupIndex) => {
|
||||
var groupEntries = meta[group],
|
||||
subEntries = [];
|
||||
var groupEntries = meta[group];
|
||||
var subEntries = [];
|
||||
if (group == 'interfaces' || group == 'disks') groupEntries = _.sortBy(groupEntries, 'name');
|
||||
if (_.isPlainObject(groupEntries)) subEntries = _.find(_.values(groupEntries), _.isArray);
|
||||
return (
|
||||
|
@ -1034,9 +1034,9 @@ export var DeleteNodesDialog = React.createClass({
|
|||
return {title: i18n('dialog.delete_nodes.title')};
|
||||
},
|
||||
renderBody() {
|
||||
var ns = 'dialog.delete_nodes.',
|
||||
notDeployedNodesAmount = this.props.nodes.reject({status: 'ready'}).length,
|
||||
deployedNodesAmount = this.props.nodes.length - notDeployedNodesAmount;
|
||||
var ns = 'dialog.delete_nodes.';
|
||||
var notDeployedNodesAmount = this.props.nodes.reject({status: 'ready'}).length;
|
||||
var deployedNodesAmount = this.props.nodes.length - notDeployedNodesAmount;
|
||||
return (
|
||||
<div className='text-danger'>
|
||||
{this.renderImportantLabel()}
|
||||
|
@ -1114,9 +1114,9 @@ export var ChangePasswordDialog = React.createClass({
|
|||
return null;
|
||||
},
|
||||
renderBody() {
|
||||
var ns = 'dialog.change_password.',
|
||||
fields = ['currentPassword', 'newPassword', 'confirmationPassword'],
|
||||
translationKeys = ['current_password', 'new_password', 'confirm_new_password'];
|
||||
var ns = 'dialog.change_password.';
|
||||
var fields = ['currentPassword', 'newPassword', 'confirmationPassword'];
|
||||
var translationKeys = ['current_password', 'new_password', 'confirm_new_password'];
|
||||
return (
|
||||
<div className='forms-box'>
|
||||
{_.map(fields, (name, index) => {
|
||||
|
@ -1223,8 +1223,8 @@ export var RegistrationDialog = React.createClass({
|
|||
});
|
||||
},
|
||||
onChange(inputName, value) {
|
||||
var registrationForm = this.props.registrationForm,
|
||||
name = registrationForm.makePath('credentials', inputName, 'value');
|
||||
var registrationForm = this.props.registrationForm;
|
||||
var name = registrationForm.makePath('credentials', inputName, 'value');
|
||||
if (registrationForm.validationError) delete registrationForm.validationError['credentials.' + inputName];
|
||||
registrationForm.set(name, value);
|
||||
},
|
||||
|
@ -1241,8 +1241,8 @@ export var RegistrationDialog = React.createClass({
|
|||
return (<span>{i18n('dialog.registration.i_agree')} <a href={link} target='_blank'>{i18n('dialog.registration.terms_and_conditions')}</a></span>);
|
||||
},
|
||||
validateRegistrationForm() {
|
||||
var registrationForm = this.props.registrationForm,
|
||||
isValid = registrationForm.isValid();
|
||||
var registrationForm = this.props.registrationForm;
|
||||
var isValid = registrationForm.isValid();
|
||||
if (!registrationForm.attributes.credentials.agree.value) {
|
||||
if (!registrationForm.validationError) registrationForm.validationError = {};
|
||||
registrationForm.validationError['credentials.agree'] = i18n('dialog.registration.agree_error');
|
||||
|
@ -1288,14 +1288,14 @@ export var RegistrationDialog = React.createClass({
|
|||
renderBody() {
|
||||
var registrationForm = this.props.registrationForm;
|
||||
if (this.state.loading) return <ProgressBar />;
|
||||
var fieldsList = registrationForm.attributes.credentials,
|
||||
actionInProgress = this.state.actionInProgress,
|
||||
error = this.state.error,
|
||||
sortedFields = _.chain(_.keys(fieldsList))
|
||||
.without('metadata')
|
||||
.sortBy((inputName) => fieldsList[inputName].weight)
|
||||
.value(),
|
||||
halfWidthField = ['first_name', 'last_name', 'company', 'phone', 'country', 'region'];
|
||||
var fieldsList = registrationForm.attributes.credentials;
|
||||
var actionInProgress = this.state.actionInProgress;
|
||||
var error = this.state.error;
|
||||
var sortedFields = _.chain(_.keys(fieldsList))
|
||||
.without('metadata')
|
||||
.sortBy((inputName) => fieldsList[inputName].weight)
|
||||
.value();
|
||||
var halfWidthField = ['first_name', 'last_name', 'company', 'phone', 'country', 'region'];
|
||||
return (
|
||||
<div className='registration-form tracking'>
|
||||
{actionInProgress && <ProgressBar />}
|
||||
|
@ -1312,14 +1312,14 @@ export var RegistrationDialog = React.createClass({
|
|||
}
|
||||
<form className='form-inline row'>
|
||||
{_.map(sortedFields, (inputName) => {
|
||||
var input = fieldsList[inputName],
|
||||
path = 'credentials.' + inputName,
|
||||
inputError = (registrationForm.validationError || {})[path],
|
||||
classes = {
|
||||
'col-md-12': !_.contains(halfWidthField, inputName),
|
||||
'col-md-6': _.contains(halfWidthField, inputName),
|
||||
'text-center': inputName == 'agree'
|
||||
};
|
||||
var input = fieldsList[inputName];
|
||||
var path = 'credentials.' + inputName;
|
||||
var inputError = (registrationForm.validationError || {})[path];
|
||||
var classes = {
|
||||
'col-md-12': !_.contains(halfWidthField, inputName),
|
||||
'col-md-6': _.contains(halfWidthField, inputName),
|
||||
'text-center': inputName == 'agree'
|
||||
};
|
||||
return <Input
|
||||
ref={inputName}
|
||||
key={inputName}
|
||||
|
@ -1405,13 +1405,13 @@ export var RetrievePasswordDialog = React.createClass({
|
|||
this.setState({passwordSent: true});
|
||||
},
|
||||
renderBody() {
|
||||
var ns = 'dialog.retrieve_password.',
|
||||
remoteRetrievePasswordForm = this.props.remoteRetrievePasswordForm;
|
||||
var ns = 'dialog.retrieve_password.';
|
||||
var remoteRetrievePasswordForm = this.props.remoteRetrievePasswordForm;
|
||||
if (this.state.loading) return <ProgressBar />;
|
||||
var error = this.state.error,
|
||||
actionInProgress = this.state.actionInProgress,
|
||||
input = (remoteRetrievePasswordForm.get('credentials') || {}).email,
|
||||
inputError = remoteRetrievePasswordForm ? (remoteRetrievePasswordForm.validationError || {})['credentials.email'] : null;
|
||||
var error = this.state.error;
|
||||
var actionInProgress = this.state.actionInProgress;
|
||||
var input = (remoteRetrievePasswordForm.get('credentials') || {}).email;
|
||||
var inputError = remoteRetrievePasswordForm ? (remoteRetrievePasswordForm.validationError || {})['credentials.email'] : null;
|
||||
return (
|
||||
<div className='retrieve-password-content'>
|
||||
{!this.state.passwordSent ?
|
||||
|
|
|
@ -31,10 +31,10 @@ EquipmentPage = React.createClass({
|
|||
navbarActiveElement: 'equipment',
|
||||
breadcrumbsPath: [['home', '#'], 'equipment'],
|
||||
fetchData() {
|
||||
var nodes = new models.Nodes(),
|
||||
clusters = new models.Clusters(),
|
||||
plugins = new models.Plugins(),
|
||||
{releases, nodeNetworkGroups, fuelSettings} = app;
|
||||
var nodes = new models.Nodes();
|
||||
var clusters = new models.Clusters();
|
||||
var plugins = new models.Plugins();
|
||||
var {releases, nodeNetworkGroups, fuelSettings} = app;
|
||||
|
||||
return $.when(
|
||||
nodes.fetch(),
|
||||
|
|
|
@ -300,20 +300,20 @@ var NotificationsPopover = React.createClass({
|
|||
return {unreadNotificationsIds: []};
|
||||
},
|
||||
renderNotification(notification) {
|
||||
var topic = notification.get('topic'),
|
||||
nodeId = notification.get('node_id'),
|
||||
notificationClasses = {
|
||||
notification: true,
|
||||
'text-danger': topic == 'error',
|
||||
'text-warning': topic == 'warning',
|
||||
clickable: nodeId,
|
||||
unread: notification.get('status') == 'unread' || _.contains(this.state.unreadNotificationsIds, notification.id)
|
||||
},
|
||||
iconClass = {
|
||||
error: 'glyphicon-exclamation-sign',
|
||||
warning: 'glyphicon-warning-sign',
|
||||
discover: 'glyphicon-bell'
|
||||
}[topic] || 'glyphicon-info-sign';
|
||||
var topic = notification.get('topic');
|
||||
var nodeId = notification.get('node_id');
|
||||
var notificationClasses = {
|
||||
notification: true,
|
||||
'text-danger': topic == 'error',
|
||||
'text-warning': topic == 'warning',
|
||||
clickable: nodeId,
|
||||
unread: notification.get('status') == 'unread' || _.contains(this.state.unreadNotificationsIds, notification.id)
|
||||
};
|
||||
var iconClass = {
|
||||
error: 'glyphicon-exclamation-sign',
|
||||
warning: 'glyphicon-warning-sign',
|
||||
discover: 'glyphicon-bell'
|
||||
}[topic] || 'glyphicon-info-sign';
|
||||
return (
|
||||
<div key={notification.id} className={utils.classNames(notificationClasses)}>
|
||||
<i className={'glyphicon ' + iconClass}></i>
|
||||
|
|
|
@ -91,18 +91,18 @@ Notification = React.createClass({
|
|||
}
|
||||
},
|
||||
render() {
|
||||
var topic = this.props.notification.get('topic'),
|
||||
notificationClasses = {
|
||||
'col-xs-12 notification': true,
|
||||
'text-danger': topic == 'error',
|
||||
'text-warning': topic == 'warning',
|
||||
unread: this.props.notification.get('status') == 'unread'
|
||||
},
|
||||
iconClass = {
|
||||
error: 'glyphicon-exclamation-sign',
|
||||
warning: 'glyphicon-warning-sign',
|
||||
discover: 'glyphicon-bell'
|
||||
}[topic] || 'glyphicon-info-sign';
|
||||
var topic = this.props.notification.get('topic');
|
||||
var notificationClasses = {
|
||||
'col-xs-12 notification': true,
|
||||
'text-danger': topic == 'error',
|
||||
'text-warning': topic == 'warning',
|
||||
unread: this.props.notification.get('status') == 'unread'
|
||||
};
|
||||
var iconClass = {
|
||||
error: 'glyphicon-exclamation-sign',
|
||||
warning: 'glyphicon-warning-sign',
|
||||
discover: 'glyphicon-bell'
|
||||
}[topic] || 'glyphicon-info-sign';
|
||||
return (
|
||||
<div className={utils.classNames(notificationClasses)} onClick={this.onNotificationClick}>
|
||||
<div className='notification-time'>{this.props.notification.get('time')}</div>
|
||||
|
|
|
@ -101,11 +101,11 @@ var PluginsPage = React.createClass({
|
|||
);
|
||||
},
|
||||
render() {
|
||||
var isMirantisIso = _.contains(app.version.get('feature_groups'), 'mirantis'),
|
||||
links = {
|
||||
catalog: isMirantisIso ? 'https://www.mirantis.com/products/openstack-drivers-and-plugins/fuel-plugins/' : 'http://stackalytics.com/report/driverlog?project_id=openstack%2Ffuel',
|
||||
documentation: utils.composeDocumentationLink('plugin-dev.html')
|
||||
};
|
||||
var isMirantisIso = _.contains(app.version.get('feature_groups'), 'mirantis');
|
||||
var links = {
|
||||
catalog: isMirantisIso ? 'https://www.mirantis.com/products/openstack-drivers-and-plugins/fuel-plugins/' : 'http://stackalytics.com/report/driverlog?project_id=openstack%2Ffuel',
|
||||
documentation: utils.composeDocumentationLink('plugin-dev.html')
|
||||
};
|
||||
return (
|
||||
<div className='plugins-page'>
|
||||
<div className='page-title'>
|
||||
|
|
|
@ -47,8 +47,8 @@ var RootComponent = React.createClass({
|
|||
return this.refs.page;
|
||||
},
|
||||
updateTitle() {
|
||||
var Page = this.state.Page,
|
||||
title = _.isFunction(Page.title) ? Page.title(this.state.pageOptions) : Page.title;
|
||||
var Page = this.state.Page;
|
||||
var title = _.isFunction(Page.title) ? Page.title(this.state.pageOptions) : Page.title;
|
||||
document.title = i18n('common.title') + (title ? ' - ' + title : '');
|
||||
},
|
||||
componentDidUpdate() {
|
||||
|
|
|
@ -80,8 +80,8 @@ export default {
|
|||
this.saveSettings(currentAttributes).done(this.setConnected);
|
||||
},
|
||||
showResponseErrors(response) {
|
||||
var jsonObj,
|
||||
error = '';
|
||||
var jsonObj;
|
||||
var error = '';
|
||||
try {
|
||||
jsonObj = JSON.parse(response.responseText);
|
||||
error = jsonObj.message;
|
||||
|
@ -127,11 +127,11 @@ export default {
|
|||
return i18n(key + '_community');
|
||||
},
|
||||
renderInput(settingName, wrapperClassName, disabledState) {
|
||||
var model = this.props.statistics || this.props.tracking,
|
||||
setting = model.get(model.makePath('statistics', settingName));
|
||||
var model = this.props.statistics || this.props.tracking;
|
||||
var setting = model.get(model.makePath('statistics', settingName));
|
||||
if (this.checkRestrictions('metadata', 'hide').result || this.checkRestrictions(settingName, 'hide').result || setting.type == 'hidden') return null;
|
||||
var error = this.getError(model, settingName),
|
||||
disabled = this.checkRestrictions('metadata').result || this.checkRestrictions(settingName).result || disabledState;
|
||||
var error = this.getError(model, settingName);
|
||||
var disabled = this.checkRestrictions('metadata').result || this.checkRestrictions(settingName).result || disabledState;
|
||||
return <Input
|
||||
key={settingName}
|
||||
type={setting.type}
|
||||
|
@ -159,42 +159,42 @@ export default {
|
|||
);
|
||||
},
|
||||
renderIntro() {
|
||||
var ns = 'statistics.',
|
||||
isMirantisIso = _.contains(app.version.get('feature_groups'), 'mirantis'),
|
||||
lists = {
|
||||
actions: [
|
||||
'operation_type',
|
||||
'operation_time',
|
||||
'actual_time',
|
||||
'network_verification',
|
||||
'ostf_results'
|
||||
],
|
||||
settings: [
|
||||
'envronments_amount',
|
||||
'distribution',
|
||||
'network_type',
|
||||
'kernel_parameters',
|
||||
'admin_network_parameters',
|
||||
'pxe_parameters',
|
||||
'dns_parameters',
|
||||
'storage_options',
|
||||
'related_projects',
|
||||
'modified_settings',
|
||||
'networking_configuration'
|
||||
],
|
||||
node_settings: [
|
||||
'deployed_nodes_amount',
|
||||
'deployed_roles',
|
||||
'disk_layout',
|
||||
'interfaces_configuration'
|
||||
],
|
||||
system_info: [
|
||||
'hypervisor',
|
||||
'hardware_info',
|
||||
'fuel_version',
|
||||
'openstack_version'
|
||||
]
|
||||
};
|
||||
var ns = 'statistics.';
|
||||
var isMirantisIso = _.contains(app.version.get('feature_groups'), 'mirantis');
|
||||
var lists = {
|
||||
actions: [
|
||||
'operation_type',
|
||||
'operation_time',
|
||||
'actual_time',
|
||||
'network_verification',
|
||||
'ostf_results'
|
||||
],
|
||||
settings: [
|
||||
'envronments_amount',
|
||||
'distribution',
|
||||
'network_type',
|
||||
'kernel_parameters',
|
||||
'admin_network_parameters',
|
||||
'pxe_parameters',
|
||||
'dns_parameters',
|
||||
'storage_options',
|
||||
'related_projects',
|
||||
'modified_settings',
|
||||
'networking_configuration'
|
||||
],
|
||||
node_settings: [
|
||||
'deployed_nodes_amount',
|
||||
'deployed_roles',
|
||||
'disk_layout',
|
||||
'interfaces_configuration'
|
||||
],
|
||||
system_info: [
|
||||
'hypervisor',
|
||||
'hardware_info',
|
||||
'fuel_version',
|
||||
'openstack_version'
|
||||
]
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div className='statistics-text-box'>
|
||||
|
@ -221,8 +221,8 @@ export default {
|
|||
},
|
||||
clearRegistrationForm() {
|
||||
if (!this.state.isConnected) {
|
||||
var tracking = this.props.tracking,
|
||||
initialData = this.props.settings.get('tracking');
|
||||
var tracking = this.props.tracking;
|
||||
var initialData = this.props.settings.get('tracking');
|
||||
_.each(tracking.get('tracking'), (data, name) => {
|
||||
var path = tracking.makePath('tracking', name, 'value');
|
||||
tracking.set(path, initialData[name].value);
|
||||
|
@ -231,11 +231,11 @@ export default {
|
|||
}
|
||||
},
|
||||
renderRegistrationForm(model, disabled, error, showProgressBar) {
|
||||
var tracking = model.get('tracking'),
|
||||
sortedFields = _.chain(_.keys(tracking))
|
||||
.without('metadata')
|
||||
.sortBy((inputName) => tracking[inputName].weight)
|
||||
.value();
|
||||
var tracking = model.get('tracking');
|
||||
var sortedFields = _.chain(_.keys(tracking))
|
||||
.without('metadata')
|
||||
.sortBy((inputName) => tracking[inputName].weight)
|
||||
.value();
|
||||
return (
|
||||
<div>
|
||||
{error &&
|
||||
|
|
|
@ -32,8 +32,8 @@ var SupportPage = React.createClass({
|
|||
fetchData() {
|
||||
var tasks = new models.Tasks();
|
||||
return $.when(app.fuelSettings.fetch({cache: true}), tasks.fetch()).then(() => {
|
||||
var tracking = new models.FuelSettings(_.cloneDeep(app.fuelSettings.attributes)),
|
||||
statistics = new models.FuelSettings(_.cloneDeep(app.fuelSettings.attributes));
|
||||
var tracking = new models.FuelSettings(_.cloneDeep(app.fuelSettings.attributes));
|
||||
var statistics = new models.FuelSettings(_.cloneDeep(app.fuelSettings.attributes));
|
||||
return {
|
||||
tasks: tasks,
|
||||
settings: app.fuelSettings,
|
||||
|
@ -161,8 +161,8 @@ var StatisticsSettings = React.createClass({
|
|||
unsavedChangesMixin
|
||||
],
|
||||
hasChanges() {
|
||||
var initialData = this.props.settings.get('statistics'),
|
||||
currentData = this.props.statistics.get('statistics');
|
||||
var initialData = this.props.settings.get('statistics');
|
||||
var currentData = this.props.statistics.get('statistics');
|
||||
return _.any(this.props.statsCheckboxes, (field) => {
|
||||
return !_.isEqual(initialData[field].value, currentData[field].value);
|
||||
});
|
||||
|
@ -174,11 +174,11 @@ var StatisticsSettings = React.createClass({
|
|||
return this.isSavingPossible() ? this.prepareStatisticsToSave() : $.Deferred().resolve();
|
||||
},
|
||||
render() {
|
||||
var statistics = this.props.statistics.get('statistics'),
|
||||
sortedSettings = _.chain(_.keys(statistics))
|
||||
.without('metadata')
|
||||
.sortBy((settingName) => statistics[settingName].weight)
|
||||
.value();
|
||||
var statistics = this.props.statistics.get('statistics');
|
||||
var sortedSettings = _.chain(_.keys(statistics))
|
||||
.without('metadata')
|
||||
.sortBy((settingName) => statistics[settingName].weight)
|
||||
.value();
|
||||
return (
|
||||
<SupportPageElement
|
||||
className='img-statistics'
|
||||
|
@ -250,8 +250,8 @@ var DiagnosticSnapshot = React.createClass({
|
|||
this.startPolling();
|
||||
},
|
||||
render() {
|
||||
var task = this.props.task,
|
||||
generating = this.state.generating;
|
||||
var task = this.props.task;
|
||||
var generating = this.state.generating;
|
||||
return (
|
||||
<SupportPageElement
|
||||
className='img-download-logs'
|
||||
|
|
|
@ -39,8 +39,8 @@ var WelcomePage = React.createClass({
|
|||
},
|
||||
onStartButtonClick() {
|
||||
this.clearRegistrationForm();
|
||||
var statistics = this.props.tracking.get('statistics'),
|
||||
currentAttributes = _.cloneDeep(this.props.settings.attributes);
|
||||
var statistics = this.props.tracking.get('statistics');
|
||||
var currentAttributes = _.cloneDeep(this.props.settings.attributes);
|
||||
statistics.user_choice_saved.value = true;
|
||||
// locked state is similar to actionInProgress but
|
||||
// we want the page isn't unlocked after successful saving
|
||||
|
@ -56,18 +56,18 @@ var WelcomePage = React.createClass({
|
|||
});
|
||||
},
|
||||
render() {
|
||||
var ns = 'welcome_page.',
|
||||
featureGroups = app.version.get('feature_groups'),
|
||||
isMirantisIso = _.contains(featureGroups, 'mirantis'),
|
||||
statsCollectorLink = 'https://stats.fuel-infra.org/',
|
||||
privacyPolicyLink = 'https://www.mirantis.com/company/privacy-policy/',
|
||||
username = this.props.settings.get('statistics').name.value;
|
||||
var disabled = this.state.actionInProgress || this.state.locked,
|
||||
buttonProps = {
|
||||
disabled: disabled,
|
||||
onClick: this.onStartButtonClick,
|
||||
className: 'btn btn-lg btn-block btn-success'
|
||||
};
|
||||
var ns = 'welcome_page.';
|
||||
var featureGroups = app.version.get('feature_groups');
|
||||
var isMirantisIso = _.contains(featureGroups, 'mirantis');
|
||||
var statsCollectorLink = 'https://stats.fuel-infra.org/';
|
||||
var privacyPolicyLink = 'https://www.mirantis.com/company/privacy-policy/';
|
||||
var username = this.props.settings.get('statistics').name.value;
|
||||
var disabled = this.state.actionInProgress || this.state.locked;
|
||||
var buttonProps = {
|
||||
disabled: disabled,
|
||||
onClick: this.onStartButtonClick,
|
||||
className: 'btn btn-lg btn-block btn-success'
|
||||
};
|
||||
return (
|
||||
<div className='welcome-page tracking'>
|
||||
<div className='col-md-8 col-md-offset-2 col-xs-10 col-xs-offset-1'>
|
||||
|
|
|
@ -154,8 +154,8 @@ var ClusterWizardPanesMixin = {
|
|||
var isCompatible = true;
|
||||
var warnings = [];
|
||||
allComponents.each((testedComponent) => {
|
||||
var type = testedComponent.get('type'),
|
||||
isInStopList = _.find(stopList, (component) => component.id == testedComponent.id);
|
||||
var type = testedComponent.get('type');
|
||||
var isInStopList = _.find(stopList, (component) => component.id == testedComponent.id);
|
||||
if (component.id == testedComponent.id || !_.contains(types, type) || isInStopList) {
|
||||
// ignore self or forward compatibilities
|
||||
return;
|
||||
|
@ -180,8 +180,8 @@ var ClusterWizardPanesMixin = {
|
|||
var isDisabled = false;
|
||||
var warnings = [];
|
||||
_.each(incompatibles, (incompatible) => {
|
||||
var type = incompatible.component.get('type'),
|
||||
isInStopList = _.find(stopList, (component) => component.id == incompatible.component.id);
|
||||
var type = incompatible.component.get('type');
|
||||
var isInStopList = _.find(stopList, (component) => component.id == incompatible.component.id);
|
||||
if (!_.contains(types, type) || isInStopList) {
|
||||
// ignore forward incompatibilities
|
||||
return;
|
||||
|
@ -277,16 +277,16 @@ var NameAndRelease = React.createClass({
|
|||
return true;
|
||||
},
|
||||
render() {
|
||||
var releases = this.props.releases,
|
||||
name = this.props.wizard.get('name'),
|
||||
nameError = this.props.wizard.get('name_error'),
|
||||
release = this.props.wizard.get('release');
|
||||
var releases = this.props.releases;
|
||||
var name = this.props.wizard.get('name');
|
||||
var nameError = this.props.wizard.get('name_error');
|
||||
var release = this.props.wizard.get('release');
|
||||
|
||||
if (this.props.loading) {
|
||||
return null;
|
||||
}
|
||||
var os = release.get('operating_system'),
|
||||
connectivityAlert = i18n('dialog.create_cluster_wizard.name_release.' + os + '_connectivity_alert');
|
||||
var os = release.get('operating_system');
|
||||
var connectivityAlert = i18n('dialog.create_cluster_wizard.name_release.' + os + '_connectivity_alert');
|
||||
return (
|
||||
<div className='create-cluster-form name-and-release'>
|
||||
<Input
|
||||
|
@ -334,8 +334,8 @@ var Compute = React.createClass({
|
|||
vCenterPath: 'hypervisor:vmware',
|
||||
vCenterNetworkBackends: ['network:neutron:ml2:nsx', 'network:neutron:ml2:dvs'],
|
||||
hasErrors(wizard) {
|
||||
var allComponents = wizard.get('components'),
|
||||
components = allComponents.getComponentsByType(this.componentType, {sorted: true});
|
||||
var allComponents = wizard.get('components');
|
||||
var components = allComponents.getComponentsByType(this.componentType, {sorted: true});
|
||||
return !_.any(components, (component) => component.get('enabled'));
|
||||
}
|
||||
},
|
||||
|
@ -379,8 +379,8 @@ var Network = React.createClass({
|
|||
title: i18n('dialog.create_cluster_wizard.network.title'),
|
||||
ml2CorePath: 'network:neutron:core:ml2',
|
||||
hasErrors(wizard) {
|
||||
var allComponents = wizard.get('components'),
|
||||
components = allComponents.getComponentsByType(this.componentType, {sorted: true});
|
||||
var allComponents = wizard.get('components');
|
||||
var components = allComponents.getComponentsByType(this.componentType, {sorted: true});
|
||||
var ml2core = _.find(components, (component) => component.id == this.ml2CorePath);
|
||||
if (ml2core && ml2core.get('enabled')) {
|
||||
var ml2 = _.filter(components, (component) => component.isML2Driver());
|
||||
|
|
Loading…
Reference in New Issue