Skip to content

Commit

Permalink
[Cloud Security] [Vulnerabilities] Add grouping capabilities (elastic…
Browse files Browse the repository at this point in the history
…#174413)

## Summary

It closes elastic#165788 and elastic#169050 and elastic#174119

This PR adds the following changes to the Findings -> Vulnerabilities
page:

- Replaced the DataGrid component with the new CloudSecurityDataTable
component
- Added the new Grouping component with custom default renderers

It also introduced the following changes:
- Added context for DataView for easier reuse of the `dataView` methods.
- Refactored the Misconfigurations component to consume the `dataView`
context
- added FTR tests for the Vulnerabilities page
- dropped Flyout navigation support (will be readded in the future)


## Screenshots


![image](https://github.com/elastic/kibana/assets/19270322/c6cb7871-ce99-4c33-a615-142aaba63ec9)


![image](https://github.com/elastic/kibana/assets/19270322/ead3358f-7300-489b-b26d-5a37cc99e01d)

## Recording



https://github.com/elastic/kibana/assets/19270322/a47be0cf-2849-424d-b19a-d65cb6f502a8



https://github.com/elastic/kibana/assets/19270322/fa395488-7a22-476e-a50e-d0f0e28429e1

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
2 people authored and CoenWarmer committed Feb 15, 2024
1 parent f474fee commit 2e025e8
Show file tree
Hide file tree
Showing 74 changed files with 1,541 additions and 4,908 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export interface Vulnerability {
id: string;
title: string;
reference: string;
severity: VulnSeverity;
severity?: VulnSeverity;
cvss: {
nvd: VectorScoreBase;
redhat?: VectorScoreBase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ import { useQuery } from '@tanstack/react-query';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import type { DataView } from '@kbn/data-plugin/common';
import { i18n } from '@kbn/i18n';
import { LATEST_FINDINGS_INDEX_PATTERN } from '../../../common/constants';
import {
LATEST_FINDINGS_INDEX_PATTERN,
LATEST_VULNERABILITIES_INDEX_PATTERN,
} from '../../../common/constants';
import { CspClientPluginStartDeps } from '../../types';

/**
* TODO: Remove this static labels once https://github.com/elastic/kibana/issues/172615 is resolved
*/
const cloudSecurityFieldLabels: Record<string, string> = {
'result.evaluation': i18n.translate(
'xpack.csp.findings.findingsTable.findingsTableColumn.resultColumnLabel',
Expand Down Expand Up @@ -45,6 +51,30 @@ const cloudSecurityFieldLabels: Record<string, string> = {
'xpack.csp.findings.findingsTable.findingsTableColumn.lastCheckedColumnLabel',
{ defaultMessage: 'Last Checked' }
),
'vulnerability.id': i18n.translate(
'xpack.csp.findings.findingsTable.findingsTableColumn.vulnerabilityIdColumnLabel',
{ defaultMessage: 'Vulnerability' }
),
'vulnerability.score.base': i18n.translate(
'xpack.csp.findings.findingsTable.findingsTableColumn.vulnerabilityScoreColumnLabel',
{ defaultMessage: 'CVSS' }
),
'vulnerability.severity': i18n.translate(
'xpack.csp.findings.findingsTable.findingsTableColumn.vulnerabilitySeverityColumnLabel',
{ defaultMessage: 'Severity' }
),
'package.name': i18n.translate(
'xpack.csp.findings.findingsTable.findingsTableColumn.packageNameColumnLabel',
{ defaultMessage: 'Package' }
),
'package.version': i18n.translate(
'xpack.csp.findings.findingsTable.findingsTableColumn.packageVersionColumnLabel',
{ defaultMessage: 'Version' }
),
'package.fixed_version': i18n.translate(
'xpack.csp.findings.findingsTable.findingsTableColumn.packageFixedVersionColumnLabel',
{ defaultMessage: 'Fix Version' }
),
} as const;

/**
Expand All @@ -61,7 +91,13 @@ export const useLatestFindingsDataView = (dataView: string) => {
throw new Error(`Data view not found [Name: {${dataView}}]`);
}

if (dataView === LATEST_FINDINGS_INDEX_PATTERN) {
/**
* TODO: Remove this update logic once https://github.com/elastic/kibana/issues/172615 is resolved
*/
if (
dataView === LATEST_FINDINGS_INDEX_PATTERN ||
dataView === LATEST_VULNERABILITIES_INDEX_PATTERN
) {
let shouldUpdate = false;
Object.entries(cloudSecurityFieldLabels).forEach(([field, label]) => {
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export const LOCAL_STORAGE_DASHBOARD_BENCHMARK_SORT_KEY =
'cloudPosture:complianceDashboard:benchmarkSort';
export const LOCAL_STORAGE_FINDINGS_LAST_SELECTED_TAB_KEY = 'cloudPosture:findings:lastSelectedTab';

export const LOCAL_STORAGE_VULNERABILITIES_GROUPING_KEY = 'cspLatestVulnerabilitiesGrouping';
export const LOCAL_STORAGE_FINDINGS_GROUPING_KEY = 'cspLatestFindingsGrouping';

export const SESSION_STORAGE_FIELDS_MODAL_SHOW_SELECTED = 'cloudPosture:fieldsModal:showSelected';

export type CloudPostureIntegrations = Record<
Expand Down Expand Up @@ -225,3 +228,5 @@ export const NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS = 10000;

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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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 { createContext, useContext } from 'react';
import { DataView } from '@kbn/data-views-plugin/common';

interface DataViewContextValue {
dataView: DataView;
dataViewRefetch?: () => void;
dataViewIsRefetching?: boolean;
}

export const DataViewContext = createContext<DataViewContextValue | undefined>(undefined);

/**
* Retrieve context's properties
*/
export const useDataViewContext = (): DataViewContextValue => {
const contextValue = useContext(DataViewContext);

if (!contextValue) {
throw new Error('useDataViewContext can only be used within DataViewContext provider');
}

return contextValue;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@
* 2.0.
*/

import { DataView } from '@kbn/data-views-plugin/common';
import { buildEsQuery, EsQueryConfig } from '@kbn/es-query';
import { i18n } from '@kbn/i18n';
import { useEffect, useMemo } from 'react';
import { FindingsBaseESQueryConfig, FindingsBaseProps, FindingsBaseURLQuery } from '../../types';
import { useDataViewContext } from '../../contexts/data_view_context';
import { FindingsBaseESQueryConfig, FindingsBaseURLQuery } from '../../types';
import { useKibana } from '../use_kibana';

const getBaseQuery = ({
dataView,
query,
filters,
config,
}: FindingsBaseURLQuery & FindingsBaseProps & FindingsBaseESQueryConfig) => {
}: FindingsBaseURLQuery &
FindingsBaseESQueryConfig & {
dataView: DataView;
}) => {
try {
return {
query: buildEsQuery(dataView, query, filters, config), // will throw for malformed query
Expand All @@ -30,18 +35,18 @@ const getBaseQuery = ({
};

export const useBaseEsQuery = ({
dataView,
filters = [],
query,
nonPersistedFilters,
}: FindingsBaseURLQuery & FindingsBaseProps) => {
}: FindingsBaseURLQuery) => {
const {
notifications: { toasts },
data: {
query: { filterManager, queryString },
},
uiSettings,
} = useKibana().services;
const { dataView } = useDataViewContext();
const allowLeadingWildcards = uiSettings.get('query:allowLeadingWildcards');
const config: EsQueryConfig = useMemo(() => ({ allowLeadingWildcards }), [allowLeadingWildcards]);
const baseEsQuery = useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/
import { Dispatch, SetStateAction, useCallback } from 'react';
import { type DataView } from '@kbn/data-views-plugin/common';
import { BoolQuery, Filter } from '@kbn/es-query';
import { CriteriaWithPagination } from '@elastic/eui';
import { DataTableRecord } from '@kbn/discover-utils/types';
Expand Down Expand Up @@ -46,13 +45,11 @@ export interface CloudPostureDataTableResult {
*/
export const useCloudPostureDataTable = ({
defaultQuery = getDefaultQuery,
dataView,
paginationLocalStorageKey,
columnsLocalStorageKey,
nonPersistedFilters,
}: {
defaultQuery?: (params: FindingsBaseURLQuery) => FindingsBaseURLQuery;
dataView: DataView;
paginationLocalStorageKey: string;
columnsLocalStorageKey?: string;
nonPersistedFilters?: Filter[];
Expand Down Expand Up @@ -116,7 +113,6 @@ export const useCloudPostureDataTable = ({
* Page URL query to ES query
*/
const baseEsQuery = useBaseEsQuery({
dataView,
filters: urlQuery.filters,
query: urlQuery.query,
...(nonPersistedFilters ? { nonPersistedFilters } : {}),
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 2e025e8

Please sign in to comment.