From 9b2049b8061e14a759a14fcd2a223e183070d901 Mon Sep 17 00:00:00 2001 From: Davis Plumlee <56367316+dplumlee@users.noreply.github.com> Date: Wed, 18 Aug 2021 02:12:16 -0400 Subject: [PATCH] [Security Solution][Detection Alerts] Changes in-progress status to acknowledged (#107972) --- .../schemas/common/schemas.ts | 7 +- ..._progress.spec.ts => acknowledged.spec.ts} | 18 +-- .../integration/header/navigation.spec.ts | 4 +- .../cypress/screens/alerts.ts | 8 +- .../security_solution/cypress/tasks/alerts.ts | 21 ++-- .../events_viewer/events_viewer.test.tsx | 20 +++- .../alerts_filter_group/index.test.tsx | 4 +- .../alerts_filter_group/index.tsx | 106 +++++++----------- .../alerts_table/alerts_utility_bar/index.tsx | 12 +- .../alerts_utility_bar/translations.ts | 6 +- .../components/alerts_table/index.tsx | 6 +- ...atus.tsx => acknowledged_alert_status.tsx} | 18 +-- .../components/alerts_table/translations.ts | 24 ++-- .../containers/detection_engine/alerts/api.ts | 2 +- .../detection_engine/detection_engine.tsx | 5 +- .../detection_engine/rules/details/index.tsx | 5 +- .../timeline/body/renderers/rule_status.tsx | 2 +- .../migrations/create_migration.ts | 6 +- x-pack/plugins/timelines/common/constants.ts | 6 + .../common/types/timeline/actions/index.ts | 8 +- .../public/components/t_grid/translations.ts | 18 +-- .../hooks/use_status_bulk_action_items.tsx | 18 +-- .../translations/translations/ja-JP.json | 4 - .../translations/translations/zh-CN.json | 5 - .../basic/tests/update_rac_alerts.ts | 31 +++++ 25 files changed, 203 insertions(+), 161 deletions(-) rename x-pack/plugins/security_solution/cypress/integration/detection_alerts/{in_progress.spec.ts => acknowledged.spec.ts} (82%) rename x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/{in_progress_alert_status.tsx => acknowledged_alert_status.tsx} (55%) diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts index c869a12faf360f..ab89ab31acc022 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts @@ -170,7 +170,12 @@ export type RuleNameOverride = t.TypeOf; export const ruleNameOverrideOrUndefined = t.union([rule_name_override, t.undefined]); export type RuleNameOverrideOrUndefined = t.TypeOf; -export const status = t.keyof({ open: null, closed: null, 'in-progress': null }); +export const status = t.keyof({ + open: null, + closed: null, + acknowledged: null, + 'in-progress': null, // TODO: Remove after `acknowledged` migrations +}); export type Status = t.TypeOf; export enum RuleExecutionStatus { diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/in_progress.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/acknowledged.spec.ts similarity index 82% rename from x-pack/plugins/security_solution/cypress/integration/detection_alerts/in_progress.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/detection_alerts/acknowledged.spec.ts index d82bfe00659f30..f933c5a4ed0a29 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/in_progress.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/acknowledged.spec.ts @@ -13,8 +13,8 @@ import { waitForAlertsPanelToBeLoaded, waitForAlerts, waitForAlertsToBeLoaded, - markInProgressFirstAlert, - goToInProgressAlerts, + markAcknowledgedFirstAlert, + goToAcknowledgedAlerts, waitForAlertsIndexToBeCreated, goToOpenedAlerts, } from '../../tasks/alerts'; @@ -26,7 +26,7 @@ import { refreshPage } from '../../tasks/security_header'; import { ALERTS_URL } from '../../urls/navigation'; -describe('Marking alerts as in-progress', () => { +describe('Marking alerts as acknowledged', () => { beforeEach(() => { cleanKibana(); loginAndWaitForPage(ALERTS_URL); @@ -37,30 +37,30 @@ describe('Marking alerts as in-progress', () => { waitForAlertsToPopulate(500); }); - it('Mark one alert in progress when more than one open alerts are selected', () => { + it('Mark one alert as acknowledged when more than one open alerts are selected', () => { cy.get(ALERTS_COUNT) .invoke('text') .then((alertNumberString) => { const numberOfAlerts = alertNumberString.split(' ')[0]; - const numberOfAlertsToBeMarkedInProgress = 1; + const numberOfAlertsToBeMarkedAcknowledged = 1; const numberOfAlertsToBeSelected = 3; cy.get(TAKE_ACTION_POPOVER_BTN).should('not.exist'); selectNumberOfAlerts(numberOfAlertsToBeSelected); cy.get(TAKE_ACTION_POPOVER_BTN).should('exist'); - markInProgressFirstAlert(); + markAcknowledgedFirstAlert(); refreshPage(); waitForAlertsToBeLoaded(); goToOpenedAlerts(); - const expectedNumberOfAlerts = +numberOfAlerts - numberOfAlertsToBeMarkedInProgress; + const expectedNumberOfAlerts = +numberOfAlerts - numberOfAlertsToBeMarkedAcknowledged; cy.get(ALERTS_COUNT).should('have.text', `${expectedNumberOfAlerts} alerts`); - goToInProgressAlerts(); + goToAcknowledgedAlerts(); waitForAlerts(); - cy.get(ALERTS_COUNT).should('have.text', `${numberOfAlertsToBeMarkedInProgress} alert`); + cy.get(ALERTS_COUNT).should('have.text', `${numberOfAlertsToBeMarkedAcknowledged} alert`); }); }); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/header/navigation.spec.ts b/x-pack/plugins/security_solution/cypress/integration/header/navigation.spec.ts index 15982f16743515..16278c919a0465 100644 --- a/x-pack/plugins/security_solution/cypress/integration/header/navigation.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/header/navigation.spec.ts @@ -51,7 +51,7 @@ import { } from '../../screens/kibana_navigation'; import { cleanKibana } from '../../tasks/common'; -describe('top-level navigation common to all pages in the Security app', () => { +describe.skip('top-level navigation common to all pages in the Security app', () => { before(() => { cleanKibana(); loginAndWaitForPage(TIMELINES_URL); @@ -111,7 +111,7 @@ describe('top-level navigation common to all pages in the Security app', () => { }); }); -describe('Kibana navigation to all pages in the Security app ', () => { +describe.skip('Kibana navigation to all pages in the Security app ', () => { before(() => { loginAndWaitForPage(KIBANA_HOME); }); diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts.ts b/x-pack/plugins/security_solution/cypress/screens/alerts.ts index 0d6787c49adb30..83b3eb8a613cf2 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts.ts @@ -39,16 +39,16 @@ export const CLOSED_ALERTS_FILTER_BTN = '[data-test-subj="closedAlerts"]'; export const EXPAND_ALERT_BTN = '[data-test-subj="expand-event"]'; -export const IN_PROGRESS_ALERTS_FILTER_BTN = '[data-test-subj="inProgressAlerts"]'; +export const ACKNOWLEDGED_ALERTS_FILTER_BTN = '[data-test-subj="acknowledgedAlerts"]'; export const LOADING_ALERTS_PANEL = '[data-test-subj="loading-alerts-panel"]'; export const MANAGE_ALERT_DETECTION_RULES_BTN = '[data-test-subj="manage-alert-detection-rules"]'; -export const MARK_ALERT_IN_PROGRESS_BTN = '[data-test-subj="in-progress-alert-status"]'; +export const MARK_ALERT_ACKNOWLEDGED_BTN = '[data-test-subj="acknowledged-alert-status"]'; -export const MARK_SELECTED_ALERTS_IN_PROGRESS_BTN = - '[data-test-subj="markSelectedAlertsInProgressButton"]'; +export const MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN = + '[data-test-subj="markSelectedAlertsAcknowledgedButton"]'; export const NUMBER_OF_ALERTS = '[data-test-subj="events-viewer-panel"] [data-test-subj="server-side-event-count"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts index 0acace399b608b..abc3eed4e14182 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts @@ -13,11 +13,11 @@ import { CLOSE_SELECTED_ALERTS_BTN, CLOSED_ALERTS_FILTER_BTN, EXPAND_ALERT_BTN, - IN_PROGRESS_ALERTS_FILTER_BTN, + ACKNOWLEDGED_ALERTS_FILTER_BTN, LOADING_ALERTS_PANEL, MANAGE_ALERT_DETECTION_RULES_BTN, - MARK_ALERT_IN_PROGRESS_BTN, - MARK_SELECTED_ALERTS_IN_PROGRESS_BTN, + MARK_ALERT_ACKNOWLEDGED_BTN, + MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN, OPEN_ALERT_BTN, OPENED_ALERTS_FILTER_BTN, SEND_ALERT_TO_TIMELINE_BTN, @@ -112,18 +112,21 @@ export const openAlerts = () => { cy.get(OPEN_ALERT_BTN).click(); }; -export const goToInProgressAlerts = () => { - cy.get(IN_PROGRESS_ALERTS_FILTER_BTN).click(); +export const goToAcknowledgedAlerts = () => { + cy.get(ACKNOWLEDGED_ALERTS_FILTER_BTN).click(); + cy.get(REFRESH_BUTTON).should('not.have.text', 'Updating'); + cy.get(REFRESH_BUTTON).should('have.text', 'Refresh'); + cy.get(TIMELINE_COLUMN_SPINNER).should('not.exist'); }; -export const markInProgressFirstAlert = () => { +export const markAcknowledgedFirstAlert = () => { cy.get(TIMELINE_CONTEXT_MENU_BTN).first().click({ force: true }); - cy.get(MARK_ALERT_IN_PROGRESS_BTN).click(); + cy.get(MARK_ALERT_ACKNOWLEDGED_BTN).click(); }; -export const markInProgressAlerts = () => { +export const markAcknowledgedAlerts = () => { cy.get(TAKE_ACTION_POPOVER_BTN).click({ force: true }); - cy.get(MARK_SELECTED_ALERTS_IN_PROGRESS_BTN).click(); + cy.get(MARK_SELECTED_ALERTS_ACKNOWLEDGED_BTN).click(); }; export const selectNumberOfAlerts = (numberOfAlerts: number) => { diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx index 253406fa9c829b..f808e31ae6d2ce 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx @@ -337,7 +337,9 @@ describe('EventsViewer', () => { } + headerFilterGroup={ + + } /> ); @@ -350,7 +352,9 @@ describe('EventsViewer', () => { } + headerFilterGroup={ + + } /> ); @@ -365,7 +369,9 @@ describe('EventsViewer', () => { } + headerFilterGroup={ + + } /> ); @@ -380,7 +386,9 @@ describe('EventsViewer', () => { } + headerFilterGroup={ + + } /> ); @@ -395,7 +403,9 @@ describe('EventsViewer', () => { } + headerFilterGroup={ + + } /> ); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.test.tsx index c53207d0a8f65c..7c0b7cae95d039 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.test.tsx @@ -12,7 +12,9 @@ import { AlertsTableFilterGroup } from './index'; describe('AlertsTableFilterGroup', () => { it('renders correctly', () => { - const wrapper = shallow(); + const wrapper = shallow( + + ); expect(wrapper.find('EuiFilterButton')).toBeTruthy(); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx index 876cc47bff84a3..8304bffefb8d0b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx @@ -5,84 +5,58 @@ * 2.0. */ -import { EuiFilterButton, EuiFilterGroup } from '@elastic/eui'; -import { rgba } from 'polished'; -import React, { useCallback, useState } from 'react'; -import styled from 'styled-components'; +import { EuiButtonGroup, EuiButtonGroupOptionProps } from '@elastic/eui'; +import React, { useCallback } from 'react'; import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; import * as i18n from '../translations'; export const FILTER_OPEN: Status = 'open'; export const FILTER_CLOSED: Status = 'closed'; -export const FILTER_IN_PROGRESS: Status = 'in-progress'; - -const StatusFilterButton = styled(EuiFilterButton)<{ $isActive: boolean }>` - background: ${({ $isActive, theme }) => ($isActive ? theme.eui.euiColorPrimary : '')}; -`; - -const StatusFilterGroup = styled(EuiFilterGroup)` - background: ${({ theme }) => rgba(theme.eui.euiColorPrimary, 0.2)}; - .euiButtonEmpty--ghost:enabled:focus { - background-color: ${({ theme }) => theme.eui.euiColorPrimary}; - } -`; +export const FILTER_ACKNOWLEDGED: Status = 'acknowledged'; interface Props { + status: Status; onFilterGroupChanged: (filterGroup: Status) => void; } -const AlertsTableFilterGroupComponent: React.FC = ({ onFilterGroupChanged }) => { - const [filterGroup, setFilterGroup] = useState(FILTER_OPEN); - - const onClickOpenFilterCallback = useCallback(() => { - setFilterGroup(FILTER_OPEN); - onFilterGroupChanged(FILTER_OPEN); - }, [setFilterGroup, onFilterGroupChanged]); - - const onClickCloseFilterCallback = useCallback(() => { - setFilterGroup(FILTER_CLOSED); - onFilterGroupChanged(FILTER_CLOSED); - }, [setFilterGroup, onFilterGroupChanged]); - - const onClickInProgressFilterCallback = useCallback(() => { - setFilterGroup(FILTER_IN_PROGRESS); - onFilterGroupChanged(FILTER_IN_PROGRESS); - }, [setFilterGroup, onFilterGroupChanged]); +const AlertsTableFilterGroupComponent: React.FC = ({ + status = FILTER_OPEN, + onFilterGroupChanged, +}) => { + const options: EuiButtonGroupOptionProps[] = [ + { + id: 'open', + label: i18n.OPEN_ALERTS, + 'data-test-subj': 'openAlerts', + }, + { + id: 'acknowledged', + label: i18n.ACKNOWLEDGED_ALERTS, + 'data-test-subj': 'acknowledgedAlerts', + }, + { + id: 'closed', + label: i18n.CLOSED_ALERTS, + 'data-test-subj': 'closedAlerts', + }, + ]; + + const onChange = useCallback( + (id: string) => { + onFilterGroupChanged(id as Status); + }, + [onFilterGroupChanged] + ); return ( - - - {i18n.OPEN_ALERTS} - - - - {i18n.IN_PROGRESS_ALERTS} - - - - {i18n.CLOSED_ALERTS} - - + ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx index 8a88c430b03e9c..cba6a3f47f3fc8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/index.tsx @@ -27,7 +27,7 @@ import * as i18n from './translations'; import { useUiSetting$ } from '../../../../common/lib/kibana'; import { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline'; import { UpdateAlertsStatus } from '../types'; -import { FILTER_CLOSED, FILTER_IN_PROGRESS, FILTER_OPEN } from '../alerts_filter_group'; +import { FILTER_CLOSED, FILTER_ACKNOWLEDGED, FILTER_OPEN } from '../alerts_filter_group'; export interface AlertsUtilityBarProps { areEventsLoading: boolean; @@ -126,18 +126,18 @@ const AlertsUtilityBarComponent: React.FC = ({ )} - {currentFilter !== FILTER_IN_PROGRESS && ( + {currentFilter !== FILTER_ACKNOWLEDGED && ( { closePopover(); - handleUpdateStatus('in-progress'); + handleUpdateStatus('acknowledged'); }} color="text" - data-test-subj="markSelectedAlertsInProgressButton" + data-test-subj="markSelectedAlertsAcknowledgedButton" > - {i18n.BATCH_ACTION_IN_PROGRESS_SELECTED} + {i18n.BATCH_ACTION_ACKNOWLEDGED_SELECTED} )} diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts index c52e443c507531..66fcbae494a415 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_utility_bar/translations.ts @@ -105,9 +105,9 @@ export const BATCH_ACTION_CLOSE_SELECTED = i18n.translate( } ); -export const BATCH_ACTION_IN_PROGRESS_SELECTED = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.inProgressSelectedTitle', +export const BATCH_ACTION_ACKNOWLEDGED_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.acknowledgedSelectedTitle', { - defaultMessage: 'Mark in progress', + defaultMessage: 'Mark as acknowledged', } ); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index dec8e3e83a1ab8..8b987de04cba27 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -174,7 +174,8 @@ export const AlertsTableComponent: React.FC = ({ title = i18n.OPENED_ALERT_SUCCESS_TOAST(updated); break; case 'in-progress': - title = i18n.IN_PROGRESS_ALERT_SUCCESS_TOAST(updated); + case 'acknowledged': + title = i18n.ACKNOWLEDGED_ALERT_SUCCESS_TOAST(updated); } displaySuccessToast(title, dispatchToaster); } @@ -193,7 +194,8 @@ export const AlertsTableComponent: React.FC = ({ title = i18n.OPENED_ALERT_FAILED_TOAST; break; case 'in-progress': - title = i18n.IN_PROGRESS_ALERT_FAILED_TOAST; + case 'acknowledged': + title = i18n.ACKNOWLEDGED_ALERT_FAILED_TOAST; } displayErrorToast(title, [error.message], dispatchToaster); }, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/in_progress_alert_status.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/acknowledged_alert_status.tsx similarity index 55% rename from x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/in_progress_alert_status.tsx rename to x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/acknowledged_alert_status.tsx index f273833c1c1b35..1c97b304a74a35 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/in_progress_alert_status.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alerts_status_actions/acknowledged_alert_status.tsx @@ -7,30 +7,30 @@ import { EuiContextMenuItem } from '@elastic/eui'; import React from 'react'; -import { FILTER_IN_PROGRESS } from '../../alerts_filter_group'; +import { FILTER_ACKNOWLEDGED } from '../../alerts_filter_group'; import * as i18n from '../../translations'; -interface InProgressAlertStatusProps { +interface AcknowledgedAlertStatusProps { onClick: () => void; disabled?: boolean; } -const InProgressAlertStatusComponent: React.FC = ({ +const AcknowledgedAlertStatusComponent: React.FC = ({ onClick, disabled, }) => { return ( - {i18n.ACTION_IN_PROGRESS_ALERT} + {i18n.ACTION_ACKNOWLEDGED_ALERT} ); }; -export const InProgressAlertStatus = React.memo(InProgressAlertStatusComponent); +export const AcknowledgedAlertStatus = React.memo(AcknowledgedAlertStatusComponent); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts index ac768cf4c929d4..c6d9cd3eef7a37 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts @@ -38,10 +38,10 @@ export const CLOSED_ALERTS = i18n.translate( } ); -export const IN_PROGRESS_ALERTS = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.inProgressAlertsTitle', +export const ACKNOWLEDGED_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.acknowledgedAlertsTitle', { - defaultMessage: 'In progress', + defaultMessage: 'Acknowledged', } ); @@ -150,10 +150,10 @@ export const ACTION_CLOSE_ALERT = i18n.translate( } ); -export const ACTION_IN_PROGRESS_ALERT = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.actions.inProgressAlertTitle', +export const ACTION_ACKNOWLEDGED_ALERT = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.actions.acknowledgedAlertTitle', { - defaultMessage: 'Mark in progress', + defaultMessage: 'Mark as acknowledged', } ); @@ -220,13 +220,13 @@ export const OPENED_ALERT_SUCCESS_TOAST = (totalAlerts: number) => 'Successfully opened {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}}.', }); -export const IN_PROGRESS_ALERT_SUCCESS_TOAST = (totalAlerts: number) => +export const ACKNOWLEDGED_ALERT_SUCCESS_TOAST = (totalAlerts: number) => i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.inProgressAlertSuccessToastMessage', + 'xpack.securitySolution.detectionEngine.alerts.acknowledgedAlertSuccessToastMessage', { values: { totalAlerts }, defaultMessage: - 'Successfully marked {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}} as in progress.', + 'Successfully marked {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}} as acknowledged.', } ); @@ -244,10 +244,10 @@ export const OPENED_ALERT_FAILED_TOAST = i18n.translate( } ); -export const IN_PROGRESS_ALERT_FAILED_TOAST = i18n.translate( - 'xpack.securitySolution.detectionEngine.alerts.inProgressAlertFailedToastMessage', +export const ACKNOWLEDGED_ALERT_FAILED_TOAST = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.acknowledgedAlertFailedToastMessage', { - defaultMessage: 'Failed to mark alert(s) as in progress', + defaultMessage: 'Failed to mark alert(s) as acknowledged', } ); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts index c2930a4ae59ff0..88882131fed030 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/api.ts @@ -77,7 +77,7 @@ export const fetchQueryRuleRegistryAlerts = async ({ * Update alert status by query * * @param query of alerts to update - * @param status to update to('open' / 'closed' / 'in-progress') + * @param status to update to('open' / 'closed' / 'acknowledged') * @param signal AbortSignal for cancelling request * * @throws An error if response is not OK diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 838f0030defe19..e117a0d640fd70 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -297,7 +297,10 @@ const DetectionEnginePageComponent: React.FC = ({ - + {timelinesUi.getLastUpdated({ updatedAt: updatedAt || 0, showUpdating: loading })} diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index ffba80d165ac56..8c8f2d00e746a2 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -754,7 +754,10 @@ const RuleDetailsPageComponent: React.FC = ({ <> - + {timelinesUi.getLastUpdated({ diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/rule_status.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/rule_status.tsx index 09248b832490a0..d75bf436028f5f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/rule_status.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/rule_status.tsx @@ -14,7 +14,7 @@ import { DefaultDraggable } from '../../../../../common/components/draggables'; const mapping = { open: 'primary', - 'in-progress': 'warning', + acknowledged: 'warning', closed: 'default', }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts index 3dead29d54bbc5..f9693c87631b73 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts @@ -71,11 +71,15 @@ export const createMigration = async ({ enrichment.indicator.reference = indicator.event?.reference; enrichment.matched = indicator.matched; enrichment.indicator.remove("matched"); - ctx._source.threat.enrichments.add(enrichment); } ctx._source.threat.remove("indicator"); } + + // migrate status + if(ctx._source.signal?.status == "in-progress") { + ctx._source.signal.status = "acknowledged"; + } `, params: { version, diff --git a/x-pack/plugins/timelines/common/constants.ts b/x-pack/plugins/timelines/common/constants.ts index 9ef20f3ef5a6f1..0c03682cc83324 100644 --- a/x-pack/plugins/timelines/common/constants.ts +++ b/x-pack/plugins/timelines/common/constants.ts @@ -12,6 +12,12 @@ export const DEFAULT_NUMBER_FORMAT = 'format:number:defaultPattern'; export const FILTER_OPEN: AlertStatus = 'open'; export const FILTER_CLOSED: AlertStatus = 'closed'; + +/** + * @deprecated + * TODO: Remove after `acknowledged` migration + */ export const FILTER_IN_PROGRESS: AlertStatus = 'in-progress'; +export const FILTER_ACKNOWLEDGED: AlertStatus = 'acknowledged'; export const RAC_ALERTS_BULK_UPDATE_URL = '/internal/rac/alerts/bulk_update'; diff --git a/x-pack/plugins/timelines/common/types/timeline/actions/index.ts b/x-pack/plugins/timelines/common/types/timeline/actions/index.ts index 7eb769c53068dc..4d426272d86214 100644 --- a/x-pack/plugins/timelines/common/types/timeline/actions/index.ts +++ b/x-pack/plugins/timelines/common/types/timeline/actions/index.ts @@ -118,4 +118,10 @@ export interface BulkActionsObjectProp { } export type BulkActionsProp = boolean | BulkActionsObjectProp; -export type AlertStatus = 'open' | 'closed' | 'in-progress'; +/** + * @deprecated + * TODO: remove when `acknowledged` migrations are finished + */ +export type InProgressStatus = 'in-progress'; + +export type AlertStatus = 'open' | 'closed' | 'acknowledged' | InProgressStatus; diff --git a/x-pack/plugins/timelines/public/components/t_grid/translations.ts b/x-pack/plugins/timelines/public/components/t_grid/translations.ts index 7ea0d8a739a48f..4158a02ba3d723 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/translations.ts +++ b/x-pack/plugins/timelines/public/components/t_grid/translations.ts @@ -45,10 +45,10 @@ export const BULK_ACTION_CLOSE_SELECTED = i18n.translate( } ); -export const BULK_ACTION_IN_PROGRESS_SELECTED = i18n.translate( - 'xpack.timelines.timeline.inProgressSelectedTitle', +export const BULK_ACTION_ACKNOWLEDGED_SELECTED = i18n.translate( + 'xpack.timelines.timeline.acknowledgedSelectedTitle', { - defaultMessage: 'Mark in progress', + defaultMessage: 'Mark as acknowledged', } ); @@ -73,11 +73,11 @@ export const OPENED_ALERT_SUCCESS_TOAST = (totalAlerts: number) => 'Successfully opened {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}}.', }); -export const IN_PROGRESS_ALERT_SUCCESS_TOAST = (totalAlerts: number) => - i18n.translate('xpack.timelines.timeline.inProgressAlertSuccessToastMessage', { +export const ACKNOWLEDGED_ALERT_SUCCESS_TOAST = (totalAlerts: number) => + i18n.translate('xpack.timelines.timeline.acknowledgedAlertSuccessToastMessage', { values: { totalAlerts }, defaultMessage: - 'Successfully marked {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}} as in progress.', + 'Successfully marked {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}} as acknowledged.', }); export const CLOSED_ALERT_FAILED_TOAST = i18n.translate( @@ -94,10 +94,10 @@ export const OPENED_ALERT_FAILED_TOAST = i18n.translate( } ); -export const IN_PROGRESS_ALERT_FAILED_TOAST = i18n.translate( - 'xpack.timelines.timeline.inProgressAlertFailedToastMessage', +export const ACKNOWLEDGED_ALERT_FAILED_TOAST = i18n.translate( + 'xpack.timelines.timeline.acknowledgedAlertFailedToastMessage', { - defaultMessage: 'Failed to mark alert(s) as in progress', + defaultMessage: 'Failed to mark alert(s) as acknowledged', } ); diff --git a/x-pack/plugins/timelines/public/hooks/use_status_bulk_action_items.tsx b/x-pack/plugins/timelines/public/hooks/use_status_bulk_action_items.tsx index fd8880ca468b61..bab9f641d97240 100644 --- a/x-pack/plugins/timelines/public/hooks/use_status_bulk_action_items.tsx +++ b/x-pack/plugins/timelines/public/hooks/use_status_bulk_action_items.tsx @@ -7,7 +7,7 @@ import React, { useMemo, useCallback } from 'react'; import { EuiContextMenuItem } from '@elastic/eui'; -import { FILTER_CLOSED, FILTER_IN_PROGRESS, FILTER_OPEN } from '../../common/constants'; +import { FILTER_CLOSED, FILTER_ACKNOWLEDGED, FILTER_OPEN } from '../../common/constants'; import * as i18n from '../components/t_grid/translations'; import type { AlertStatus, StatusBulkActionsProps } from '../../common/types/timeline'; import { useUpdateAlertsStatus } from '../container/use_update_alerts'; @@ -48,7 +48,8 @@ export const useStatusBulkActionItems = ({ title = i18n.OPENED_ALERT_SUCCESS_TOAST(updated); break; case 'in-progress': - title = i18n.IN_PROGRESS_ALERT_SUCCESS_TOAST(updated); + case 'acknowledged': + title = i18n.ACKNOWLEDGED_ALERT_SUCCESS_TOAST(updated); } addSuccess({ title }); } @@ -70,7 +71,8 @@ export const useStatusBulkActionItems = ({ title = i18n.OPENED_ALERT_FAILED_TOAST; break; case 'in-progress': - title = i18n.IN_PROGRESS_ALERT_FAILED_TOAST; + case 'acknowledged': + title = i18n.ACKNOWLEDGED_ALERT_FAILED_TOAST; } addError(error.message, { title }); if (onUpdateFailure) { @@ -131,15 +133,15 @@ export const useStatusBulkActionItems = ({ ); } - if (currentStatus !== FILTER_IN_PROGRESS) { + if (currentStatus !== FILTER_ACKNOWLEDGED) { actionItems.push( onClickUpdate(FILTER_IN_PROGRESS)} + key="acknowledge" + data-test-subj="acknowledged-alert-status" + onClick={() => onClickUpdate(FILTER_ACKNOWLEDGED)} size="s" > - {i18n.BULK_ACTION_IN_PROGRESS_SELECTED} + {i18n.BULK_ACTION_ACKNOWLEDGED_SELECTED} ); } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1216d2368e0287..fe6d60f63ecfec 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -20427,7 +20427,6 @@ "xpack.securitySolution.detectionEngine.alerts.actions.addEventFilter": "エンドポイントイベントフィルターを追加", "xpack.securitySolution.detectionEngine.alerts.actions.addException": "ルール例外の追加", "xpack.securitySolution.detectionEngine.alerts.actions.closeAlertTitle": "アラートを閉じる", - "xpack.securitySolution.detectionEngine.alerts.actions.inProgressAlertTitle": "実行中に設定", "xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineAriaLabel": "アラートをタイムラインに送信", "xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineTitle": "タイムラインで調査", "xpack.securitySolution.detectionEngine.alerts.actions.openAlertTitle": "アラートを開く", @@ -20439,8 +20438,6 @@ "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.stackByLabel": "積み上げ", "xpack.securitySolution.detectionEngine.alerts.histogram.topNLabel": "トップ{fieldName}", "xpack.securitySolution.detectionEngine.alerts.histogram.viewAlertsButtonLabel": "アラートを表示", - "xpack.securitySolution.detectionEngine.alerts.inProgressAlertFailedToastMessage": "アラートを実行中に設定できませんでした", - "xpack.securitySolution.detectionEngine.alerts.inProgressAlertsTitle": "進行中", "xpack.securitySolution.detectionEngine.alerts.loadingAlertsTitle": "アラートを読み込んでいます", "xpack.securitySolution.detectionEngine.alerts.moreActionsAriaLabel": "さらにアクションを表示", "xpack.securitySolution.detectionEngine.alerts.openAlertsTitle": "開く", @@ -20451,7 +20448,6 @@ "xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts": "脅威インジケーターアラートのみを表示", "xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle": "追加のフィルター", "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle": "選択した項目を閉じる", - "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.inProgressSelectedTitle": "実行中に設定", "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle": "選択した項目を開く", "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInHostsTitle": "ホストで選択した項目を表示", "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInNetworkTitle": "ネットワークで選択した項目を表示", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e1f512568a99bb..34fc311e4f5ec8 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -20701,7 +20701,6 @@ "xpack.securitySolution.detectionEngine.alerts.actions.addEventFilter": "添加终端事件筛选", "xpack.securitySolution.detectionEngine.alerts.actions.addException": "添加规则例外", "xpack.securitySolution.detectionEngine.alerts.actions.closeAlertTitle": "关闭告警", - "xpack.securitySolution.detectionEngine.alerts.actions.inProgressAlertTitle": "标记为进行中", "xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineAriaLabel": "将告警发送到时间线", "xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineTitle": "在时间线中调查", "xpack.securitySolution.detectionEngine.alerts.actions.openAlertTitle": "打开告警", @@ -20715,9 +20714,6 @@ "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.stackByLabel": "堆叠依据", "xpack.securitySolution.detectionEngine.alerts.histogram.topNLabel": "排名靠前的{fieldName}", "xpack.securitySolution.detectionEngine.alerts.histogram.viewAlertsButtonLabel": "查看告警", - "xpack.securitySolution.detectionEngine.alerts.inProgressAlertFailedToastMessage": "无法将告警标记为进行中", - "xpack.securitySolution.detectionEngine.alerts.inProgressAlertsTitle": "进行中", - "xpack.securitySolution.detectionEngine.alerts.inProgressAlertSuccessToastMessage": "已成功将 {totalAlerts} 个{totalAlerts, plural, other {告警}}标记为进行中。", "xpack.securitySolution.detectionEngine.alerts.loadingAlertsTitle": "正在加载告警", "xpack.securitySolution.detectionEngine.alerts.moreActionsAriaLabel": "更多操作", "xpack.securitySolution.detectionEngine.alerts.openAlertsTitle": "打开", @@ -20729,7 +20725,6 @@ "xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showOnlyThreatIndicatorAlerts": "仅显示威胁指标告警", "xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle": "其他筛选", "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle": "关闭所选", - "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.inProgressSelectedTitle": "标记为进行中", "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle": "打开所选", "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInHostsTitle": "查看主机中所选", "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInNetworkTitle": "查看网络中所选", diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/update_rac_alerts.ts b/x-pack/test/detection_engine_api_integration/basic/tests/update_rac_alerts.ts index e14b29765e7b0b..d8e5f42bbd5860 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/update_rac_alerts.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/update_rac_alerts.ts @@ -145,6 +145,37 @@ export default ({ getService }: FtrProviderContext) => { ); expect(everySignalClosed).to.eql(true); }); + + it('should be able mark 10 signals as acknowledged immediately and they all should be acknowledged', async () => { + const rule = getRuleForSignalTesting(['auditbeat-*']); + const { id } = await createRule(supertest, rule); + await waitForRuleSuccessOrStatus(supertest, id); + await waitForSignalsToBePresent(supertest, 10, [id]); + const signalsOpen = await getSignalsByIds(supertest, [id]); + const signalIds = signalsOpen.hits.hits.map((signal) => signal._id); + + // set all of the signals to the state of acknowledged. There is no reason to use a waitUntil here + // as this route intentionally has a waitFor within it and should only return when the query has + // the data. + await supertest + .post(RAC_ALERTS_BULK_UPDATE_URL) + .set('kbn-xsrf', 'true') + .send({ ids: signalIds, status: 'acknowledged', index: '.siem-signals-default' }) + .expect(200); + + const { + body: acknowledgedSignals, + }: { body: estypes.SearchResponse<{ signal: Signal }> } = await supertest + .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) + .set('kbn-xsrf', 'true') + .send(getQuerySignalIds(signalIds)) + .expect(200); + + const everyAcknowledgedSignal = acknowledgedSignals.hits.hits.every( + (hit) => hit._source?.signal?.status === 'acknowledged' + ); + expect(everyAcknowledgedSignal).to.eql(true); + }); }); }); };