Cleanup Nodes selectors
* unify and simplify selectors which work with node capabilities * replace non selector getAssingedNodes with getAvailableNodesByRole selector * fix available nodes selector, to filter on registeredNodes as deployed and maintenance nodes are not considered available for deployment Closes-Bug: #1637131 Change-Id: Ib057129dd5f813801ee58a0f64218c7ed9ecf5c6
This commit is contained in:
parent
0237a8ae83
commit
da08626267
|
@ -0,0 +1,5 @@
|
|||
fixes:
|
||||
- |
|
||||
Fixes `bug 1637131 <https://bugs.launchpad.net/tripleo/+bug/1637131>`__
|
||||
Available Nodes are now based on registeredNodes as Deployed
|
||||
and Maintenance Nodes are not considered available for deployment
|
|
@ -7,7 +7,7 @@ import { getAllPlansButCurrent } from '../../selectors/plans';
|
|||
import { getCurrentStack,
|
||||
getCurrentStackDeploymentProgress,
|
||||
getCurrentStackDeploymentInProgress } from '../../selectors/stacks';
|
||||
import { getAvailableNodes, getUnassignedAvailableNodes } from '../../selectors/nodes';
|
||||
import { getAvailableNodesByRole, getUnassignedAvailableNodes } from '../../selectors/nodes';
|
||||
import { getEnvironmentConfigurationSummary } from '../../selectors/environmentConfiguration';
|
||||
import { getCurrentPlan } from '../../selectors/plans';
|
||||
import { getRoles } from '../../selectors/roles';
|
||||
|
@ -126,7 +126,7 @@ class DeploymentPlan extends React.Component {
|
|||
</DeploymentPlanStep>
|
||||
<DeploymentPlanStep title={formatMessage(messages.configureRolesStepHeader)}
|
||||
disabled={this.props.currentStackDeploymentInProgress}>
|
||||
<RolesStep availableNodes={this.props.availableNodes}
|
||||
<RolesStep availableNodesByRole={this.props.availableNodesByRole}
|
||||
fetchNodes={this.props.fetchNodes}
|
||||
fetchRoles={this.props.fetchRoles.bind(this, currentPlanName)}
|
||||
isFetchingNodes={this.props.isFetchingNodes}
|
||||
|
@ -163,7 +163,7 @@ class DeploymentPlan extends React.Component {
|
|||
}
|
||||
|
||||
DeploymentPlan.propTypes = {
|
||||
availableNodes: ImmutablePropTypes.map,
|
||||
availableNodesByRole: ImmutablePropTypes.map,
|
||||
children: React.PropTypes.node,
|
||||
choosePlan: React.PropTypes.func,
|
||||
currentPlan: ImmutablePropTypes.record,
|
||||
|
@ -215,7 +215,7 @@ export function mapStateToProps(state) {
|
|||
isRequestingStackDelete: state.stacks.get('isRequestingStackDelete'),
|
||||
hasPlans: !state.plans.get('all').isEmpty(),
|
||||
inactivePlans: getAllPlansButCurrent(state),
|
||||
availableNodes: getAvailableNodes(state),
|
||||
availableNodesByRole: getAvailableNodesByRole(state),
|
||||
roles: getRoles(state),
|
||||
rolesLoaded: state.roles.get('loaded'),
|
||||
stacksLoaded: state.stacks.get('isLoaded'),
|
||||
|
|
|
@ -7,10 +7,9 @@ import { Link } from 'react-router';
|
|||
import React from 'react';
|
||||
import { List, Map } from 'immutable';
|
||||
|
||||
import { getAvailableNodes,
|
||||
import { getAvailableNodesByRole,
|
||||
getUnassignedAvailableNodes,
|
||||
getNodesOperationInProgress,
|
||||
getAssignedNodes } from '../../selectors/nodes';
|
||||
getNodesOperationInProgress } from '../../selectors/nodes';
|
||||
import { getRoles } from '../../selectors/roles';
|
||||
import { getCurrentPlan } from '../../selectors/plans';
|
||||
import FormErrorList from '../ui/forms/FormErrorList';
|
||||
|
@ -84,7 +83,7 @@ class NodesAssignment extends React.Component {
|
|||
const role = this.props.roles.get(roleIdentifier);
|
||||
const roleName = role ? role.title : roleIdentifier;
|
||||
const nodesToAssign = this.props.unassignedAvailableNodes
|
||||
.merge(getAssignedNodes(this.props.availableNodes, roleIdentifier))
|
||||
.merge(this.props.availableNodesByRole.get(roleIdentifier))
|
||||
.sortBy(node => node.get('uuid'));
|
||||
|
||||
return (
|
||||
|
@ -126,7 +125,7 @@ class NodesAssignment extends React.Component {
|
|||
}
|
||||
NodesAssignment.propTypes = {
|
||||
assignNodes: React.PropTypes.func.isRequired,
|
||||
availableNodes: ImmutablePropTypes.map,
|
||||
availableNodesByRole: ImmutablePropTypes.map,
|
||||
currentPlan: ImmutablePropTypes.record,
|
||||
fetchNodes: React.PropTypes.func.isRequired,
|
||||
formErrors: ImmutablePropTypes.list.isRequired,
|
||||
|
@ -145,7 +144,7 @@ NodesAssignment.defaultProps = {
|
|||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
availableNodes: getAvailableNodes(state),
|
||||
availableNodesByRole: getAvailableNodesByRole(state),
|
||||
currentPlan: getCurrentPlan(state),
|
||||
isFetchingNodes: state.nodes.get('isFetching'),
|
||||
nodesInProgress: state.nodes.get('nodesInProgress'),
|
||||
|
|
|
@ -2,7 +2,6 @@ import { defineMessages, injectIntl } from 'react-intl';
|
|||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import React from 'react';
|
||||
|
||||
import { getAssignedNodes } from '../../selectors/nodes';
|
||||
import Loader from '../ui/Loader';
|
||||
import RoleCard from './RoleCard';
|
||||
|
||||
|
@ -26,12 +25,6 @@ class Roles extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
getAssignedNodes(availableNodes, roleName) {
|
||||
return availableNodes.filter(
|
||||
node => node.getIn(['properties', 'capabilities']).includes(`profile:${roleName}`)
|
||||
);
|
||||
}
|
||||
|
||||
renderRoleCards() {
|
||||
return this.props.roles.map(role => {
|
||||
return (
|
||||
|
@ -40,8 +33,7 @@ class Roles extends React.Component {
|
|||
title={role.title}
|
||||
identifier={role.identifier}
|
||||
fetchNodes={this.props.fetchNodes}
|
||||
assignedNodesCount={getAssignedNodes(this.props.availableNodes,
|
||||
role.identifier).size}
|
||||
assignedNodesCount={this.props.availableNodesByRole.get(role.identifier).size}
|
||||
availableNodesCount={this.props.unassignedAvailableNodes.size}/>
|
||||
</div>
|
||||
);
|
||||
|
@ -65,7 +57,7 @@ class Roles extends React.Component {
|
|||
}
|
||||
}
|
||||
Roles.propTypes = {
|
||||
availableNodes: ImmutablePropTypes.map,
|
||||
availableNodesByRole: ImmutablePropTypes.map,
|
||||
fetchNodes: React.PropTypes.func.isRequired,
|
||||
fetchRoles: React.PropTypes.func.isRequired,
|
||||
intl: React.PropTypes.object,
|
||||
|
|
|
@ -17,14 +17,14 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const RolesStep = ({ isFetchingNodes,
|
||||
availableNodes,
|
||||
unassignedAvailableNodes,
|
||||
roles,
|
||||
fetchRoles,
|
||||
fetchNodes,
|
||||
intl,
|
||||
isFetchingRoles,
|
||||
rolesLoaded }) => {
|
||||
availableNodesByRole,
|
||||
unassignedAvailableNodes,
|
||||
roles,
|
||||
fetchRoles,
|
||||
fetchNodes,
|
||||
intl,
|
||||
isFetchingRoles,
|
||||
rolesLoaded }) => {
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
|
@ -38,7 +38,7 @@ const RolesStep = ({ isFetchingNodes,
|
|||
</Loader>
|
||||
</p>
|
||||
<Roles roles={roles.toList().toJS()}
|
||||
availableNodes={availableNodes}
|
||||
availableNodesByRole={availableNodesByRole}
|
||||
unassignedAvailableNodes={unassignedAvailableNodes}
|
||||
fetchRoles={fetchRoles}
|
||||
fetchNodes={fetchNodes}
|
||||
|
@ -49,7 +49,7 @@ const RolesStep = ({ isFetchingNodes,
|
|||
);
|
||||
};
|
||||
RolesStep.propTypes = {
|
||||
availableNodes: ImmutablePropTypes.map.isRequired,
|
||||
availableNodesByRole: ImmutablePropTypes.map.isRequired,
|
||||
fetchNodes: React.PropTypes.func.isRequired,
|
||||
fetchRoles: React.PropTypes.func.isRequired,
|
||||
intl: React.PropTypes.object,
|
||||
|
|
|
@ -24,10 +24,8 @@ export const getNodesWithMacs = createSelector(
|
|||
);
|
||||
|
||||
export const getRegisteredNodes = createSelector(
|
||||
getNodesWithMacs, (nodes) => {
|
||||
return nodes.filterNot( node => node.get('provision_state') === 'active' ||
|
||||
node.get('maintenance') );
|
||||
}
|
||||
getNodesWithMacs, (nodes) =>
|
||||
nodes.filterNot(node => node.get('provision_state') === 'active' || node.get('maintenance'))
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -35,7 +33,7 @@ export const getRegisteredNodes = createSelector(
|
|||
*/
|
||||
export const getProfilesList = createSelector(
|
||||
getNodes, nodes => nodes.reduce((profiles, v, k) => {
|
||||
const profile = parseNodeCapabilities(v.getIn(['properties', 'capabilities'])).profile;
|
||||
const profile = _getNodeCapabilities(v).profile;
|
||||
return profile ? profiles.push(profile) : profiles;
|
||||
}, List()).sort()
|
||||
);
|
||||
|
@ -49,44 +47,36 @@ export const getAvailableNodeProfiles = createSelector(
|
|||
);
|
||||
|
||||
export const getAvailableNodes = createSelector(
|
||||
getNodesWithMacs, (nodes) => nodes.filter(node => node.get('provision_state') === 'available')
|
||||
getRegisteredNodes, (nodes) => nodes.filter(node => node.get('provision_state') === 'available')
|
||||
);
|
||||
|
||||
export const getAvailableNodesByRole = createSelector(
|
||||
[getAvailableNodes, getRoles], (nodes, roles) =>
|
||||
roles.map(role => nodes.filter(node => _getNodeCapabilities(node).profile === role.identifier))
|
||||
);
|
||||
|
||||
export const getDeployedNodes = createSelector(
|
||||
getNodesWithMacs, (nodes) => {
|
||||
return nodes.filter( node => node.get('provision_state') === 'active' );
|
||||
}
|
||||
getNodesWithMacs, (nodes) =>
|
||||
nodes.filter( node => node.get('provision_state') === 'active' )
|
||||
);
|
||||
|
||||
export const getMaintenanceNodes = createSelector(
|
||||
getNodesWithMacs, (nodes) => {
|
||||
return nodes.filter( node => node.get('maintenance') );
|
||||
}
|
||||
getNodesWithMacs, (nodes) =>
|
||||
nodes.filter(node => node.get('maintenance'))
|
||||
);
|
||||
|
||||
export const getUnassignedAvailableNodes = createSelector(
|
||||
getAvailableNodes, (availableNodes) => {
|
||||
return availableNodes.filterNot(
|
||||
node => node.getIn(['properties', 'capabilities'], '').match(/.*profile:([\w\-]+)/)
|
||||
);
|
||||
}
|
||||
getAvailableNodes, (availableNodes) =>
|
||||
availableNodes.filterNot(node => _getNodeCapabilities(node).profile)
|
||||
);
|
||||
|
||||
/*
|
||||
* booleam, returns true if there are any nodes with operation in progress
|
||||
*/
|
||||
export const getNodesOperationInProgress = createSelector(
|
||||
nodesInProgress, (nodesInProgress) => {
|
||||
return !nodesInProgress.isEmpty();
|
||||
}
|
||||
nodesInProgress, (nodesInProgress) => !nodesInProgress.isEmpty()
|
||||
);
|
||||
|
||||
export const getAssignedNodes = (availableNodes, roleIdentifier) => {
|
||||
return availableNodes.filter(
|
||||
node => node.getIn(['properties', 'capabilities'], '').includes(`profile:${roleIdentifier}`)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to convert list of port uuids into map of actual ports
|
||||
* @param ports - Map of ports to filter on
|
||||
|
@ -94,3 +84,11 @@ export const getAssignedNodes = (availableNodes, roleIdentifier) => {
|
|||
*/
|
||||
const filterPorts = (ports) =>
|
||||
portUUIDs => ports.filter((p, k) => portUUIDs.includes(k));
|
||||
|
||||
/**
|
||||
* Helper function to get node capabilities object
|
||||
* @param node
|
||||
* @returns capabilities object
|
||||
*/
|
||||
const _getNodeCapabilities = (node) =>
|
||||
parseNodeCapabilities(node.getIn(['properties', 'capabilities'], ''));
|
||||
|
|
Loading…
Reference in New Issue