From 3fb931ee46736a824ec98067a0885d3813802356 Mon Sep 17 00:00:00 2001 From: Cody Jackson Date: Thu, 19 Dec 2019 10:44:13 -0700 Subject: [PATCH] Update the downloaded report The downloaded report now has: - A column for passed_nodes - A column for failed_nodes - A column for all nodes the test ran against - The benchmark version in the header rancher/rancher#24671 --- .../cluster/cis/scan/detail/controller.js | 10 +-- app/models/clusterscan.js | 65 +++++++++++++++---- lib/shared/addon/utils/util.js | 10 +++ lib/shared/app/utils/util.js | 1 + 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/app/authenticated/cluster/cis/scan/detail/controller.js b/app/authenticated/cluster/cis/scan/detail/controller.js index 2d331ec1c..be3b874ba 100644 --- a/app/authenticated/cluster/cis/scan/detail/controller.js +++ b/app/authenticated/cluster/cis/scan/detail/controller.js @@ -74,15 +74,9 @@ export default Controller.extend({ return tests.map((test) => { const state = this.getCheckState(test); - const nodeTypes = test.node_type; - - const nodeNames = nodeTypes.reduce((agg, nodeType) => [...agg, ...get(this, `model.scan.report.nodes.${ nodeType }`)], []); - const uniqueNodeNames = Object.keys(nodeNames.reduce((agg, nodeName) => ({ - ...agg, - [nodeName]: true - }), {})); + const nodeNames = get(this, 'model.scan').getNodeNamesFromNodeType(test.node_type); const checkNodes = test.nodes || []; - const nodes = uniqueNodeNames.map((nodeName) => ({ + const nodes = nodeNames.map((nodeName) => ({ state: this.getNodeState(test, nodeName, checkNodes), nodeId: get(this, 'model.nodes').findBy('nodeName', nodeName).id, name: nodeName diff --git a/app/models/clusterscan.js b/app/models/clusterscan.js index f28d10b16..60be9c0f7 100644 --- a/app/models/clusterscan.js +++ b/app/models/clusterscan.js @@ -3,6 +3,7 @@ import { computed, get, set, observer } from '@ember/object'; import moment from 'moment'; import { downloadFile } from 'shared/utils/download-files'; import ObjectsToCsv from 'objects-to-csv'; +import { extractUniqueStrings } from '../utils/util'; const ClusterScan = Resource.extend({ type: 'clusterScan', @@ -49,25 +50,23 @@ const ClusterScan = Resource.extend({ }), referencedResults: computed('report', function() { - const results = (get(this, 'report.results') || []) + return (get(this, 'report.results') || []) .map((result) => result.checks) .reduce((agg, check) => [...agg, ...(check || [])], []); - const nodes = get(this, 'report.nodes') || {}; - - return results.map((result) => { - return { - ...result, - nodes: this.getNodes(nodes, result.node_type) - }; - }); }), - resultsForCsv: computed('referencedResults', function() { + resultsForCsv: computed('referencedResults', 'report', function() { return get(this, 'referencedResults').map((result) => { + const nodesAndStateForTest = this.getNodesAndStateForTestResult(result); + const version = `Version: ${ get(this, 'report.version') }`; + return { + [version]: '', ...result, - nodes: result.nodes.join(','), - node_type: result.node_type.join(',') + nodes: nodesAndStateForTest.nodes.join(','), + passed_nodes: nodesAndStateForTest.passedNodes.join(','), + failed_nodes: nodesAndStateForTest.failedNodes.join(','), + node_type: result.node_type.join(',') }; }) }), @@ -114,6 +113,48 @@ const ClusterScan = Resource.extend({ return nodeTypes.reduce((agg, nodeType) => [...agg, ...nodes[nodeType]], []); }, + getNodeNamesFromNodeType(nodeType) { + const nodeNames = nodeType + .reduce((agg, nodeType) => [...agg, ...get(this, `report.nodes.${ nodeType }`)], []); + + return extractUniqueStrings(nodeNames); + }, + + getNodesAndStateForTestResult(testResult) { + if (testResult.state === 'skip') { + return { + nodes: [], + passedNodes: [], + failedNodes: [] + } + } + + const nodeNames = this.getNodeNamesFromNodeType(testResult.node_type); + + if (testResult.state === 'pass') { + return { + nodes: nodeNames, + passedNodes: nodeNames, + failedNodes: [] + } + } + + if (testResult.state === 'fail') { + return { + nodes: nodeNames, + passedNodes: [], + failedNodes: nodeNames + } + } + + // if mixed + return { + nodes: nodeNames, + passedNodes: nodeNames.filter((node) => !testResult.nodes.includes(node)), + failedNodes: testResult.nodes + } + }, + async _loadReport() { try { const report = await this.followLink('report'); diff --git a/lib/shared/addon/utils/util.js b/lib/shared/addon/utils/util.js index b31f289e1..b08918996 100644 --- a/lib/shared/addon/utils/util.js +++ b/lib/shared/addon/utils/util.js @@ -556,6 +556,15 @@ export function parseCamelcase(str = '') { return ucFirst(str).replace(/([A-Z]+)*([A-Z][a-z])/g, '$1 $2') } +export function extractUniqueStrings(strings) { + const index = strings.reduce((agg, s) => ({ + ...agg, + [s]: true + }), {}); + + return Object.keys(index); +} + var Util = { absoluteUrl, addAuthorization, @@ -601,6 +610,7 @@ var Util = { validateEndpoint, requiredError, parseCamelcase, + extractUniqueStrings, }; window.Util = Util; diff --git a/lib/shared/app/utils/util.js b/lib/shared/app/utils/util.js index c9e3a4f24..098fb98e8 100644 --- a/lib/shared/app/utils/util.js +++ b/lib/shared/app/utils/util.js @@ -31,4 +31,5 @@ export { isNumeric, requiredError, parseCamelcase, + extractUniqueStrings, } from 'shared/utils/util';