diff --git a/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts b/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts
index cbeb334e2aa61..6222b457e7ad6 100644
--- a/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts
+++ b/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts
@@ -196,6 +196,15 @@ const CLOUD_PROVIDER_NAMES = {
GCP: 'Google Cloud Platform',
};
+export const CLOUD_PROVIDERS = {
+ AWS: 'aws',
+ AZURE: 'azure',
+ GCP: 'gcp',
+};
+
+/**
+ * Returns the cloud provider name or benchmark applicable name for the given benchmark id
+ */
export const getBenchmarkApplicableTo = (benchmarkId: BenchmarksCisId) => {
switch (benchmarkId) {
case 'cis_k8s':
@@ -205,7 +214,7 @@ export const getBenchmarkApplicableTo = (benchmarkId: BenchmarksCisId) => {
case 'cis_aws':
return CLOUD_PROVIDER_NAMES.AWS;
case 'cis_eks':
- return 'Amazon Elastic Kubernetes Service';
+ return 'Amazon Elastic Kubernetes Service (EKS)';
case 'cis_gcp':
return CLOUD_PROVIDER_NAMES.GCP;
}
diff --git a/x-pack/plugins/cloud_security_posture/public/common/constants.ts b/x-pack/plugins/cloud_security_posture/public/common/constants.ts
index bd266c98b8015..735a28a8ed0e1 100644
--- a/x-pack/plugins/cloud_security_posture/public/common/constants.ts
+++ b/x-pack/plugins/cloud_security_posture/public/common/constants.ts
@@ -230,3 +230,10 @@ export const DETECTION_ENGINE_RULES_KEY = 'detection_engine_rules';
export const DETECTION_ENGINE_ALERTS_KEY = 'detection_engine_alerts';
export const DEFAULT_GROUPING_TABLE_HEIGHT = 512;
+
+export const FINDINGS_GROUPING_OPTIONS = {
+ RESOURCE_NAME: 'resource.name',
+ RULE_NAME: 'rule.name',
+ CLOUD_ACCOUNT_NAME: 'cloud.account.name',
+ ORCHESTRATOR_CLUSTER_NAME: 'orchestrator.cluster.name',
+};
diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts
index fbeeeb32a0c2e..4b98057fc10c4 100644
--- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts
+++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts
@@ -57,7 +57,7 @@ const useNavigate = (pathname: string, dataViewId = SECURITY_DEFAULT_DATA_VIEW_I
const { services } = useKibana();
return useCallback(
- (filterParams: NavFilter = {}) => {
+ (filterParams: NavFilter = {}, groupBy?: string[]) => {
const filters = Object.entries(filterParams).map(([key, filterValue]) =>
createFilter(key, filterValue, dataViewId)
);
@@ -68,10 +68,11 @@ const useNavigate = (pathname: string, dataViewId = SECURITY_DEFAULT_DATA_VIEW_I
// Set query language from user's preference
query: services.data.query.queryString.getDefaultQuery(),
filters,
+ ...(groupBy && { groupBy }),
}),
});
},
- [pathname, history, services.data.query.queryString, dataViewId]
+ [history, pathname, services.data.query.queryString, dataViewId]
);
};
diff --git a/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.test.tsx b/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.test.tsx
new file mode 100644
index 0000000000000..1973620c8d9d8
--- /dev/null
+++ b/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.test.tsx
@@ -0,0 +1,69 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { render, fireEvent } from '@testing-library/react';
+import { AccountsEvaluatedWidget } from './accounts_evaluated_widget';
+import { BenchmarkData } from '../../common/types_old';
+import { TestProvider } from '../test/test_provider';
+
+const mockNavToFindings = jest.fn();
+jest.mock('../common/hooks/use_navigate_findings', () => ({
+ useNavigateFindings: () => mockNavToFindings,
+}));
+
+describe('AccountsEvaluatedWidget', () => {
+ const benchmarkAssets = [
+ { meta: { benchmarkId: 'cis_aws', assetCount: 10 } },
+ { meta: { benchmarkId: 'cis_k8s', assetCount: 20 } },
+ ] as BenchmarkData[];
+
+ it('renders the component with benchmark data correctly', () => {
+ const { getByText } = render(
+
+
+
+ );
+
+ expect(getByText('10')).toBeInTheDocument();
+ expect(getByText('20')).toBeInTheDocument();
+ });
+
+ it('calls navToFindingsByCloudProvider when a benchmark with provider is clicked', () => {
+ const { getByText } = render(
+
+
+
+ );
+
+ fireEvent.click(getByText('10'));
+
+ expect(mockNavToFindings).toHaveBeenCalledWith(
+ {
+ 'cloud.provider': 'aws',
+ },
+ ['cloud.account.name']
+ );
+ });
+
+ it('calls navToFindingsByCisBenchmark when a benchmark with benchmarkId is clicked', () => {
+ const { getByText } = render(
+
+
+
+ );
+
+ fireEvent.click(getByText('20'));
+
+ expect(mockNavToFindings).toHaveBeenCalledWith(
+ {
+ 'rule.benchmark.id': 'cis_k8s',
+ },
+ ['orchestrator.cluster.name']
+ );
+ });
+});
diff --git a/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.tsx b/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.tsx
index a9b118be899ab..aeb734005a65b 100644
--- a/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.tsx
+++ b/x-pack/plugins/cloud_security_posture/public/components/accounts_evaluated_widget.tsx
@@ -7,38 +7,40 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';
+import { CLOUD_PROVIDERS, getBenchmarkApplicableTo } from '../../common/utils/helpers';
import { CIS_AWS, CIS_GCP, CIS_AZURE, CIS_K8S, CIS_EKS } from '../../common/constants';
import { CISBenchmarkIcon } from './cis_benchmark_icon';
import { CompactFormattedNumber } from './compact_formatted_number';
import { useNavigateFindings } from '../common/hooks/use_navigate_findings';
import { BenchmarkData } from '../../common/types_old';
+import { FINDINGS_GROUPING_OPTIONS } from '../common/constants';
// order in array will determine order of appearance in the dashboard
const benchmarks = [
{
type: CIS_AWS,
- name: 'Amazon Web Services (AWS)',
- provider: 'aws',
+ name: getBenchmarkApplicableTo(CIS_AWS),
+ provider: CLOUD_PROVIDERS.AWS,
},
{
type: CIS_GCP,
- name: 'Google Cloud Platform (GCP)',
- provider: 'gcp',
+ name: getBenchmarkApplicableTo(CIS_GCP),
+ provider: CLOUD_PROVIDERS.GCP,
},
{
type: CIS_AZURE,
- name: 'Azure',
- provider: 'azure',
+ name: getBenchmarkApplicableTo(CIS_AZURE),
+ provider: CLOUD_PROVIDERS.AZURE,
},
{
type: CIS_K8S,
- name: 'Kubernetes',
- benchmarkId: 'cis_k8s',
+ name: getBenchmarkApplicableTo(CIS_K8S),
+ benchmarkId: CIS_K8S,
},
{
type: CIS_EKS,
- name: 'Amazon Elastic Kubernetes Service (EKS)',
- benchmarkId: 'cis_eks',
+ name: getBenchmarkApplicableTo(CIS_EKS),
+ benchmarkId: CIS_EKS,
},
];
@@ -59,11 +61,13 @@ export const AccountsEvaluatedWidget = ({
const navToFindings = useNavigateFindings();
const navToFindingsByCloudProvider = (provider: string) => {
- navToFindings({ 'cloud.provider': provider });
+ navToFindings({ 'cloud.provider': provider }, [FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME]);
};
const navToFindingsByCisBenchmark = (cisBenchmark: string) => {
- navToFindings({ 'rule.benchmark.id': cisBenchmark });
+ navToFindings({ 'rule.benchmark.id': cisBenchmark }, [
+ FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME,
+ ]);
};
const benchmarkElements = benchmarks.map((benchmark) => {
@@ -75,10 +79,10 @@ export const AccountsEvaluatedWidget = ({
key={benchmark.type}
onClick={() => {
if (benchmark.provider) {
- navToFindingsByCloudProvider(benchmark.provider);
+ return navToFindingsByCloudProvider(benchmark.provider);
}
if (benchmark.benchmarkId) {
- navToFindingsByCisBenchmark(benchmark.benchmarkId);
+ return navToFindingsByCisBenchmark(benchmark.benchmarkId);
}
}}
css={css`
diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmark_details_box.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmark_details_box.tsx
index dc140fef121b3..ac9b48ddfdbfe 100644
--- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmark_details_box.tsx
+++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/dashboard_sections/benchmark_details_box.tsx
@@ -17,23 +17,32 @@ import {
import { FormattedMessage } from '@kbn/i18n-react';
import React from 'react';
import { i18n } from '@kbn/i18n';
+import { FINDINGS_GROUPING_OPTIONS } from '../../../common/constants';
import { getBenchmarkIdQuery } from './benchmarks_section';
import { BenchmarkData } from '../../../../common/types_old';
import { useNavigateFindings } from '../../../common/hooks/use_navigate_findings';
import { CISBenchmarkIcon } from '../../../components/cis_benchmark_icon';
import cisLogoIcon from '../../../assets/icons/cis_logo.svg';
+
+interface BenchmarkInfo {
+ name: string;
+ assetType: string;
+ handleClick: () => void;
+}
+
export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData }) => {
const navToFindings = useNavigateFindings();
- const handleBenchmarkClick = () => {
- return navToFindings(getBenchmarkIdQuery(benchmark));
- };
+ const handleClickCloudProvider = () =>
+ navToFindings(getBenchmarkIdQuery(benchmark), [FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME]);
+
+ const handleClickCluster = () =>
+ navToFindings(getBenchmarkIdQuery(benchmark), [
+ FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME,
+ ]);
- const getBenchmarkInfo = (
- benchmarkId: string,
- cloudAssetCount: number
- ): { name: string; assetType: string } => {
- const benchmarks: Record = {
+ const getBenchmarkInfo = (benchmarkId: string, cloudAssetCount: number): BenchmarkInfo => {
+ const benchmarks: Record = {
cis_gcp: {
name: i18n.translate(
'xpack.csp.dashboard.benchmarkSection.benchmarkName.cisGcpBenchmarkName',
@@ -48,6 +57,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData })
values: { count: cloudAssetCount },
}
),
+ handleClick: handleClickCloudProvider,
},
cis_aws: {
name: i18n.translate(
@@ -63,6 +73,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData })
values: { count: cloudAssetCount },
}
),
+ handleClick: handleClickCloudProvider,
},
cis_azure: {
name: i18n.translate(
@@ -78,6 +89,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData })
values: { count: cloudAssetCount },
}
),
+ handleClick: handleClickCloudProvider,
},
cis_k8s: {
name: i18n.translate(
@@ -93,6 +105,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData })
values: { count: cloudAssetCount },
}
),
+ handleClick: handleClickCluster,
},
cis_eks: {
name: i18n.translate(
@@ -108,6 +121,7 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData })
values: { count: cloudAssetCount },
}
),
+ handleClick: handleClickCluster,
},
};
return benchmarks[benchmarkId];
@@ -149,14 +163,14 @@ export const BenchmarkDetailsBox = ({ benchmark }: { benchmark: BenchmarkData })
}
>
-
+
{benchmarkInfo.name}
-
+
{benchmarkInfo.assetType}
diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/constants.ts b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/constants.ts
index 3d8200a144bd5..1292da8601357 100644
--- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/constants.ts
+++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/constants.ts
@@ -7,6 +7,7 @@
import { i18n } from '@kbn/i18n';
import { GroupOption } from '@kbn/securitysolution-grouping';
+import { FINDINGS_GROUPING_OPTIONS } from '../../../common/constants';
import { FindingsBaseURLQuery } from '../../../common/types';
import { CloudSecurityDefaultColumn } from '../../../components/cloud_security_data_table';
@@ -16,13 +17,6 @@ export const FINDINGS_UNIT = (totalCount: number) =>
defaultMessage: `{totalCount, plural, =1 {finding} other {findings}}`,
});
-export const GROUPING_OPTIONS = {
- RESOURCE_NAME: 'resource.name',
- RULE_NAME: 'rule.name',
- CLOUD_ACCOUNT_NAME: 'cloud.account.name',
- ORCHESTRATOR_CLUSTER_NAME: 'orchestrator.cluster.name',
-};
-
export const NULL_GROUPING_UNIT = i18n.translate('xpack.csp.findings.grouping.nullGroupUnit', {
defaultMessage: 'findings',
});
@@ -51,25 +45,25 @@ export const defaultGroupingOptions: GroupOption[] = [
label: i18n.translate('xpack.csp.findings.latestFindings.groupByResource', {
defaultMessage: 'Resource',
}),
- key: GROUPING_OPTIONS.RESOURCE_NAME,
+ key: FINDINGS_GROUPING_OPTIONS.RESOURCE_NAME,
},
{
label: i18n.translate('xpack.csp.findings.latestFindings.groupByRuleName', {
defaultMessage: 'Rule name',
}),
- key: GROUPING_OPTIONS.RULE_NAME,
+ key: FINDINGS_GROUPING_OPTIONS.RULE_NAME,
},
{
label: i18n.translate('xpack.csp.findings.latestFindings.groupByCloudAccount', {
defaultMessage: 'Cloud account',
}),
- key: GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME,
+ key: FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME,
},
{
label: i18n.translate('xpack.csp.findings.latestFindings.groupByKubernetesCluster', {
defaultMessage: 'Kubernetes cluster',
}),
- key: GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME,
+ key: FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME,
},
];
diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_group_renderer.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_group_renderer.tsx
index fe8536eaf0f69..6dbc78cbf0857 100644
--- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_group_renderer.tsx
+++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/latest_findings_group_renderer.tsx
@@ -17,6 +17,7 @@ import { css } from '@emotion/react';
import { GroupPanelRenderer, RawBucket, StatRenderer } from '@kbn/securitysolution-grouping/src';
import React from 'react';
import { i18n } from '@kbn/i18n';
+import { FINDINGS_GROUPING_OPTIONS } from '../../../common/constants';
import {
NullGroup,
LoadingGroup,
@@ -26,7 +27,7 @@ import { getAbbreviatedNumber } from '../../../common/utils/get_abbreviated_numb
import { CISBenchmarkIcon } from '../../../components/cis_benchmark_icon';
import { ComplianceScoreBar } from '../../../components/compliance_score_bar';
import { FindingsGroupingAggregation } from './use_grouped_findings';
-import { GROUPING_OPTIONS, NULL_GROUPING_MESSAGES, NULL_GROUPING_UNIT } from './constants';
+import { NULL_GROUPING_MESSAGES, NULL_GROUPING_UNIT } from './constants';
import { FINDINGS_GROUPING_COUNTER } from '../test_subjects';
export const groupPanelRenderer: GroupPanelRenderer = (
@@ -45,7 +46,7 @@ export const groupPanelRenderer: GroupPanelRenderer
);
switch (selectedGroup) {
- case GROUPING_OPTIONS.RESOURCE_NAME:
+ case FINDINGS_GROUPING_OPTIONS.RESOURCE_NAME:
return nullGroupMessage ? (
renderNullGroup(NULL_GROUPING_MESSAGES.RESOURCE_NAME)
) : (
@@ -78,7 +79,7 @@ export const groupPanelRenderer: GroupPanelRenderer
);
- case GROUPING_OPTIONS.RULE_NAME:
+ case FINDINGS_GROUPING_OPTIONS.RULE_NAME:
return nullGroupMessage ? (
renderNullGroup(NULL_GROUPING_MESSAGES.RULE_NAME)
) : (
@@ -100,7 +101,7 @@ export const groupPanelRenderer: GroupPanelRenderer
);
- case GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME:
+ case FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME:
return nullGroupMessage ? (
renderNullGroup(NULL_GROUPING_MESSAGES.CLOUD_ACCOUNT_NAME)
) : (
@@ -129,7 +130,7 @@ export const groupPanelRenderer: GroupPanelRenderer
);
- case GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME:
+ case FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME:
return nullGroupMessage ? (
renderNullGroup(NULL_GROUPING_MESSAGES.ORCHESTRATOR_CLUSTER_NAME)
) : (
diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx
index 74efd68b5378b..81df07731c5dd 100644
--- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx
+++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/latest_findings/use_latest_findings_grouping.tsx
@@ -15,7 +15,10 @@ import {
} from '@kbn/securitysolution-grouping/src';
import { useMemo } from 'react';
import { buildEsQuery, Filter } from '@kbn/es-query';
-import { LOCAL_STORAGE_FINDINGS_GROUPING_KEY } from '../../../common/constants';
+import {
+ FINDINGS_GROUPING_OPTIONS,
+ LOCAL_STORAGE_FINDINGS_GROUPING_KEY,
+} from '../../../common/constants';
import { useDataViewContext } from '../../../common/contexts/data_view_context';
import { Evaluation } from '../../../../common/types_old';
import { LATEST_FINDINGS_RETENTION_POLICY } from '../../../../common/constants';
@@ -24,13 +27,7 @@ import {
FindingsRootGroupingAggregation,
useGroupedFindings,
} from './use_grouped_findings';
-import {
- FINDINGS_UNIT,
- groupingTitle,
- defaultGroupingOptions,
- getDefaultQuery,
- GROUPING_OPTIONS,
-} from './constants';
+import { FINDINGS_UNIT, groupingTitle, defaultGroupingOptions, getDefaultQuery } from './constants';
import { useCloudSecurityGrouping } from '../../../components/cloud_security_grouping';
import { getFilters } from '../utils/get_filters';
import { useGetCspBenchmarkRulesStatesApi } from './use_get_benchmark_rules_state_api';
@@ -80,26 +77,26 @@ const getAggregationsByGroupField = (field: string): NamedAggregation[] => {
];
switch (field) {
- case GROUPING_OPTIONS.RESOURCE_NAME:
+ case FINDINGS_GROUPING_OPTIONS.RESOURCE_NAME:
return [
...aggMetrics,
getTermAggregation('resourceName', 'resource.id'),
getTermAggregation('resourceSubType', 'resource.sub_type'),
getTermAggregation('resourceType', 'resource.type'),
];
- case GROUPING_OPTIONS.RULE_NAME:
+ case FINDINGS_GROUPING_OPTIONS.RULE_NAME:
return [
...aggMetrics,
getTermAggregation('benchmarkName', 'rule.benchmark.name'),
getTermAggregation('benchmarkVersion', 'rule.benchmark.version'),
];
- case GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME:
+ case FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME:
return [
...aggMetrics,
getTermAggregation('benchmarkName', 'rule.benchmark.name'),
getTermAggregation('benchmarkId', 'rule.benchmark.id'),
];
- case GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME:
+ case FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME:
return [
...aggMetrics,
getTermAggregation('benchmarkName', 'rule.benchmark.name'),