From f7d994c3135d81ab8a110be7648a90b539ebd5d0 Mon Sep 17 00:00:00 2001
From: christineweng <18648970+christineweng@users.noreply.github.com>
Date: Tue, 16 Jan 2024 15:30:32 -0600
Subject: [PATCH] [Security Solution] Alert flyout - update document id in
analyzer preview and same ancestry (#174651)
## Summary
Address: https://github.com/elastic/kibana/issues/169373
This PR updates the use of `kibana.alert.ancestor.id` to `_id`
(available in flyout context as `eventId`) in analyzer preview and
alerts by ancestry. This change allows upgrade from 7.x kibana to 8.10+
to utilize analyzer preview.
No UI change introduced.
**How to test**
- Analyzer preview should match that of prior to the change
- Alert by ancestry in correlations overview (right section) and
correlations tab (left section -> Insights) should match that of prior
to the change
- Analyzer preview should match the analyzer viewer in alerts table
### Checklist
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
(cherry picked from commit f288919b144dbfc2e99a3ff689ddfc0707c89379)
---
.../components/correlations_details.test.tsx | 4 +--
.../left/components/correlations_details.tsx | 15 ++--------
.../related_alerts_by_ancestry.test.tsx | 8 +-----
.../components/related_alerts_by_ancestry.tsx | 9 ++----
.../components/analyzer_preview.test.tsx | 6 ++--
.../right/components/analyzer_preview.tsx | 12 +++-----
.../components/correlations_overview.test.tsx | 4 +--
.../components/correlations_overview.tsx | 10 ++-----
.../components/related_alerts_by_ancestry.tsx | 2 +-
.../use_fetch_related_alerts_by_ancestry.ts | 2 +-
...e_show_related_alerts_by_ancestry.test.tsx | 28 ++++---------------
.../use_show_related_alerts_by_ancestry.ts | 11 +-------
12 files changed, 29 insertions(+), 82 deletions(-)
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.test.tsx
index 21214670241aa..2c1a6c27a52d3 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.test.tsx
@@ -67,7 +67,7 @@ describe('CorrelationsDetails', () => {
it('renders all sections', () => {
jest
.mocked(useShowRelatedAlertsByAncestry)
- .mockReturnValue({ show: true, documentId: 'documentId', indices: ['index1'] });
+ .mockReturnValue({ show: true, indices: ['index1'] });
jest
.mocked(useShowRelatedAlertsBySameSourceEvent)
.mockReturnValue({ show: true, originalEventId: 'originalEventId' });
@@ -115,7 +115,7 @@ describe('CorrelationsDetails', () => {
it('should render no section and show error message if show values are false', () => {
jest
.mocked(useShowRelatedAlertsByAncestry)
- .mockReturnValue({ show: false, documentId: 'documentId', indices: ['index1'] });
+ .mockReturnValue({ show: false, indices: ['index1'] });
jest
.mocked(useShowRelatedAlertsBySameSourceEvent)
.mockReturnValue({ show: false, originalEventId: 'originalEventId' });
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.tsx
index 0302083236532..739a17b7699a8 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.tsx
@@ -30,11 +30,7 @@ export const CorrelationsDetails: React.FC = () => {
const { dataAsNestedObject, dataFormattedForFieldBrowser, eventId, getFieldsData, scopeId } =
useLeftPanelContext();
- const {
- show: showAlertsByAncestry,
- documentId,
- indices,
- } = useShowRelatedAlertsByAncestry({
+ const { show: showAlertsByAncestry, indices } = useShowRelatedAlertsByAncestry({
getFieldsData,
dataAsNestedObject,
dataFormattedForFieldBrowser,
@@ -86,14 +82,9 @@ export const CorrelationsDetails: React.FC = () => {
)}
- {showAlertsByAncestry && documentId && indices && (
+ {showAlertsByAncestry && indices && (
-
+
)}
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.test.tsx
index d7f4a35fd11c5..063ebce7354aa 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.test.tsx
@@ -27,7 +27,6 @@ jest.mock('../hooks/use_paginated_alerts');
const documentId = 'documentId';
const indices = ['index1'];
const scopeId = 'scopeId';
-const eventId = 'eventId';
const TOGGLE_ICON = EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID(
CORRELATIONS_DETAILS_BY_ANCESTRY_SECTION_TEST_ID
@@ -42,12 +41,7 @@ const TITLE_TEXT = EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID(
const renderRelatedAlertsByAncestry = () =>
render(
-
+
);
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.tsx
index 050d2b4ae1966..b8bb13fd1bd9f 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.tsx
@@ -13,7 +13,7 @@ import { CORRELATIONS_DETAILS_BY_ANCESTRY_SECTION_TEST_ID } from './test_ids';
export interface RelatedAlertsByAncestryProps {
/**
- * Value of the kibana.alert.ancestors.id field
+ * Id of the document
*/
documentId: string;
/**
@@ -24,10 +24,6 @@ export interface RelatedAlertsByAncestryProps {
* Maintain backwards compatibility // TODO remove when possible
*/
scopeId: string;
- /**
- * Id of the document
- */
- eventId: string;
}
/**
@@ -37,7 +33,6 @@ export const RelatedAlertsByAncestry: React.VFC =
documentId,
indices,
scopeId,
- eventId,
}) => {
const { loading, error, data, dataCount } = useFetchRelatedAlertsByAncestry({
documentId,
@@ -61,7 +56,7 @@ export const RelatedAlertsByAncestry: React.VFC =
loading={loading}
alertIds={data}
scopeId={scopeId}
- eventId={eventId}
+ eventId={documentId}
noItemsMessage={
', () => {
expect(mockUseAlertPrevalenceFromProcessTree).toHaveBeenCalledWith({
isActiveTimeline: false,
- documentId: 'ancestors-id',
+ documentId: 'eventId',
indices: ['rule-indices'],
});
expect(wrapper.getByTestId(ANALYZER_PREVIEW_TEST_ID)).toBeInTheDocument();
});
- it('shows error message when documentid and index are not present', () => {
+ it('shows error message when index is not present', () => {
mockUseAlertPrevalenceFromProcessTree.mockReturnValue({
loading: false,
error: false,
@@ -82,7 +82,7 @@ describe('', () => {
expect(mockUseAlertPrevalenceFromProcessTree).toHaveBeenCalledWith({
isActiveTimeline: false,
- documentId: '',
+ documentId: 'eventId',
indices: [],
});
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview.tsx
index e8f23bc4638bd..0beb237f17cf2 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview.tsx
@@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { ANALYZER_PREVIEW_TEST_ID, ANALYZER_PREVIEW_LOADING_TEST_ID } from './test_ids';
import { getTreeNodes } from '../utils/analyzer_helpers';
-import { ANCESTOR_ID, RULE_INDICES } from '../../shared/constants/field_names';
+import { RULE_INDICES } from '../../shared/constants/field_names';
import { useRightPanelContext } from '../context';
import { useAlertPrevalenceFromProcessTree } from '../../../../common/containers/alerts/use_alert_prevalence_from_process_tree';
import type { StatsNode } from '../../../../common/containers/alerts/use_alert_prevalence_from_process_tree';
@@ -33,18 +33,14 @@ interface Cache {
*/
export const AnalyzerPreview: React.FC = () => {
const [cache, setCache] = useState>({});
- const { dataFormattedForFieldBrowser: data, scopeId } = useRightPanelContext();
-
- const documentId = find({ category: 'kibana', field: ANCESTOR_ID }, data);
- const processDocumentId =
- documentId && Array.isArray(documentId.values) ? documentId.values[0] : '';
+ const { dataFormattedForFieldBrowser: data, scopeId, eventId } = useRightPanelContext();
const index = find({ category: 'kibana', field: RULE_INDICES }, data);
const indices = index?.values ?? [];
const { statsNodes, loading, error } = useAlertPrevalenceFromProcessTree({
isActiveTimeline: isActiveTimeline(scopeId),
- documentId: processDocumentId,
+ documentId: eventId,
indices,
});
@@ -59,7 +55,7 @@ export const AnalyzerPreview: React.FC = () => {
[cache.statsNodes]
);
- const showAnalyzerTree = documentId && index && items && items.length > 0 && !error;
+ const showAnalyzerTree = eventId && index && items && items.length > 0 && !error;
return loading ? (
', () => {
it('should show component with all rows in expandable panel', () => {
jest
.mocked(useShowRelatedAlertsByAncestry)
- .mockReturnValue({ show: true, documentId: 'documentId', indices: ['index1'] });
+ .mockReturnValue({ show: true, indices: ['index1'] });
jest
.mocked(useShowRelatedAlertsBySameSourceEvent)
.mockReturnValue({ show: true, originalEventId: 'originalEventId' });
@@ -145,7 +145,7 @@ describe('', () => {
it('should hide rows and show error message if show values are false', () => {
jest
.mocked(useShowRelatedAlertsByAncestry)
- .mockReturnValue({ show: false, documentId: 'documentId', indices: ['index1'] });
+ .mockReturnValue({ show: false, indices: ['index1'] });
jest
.mocked(useShowRelatedAlertsBySameSourceEvent)
.mockReturnValue({ show: false, originalEventId: 'originalEventId' });
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.tsx
index 52e66fed55b5d..44689eaed616d 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.tsx
@@ -56,11 +56,7 @@ export const CorrelationsOverview: React.FC = () => {
});
}, [eventId, openLeftPanel, indexName, scopeId]);
- const {
- show: showAlertsByAncestry,
- documentId,
- indices,
- } = useShowRelatedAlertsByAncestry({
+ const { show: showAlertsByAncestry, indices } = useShowRelatedAlertsByAncestry({
getFieldsData,
dataAsNestedObject,
dataFormattedForFieldBrowser,
@@ -115,8 +111,8 @@ export const CorrelationsOverview: React.FC = () => {
{showAlertsBySession && entityId && (
)}
- {showAlertsByAncestry && documentId && indices && (
-
+ {showAlertsByAncestry && indices && (
+
)}
) : (
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/related_alerts_by_ancestry.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/related_alerts_by_ancestry.tsx
index 1c41fbe0969b3..2e628ba61a7be 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/related_alerts_by_ancestry.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/related_alerts_by_ancestry.tsx
@@ -15,7 +15,7 @@ const ICON = 'warning';
export interface RelatedAlertsByAncestryProps {
/**
- * Value of the kibana.alert.ancestors.id field
+ * Id of the document
*/
documentId: string;
/**
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_fetch_related_alerts_by_ancestry.ts b/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_fetch_related_alerts_by_ancestry.ts
index 73415c880a3c1..b44349a06eec9 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_fetch_related_alerts_by_ancestry.ts
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_fetch_related_alerts_by_ancestry.ts
@@ -11,7 +11,7 @@ import { isActiveTimeline } from '../../../../helpers';
export interface UseFetchRelatedAlertsByAncestryParams {
/**
- * Value of the kibana.alert.ancestors.id field
+ * Id of the document
*/
documentId: string;
/**
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_show_related_alerts_by_ancestry.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_show_related_alerts_by_ancestry.test.tsx
index a452e0e3a1686..8b70fcebdefb7 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_show_related_alerts_by_ancestry.test.tsx
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_show_related_alerts_by_ancestry.test.tsx
@@ -16,6 +16,7 @@ import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_ex
import { licenseService } from '../../../../common/hooks/use_license';
import { mockDataFormattedForFieldBrowser } from '../mocks/mock_data_formatted_for_field_browser';
import { mockDataAsNestedObject } from '../mocks/mock_data_as_nested_object';
+import { useIsInvestigateInResolverActionEnabled } from '../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver';
jest.mock('../../../../common/hooks/use_experimental_features');
jest.mock('../../../../common/hooks/use_license', () => {
@@ -29,6 +30,9 @@ jest.mock('../../../../common/hooks/use_license', () => {
},
};
});
+jest.mock(
+ '../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver'
+);
const licenseServiceMock = licenseService as jest.Mocked;
const dataAsNestedObject = mockDataAsNestedObject;
@@ -40,8 +44,9 @@ describe('useShowRelatedAlertsByAncestry', () => {
UseShowRelatedAlertsByAncestryResult
>;
- it('should return false if getFieldsData returns null', () => {
+ it('should return false if Process Entity Info is not available', () => {
(useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true);
+ (useIsInvestigateInResolverActionEnabled as jest.Mock).mockReturnValue(false);
licenseServiceMock.isPlatinumPlus.mockReturnValue(true);
const getFieldsData = () => null;
hookResult = renderHook(() =>
@@ -69,7 +74,6 @@ describe('useShowRelatedAlertsByAncestry', () => {
expect(hookResult.result.current).toEqual({
show: false,
- documentId: 'value',
indices: ['rule-parameters-index'],
});
});
@@ -88,26 +92,6 @@ describe('useShowRelatedAlertsByAncestry', () => {
expect(hookResult.result.current).toEqual({
show: false,
- documentId: 'value',
- indices: ['rule-parameters-index'],
- });
- });
-
- it('should return true if getFieldsData has the correct fields', () => {
- (useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true);
- licenseServiceMock.isPlatinumPlus.mockReturnValue(true);
- const getFieldsData = () => 'value';
- hookResult = renderHook(() =>
- useShowRelatedAlertsByAncestry({
- getFieldsData,
- dataAsNestedObject,
- dataFormattedForFieldBrowser,
- })
- );
-
- expect(hookResult.result.current).toEqual({
- show: true,
- documentId: 'value',
indices: ['rule-parameters-index'],
});
});
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_show_related_alerts_by_ancestry.ts b/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_show_related_alerts_by_ancestry.ts
index 53a1b336ff456..f1627b749bfe1 100644
--- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_show_related_alerts_by_ancestry.ts
+++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/hooks/use_show_related_alerts_by_ancestry.ts
@@ -13,8 +13,7 @@ import type { GetFieldsData } from '../../../../common/hooks/use_get_fields_data
import { useIsInvestigateInResolverActionEnabled } from '../../../../detections/components/alerts_table/timeline_actions/investigate_in_resolver';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
import { useLicense } from '../../../../common/hooks/use_license';
-import { getField } from '../utils';
-import { ANCESTOR_ID, RULE_PARAMETERS_INDEX } from '../constants/field_names';
+import { RULE_PARAMETERS_INDEX } from '../constants/field_names';
export interface UseShowRelatedAlertsByAncestryParams {
/**
@@ -36,10 +35,6 @@ export interface UseShowRelatedAlertsByAncestryResult {
* Returns true if the user has at least platinum privilege, and if the document has ancestry data
*/
show: boolean;
- /**
- * Value of the kibana.alert.ancestors.id field
- */
- documentId?: string;
/**
* Values of the kibana.alert.rule.parameters.index field
*/
@@ -59,8 +54,6 @@ export const useShowRelatedAlertsByAncestry = ({
);
const hasProcessEntityInfo = useIsInvestigateInResolverActionEnabled(dataAsNestedObject);
- const originalDocumentId = getField(getFieldsData(ANCESTOR_ID));
-
// can't use getFieldsData here as the kibana.alert.rule.parameters is different and can be nested
const originalDocumentIndex = useMemo(
() => find({ category: 'kibana', field: RULE_PARAMETERS_INDEX }, dataFormattedForFieldBrowser),
@@ -72,13 +65,11 @@ export const useShowRelatedAlertsByAncestry = ({
const show =
isRelatedAlertsByProcessAncestryEnabled &&
hasProcessEntityInfo &&
- originalDocumentId != null &&
originalDocumentIndex != null &&
hasAtLeastPlatinum;
return {
show,
- ...(originalDocumentId && { documentId: originalDocumentId }),
...(originalDocumentIndex &&
originalDocumentIndex.values && { indices: originalDocumentIndex.values }),
};