Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution] Migrates siem-detection-engine-rule-actions ruleAlertId and actions to saved object references array #113577

Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d04cb92
Integration of saved object references
FrankHassanabad Sep 30, 2021
e0d7ae0
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
FrankHassanabad Sep 30, 2021
5fe3369
Removed 1 TODO line
FrankHassanabad Sep 30, 2021
93f15b3
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
FrankHassanabad Oct 1, 2021
b8c4210
Added e2e tests
FrankHassanabad Oct 1, 2021
9014c52
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
FrankHassanabad Oct 4, 2021
27b753f
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
FrankHassanabad Oct 4, 2021
3cd12d6
Small fix to error messages
FrankHassanabad Oct 4, 2021
0a041be
Added more unit tests where previously they were missing
FrankHassanabad Oct 5, 2021
739314c
More tests and changes from feedback from PR review
FrankHassanabad Oct 5, 2021
494b764
Updated and added logging to some of the rest routes and into areas o…
FrankHassanabad Oct 5, 2021
4c6155c
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
FrankHassanabad Oct 5, 2021
d8b75db
Updated one more logger error message.
FrankHassanabad Oct 5, 2021
d675e9e
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
FrankHassanabad Oct 5, 2021
ccb501c
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
FrankHassanabad Oct 5, 2021
5f0733d
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
kibanamachine Oct 6, 2021
b80aab8
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
kibanamachine Oct 6, 2021
f25c902
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
kibanamachine Oct 6, 2021
2c157e3
Merge branch 'master' into migrate-siem-detection-engine-rule-actions
kibanamachine Oct 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('legacy_extract_rule_id', () => {
).toEqual<FuncReturn>([]);

expect(logger.error).toBeCalledWith(
'Security Solution notification (Legacy) system "ruleAlertId" is null or undefined when it never should be. ,This indicates potentially that saved object migrations did not run correctly. Returning empty reference'
'Security Solution notification (Legacy) system "ruleAlertId" is null or undefined when it never should be. This indicates potentially that saved object migrations did not run correctly. Returning empty reference.'
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
*/

import { Logger, SavedObjectReference } from 'src/core/server';

// eslint-disable-next-line no-restricted-imports
import { legacyGetRuleReference } from '../../rule_actions/legacy_utils';
// eslint-disable-next-line no-restricted-imports
import { LegacyRulesNotificationParams } from '../legacy_types';

Expand All @@ -30,17 +33,11 @@ export const legacyExtractRuleId = ({
logger.error(
[
'Security Solution notification (Legacy) system "ruleAlertId" is null or undefined when it never should be. ',
'This indicates potentially that saved object migrations did not run correctly. Returning empty reference',
].join()
'This indicates potentially that saved object migrations did not run correctly. Returning empty reference.',
].join('')
);
return [];
} else {
return [
{
id: ruleAlertId,
name: 'alert_0',
type: 'alert',
},
];
return [legacyGetRuleReference(ruleAlertId)];
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import { loggingSystemMock } from 'src/core/server/mocks';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { getQueryRuleParams } from '../../schemas/rule_schemas.mock';
import { requestContextMock, requestMock, serverMock } from '../__mocks__';
Expand All @@ -23,9 +24,11 @@ describe.each([
])('find_rules - %s', (_, isRuleRegistryEnabled) => {
let server: ReturnType<typeof serverMock.create>;
let { clients, context } = requestContextMock.createTools();
let logger: ReturnType<typeof loggingSystemMock.createLogger>;

beforeEach(async () => {
server = serverMock.create();
logger = loggingSystemMock.createLogger();
({ clients, context } = requestContextMock.createTools());

clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled));
Expand All @@ -35,7 +38,7 @@ describe.each([
clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse());
clients.ruleExecutionLogClient.findBulk.mockResolvedValue(getFindBulkResultStatus());

findRulesRoute(server.router, isRuleRegistryEnabled);
findRulesRoute(server.router, logger, isRuleRegistryEnabled);
});

describe('status codes with actionClient and alertClient', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { transformError } from '@kbn/securitysolution-es-utils';
import { Logger } from 'src/core/server';
import { findRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/find_rules_type_dependents';
import {
findRulesSchema,
Expand All @@ -17,11 +18,13 @@ import { findRules } from '../../rules/find_rules';
import { buildSiemResponse } from '../utils';
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
import { transformFindAlerts } from './utils';

// eslint-disable-next-line no-restricted-imports
import { legacyGetBulkRuleActionsSavedObject } from '../../rule_actions/legacy_get_bulk_rule_actions_saved_object';

export const findRulesRoute = (
router: SecuritySolutionPluginRouter,
logger: Logger,
isRuleRegistryEnabled: boolean
) => {
router.get(
Expand Down Expand Up @@ -71,7 +74,7 @@ export const findRulesRoute = (
logsCount: 1,
spaceId: context.securitySolution.getSpaceId(),
}),
legacyGetBulkRuleActionsSavedObject({ alertIds, savedObjectsClient }),
legacyGetBulkRuleActionsSavedObject({ alertIds, savedObjectsClient, logger }),
]);
const transformed = transformFindAlerts(rules, ruleStatuses, ruleActions);
if (transformed == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/

import { schema } from '@kbn/config-schema';
import { Logger } from 'src/core/server';

import type { SecuritySolutionPluginRouter } from '../../../../types';
// eslint-disable-next-line no-restricted-imports
import { legacyUpdateOrCreateRuleActionsSavedObject } from '../../rule_actions/legacy_update_or_create_rule_actions_saved_object';
Expand All @@ -25,7 +27,10 @@ import { legacyCreateNotifications } from '../../notifications/legacy_create_not
* @deprecated Once we no longer have legacy notifications and "side car actions" this can be removed.
* @param router The router
*/
export const legacyCreateLegacyNotificationRoute = (router: SecuritySolutionPluginRouter): void => {
export const legacyCreateLegacyNotificationRoute = (
router: SecuritySolutionPluginRouter,
logger: Logger
): void => {
router.post(
{
path: '/internal/api/detection/legacy/notifications',
Expand Down Expand Up @@ -95,6 +100,7 @@ export const legacyCreateLegacyNotificationRoute = (router: SecuritySolutionPlug
savedObjectsClient,
actions,
throttle: interval,
logger,
});
} catch (error) {
const message = error instanceof Error ? error.message : 'unknown';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* 2.0.
*/

import { loggingSystemMock } from 'src/core/server/mocks';

import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { readRulesRoute } from './read_rules_route';
import {
Expand All @@ -22,16 +24,18 @@ describe.each([
])('read_rules - %s', (_, isRuleRegistryEnabled) => {
let server: ReturnType<typeof serverMock.create>;
let { clients, context } = requestContextMock.createTools();
let logger: ReturnType<typeof loggingSystemMock.createLogger>;

beforeEach(() => {
server = serverMock.create();
logger = loggingSystemMock.createLogger();
({ clients, context } = requestContextMock.createTools());

clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); // rule exists
clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse()); // successful transform
clients.ruleExecutionLogClient.find.mockResolvedValue([]);

readRulesRoute(server.router, isRuleRegistryEnabled);
readRulesRoute(server.router, logger, isRuleRegistryEnabled);
});

describe('status codes with actionClient and alertClient', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { transformError } from '@kbn/securitysolution-es-utils';
import { Logger } from 'src/core/server';
import { queryRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/query_rules_type_dependents';
import {
queryRulesSchema,
Expand All @@ -24,6 +25,7 @@ import { legacyGetRuleActionsSavedObject } from '../../rule_actions/legacy_get_r

export const readRulesRoute = (
router: SecuritySolutionPluginRouter,
logger: Logger,
isRuleRegistryEnabled: boolean
) => {
router.get(
Expand Down Expand Up @@ -66,6 +68,7 @@ export const readRulesRoute = (
const legacyRuleActions = await legacyGetRuleActionsSavedObject({
savedObjectsClient,
ruleAlertId: rule.id,
logger,
});
const ruleStatuses = await ruleStatusClient.find({
logsCount: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import {
} from '../../schemas/rule_schemas.mock';
// eslint-disable-next-line no-restricted-imports
import { LegacyRulesActionsSavedObject } from '../../rule_actions/legacy_get_rule_actions_saved_object';
import { RuleAlertAction } from '../../../../../common/detection_engine/types';
// eslint-disable-next-line no-restricted-imports
import { LegacyRuleAlertAction } from '../../rule_actions/legacy_types';

type PromiseFromStreams = ImportRulesSchemaDecoded | Error;

Expand Down Expand Up @@ -306,7 +307,7 @@ describe.each([
});

test('outputs 200 if the data is of type siem alert and has a legacy rule action', () => {
const actions: RuleAlertAction[] = [
const actions: LegacyRuleAlertAction[] = [
{
id: '456',
params: {},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* 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 { savedObjectsClientMock } from 'src/core/server/mocks';

// eslint-disable-next-line no-restricted-imports
import { legacyCreateRuleActionsSavedObject } from './legacy_create_rule_actions_saved_object';
// eslint-disable-next-line no-restricted-imports
import { LegacyIRuleActionsAttributesSavedObjectAttributes } from './legacy_types';

describe('legacy_create_rule_actions_saved_object', () => {
let savedObjectsClient: ReturnType<typeof savedObjectsClientMock.create>;

beforeEach(() => {
savedObjectsClient = savedObjectsClientMock.create();
});

test('it creates a rule actions saved object with empty actions array', () => {
legacyCreateRuleActionsSavedObject({
ruleAlertId: '123',
savedObjectsClient,
actions: [],
throttle: '1d',
});
const [[, arg2, arg3]] = savedObjectsClient.create.mock.calls;
expect(arg2).toEqual<LegacyIRuleActionsAttributesSavedObjectAttributes>({
actions: [],
alertThrottle: '1d',
ruleThrottle: '1d',
});
expect(arg3).toEqual({
references: [
{
id: '123',
name: 'alert_0',
type: 'alert',
},
],
});
});

test('it creates a rule actions saved object with 1 single action', () => {
legacyCreateRuleActionsSavedObject({
ruleAlertId: '123',
savedObjectsClient,
actions: [
{
id: '456',
group: 'default',
actionTypeId: '.slack',
params: {
kibana_siem_app_url: 'www.example.com',
},
},
],
throttle: '1d',
});
const [[, arg2, arg3]] = savedObjectsClient.create.mock.calls;
expect(arg2).toEqual<LegacyIRuleActionsAttributesSavedObjectAttributes>({
actions: [
{
actionRef: 'action_0',
action_type_id: '.slack',
group: 'default',
params: {
kibana_siem_app_url: 'www.example.com',
},
},
],
alertThrottle: '1d',
ruleThrottle: '1d',
});
expect(arg3).toEqual({
references: [
{
id: '123',
name: 'alert_0',
type: 'alert',
},
{
id: '456',
name: 'action_0',
type: 'action',
},
],
});
});

test('it creates a rule actions saved object with 2 actions', () => {
legacyCreateRuleActionsSavedObject({
ruleAlertId: '123',
savedObjectsClient,
actions: [
{
id: '456',
group: 'default',
actionTypeId: '.slack',
params: {
kibana_siem_app_url: 'www.example.com',
},
},
{
id: '555',
group: 'default_2',
actionTypeId: '.email',
params: {
kibana_siem_app_url: 'www.example.com/2',
},
},
],
throttle: '1d',
});
const [[, arg2, arg3]] = savedObjectsClient.create.mock.calls;
expect(arg2).toEqual<LegacyIRuleActionsAttributesSavedObjectAttributes>({
actions: [
{
actionRef: 'action_0',
action_type_id: '.slack',
group: 'default',
params: {
kibana_siem_app_url: 'www.example.com',
},
},
{
actionRef: 'action_1',
action_type_id: '.email',
group: 'default_2',
params: {
kibana_siem_app_url: 'www.example.com/2',
},
},
],
alertThrottle: '1d',
ruleThrottle: '1d',
});
expect(arg3).toEqual({
references: [
{
id: '123',
name: 'alert_0',
type: 'alert',
},
{
id: '456',
name: 'action_0',
type: 'action',
},
{
id: '555',
name: 'action_1',
type: 'action',
},
],
});
});
});
Loading