ui/app/authenticated/cluster/cis/scan/detail/controller.js

186 lines
4.8 KiB
JavaScript

import Controller from '@ember/controller';
import { computed, get, set } from '@ember/object';
import { inject as service } from '@ember/service';
export default Controller.extend({
modalService: service('modal'),
router: service(),
scope: service(),
growl: service(),
intl: service(),
securityScanConfig: service(),
cisHelpers: service(),
tableHeaders: [
{
name: 'collapse',
width: 40,
},
{
name: 'state',
sort: ['sortableState', 'sortableId'],
translationKey: 'cis.scan.detail.table.state',
width: 100,
},
{
name: 'id',
sort: ['sortableId'],
translationKey: 'cis.scan.detail.table.number',
width: 100,
},
{
name: 'description',
sort: ['description', 'sortableId'],
translationKey: 'cis.scan.detail.table.description',
}
],
sortBy: 'state',
runningClusterScans: computed.filterBy('clusterScans', 'isRunning', true),
actions: {
async runScan() {
get(this, 'scope.currentCluster').send('runCISScan', { onRun: () => get(this, 'router').replaceWith('authenticated.cluster.cis/scan') });
},
download() {
get(this, 'model.scan').send('download');
},
async delete() {
await get(this, 'modalService').toggleModal('confirm-delete', {
escToClose: true,
resources: [get(this, 'model.scan')],
onDeleteFinished: () => get(this, 'router').replaceWith('authenticated.cluster.cis/scan')
});
},
clearSearchText() {
set(this, 'searchText', '');
}
},
tests: computed('model.nodes', 'model.scan.report.results', 'securityScanConfig.skipList', function() {
const results = get(this, 'model.scan.report.results');
if (!results) {
return [];
}
const tests = results.reduce((agg, result) => [...agg, ...result.checks], []);
return tests.map((test) => {
const state = this.getCheckState(test);
const nodeNames = get(this, 'model.scan').getNodeNamesFromNodeType(test.node_type);
const checkNodes = test.nodes || [];
const nodes = nodeNames.map((nodeName) => {
const node = get(this, 'model.nodes').findBy('nodeName', nodeName);
const nodeId = node ? node.id : null;
return {
state: this.getNodeState(test, nodeName, checkNodes),
nodeId,
name: nodeName
};
});
return {
state,
sortableState: this.getSortableState(state),
id: test.id,
sortableId: this.cisHelpers.createSortableId(test.id),
description: test.description,
remediation: state === 'Fail' ? test.remediation : null,
nodes,
toggleSkip: () => {
this.toggleSkip(test.id)
},
skipList: get(this, 'securityScanConfig.skipList'),
_availableActions: []
};
});
}),
clusterScans: computed('model.clusterScans.[]', 'scope.currentCluster.id', function() {
return get(this, 'model.clusterScans').filterBy('clusterId', get(this, 'scope.currentCluster.id'));
}),
toggleSkip(testId) {
this.securityScanConfig.validateSecurityScanConfig();
const isSkipped = get(this, 'securityScanConfig.skipList').indexOf(testId) !== -1;
const fn = isSkipped ? this.unskip : this.skip;
fn.call(this, testId);
},
skip(testId) {
const newSkipList = [...get(this, 'securityScanConfig.skipList'), testId];
this.securityScanConfig.editSkipList(newSkipList);
},
unskip(testId) {
const newSkipList = get(this, 'securityScanConfig.skipList').filter((skippedTestId) => skippedTestId !== testId);
this.securityScanConfig.editSkipList(newSkipList);
},
getCheckState(check) {
switch (check.state) {
case 'pass':
return 'Pass';
case 'skip':
return 'Skipped';
case 'notApplicable':
return 'N/A';
default:
return 'Fail';
}
},
getSortableState(state) {
if (state === 'Fail') {
return 0;
}
if (state === 'Skipped') {
return 1;
}
if (state === 'Pass') {
return 2;
}
return 3;
},
/**
* Per the API.
* When check state is pass Pass.
* When check state is fail Fail.
* When check state is skip Skip.
* When check state is mixed fail if nodeName is in checkNodes otherwise pass
*/
getNodeState(check, nodeName, checkNodes) {
if (check.state === 'pass') {
return 'Pass';
}
if (check.state === 'fail') {
return 'Fail';
}
if (check.state === 'skip') {
return 'Skipped';
}
if (check.state === 'notApplicable') {
return 'N/A';
}
return checkNodes.includes(nodeName)
? 'Fail'
: 'Pass';
}
});