tripleo-ui/src/js/selectors/validations.js

205 lines
6.1 KiB
JavaScript

/**
* Copyright 2017 Red Hat Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
import { createSelector } from 'reselect';
import { getCurrentPlanName } from './plans';
import { getFilterByName } from './filters';
import MistralConstants from '../constants/MistralConstants';
const validations = state => state.validations.get('validations');
const executions = state => state.executions.get('executions');
const validationsToolbarFilter = state =>
getFilterByName(state, 'validationsToolbar');
/**
* Filter workflow executions only to validations and current plan
*/
export const getValidationExecutionsForCurrentPlan = createSelector(
[executions, getCurrentPlanName],
(executions, currentPlanName) => {
const mostRecentPlanUpdate = getMostRecentPlanUpdate(
executions,
currentPlanName
);
return executions.filter(
execution =>
execution.get('workflow_name') === MistralConstants.VALIDATIONS_RUN &&
execution.getIn(['input', 'plan']) === currentPlanName &&
execution.get('updated_at') > mostRecentPlanUpdate
);
}
);
/**
* Adds map of validation results to each validation
*/
export const getValidationsWithResults = createSelector(
[validations, getValidationExecutionsForCurrentPlan],
(validations, results) =>
validations.map(validation => {
const validationResults = getValidationResults(validation.id, results);
return validation
.set('results', validationResults)
.set('status', getValidationStatus(validationResults));
})
);
/**
* Filter validations using the active Toolbar filters.
* Only include validations younger than the most recent update to a plan.
*/
export const getFilteredValidations = createSelector(
[getValidationsWithResults, validationsToolbarFilter],
(validations, validationsToolbarFilter) => {
const activeFilters = validationsToolbarFilter.get('activeFilters');
return activeFilters
.reduce(
(filteredValidations, filter) =>
filteredValidations.filter(validation => {
switch (filter.filterBy) {
case 'name':
return validation.name
.toLowerCase()
.includes(filter.filterString.toLowerCase());
case 'group': {
return validation.groups.reduce(
(result, group) =>
result
? result
: group
.toLowerCase()
.includes(filter.filterString.toLowerCase()),
false
);
}
default:
return false;
}
}),
validations
)
.sortBy(validation =>
validation.getIn(validationsToolbarFilter.get('sortBy').split('.'))
)
.update(
validations =>
validationsToolbarFilter.get('sortDir') === 'desc'
? validations.reverse()
: validations
);
}
);
export const getValidationStatusCounts = createSelector(
[getValidationsWithResults],
validations => validations.countBy(v => v.status).sortBy((v, k) => k)
);
/**
* Helper function to get the most recent time a plan has been updated or
* created.
*/
export const getMostRecentPlanUpdate = (executions, planName) =>
executions
.filter(
execution =>
[MistralConstants.PLAN_UPDATE, MistralConstants.PLAN_CREATE].includes(
execution.workflow_name
) && execution.getIn(['input', 'container']) === planName
)
.map(execution => execution.get('updated_at'))
.sort()
.last() || 0;
/**
* Helper function to get a validation results by validation name
*/
const getValidationResults = (validationId, results) =>
results.filter(
result => result.getIn(['input', 'validation_name']) === validationId
);
/**
* Helper function to determine validation status based on validation's results
*/
const getValidationStatus = validationResults => {
switch (true) {
case validationResults.isEmpty():
return 'new';
case validationResults.last().state === 'RUNNING':
return 'running';
case validationResults.last().output.get('status') === 'SUCCESS':
if (
validationResults
.last()
.output.get('stdout', '')
.includes('Warnings:')
) {
return 'warning';
}
return 'success';
case validationResults.last().output.get('status') === 'FAILED':
return 'failed';
case validationResults.last().state === 'PAUSED':
return 'paused';
default:
return 'error';
}
};
/**
* Selects pre deployment validations
*/
export const getPreDeploymentValidationsWithResults = createSelector(
getValidationsWithResults,
validations => {
const preDeploymentValidationGroups = [
'pre-deployment',
'pre',
'pre-introspection'
];
return validations.filter(
validation =>
!validation.groups
.toSet()
.intersect(preDeploymentValidationGroups)
.isEmpty()
);
}
);
/**
* Provides aggregate counts of pre-deployment validations by their status
*/
export const getPreDeploymentValidationsStatusCounts = createSelector(
getPreDeploymentValidationsWithResults,
validations => validations.countBy(validation => validation.status)
);
/**
* Provides aggregate counts of pre-deployment validations by their status
*/
export const allPreDeploymentValidationsSuccessful = createSelector(
getPreDeploymentValidationsStatusCounts,
counts =>
counts
.keySeq()
.toSet()
.intersect(['new', 'running', 'failed', 'paused', 'error'])
.isEmpty()
);