From 94271d85e51ded8cd9991954859d14cb06ae5c8f Mon Sep 17 00:00:00 2001 From: Ying Date: Wed, 10 Jan 2024 10:56:05 -0500 Subject: [PATCH] Default alerts as data docs for legacy siem notification rule type --- .../alert_as_data_fields.test.ts.snap | 6 +- .../routes/__mocks__/request_responses.ts | 6 +- .../api/create_legacy_notification/route.ts | 4 +- .../rule_actions_legacy/index.ts | 8 +- .../legacy_create_notifications.ts | 6 +- .../legacy_read_notifications.ts | 9 +- ...gacy_rules_notification_alert_type.test.ts | 250 ------- ...egacy_rules_notification_rule_type.test.ts | 647 ++++++++++++++++++ ...=> legacy_rules_notification_rule_type.ts} | 34 +- .../legacy_saved_object_references/README.md | 2 +- .../legacy_extract_references.ts | 2 +- .../logic/notifications/legacy_types.ts | 52 +- .../security_solution/server/plugin.ts | 8 +- 13 files changed, 726 insertions(+), 308 deletions(-) delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_rule_type.test.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/{legacy_rules_notification_alert_type.ts => legacy_rules_notification_rule_type.ts} (85%) diff --git a/x-pack/plugins/alerting/server/integration_tests/__snapshots__/alert_as_data_fields.test.ts.snap b/x-pack/plugins/alerting/server/integration_tests/__snapshots__/alert_as_data_fields.test.ts.snap index 3f3785b89f619..d2c775234c8bb 100644 --- a/x-pack/plugins/alerting/server/integration_tests/__snapshots__/alert_as_data_fields.test.ts.snap +++ b/x-pack/plugins/alerting/server/integration_tests/__snapshots__/alert_as_data_fields.test.ts.snap @@ -5802,7 +5802,11 @@ Object { } `; -exports[`Alert as data fields checks detect AAD fields changes for: siem.notifications 1`] = `undefined`; +exports[`Alert as data fields checks detect AAD fields changes for: siem.notifications 1`] = ` +Object { + "fieldMap": Object {}, +} +`; exports[`Alert as data fields checks detect AAD fields changes for: siem.queryRule 1`] = ` Object { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts index 2f6ea38b40b81..0459636ff75ca 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -46,7 +46,7 @@ import { } from '../../../../../common/api/detection_engine/signals_migration/mocks'; // eslint-disable-next-line no-restricted-imports -import type { LegacyRuleNotificationAlertType } from '../../rule_actions_legacy'; +import type { LegacyRuleNotificationRuleType } from '../../rule_actions_legacy'; import type { RuleAlertType, RuleParams } from '../../rule_schema'; import { getQueryRuleParams } from '../../rule_schema/mocks'; @@ -520,7 +520,7 @@ export const legacyGetNotificationResult = ({ }: { id?: string; ruleId?: string; -} = {}): LegacyRuleNotificationAlertType => ({ +} = {}): LegacyRuleNotificationRuleType => ({ id, name: 'Notification for Rule Test', tags: [], @@ -567,7 +567,7 @@ export const legacyGetNotificationResult = ({ */ export const legacyGetFindNotificationsResultWithSingleHit = ( ruleId = '123' -): FindHit => ({ +): FindHit => ({ page: 1, perPage: 1, total: 1, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts index df2c4bb3366b9..518ece11dbefe 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts @@ -14,7 +14,7 @@ import { legacyUpdateOrCreateRuleActionsSavedObject } from '../../logic/rule_act // eslint-disable-next-line no-restricted-imports import { legacyReadNotifications } from '../../logic/notifications/legacy_read_notifications'; // eslint-disable-next-line no-restricted-imports -import type { LegacyRuleNotificationAlertTypeParams } from '../../logic/notifications/legacy_types'; +import type { LegacyRuleNotificationRuleTypeParams } from '../../logic/notifications/legacy_types'; // eslint-disable-next-line no-restricted-imports import { legacyCreateNotifications } from '../../logic/notifications/legacy_create_notifications'; import { UPDATE_OR_CREATE_LEGACY_ACTIONS } from '../../../../../../common/constants'; @@ -75,7 +75,7 @@ export const legacyCreateLegacyNotificationRoute = ( ruleAlertId, }); if (notification != null) { - await rulesClient.update({ + await rulesClient.update({ id: notification.id, data: { tags: [], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/index.ts index fddf872583040..e577d0ac5355a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/index.ts @@ -8,13 +8,13 @@ export * from './api/register_routes'; // eslint-disable-next-line no-restricted-imports -export { legacyRulesNotificationAlertType } from './logic/notifications/legacy_rules_notification_alert_type'; +export { legacyRulesNotificationRuleType } from './logic/notifications/legacy_rules_notification_rule_type'; // eslint-disable-next-line no-restricted-imports -export { legacyIsNotificationAlertExecutor } from './logic/notifications/legacy_types'; +export { isLegacyNotificationRuleExecutor } from './logic/notifications/legacy_types'; // eslint-disable-next-line no-restricted-imports export type { - LegacyRuleNotificationAlertType, - LegacyRuleNotificationAlertTypeParams, + LegacyRuleNotificationRuleType, + LegacyRuleNotificationRuleTypeParams, } from './logic/notifications/legacy_types'; export type { NotificationRuleTypeParams } from './logic/notifications/schedule_notification_actions'; export { scheduleNotificationActions } from './logic/notifications/schedule_notification_actions'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.ts index 983519404b222..34428140e9a12 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.ts @@ -10,7 +10,7 @@ import { SERVER_APP_ID, LEGACY_NOTIFICATIONS_ID } from '../../../../../../common // eslint-disable-next-line no-restricted-imports import type { CreateNotificationParams, - LegacyRuleNotificationAlertTypeParams, + LegacyRuleNotificationRuleTypeParams, } from './legacy_types'; /** @@ -23,8 +23,8 @@ export const legacyCreateNotifications = async ({ ruleAlertId, interval, name, -}: CreateNotificationParams): Promise> => - rulesClient.create({ +}: CreateNotificationParams): Promise> => + rulesClient.create({ data: { name, tags: [], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.ts index 187cde7ce8c9d..fda0b6b45ca56 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.ts @@ -9,7 +9,7 @@ import type { RuleTypeParams, SanitizedRule } from '@kbn/alerting-plugin/common' // eslint-disable-next-line no-restricted-imports import type { LegacyReadNotificationParams } from './legacy_types'; // eslint-disable-next-line no-restricted-imports -import { legacyIsAlertType } from './legacy_types'; +import { isLegacyRuleType } from './legacy_types'; // eslint-disable-next-line no-restricted-imports import { legacyFindNotifications } from './legacy_find_notifications'; @@ -24,7 +24,7 @@ export const legacyReadNotifications = async ({ if (id != null) { try { const notification = await rulesClient.get({ id }); - if (legacyIsAlertType(notification)) { + if (isLegacyRuleType(notification)) { return notification; } else { return null; @@ -43,10 +43,7 @@ export const legacyReadNotifications = async ({ filter: `alert.attributes.params.ruleAlertId: "${ruleAlertId}"`, page: 1, }); - if ( - notificationFromFind.data.length === 0 || - !legacyIsAlertType(notificationFromFind.data[0]) - ) { + if (notificationFromFind.data.length === 0 || !isLegacyRuleType(notificationFromFind.data[0])) { return null; } else { return notificationFromFind.data[0]; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts deleted file mode 100644 index 0f0eeece6f8f6..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts +++ /dev/null @@ -1,250 +0,0 @@ -/* - * 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 { loggingSystemMock } from '@kbn/core/server/mocks'; -import type { RuleExecutorServicesMock } from '@kbn/alerting-plugin/server/mocks'; -import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; -import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; - -import { getRuleMock } from '../../../routes/__mocks__/request_responses'; -// eslint-disable-next-line no-restricted-imports -import { legacyRulesNotificationAlertType } from './legacy_rules_notification_alert_type'; -import { buildSignalsSearchQuery } from './build_signals_query'; -// eslint-disable-next-line no-restricted-imports -import type { LegacyNotificationExecutorOptions } from './legacy_types'; -import { - sampleDocSearchResultsNoSortIdNoVersion, - sampleDocSearchResultsWithSortId, - sampleEmptyDocSearchResults, -} from '../../../rule_types/__mocks__/es_results'; -import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE } from '../../../../../../common/constants'; -import { getQueryRuleParams } from '../../../rule_schema/mocks'; - -jest.mock('./build_signals_query'); - -/** - * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function - */ -describe('legacyRules_notification_alert_type', () => { - let payload: LegacyNotificationExecutorOptions; - let alert: ReturnType; - let logger: ReturnType; - let alertServices: RuleExecutorServicesMock; - - beforeEach(() => { - alertServices = alertsMock.createRuleExecutorServices(); - logger = loggingSystemMock.createLogger(); - - payload = { - executionId: 'b33f65d7-b33f-4aae-8d20-c93613dec9f9', - services: alertServices, - params: { ruleAlertId: '2222' }, - state: {}, - spaceId: '', - startedAt: new Date('2019-12-14T16:40:33.400Z'), - previousStartedAt: new Date('2019-12-13T16:40:33.400Z'), - rule: { - id: '1111', - name: 'name', - tags: [], - consumer: 'foo', - producer: 'foo', - revision: 0, - ruleTypeId: 'ruleType', - ruleTypeName: 'Name of rule', - enabled: true, - schedule: { - interval: '1h', - }, - actions: [], - createdBy: 'elastic', - updatedBy: 'elastic', - createdAt: new Date('2019-12-14T16:40:33.400Z'), - updatedAt: new Date('2019-12-14T16:40:33.400Z'), - throttle: null, - notifyWhen: null, - muteAll: false, - snoozeSchedule: [], - }, - logger, - flappingSettings: DEFAULT_FLAPPING_SETTINGS, - getTimeRange: () => { - const date = new Date('2019-12-14T16:40:33.400Z').toISOString(); - return { dateStart: date, dateEnd: date }; - }, - }; - - alert = legacyRulesNotificationAlertType({ - logger, - }); - }); - - describe('executor', () => { - it('throws an error if rule alert was not found', async () => { - alertServices.savedObjectsClient.get.mockResolvedValue({ - id: 'id', - attributes: {}, - type: 'type', - references: [], - }); - await alert.executor(payload); - expect(logger.error).toHaveBeenCalledWith( - `Security Solution notification (Legacy) saved object for alert ${payload.params.ruleAlertId} was not found with id: \"1111\". space id: \"\" This indicates a dangling (Legacy) notification alert. You should delete this rule through \"Kibana UI -> Stack Management -> Rules and Connectors\" to remove this error message.` - ); - }); - - it('should call buildSignalsSearchQuery with proper params', async () => { - const ruleAlert = getRuleMock(getQueryRuleParams()); - alertServices.savedObjectsClient.get.mockResolvedValue({ - id: 'id', - type: 'type', - references: [], - attributes: ruleAlert, - }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( - sampleDocSearchResultsWithSortId() - ); - - await alert.executor(payload); - - expect(buildSignalsSearchQuery).toHaveBeenCalledWith( - expect.objectContaining({ - from: '1576255233400', - index: '.siem-signals', - ruleId: 'rule-1', - to: '1576341633400', - size: DEFAULT_RULE_NOTIFICATION_QUERY_SIZE, - }) - ); - }); - - it('should resolve results_link when meta is undefined to use "/app/security"', async () => { - const ruleAlert = getRuleMock(getQueryRuleParams()); - delete ruleAlert.params.meta; - alertServices.savedObjectsClient.get.mockResolvedValue({ - id: 'rule-id', - type: 'type', - references: [], - attributes: ruleAlert, - }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( - sampleDocSearchResultsWithSortId() - ); - - await alert.executor(payload); - expect(alertServices.alertFactory.create).toHaveBeenCalled(); - - const [{ value: alertInstanceMock }] = alertServices.alertFactory.create.mock.results; - expect(alertInstanceMock.scheduleActions).toHaveBeenCalledWith( - 'default', - expect.objectContaining({ - results_link: - '/app/security/detections/rules/id/rule-id?timerange=(global:(linkTo:!(timeline),timerange:(from:1576255233400,kind:absolute,to:1576341633400)),timeline:(linkTo:!(global),timerange:(from:1576255233400,kind:absolute,to:1576341633400)))', - }) - ); - }); - - it('should resolve results_link when meta is an empty object to use "/app/security"', async () => { - const ruleAlert = getRuleMock(getQueryRuleParams()); - ruleAlert.params.meta = {}; - alertServices.savedObjectsClient.get.mockResolvedValue({ - id: 'rule-id', - type: 'type', - references: [], - attributes: ruleAlert, - }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( - sampleDocSearchResultsWithSortId() - ); - await alert.executor(payload); - expect(alertServices.alertFactory.create).toHaveBeenCalled(); - - const [{ value: alertInstanceMock }] = alertServices.alertFactory.create.mock.results; - expect(alertInstanceMock.scheduleActions).toHaveBeenCalledWith( - 'default', - expect.objectContaining({ - results_link: - '/app/security/detections/rules/id/rule-id?timerange=(global:(linkTo:!(timeline),timerange:(from:1576255233400,kind:absolute,to:1576341633400)),timeline:(linkTo:!(global),timerange:(from:1576255233400,kind:absolute,to:1576341633400)))', - }) - ); - }); - - it('should resolve results_link to custom kibana link when given one', async () => { - const ruleAlert = getRuleMock(getQueryRuleParams()); - ruleAlert.params.meta = { - kibana_siem_app_url: 'http://localhost', - }; - alertServices.savedObjectsClient.get.mockResolvedValue({ - id: 'rule-id', - type: 'type', - references: [], - attributes: ruleAlert, - }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( - sampleDocSearchResultsWithSortId() - ); - await alert.executor(payload); - expect(alertServices.alertFactory.create).toHaveBeenCalled(); - - const [{ value: alertInstanceMock }] = alertServices.alertFactory.create.mock.results; - expect(alertInstanceMock.scheduleActions).toHaveBeenCalledWith( - 'default', - expect.objectContaining({ - results_link: - 'http://localhost/detections/rules/id/rule-id?timerange=(global:(linkTo:!(timeline),timerange:(from:1576255233400,kind:absolute,to:1576341633400)),timeline:(linkTo:!(global),timerange:(from:1576255233400,kind:absolute,to:1576341633400)))', - }) - ); - }); - - it('should not call alertFactory.create if signalsCount was 0', async () => { - const ruleAlert = getRuleMock(getQueryRuleParams()); - alertServices.savedObjectsClient.get.mockResolvedValue({ - id: 'id', - type: 'type', - references: [], - attributes: ruleAlert, - }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( - sampleEmptyDocSearchResults() - ); - - await alert.executor(payload); - - expect(alertServices.alertFactory.create).not.toHaveBeenCalled(); - }); - - it('should call scheduleActions if signalsCount was greater than 0', async () => { - const ruleAlert = getRuleMock(getQueryRuleParams()); - alertServices.savedObjectsClient.get.mockResolvedValue({ - id: 'id', - type: 'type', - references: [], - attributes: ruleAlert, - }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( - sampleDocSearchResultsNoSortIdNoVersion() - ); - - await alert.executor(payload); - - expect(alertServices.alertFactory.create).toHaveBeenCalled(); - - const [{ value: alertInstanceMock }] = alertServices.alertFactory.create.mock.results; - expect(alertInstanceMock.replaceState).toHaveBeenCalledWith( - expect.objectContaining({ signals_count: 100 }) - ); - expect(alertInstanceMock.scheduleActions).toHaveBeenCalledWith( - 'default', - expect.objectContaining({ - rule: expect.objectContaining({ - name: ruleAlert.name, - }), - }) - ); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_rule_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_rule_type.test.ts new file mode 100644 index 0000000000000..d485cb75e6439 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_rule_type.test.ts @@ -0,0 +1,647 @@ +/* + * 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 { loggingSystemMock } from '@kbn/core/server/mocks'; +import type { RuleExecutorServicesMock } from '@kbn/alerting-plugin/server/mocks'; +import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; +import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; + +import { getRuleMock } from '../../../routes/__mocks__/request_responses'; +// eslint-disable-next-line no-restricted-imports +import { legacyRulesNotificationRuleType } from './legacy_rules_notification_rule_type'; +import { buildSignalsSearchQuery } from './build_signals_query'; +// eslint-disable-next-line no-restricted-imports +import type { LegacyNotificationExecutorOptions } from './legacy_types'; +import { + sampleDocSearchResultsNoSortIdNoVersion, + sampleDocSearchResultsWithSortId, + sampleEmptyDocSearchResults, +} from '../../../rule_types/__mocks__/es_results'; +import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE } from '../../../../../../common/constants'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; + +jest.mock('./build_signals_query'); + +/** + * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function + */ +describe('legacyRules_notification_rule_type', () => { + let payload: LegacyNotificationExecutorOptions; + let rule: ReturnType; + let logger: ReturnType; + let alertServices: RuleExecutorServicesMock; + + beforeEach(() => { + alertServices = alertsMock.createRuleExecutorServices(); + logger = loggingSystemMock.createLogger(); + + payload = { + executionId: 'b33f65d7-b33f-4aae-8d20-c93613dec9f9', + services: alertServices, + params: { ruleAlertId: '2222' }, + state: {}, + spaceId: '', + startedAt: new Date('2019-12-14T16:40:33.400Z'), + previousStartedAt: new Date('2019-12-13T16:40:33.400Z'), + rule: { + id: '1111', + name: 'name', + tags: [], + consumer: 'foo', + producer: 'foo', + revision: 0, + ruleTypeId: 'ruleType', + ruleTypeName: 'Name of rule', + enabled: true, + schedule: { + interval: '1h', + }, + actions: [], + createdBy: 'elastic', + updatedBy: 'elastic', + createdAt: new Date('2019-12-14T16:40:33.400Z'), + updatedAt: new Date('2019-12-14T16:40:33.400Z'), + throttle: null, + notifyWhen: null, + muteAll: false, + snoozeSchedule: [], + }, + logger, + flappingSettings: DEFAULT_FLAPPING_SETTINGS, + getTimeRange: () => { + const date = new Date('2019-12-14T16:40:33.400Z').toISOString(); + return { dateStart: date, dateEnd: date }; + }, + }; + + rule = legacyRulesNotificationRuleType({ + logger, + }); + }); + + describe('executor', () => { + it('throws an error if rule alert was not found', async () => { + alertServices.savedObjectsClient.get.mockResolvedValue({ + id: 'id', + attributes: {}, + type: 'type', + references: [], + }); + await rule.executor(payload); + expect(logger.error).toHaveBeenCalledWith( + `Security Solution notification (Legacy) saved object for alert ${payload.params.ruleAlertId} was not found with id: \"1111\". space id: \"\" This indicates a dangling (Legacy) notification alert. You should delete this rule through \"Kibana UI -> Stack Management -> Rules and Connectors\" to remove this error message.` + ); + }); + + it('should call buildSignalsSearchQuery with proper params', async () => { + const ruleAlert = getRuleMock(getQueryRuleParams()); + alertServices.savedObjectsClient.get.mockResolvedValue({ + id: 'id', + type: 'type', + references: [], + attributes: ruleAlert, + }); + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsWithSortId() + ); + + await rule.executor(payload); + + expect(buildSignalsSearchQuery).toHaveBeenCalledWith( + expect.objectContaining({ + from: '1576255233400', + index: '.siem-signals', + ruleId: 'rule-1', + to: '1576341633400', + size: DEFAULT_RULE_NOTIFICATION_QUERY_SIZE, + }) + ); + }); + + it('should resolve results_link when meta is undefined to use "/app/security"', async () => { + const ruleAlert = getRuleMock(getQueryRuleParams()); + delete ruleAlert.params.meta; + alertServices.savedObjectsClient.get.mockResolvedValue({ + id: 'rule-id', + type: 'type', + references: [], + attributes: ruleAlert, + }); + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsWithSortId() + ); + + await rule.executor(payload); + expect(alertServices.alertsClient.report).toHaveBeenCalledWith({ + actionGroup: 'default', + context: { + alerts: [ + { + '@timestamp': expect.any(String), + destination: { + ip: '127.0.0.1', + }, + someKey: 'someValue', + source: { + ip: '127.0.0.1', + }, + }, + ], + results_link: + '/app/security/detections/rules/id/rule-id?timerange=(global:(linkTo:!(timeline),timerange:(from:1576255233400,kind:absolute,to:1576341633400)),timeline:(linkTo:!(global),timerange:(from:1576255233400,kind:absolute,to:1576341633400)))', + rule: { + alert_suppression: undefined, + author: ['Elastic'], + building_block_type: 'default', + data_view_id: undefined, + description: 'Detecting root and admin users', + exceptions_list: [ + { + id: 'some_uuid', + list_id: 'list_id_single', + namespace_type: 'single', + type: 'detection', + }, + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ], + false_positives: [], + filters: [ + { + query: { + match_phrase: { + 'host.name': 'some-host', + }, + }, + }, + ], + from: 'now-6m', + id: 'rule-id', + immutable: false, + index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + investigation_fields: undefined, + language: 'kuery', + license: 'Elastic License', + max_signals: 10000, + name: 'Detect Root/Admin Users', + namespace: undefined, + note: '# Investigative notes', + output_index: '.siem-signals', + query: 'user.name: root or user.name: admin', + references: ['http://example.com', 'https://example.com'], + related_integrations: [], + required_fields: [], + response_actions: undefined, + risk_score: 50, + risk_score_mapping: [], + rule_id: 'rule-1', + rule_name_override: undefined, + saved_id: undefined, + setup: '', + severity: 'high', + severity_mapping: [], + threat: [ + { + framework: 'MITRE ATT&CK', + tactic: { + id: 'TA0000', + name: 'test tactic', + reference: 'https://attack.mitre.org/tactics/TA0000/', + }, + technique: [ + { + id: 'T0000', + name: 'test technique', + reference: 'https://attack.mitre.org/techniques/T0000/', + subtechnique: [ + { + id: 'T0000.000', + name: 'test subtechnique', + reference: 'https://attack.mitre.org/techniques/T0000/000/', + }, + ], + }, + ], + }, + ], + timeline_id: 'some-timeline-id', + timeline_title: 'some-timeline-title', + timestamp_override: undefined, + timestamp_override_fallback_disabled: undefined, + to: 'now', + type: 'query', + version: 1, + }, + }, + id: '1111', + state: { + signals_count: 1, + }, + }); + }); + + it('should resolve results_link when meta is an empty object to use "/app/security"', async () => { + const ruleAlert = getRuleMock(getQueryRuleParams()); + ruleAlert.params.meta = {}; + alertServices.savedObjectsClient.get.mockResolvedValue({ + id: 'rule-id', + type: 'type', + references: [], + attributes: ruleAlert, + }); + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsWithSortId() + ); + await rule.executor(payload); + expect(alertServices.alertsClient.report).toHaveBeenCalledWith({ + actionGroup: 'default', + context: { + alerts: [ + { + '@timestamp': expect.any(String), + destination: { + ip: '127.0.0.1', + }, + someKey: 'someValue', + source: { + ip: '127.0.0.1', + }, + }, + ], + results_link: + '/app/security/detections/rules/id/rule-id?timerange=(global:(linkTo:!(timeline),timerange:(from:1576255233400,kind:absolute,to:1576341633400)),timeline:(linkTo:!(global),timerange:(from:1576255233400,kind:absolute,to:1576341633400)))', + rule: { + alert_suppression: undefined, + author: ['Elastic'], + building_block_type: 'default', + data_view_id: undefined, + description: 'Detecting root and admin users', + exceptions_list: [ + { + id: 'some_uuid', + list_id: 'list_id_single', + namespace_type: 'single', + type: 'detection', + }, + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ], + false_positives: [], + filters: [ + { + query: { + match_phrase: { + 'host.name': 'some-host', + }, + }, + }, + ], + from: 'now-6m', + id: 'rule-id', + immutable: false, + index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + investigation_fields: undefined, + language: 'kuery', + license: 'Elastic License', + max_signals: 10000, + meta: {}, + name: 'Detect Root/Admin Users', + namespace: undefined, + note: '# Investigative notes', + output_index: '.siem-signals', + query: 'user.name: root or user.name: admin', + references: ['http://example.com', 'https://example.com'], + related_integrations: [], + required_fields: [], + response_actions: undefined, + risk_score: 50, + risk_score_mapping: [], + rule_id: 'rule-1', + rule_name_override: undefined, + saved_id: undefined, + setup: '', + severity: 'high', + severity_mapping: [], + threat: [ + { + framework: 'MITRE ATT&CK', + tactic: { + id: 'TA0000', + name: 'test tactic', + reference: 'https://attack.mitre.org/tactics/TA0000/', + }, + technique: [ + { + id: 'T0000', + name: 'test technique', + reference: 'https://attack.mitre.org/techniques/T0000/', + subtechnique: [ + { + id: 'T0000.000', + name: 'test subtechnique', + reference: 'https://attack.mitre.org/techniques/T0000/000/', + }, + ], + }, + ], + }, + ], + timeline_id: 'some-timeline-id', + timeline_title: 'some-timeline-title', + timestamp_override: undefined, + timestamp_override_fallback_disabled: undefined, + to: 'now', + type: 'query', + version: 1, + }, + }, + id: '1111', + state: { + signals_count: 1, + }, + }); + }); + + it('should resolve results_link to custom kibana link when given one', async () => { + const ruleAlert = getRuleMock(getQueryRuleParams()); + ruleAlert.params.meta = { + kibana_siem_app_url: 'http://localhost', + }; + alertServices.savedObjectsClient.get.mockResolvedValue({ + id: 'rule-id', + type: 'type', + references: [], + attributes: ruleAlert, + }); + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsWithSortId() + ); + await rule.executor(payload); + expect(alertServices.alertsClient.report).toHaveBeenCalledWith({ + actionGroup: 'default', + context: { + alerts: [ + { + '@timestamp': expect.any(String), + destination: { + ip: '127.0.0.1', + }, + someKey: 'someValue', + source: { + ip: '127.0.0.1', + }, + }, + ], + results_link: + 'http://localhost/detections/rules/id/rule-id?timerange=(global:(linkTo:!(timeline),timerange:(from:1576255233400,kind:absolute,to:1576341633400)),timeline:(linkTo:!(global),timerange:(from:1576255233400,kind:absolute,to:1576341633400)))', + rule: { + alert_suppression: undefined, + author: ['Elastic'], + building_block_type: 'default', + data_view_id: undefined, + description: 'Detecting root and admin users', + exceptions_list: [ + { + id: 'some_uuid', + list_id: 'list_id_single', + namespace_type: 'single', + type: 'detection', + }, + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ], + false_positives: [], + filters: [ + { + query: { + match_phrase: { + 'host.name': 'some-host', + }, + }, + }, + ], + from: 'now-6m', + id: 'rule-id', + immutable: false, + index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + investigation_fields: undefined, + language: 'kuery', + license: 'Elastic License', + max_signals: 10000, + meta: { + kibana_siem_app_url: 'http://localhost', + }, + name: 'Detect Root/Admin Users', + namespace: undefined, + note: '# Investigative notes', + output_index: '.siem-signals', + query: 'user.name: root or user.name: admin', + references: ['http://example.com', 'https://example.com'], + related_integrations: [], + required_fields: [], + response_actions: undefined, + risk_score: 50, + risk_score_mapping: [], + rule_id: 'rule-1', + rule_name_override: undefined, + saved_id: undefined, + setup: '', + severity: 'high', + severity_mapping: [], + threat: [ + { + framework: 'MITRE ATT&CK', + tactic: { + id: 'TA0000', + name: 'test tactic', + reference: 'https://attack.mitre.org/tactics/TA0000/', + }, + technique: [ + { + id: 'T0000', + name: 'test technique', + reference: 'https://attack.mitre.org/techniques/T0000/', + subtechnique: [ + { + id: 'T0000.000', + name: 'test subtechnique', + reference: 'https://attack.mitre.org/techniques/T0000/000/', + }, + ], + }, + ], + }, + ], + timeline_id: 'some-timeline-id', + timeline_title: 'some-timeline-title', + timestamp_override: undefined, + timestamp_override_fallback_disabled: undefined, + to: 'now', + type: 'query', + version: 1, + }, + }, + id: '1111', + state: { + signals_count: 1, + }, + }); + }); + + it('should not call alertsClient.report if signalsCount was 0', async () => { + const ruleAlert = getRuleMock(getQueryRuleParams()); + alertServices.savedObjectsClient.get.mockResolvedValue({ + id: 'id', + type: 'type', + references: [], + attributes: ruleAlert, + }); + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleEmptyDocSearchResults() + ); + + await rule.executor(payload); + + expect(alertServices.alertsClient.report).not.toHaveBeenCalled(); + }); + + it('should call scheduleActions if signalsCount was greater than 0', async () => { + const ruleAlert = getRuleMock(getQueryRuleParams()); + alertServices.savedObjectsClient.get.mockResolvedValue({ + id: 'id', + type: 'type', + references: [], + attributes: ruleAlert, + }); + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsNoSortIdNoVersion() + ); + + await rule.executor(payload); + + expect(alertServices.alertsClient.report).toHaveBeenCalledWith({ + actionGroup: 'default', + context: { + alerts: [ + { + '@timestamp': expect.any(String), + someKey: 'someValue', + }, + ], + results_link: + '/app/security/detections/rules/id/id?timerange=(global:(linkTo:!(timeline),timerange:(from:1576255233400,kind:absolute,to:1576341633400)),timeline:(linkTo:!(global),timerange:(from:1576255233400,kind:absolute,to:1576341633400)))', + rule: { + alert_suppression: undefined, + author: ['Elastic'], + building_block_type: 'default', + data_view_id: undefined, + description: 'Detecting root and admin users', + exceptions_list: [ + { + id: 'some_uuid', + list_id: 'list_id_single', + namespace_type: 'single', + type: 'detection', + }, + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ], + false_positives: [], + filters: [ + { + query: { + match_phrase: { + 'host.name': 'some-host', + }, + }, + }, + ], + from: 'now-6m', + id: 'id', + immutable: false, + index: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + investigation_fields: undefined, + language: 'kuery', + license: 'Elastic License', + max_signals: 10000, + meta: { + someMeta: 'someField', + }, + name: 'Detect Root/Admin Users', + namespace: undefined, + note: '# Investigative notes', + output_index: '.siem-signals', + query: 'user.name: root or user.name: admin', + references: ['http://example.com', 'https://example.com'], + related_integrations: [], + required_fields: [], + response_actions: undefined, + risk_score: 50, + risk_score_mapping: [], + rule_id: 'rule-1', + rule_name_override: undefined, + saved_id: undefined, + setup: '', + severity: 'high', + severity_mapping: [], + threat: [ + { + framework: 'MITRE ATT&CK', + tactic: { + id: 'TA0000', + name: 'test tactic', + reference: 'https://attack.mitre.org/tactics/TA0000/', + }, + technique: [ + { + id: 'T0000', + name: 'test technique', + reference: 'https://attack.mitre.org/techniques/T0000/', + subtechnique: [ + { + id: 'T0000.000', + name: 'test subtechnique', + reference: 'https://attack.mitre.org/techniques/T0000/000/', + }, + ], + }, + ], + }, + ], + timeline_id: 'some-timeline-id', + timeline_title: 'some-timeline-title', + timestamp_override: undefined, + timestamp_override_fallback_disabled: undefined, + to: 'now', + type: 'query', + version: 1, + }, + }, + id: '1111', + state: { + signals_count: 100, + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_rule_type.ts similarity index 85% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_rule_type.ts index 206444e82d7aa..5e237f8564559 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_rule_type.ts @@ -5,9 +5,11 @@ * 2.0. */ +import { mapKeys, snakeCase } from 'lodash/fp'; import type { Logger } from '@kbn/core/server'; import { parseScheduleDates } from '@kbn/securitysolution-io-ts-utils'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; +import { AlertsClientError, DEFAULT_AAD_CONFIG } from '@kbn/alerting-plugin/server'; import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE, LEGACY_NOTIFICATIONS_ID, @@ -15,12 +17,12 @@ import { } from '../../../../../../common/constants'; // eslint-disable-next-line no-restricted-imports -import type { LegacyNotificationAlertTypeDefinition } from './legacy_types'; +import type { LegacyNotificationRuleTypeDefinition } from './legacy_types'; // eslint-disable-next-line no-restricted-imports import { legacyRulesNotificationParams } from './legacy_types'; import type { AlertAttributes } from '../../../rule_types/types'; import { siemRuleActionGroups } from '../../../rule_types/utils/siem_rule_action_groups'; -import { scheduleNotificationActions } from './schedule_notification_actions'; +import { formatAlertsForNotificationActions } from './schedule_notification_actions'; import { getNotificationResultsLink } from './utils'; import { getSignals } from './get_signals'; // eslint-disable-next-line no-restricted-imports @@ -31,11 +33,11 @@ import { legacyInjectReferences } from './legacy_saved_object_references/legacy_ /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function */ -export const legacyRulesNotificationAlertType = ({ +export const legacyRulesNotificationRuleType = ({ logger, }: { logger: Logger; -}): LegacyNotificationAlertTypeDefinition => ({ +}): LegacyNotificationRuleTypeDefinition => ({ id: LEGACY_NOTIFICATIONS_ID, name: 'Security Solution notification (Legacy)', actionGroups: siemRuleActionGroups, @@ -52,6 +54,7 @@ export const legacyRulesNotificationAlertType = ({ }, minimumLicenseRequired: 'basic', isExportable: false, + alerts: DEFAULT_AAD_CONFIG, async executor({ startedAt, previousStartedAt, @@ -60,6 +63,11 @@ export const legacyRulesNotificationAlertType = ({ params, spaceId, }) { + const { alertsClient } = services; + if (!alertsClient) { + throw new AlertsClientError(); + } + const ruleAlertSavedObject = await services.savedObjectsClient.get( 'alert', params.ruleAlertId @@ -127,13 +135,17 @@ export const legacyRulesNotificationAlertType = ({ ); if (signalsCount !== 0) { - const alertInstance = services.alertFactory.create(ruleId); - scheduleNotificationActions({ - alertInstance, - signalsCount, - resultsLink, - ruleParams, - signals, + alertsClient.report({ + id: ruleId, + actionGroup: 'default', + state: { + signals_count: signalsCount, + }, + context: { + results_link: resultsLink, + rule: mapKeys(snakeCase, ruleParams), + alerts: formatAlertsForNotificationActions(signals), + }, }); } }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/README.md b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/README.md index 22e1da8dff5b3..09792ae0441bf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/README.md +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/README.md @@ -2,7 +2,7 @@ This is where you add code when you have rules which contain saved object refere when you have "joins" in the saved objects between one saved object and another one. This can be a 1 to M (1 to many) relationship for example where you have a rule which contains the "id" of another saved object. -NOTE: This is the "legacy saved object references" and should only be for the "legacy_rules_notification_alert_type". +NOTE: This is the "legacy saved object references" and should only be for the "legacy_rules_notification_rule_type". The legacy notification system is being phased out and deprecated in favor of using the newer alerting notification system. It would be considered wrong to see additional code being added here at this point. However, maintenance should be expected until we have all users moved away from the legacy system. diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_references.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_references.ts index 069017fcabbcb..c388422aedcf9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_references.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_references.ts @@ -30,7 +30,7 @@ import { legacyExtractRuleId } from './legacy_extract_rule_id'; * Optionally you can remove any parameters you do not want to store within the Saved Object here: * const paramsWithoutSavedObjectReferences = { removeParam, ...otherParams }; * - * If you do remove params, then update the types in: security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.ts + * If you do remove params, then update the types in: security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_rule_type.ts * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function * @param logger Kibana injected logger * @param params The params of the base rule(s). diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_types.ts index 2aea76d8c51e1..824ad7573e10c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_types.ts @@ -19,19 +19,20 @@ import type { RuleExecutorOptions, } from '@kbn/alerting-plugin/server'; import type { Rule, RuleAction } from '@kbn/alerting-plugin/common'; +import type { DefaultAlert } from '@kbn/alerts-as-data-utils'; import { LEGACY_NOTIFICATIONS_ID } from '../../../../../../common/constants'; /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function */ -export interface LegacyRuleNotificationAlertTypeParams extends RuleTypeParams { +export interface LegacyRuleNotificationRuleTypeParams extends RuleTypeParams { ruleAlertId: string; } /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function */ -export type LegacyRuleNotificationAlertType = Rule; +export type LegacyRuleNotificationRuleType = Rule; /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function @@ -81,35 +82,40 @@ export interface LegacyReadNotificationParams { /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function */ -export const legacyIsAlertType = ( - partialAlert: PartialRule -): partialAlert is LegacyRuleNotificationAlertType => { - return partialAlert.alertTypeId === LEGACY_NOTIFICATIONS_ID; +export const isLegacyRuleType = ( + partialRule: PartialRule +): partialRule is LegacyRuleNotificationRuleType => { + return partialRule.alertTypeId === LEGACY_NOTIFICATIONS_ID; }; /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function */ export type LegacyNotificationExecutorOptions = RuleExecutorOptions< - LegacyRuleNotificationAlertTypeParams, + LegacyRuleNotificationRuleTypeParams, RuleTypeState, AlertInstanceState, - AlertInstanceContext + AlertInstanceContext, + 'default', + DefaultAlert >; /** - * This returns true because by default a NotificationAlertTypeDefinition is an AlertType + * This returns true because by default a NotificationRuleTypeDefinition is an RuleType * since we are only increasing the strictness of params. * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function */ -export const legacyIsNotificationAlertExecutor = ( - obj: LegacyNotificationAlertTypeDefinition +export const isLegacyNotificationRuleExecutor = ( + obj: LegacyNotificationRuleTypeDefinition ): obj is RuleType< - LegacyRuleNotificationAlertTypeParams, - LegacyRuleNotificationAlertTypeParams, + LegacyRuleNotificationRuleTypeParams, + LegacyRuleNotificationRuleTypeParams, RuleTypeState, AlertInstanceState, - AlertInstanceContext + AlertInstanceContext, + 'default', + never, + DefaultAlert > => { return true; }; @@ -117,14 +123,16 @@ export const legacyIsNotificationAlertExecutor = ( /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function */ -export type LegacyNotificationAlertTypeDefinition = Omit< +export type LegacyNotificationRuleTypeDefinition = Omit< RuleType< - LegacyRuleNotificationAlertTypeParams, - LegacyRuleNotificationAlertTypeParams, + LegacyRuleNotificationRuleTypeParams, + LegacyRuleNotificationRuleTypeParams, RuleTypeState, AlertInstanceState, AlertInstanceContext, - 'default' + 'default', + never, + DefaultAlert >, 'executor' > & { @@ -136,17 +144,17 @@ export type LegacyNotificationAlertTypeDefinition = Omit< }; /** - * This is the notification type used within legacy_rules_notification_alert_type for the alert params. + * This is the notification type used within legacy_rules_notification_rule_type for the alert params. * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function - * @see legacy_rules_notification_alert_type + * @see legacy_rules_notification_rule_type */ export const legacyRulesNotificationParams = schema.object({ ruleAlertId: schema.string(), }); /** - * This legacy rules notification type used within legacy_rules_notification_alert_type for the alert params. + * This legacy rules notification type used within legacy_rules_notification_rule_type for the alert params. * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function - * @see legacy_rules_notification_alert_type + * @see legacy_rules_notification_rule_type */ export type LegacyRulesNotificationParams = TypeOf; diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 01154dc06f5f6..4c4ec0cdc801b 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -73,8 +73,8 @@ import type { } from './lib/detection_engine/rule_types/types'; // eslint-disable-next-line no-restricted-imports import { - legacyIsNotificationAlertExecutor, - legacyRulesNotificationAlertType, + isLegacyNotificationRuleExecutor, + legacyRulesNotificationRuleType, } from './lib/detection_engine/rule_actions_legacy'; import { createSecurityRuleTypeWrapper, @@ -354,9 +354,9 @@ export class Plugin implements ISecuritySolutionPlugin { ); if (plugins.alerting != null) { - const ruleNotificationType = legacyRulesNotificationAlertType({ logger }); + const ruleNotificationType = legacyRulesNotificationRuleType({ logger }); - if (legacyIsNotificationAlertExecutor(ruleNotificationType)) { + if (isLegacyNotificationRuleExecutor(ruleNotificationType)) { plugins.alerting.registerType(ruleNotificationType); } }