From c857404f74761c080de47ab129f3ddeff2eca14d Mon Sep 17 00:00:00 2001 From: Mike Burgess Date: Wed, 28 Feb 2024 20:16:01 +0000 Subject: [PATCH] Rename tag -> control_tag in benchmark filtering --- .../DashboardTagGroupSelect/index.tsx | 2 +- .../components/SaveSnapshotButton/index.tsx | 8 +++++- .../check/CheckFilterEditor/index.test.ts | 6 ++--- .../check/CheckFilterEditor/index.tsx | 6 ++--- .../check/CheckGroupingConfig/index.tsx | 4 +-- .../check/CheckGroupingEditor/index.tsx | 8 +++--- .../dashboards/check/common/index.ts | 6 ++--- ui/dashboard/src/hooks/useCheckGrouping.tsx | 26 +++++++++++-------- .../src/hooks/useCheckGroupingConfig.ts | 8 +++--- ui/dashboard/src/hooks/useDashboard.tsx | 2 +- ui/dashboard/src/utils/snapshot.test.ts | 8 +++--- ui/dashboard/src/utils/snapshot.ts | 5 +++- 12 files changed, 52 insertions(+), 37 deletions(-) diff --git a/ui/dashboard/src/components/DashboardTagGroupSelect/index.tsx b/ui/dashboard/src/components/DashboardTagGroupSelect/index.tsx index 5e142442..80428e69 100644 --- a/ui/dashboard/src/components/DashboardTagGroupSelect/index.tsx +++ b/ui/dashboard/src/components/DashboardTagGroupSelect/index.tsx @@ -86,7 +86,7 @@ const DashboardTagGroupSelect = () => { {/*@ts-ignore*/} - Group by: + Group by: {value.label} diff --git a/ui/dashboard/src/components/SaveSnapshotButton/index.tsx b/ui/dashboard/src/components/SaveSnapshotButton/index.tsx index aa555863..da8356ff 100644 --- a/ui/dashboard/src/components/SaveSnapshotButton/index.tsx +++ b/ui/dashboard/src/components/SaveSnapshotButton/index.tsx @@ -14,6 +14,7 @@ import { import { saveAs } from "file-saver"; import { timestampForFilename } from "@powerpipe/utils/date"; import { useDashboard } from "@powerpipe/hooks/useDashboard"; +import { validateFilter } from "@powerpipe/components/dashboards/check/CheckFilterEditor"; const SaveSnapshotButton = () => { const { dashboard, dataMode, selectedDashboard, snapshot } = useDashboard(); @@ -33,7 +34,12 @@ const SaveSnapshotButton = () => { const metadata: DashboardSnapshotMetadata = { view: {}, }; - if (!!filterConfig) { + // If a benchmark + if ( + dashboard.artificial && + !!filterConfig && + validateFilter(filterConfig) + ) { // @ts-ignore metadata.view.filter_by = filterToSnapshotMetadata(filterConfig); } diff --git a/ui/dashboard/src/components/dashboards/check/CheckFilterEditor/index.test.ts b/ui/dashboard/src/components/dashboards/check/CheckFilterEditor/index.test.ts index 09385dea..c386a6b9 100644 --- a/ui/dashboard/src/components/dashboards/check/CheckFilterEditor/index.test.ts +++ b/ui/dashboard/src/components/dashboards/check/CheckFilterEditor/index.test.ts @@ -14,7 +14,7 @@ const filterTestCases: TestCase[] = [ }, { name: "valid filter with type and value", - input: { operator: "equal", type: "tag", value: "production" }, + input: { operator: "equal", type: "control_tag", value: "production" }, expected: true, }, { @@ -40,7 +40,7 @@ const filterTestCases: TestCase[] = [ { operator: "equal", type: "resource", value: "*mybucket*" }, { operator: "equal", - type: "tag", + type: "control_tag", key: "environment", value: "production", }, @@ -64,7 +64,7 @@ const filterTestCases: TestCase[] = [ // input: { // or: [ // { type: "resource", value: "*mybucket*" }, -// { type: "tag", key: "environment", value: "production" }, +// { type: "control_tag", key: "environment", value: "production" }, // ], // }, // expected: true, diff --git a/ui/dashboard/src/components/dashboards/check/CheckFilterEditor/index.tsx b/ui/dashboard/src/components/dashboards/check/CheckFilterEditor/index.tsx index e3c6ef97..f88ebb29 100644 --- a/ui/dashboard/src/components/dashboards/check/CheckFilterEditor/index.tsx +++ b/ui/dashboard/src/components/dashboards/check/CheckFilterEditor/index.tsx @@ -104,18 +104,18 @@ const CheckFilterTypeSelect = ({ const allTypes: SelectOption[] = [ { value: "benchmark", label: "Benchmark" }, { value: "control", label: "Control" }, + { value: "control_tag", label: "Control Tag" }, { value: "dimension", label: "Dimension" }, { value: "reason", label: "Reason" }, { value: "resource", label: "Resource" }, { value: "severity", label: "Severity" }, { value: "status", label: "Status" }, - { value: "tag", label: "Tag" }, ]; return allTypes.filter( (t) => t.value === type || t.value === "dimension" || - t.value === "tag" || + t.value === "control_tag" || // @ts-ignore !existingTypes.includes(t.value), ); @@ -337,7 +337,7 @@ const CheckFilterEditorItem = ({ update={update} /> - {(item.type === "dimension" || item.type === "tag") && ( + {(item.type === "dimension" || item.type === "control_tag") && ( <> =
diff --git a/ui/dashboard/src/components/dashboards/check/CheckGroupingConfig/index.tsx b/ui/dashboard/src/components/dashboards/check/CheckGroupingConfig/index.tsx index 06a39b79..800a6cde 100644 --- a/ui/dashboard/src/components/dashboards/check/CheckGroupingConfig/index.tsx +++ b/ui/dashboard/src/components/dashboards/check/CheckGroupingConfig/index.tsx @@ -14,8 +14,8 @@ type CheckGroupingTitleLabelProps = { const CheckGroupingTitleLabel = ({ item }: CheckGroupingTitleLabelProps) => { switch (item.type) { + case "control_tag": case "dimension": - case "tag": return (
{item.type} @@ -46,7 +46,7 @@ const CheckGroupingConfig = ({ onClose }: CheckGroupingConfigProps) => { "grouping", toSave .map((c) => - c.type === "dimension" || c.type === "tag" + c.type === "dimension" || c.type === "control_tag" ? `${c.type}|${c.value}` : c.type, ) diff --git a/ui/dashboard/src/components/dashboards/check/CheckGroupingEditor/index.tsx b/ui/dashboard/src/components/dashboards/check/CheckGroupingEditor/index.tsx index 732b2e56..4c46f0c9 100644 --- a/ui/dashboard/src/components/dashboards/check/CheckGroupingEditor/index.tsx +++ b/ui/dashboard/src/components/dashboards/check/CheckGroupingEditor/index.tsx @@ -73,13 +73,13 @@ const CheckGroupingTypeSelect = ({ { value: "result", label: "Result" }, { value: "severity", label: "Severity" }, { value: "status", label: "Status" }, - { value: "tag", label: "Tag" }, + { value: "control_tag", label: "Control Tag" }, ]; return allTypes.filter( (t) => t.value === type || t.value === "dimension" || - t.value === "tag" || + t.value === "control_tag" || // @ts-ignore !existingTypes.includes(t.value), ); @@ -192,7 +192,7 @@ const CheckGroupingEditorItem = ({ update={update} />
- {(item.type === "dimension" || item.type === "tag") && ( + {(item.type === "dimension" || item.type === "control_tag") && ( <> =
@@ -246,7 +246,7 @@ const CheckGroupingEditor = ({ config, onApply }: CheckGroupingEditorProps) => { case "status": return !c.value; case "dimension": - case "tag": + case "control_tag": return !!c.value; case "result": return true; diff --git a/ui/dashboard/src/components/dashboards/check/common/index.ts b/ui/dashboard/src/components/dashboards/check/common/index.ts index 7f14410c..89fb5afb 100644 --- a/ui/dashboard/src/components/dashboards/check/common/index.ts +++ b/ui/dashboard/src/components/dashboards/check/common/index.ts @@ -9,6 +9,7 @@ import { DashboardRunState } from "@powerpipe/types"; export type CheckNodeType = | "benchmark" | "control" + | "control_tag" | "dimension" | "empty_result" | "error" @@ -18,8 +19,7 @@ export type CheckNodeType = | "running" | "root" | "severity" - | "status" - | "tag"; + | "status"; export type CheckNode = { sort: string; @@ -117,8 +117,8 @@ export type CheckControlRun = { export type CheckDisplayGroupType = | "benchmark" | "control" + | "control_tag" | "result" - | "tag" | "dimension" | "reason" | "resource" diff --git a/ui/dashboard/src/hooks/useCheckGrouping.tsx b/ui/dashboard/src/hooks/useCheckGrouping.tsx index 4c474f1d..5a1fcb68 100644 --- a/ui/dashboard/src/hooks/useCheckGrouping.tsx +++ b/ui/dashboard/src/hooks/useCheckGrouping.tsx @@ -59,8 +59,8 @@ type CheckGroupFilterStatusValuesMap = { export type CheckGroupFilterValues = { status: CheckGroupFilterStatusValuesMap; + control_tag: { key: {}; value: {} }; dimension: { key: {}; value: {} }; - tag: { key: {}; value: {} }; }; type ICheckGroupingContext = { @@ -249,7 +249,7 @@ const getCheckGroupingKey = ( switch (group.type) { case "dimension": return getCheckDimensionGroupingKey(group.value, checkResult.dimensions); - case "tag": + case "control_tag": return getCheckTagGroupingKey(group.value, checkResult.tags); case "reason": return getCheckReasonGroupingKey(checkResult.reason); @@ -295,11 +295,11 @@ const getCheckGroupingNode = ( dimensionValue, children, ); - case "tag": + case "control_tag": const value = getCheckTagGroupingKey(group.value, checkResult.tags); return new KeyValuePairNode( value, - "tag", + "control_tag", group.value || "Tag key not set", value, children, @@ -579,7 +579,7 @@ function recordFilterValues( reason: { value: {} }; resource: { value: {} }; control: { value: {} }; - tag: { value: {}; key: {} }; + control_tag: { value: {}; key: {} }; dimension: { value: {}; key: {} }; benchmark: { value: {} }; status: { @@ -650,15 +650,19 @@ function recordFilterValues( // Record the dimension keys/values + value/key counts of this check result to allow assisted filtering later for (const [tagKey, tagValue] of Object.entries(checkResult.tags || {})) { - filterValues.tag.key[tagKey] = filterValues.tag.key[tagKey] || { + filterValues.control_tag.key[tagKey] = filterValues.control_tag.key[ + tagKey + ] || { [tagValue]: 0, }; - filterValues.tag.key[tagKey][tagValue] += 1; + filterValues.control_tag.key[tagKey][tagValue] += 1; - filterValues.tag.value[tagValue] = filterValues.tag.value[tagValue] || { + filterValues.control_tag.value[tagValue] = filterValues.control_tag.value[ + tagValue + ] || { [tagKey]: 0, }; - filterValues.tag.value[tagValue][tagKey] += 1; + filterValues.control_tag.value[tagValue][tagKey] += 1; } } @@ -743,7 +747,7 @@ const includeResult = ( matches.push(matchesDimensions); break; } - case "tag": { + case "control_tag": { // @ts-ignore const keyRegex = new RegExp(`^${wildcardToRegex(filter.key)}$`); let matchesTags = false; @@ -777,12 +781,12 @@ const useGrouping = ( const filterValues = { benchmark: { value: {} }, control: { value: {} }, + control_tag: { key: {}, value: {} }, dimension: { key: {}, value: {} }, reason: { value: {} }, resource: { value: {} }, severity: { value: {} }, status: { alarm: 0, empty: 0, error: 0, info: 0, ok: 0, skip: 0 }, - tag: { key: {}, value: {} }, }; if (!definition || skip || !panelsMap) { diff --git a/ui/dashboard/src/hooks/useCheckGroupingConfig.ts b/ui/dashboard/src/hooks/useCheckGroupingConfig.ts index 68723e9c..d90eca7b 100644 --- a/ui/dashboard/src/hooks/useCheckGroupingConfig.ts +++ b/ui/dashboard/src/hooks/useCheckGroupingConfig.ts @@ -8,13 +8,13 @@ import { useSearchParams } from "react-router-dom"; const groupingKeys = [ "benchmark", "control", + "control_tag", "dimension", "reason", "resource", "result", "severity", "status", - "tag", ]; const useCheckGroupingConfig = () => { @@ -54,9 +54,9 @@ const useCheckGroupingConfig = () => { // { type: "severity" }, // { type: "dimension", value: "account_id" }, // { type: "dimension", value: "region" }, - // { type: "tag", value: "service" }, - // { type: "tag", value: "cis_type" }, - // { type: "tag", value: "cis_level" }, + // { type: "control_tag", value: "service" }, + // { type: "control_tag", value: "cis_type" }, + // { type: "control_tag", value: "cis_level" }, { type: "benchmark" }, { type: "control" }, { type: "result" }, diff --git a/ui/dashboard/src/hooks/useDashboard.tsx b/ui/dashboard/src/hooks/useDashboard.tsx index a2db5fa7..18b2d708 100644 --- a/ui/dashboard/src/hooks/useDashboard.tsx +++ b/ui/dashboard/src/hooks/useDashboard.tsx @@ -145,7 +145,7 @@ const DashboardProvider = ({ "grouping", state.snapshot.metadata.view.group_by .map((c) => - c.type === "dimension" || c.type === "tag" + c.type === "dimension" || c.type === "control_tag" ? `${c.type}|${c.value}` : c.type, ) diff --git a/ui/dashboard/src/utils/snapshot.test.ts b/ui/dashboard/src/utils/snapshot.test.ts index 6da76280..2de3428f 100644 --- a/ui/dashboard/src/utils/snapshot.test.ts +++ b/ui/dashboard/src/utils/snapshot.test.ts @@ -219,14 +219,16 @@ describe("snapshot utils", () => { }); it("should omit tag with no value", () => { - const input: CheckDisplayGroup[] = [{ type: "tag" }]; + const input: CheckDisplayGroup[] = [{ type: "control_tag" }]; const expected = []; expect(groupingToSnapshotMetadata(input)).toEqual(expected); }); it("should handle tag with value", () => { - const input: CheckDisplayGroup[] = [{ type: "tag", value: "category" }]; - const expected = [{ type: "tag", value: "category" }]; + const input: CheckDisplayGroup[] = [ + { type: "control_tag", value: "category" }, + ]; + const expected = [{ type: "control_tag", value: "category" }]; expect(groupingToSnapshotMetadata(input)).toEqual(expected); }); diff --git a/ui/dashboard/src/utils/snapshot.ts b/ui/dashboard/src/utils/snapshot.ts index 89cee379..e8842261 100644 --- a/ui/dashboard/src/utils/snapshot.ts +++ b/ui/dashboard/src/utils/snapshot.ts @@ -72,7 +72,10 @@ const groupingToSnapshotMetadata = ( return grouping .filter((g) => { - return !((g.type === "dimension" || g.type === "tag") && !g.value); + return !( + (g.type === "dimension" || g.type === "control_tag") && + !g.value + ); }) .map((g) => { const mapped: { type: CheckDisplayGroupType; value?: string } = {