mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[7.12][SECURITY SOLUTIONS][Alerts Actions] Fix migration from 7.11.0/7.11.1 to 7.12 (#94881)
* do not modify connector with the right structure * review trying to bring back incident to live when we can * manage custom action
This commit is contained in:
parent
a576e2a0dd
commit
b7f9a41f48
3 changed files with 378 additions and 182 deletions
|
@ -571,6 +571,132 @@ describe('7.11.2', () => {
|
|||
} as SavedObjectUnsanitizedDoc<RawAlert>;
|
||||
expect(isAnyActionSupportIncidents(doc)).toBe(false);
|
||||
});
|
||||
|
||||
test('it does not transforms alerts when the right structure connectors is already applied', () => {
|
||||
const migration7112 = getMigrations(encryptedSavedObjectsSetup)['7.11.2'];
|
||||
const alert = getMockData({
|
||||
actions: [
|
||||
{
|
||||
actionTypeId: '.server-log',
|
||||
group: 'threshold met',
|
||||
params: {
|
||||
level: 'info',
|
||||
message: 'log message',
|
||||
},
|
||||
id: '99257478-e591-4560-b264-441bdd4fe1d9',
|
||||
},
|
||||
{
|
||||
actionTypeId: '.servicenow',
|
||||
group: 'threshold met',
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
short_description: 'SN short desc',
|
||||
description: 'SN desc',
|
||||
severity: '2',
|
||||
impact: '2',
|
||||
urgency: '2',
|
||||
},
|
||||
comments: [{ commentId: '1', comment: 'sn comment' }],
|
||||
},
|
||||
},
|
||||
id: '1266562a-4e1f-4305-99ca-1b44c469b26e',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(migration7112(alert, migrationContext)).toEqual(alert);
|
||||
});
|
||||
|
||||
test('if incident attribute is an empty object, copy back the related attributes from subActionParams back to incident', () => {
|
||||
const migration7112 = getMigrations(encryptedSavedObjectsSetup)['7.11.2'];
|
||||
const alert = getMockData({
|
||||
actions: [
|
||||
{
|
||||
actionTypeId: '.server-log',
|
||||
group: 'threshold met',
|
||||
params: {
|
||||
level: 'info',
|
||||
message: 'log message',
|
||||
},
|
||||
id: '99257478-e591-4560-b264-441bdd4fe1d9',
|
||||
},
|
||||
{
|
||||
actionTypeId: '.servicenow',
|
||||
group: 'threshold met',
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
short_description: 'SN short desc',
|
||||
description: 'SN desc',
|
||||
severity: '2',
|
||||
impact: '2',
|
||||
urgency: '2',
|
||||
incident: {},
|
||||
comments: [{ commentId: '1', comment: 'sn comment' }],
|
||||
},
|
||||
},
|
||||
id: '1266562a-4e1f-4305-99ca-1b44c469b26e',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(migration7112(alert, migrationContext)).toEqual({
|
||||
...alert,
|
||||
attributes: {
|
||||
...alert.attributes,
|
||||
actions: [
|
||||
alert.attributes.actions![0],
|
||||
{
|
||||
actionTypeId: '.servicenow',
|
||||
group: 'threshold met',
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
short_description: 'SN short desc',
|
||||
description: 'SN desc',
|
||||
severity: '2',
|
||||
impact: '2',
|
||||
urgency: '2',
|
||||
},
|
||||
comments: [{ commentId: '1', comment: 'sn comment' }],
|
||||
},
|
||||
},
|
||||
id: '1266562a-4e1f-4305-99ca-1b44c469b26e',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('custom action does not get migrated/loss', () => {
|
||||
const migration7112 = getMigrations(encryptedSavedObjectsSetup)['7.11.2'];
|
||||
const alert = getMockData({
|
||||
actions: [
|
||||
{
|
||||
actionTypeId: '.mike',
|
||||
group: 'threshold met',
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
short_description: 'SN short desc',
|
||||
description: 'SN desc',
|
||||
severity: '2',
|
||||
impact: '2',
|
||||
urgency: '2',
|
||||
incident: {},
|
||||
comments: [{ commentId: '1', comment: 'sn comment' }],
|
||||
},
|
||||
},
|
||||
id: '1266562a-4e1f-4305-99ca-1b44c469b26e',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(migration7112(alert, migrationContext)).toEqual(alert);
|
||||
});
|
||||
});
|
||||
|
||||
function getUpdatedAt(): string {
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
SavedObjectUnsanitizedDoc,
|
||||
SavedObjectMigrationFn,
|
||||
SavedObjectMigrationContext,
|
||||
SavedObjectAttributes,
|
||||
} from '../../../../../src/core/server';
|
||||
import { RawAlert, RawAlertAction } from '../types';
|
||||
import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server';
|
||||
|
@ -180,113 +181,147 @@ function initializeExecutionStatus(
|
|||
};
|
||||
}
|
||||
|
||||
function isEmptyObject(obj: {}) {
|
||||
for (const attr in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, attr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function restructureConnectorsThatSupportIncident(
|
||||
doc: SavedObjectUnsanitizedDoc<RawAlert>
|
||||
): SavedObjectUnsanitizedDoc<RawAlert> {
|
||||
const { actions } = doc.attributes;
|
||||
const newActions = actions.reduce((acc, action) => {
|
||||
if (action.params.subAction !== 'pushToService') {
|
||||
return [...acc, action];
|
||||
}
|
||||
|
||||
if (action.actionTypeId === '.servicenow') {
|
||||
const { title, comments, comment, description, severity, urgency, impact } = action.params
|
||||
.subActionParams as {
|
||||
title: string;
|
||||
description?: string;
|
||||
severity?: string;
|
||||
urgency?: string;
|
||||
impact?: string;
|
||||
comment?: string;
|
||||
comments?: Array<{ commentId: string; comment: string }>;
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
short_description: title,
|
||||
description,
|
||||
severity,
|
||||
urgency,
|
||||
impact,
|
||||
if (
|
||||
['.servicenow', '.jira', '.resilient'].includes(action.actionTypeId) &&
|
||||
action.params.subAction === 'pushToService'
|
||||
) {
|
||||
// Future developer, we needed to do that because when we created this migration
|
||||
// we forget to think about user already using 7.11.0 and having an incident attribute build the right way
|
||||
// IMPORTANT -> if you change this code please do the same inside of this file
|
||||
// x-pack/plugins/alerting/server/saved_objects/migrations.ts
|
||||
const subActionParamsIncident =
|
||||
(action.params?.subActionParams as SavedObjectAttributes)?.incident ?? null;
|
||||
if (subActionParamsIncident != null && !isEmptyObject(subActionParamsIncident)) {
|
||||
return [...acc, action];
|
||||
}
|
||||
if (action.actionTypeId === '.servicenow') {
|
||||
const {
|
||||
title,
|
||||
comments,
|
||||
comment,
|
||||
description,
|
||||
severity,
|
||||
urgency,
|
||||
impact,
|
||||
short_description: shortDescription,
|
||||
} = action.params.subActionParams as {
|
||||
title: string;
|
||||
description?: string;
|
||||
severity?: string;
|
||||
urgency?: string;
|
||||
impact?: string;
|
||||
comment?: string;
|
||||
comments?: Array<{ commentId: string; comment: string }>;
|
||||
short_description?: string;
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
short_description: shortDescription ?? title,
|
||||
description,
|
||||
severity,
|
||||
urgency,
|
||||
impact,
|
||||
},
|
||||
comments: [
|
||||
...(comments ?? []),
|
||||
...(comment != null ? [{ commentId: '1', comment }] : []),
|
||||
],
|
||||
},
|
||||
comments: [
|
||||
...(comments ?? []),
|
||||
...(comment != null ? [{ commentId: '1', comment }] : []),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as RawAlertAction[];
|
||||
}
|
||||
|
||||
if (action.actionTypeId === '.jira') {
|
||||
const { title, comments, description, issueType, priority, labels, parent } = action.params
|
||||
.subActionParams as {
|
||||
title: string;
|
||||
description: string;
|
||||
issueType: string;
|
||||
priority?: string;
|
||||
labels?: string[];
|
||||
parent?: string;
|
||||
comments?: unknown[];
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
summary: title,
|
||||
description,
|
||||
issueType,
|
||||
priority,
|
||||
labels,
|
||||
parent,
|
||||
] as RawAlertAction[];
|
||||
} else if (action.actionTypeId === '.jira') {
|
||||
const {
|
||||
title,
|
||||
comments,
|
||||
description,
|
||||
issueType,
|
||||
priority,
|
||||
labels,
|
||||
parent,
|
||||
summary,
|
||||
} = action.params.subActionParams as {
|
||||
title: string;
|
||||
description: string;
|
||||
issueType: string;
|
||||
priority?: string;
|
||||
labels?: string[];
|
||||
parent?: string;
|
||||
comments?: unknown[];
|
||||
summary?: string;
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
summary: summary ?? title,
|
||||
description,
|
||||
issueType,
|
||||
priority,
|
||||
labels,
|
||||
parent,
|
||||
},
|
||||
comments,
|
||||
},
|
||||
comments,
|
||||
},
|
||||
},
|
||||
},
|
||||
] as RawAlertAction[];
|
||||
}
|
||||
|
||||
if (action.actionTypeId === '.resilient') {
|
||||
const { title, comments, description, incidentTypes, severityCode } = action.params
|
||||
.subActionParams as {
|
||||
title: string;
|
||||
description: string;
|
||||
incidentTypes?: number[];
|
||||
severityCode?: number;
|
||||
comments?: unknown[];
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
name: title,
|
||||
description,
|
||||
incidentTypes,
|
||||
severityCode,
|
||||
] as RawAlertAction[];
|
||||
} else if (action.actionTypeId === '.resilient') {
|
||||
const { title, comments, description, incidentTypes, severityCode, name } = action.params
|
||||
.subActionParams as {
|
||||
title: string;
|
||||
description: string;
|
||||
incidentTypes?: number[];
|
||||
severityCode?: number;
|
||||
comments?: unknown[];
|
||||
name?: string;
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
name: name ?? title,
|
||||
description,
|
||||
incidentTypes,
|
||||
severityCode,
|
||||
},
|
||||
comments,
|
||||
},
|
||||
comments,
|
||||
},
|
||||
},
|
||||
},
|
||||
] as RawAlertAction[];
|
||||
] as RawAlertAction[];
|
||||
}
|
||||
}
|
||||
|
||||
return acc;
|
||||
return [...acc, action];
|
||||
}, [] as RawAlertAction[]);
|
||||
|
||||
return {
|
||||
|
|
|
@ -8,117 +8,152 @@
|
|||
import {
|
||||
SavedObjectUnsanitizedDoc,
|
||||
SavedObjectSanitizedDoc,
|
||||
SavedObjectAttributes,
|
||||
} from '../../../../../../../src/core/server';
|
||||
import { IRuleActionsAttributesSavedObjectAttributes, RuleAlertAction } from './types';
|
||||
|
||||
function isEmptyObject(obj: {}) {
|
||||
for (const attr in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, attr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export const ruleActionsSavedObjectMigration = {
|
||||
'7.11.2': (
|
||||
doc: SavedObjectUnsanitizedDoc<IRuleActionsAttributesSavedObjectAttributes>
|
||||
): SavedObjectSanitizedDoc<IRuleActionsAttributesSavedObjectAttributes> => {
|
||||
const { actions } = doc.attributes;
|
||||
const newActions = actions.reduce((acc, action) => {
|
||||
if (action.params.subAction !== 'pushToService') {
|
||||
return [...acc, action];
|
||||
}
|
||||
|
||||
if (action.action_type_id === '.servicenow') {
|
||||
const { title, comments, comment, description, severity, urgency, impact } = action.params
|
||||
.subActionParams as {
|
||||
title: string;
|
||||
description?: string;
|
||||
severity?: string;
|
||||
urgency?: string;
|
||||
impact?: string;
|
||||
comment?: string;
|
||||
comments?: Array<{ commentId: string; comment: string }>;
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
short_description: title,
|
||||
description,
|
||||
severity,
|
||||
urgency,
|
||||
impact,
|
||||
if (
|
||||
['.servicenow', '.jira', '.resilient'].includes(action.action_type_id) &&
|
||||
action.params.subAction === 'pushToService'
|
||||
) {
|
||||
// Future developer, we needed to do that because when we created this migration
|
||||
// we forget to think about user already using 7.11.0 and having an incident attribute build the right way
|
||||
// IMPORTANT -> if you change this code please do the same inside of this file
|
||||
// x-pack/plugins/alerting/server/saved_objects/migrations.ts
|
||||
const subActionParamsIncident =
|
||||
(action.params?.subActionParams as SavedObjectAttributes)?.incident ?? null;
|
||||
if (subActionParamsIncident != null && !isEmptyObject(subActionParamsIncident)) {
|
||||
return [...acc, action];
|
||||
}
|
||||
if (action.action_type_id === '.servicenow') {
|
||||
const {
|
||||
title,
|
||||
comments,
|
||||
comment,
|
||||
description,
|
||||
severity,
|
||||
urgency,
|
||||
impact,
|
||||
short_description: shortDescription,
|
||||
} = action.params.subActionParams as {
|
||||
title: string;
|
||||
description?: string;
|
||||
severity?: string;
|
||||
urgency?: string;
|
||||
impact?: string;
|
||||
comment?: string;
|
||||
comments?: Array<{ commentId: string; comment: string }>;
|
||||
short_description?: string;
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
short_description: shortDescription ?? title,
|
||||
description,
|
||||
severity,
|
||||
urgency,
|
||||
impact,
|
||||
},
|
||||
comments: [
|
||||
...(comments ?? []),
|
||||
...(comment != null ? [{ commentId: '1', comment }] : []),
|
||||
],
|
||||
},
|
||||
comments: [
|
||||
...(comments ?? []),
|
||||
...(comment != null ? [{ commentId: '1', comment }] : []),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as RuleAlertAction[];
|
||||
}
|
||||
|
||||
if (action.action_type_id === '.jira') {
|
||||
const { title, comments, description, issueType, priority, labels, parent } = action.params
|
||||
.subActionParams as {
|
||||
title: string;
|
||||
description: string;
|
||||
issueType: string;
|
||||
priority?: string;
|
||||
labels?: string[];
|
||||
parent?: string;
|
||||
comments?: unknown[];
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
summary: title,
|
||||
description,
|
||||
issueType,
|
||||
priority,
|
||||
labels,
|
||||
parent,
|
||||
] as RuleAlertAction[];
|
||||
} else if (action.action_type_id === '.jira') {
|
||||
const {
|
||||
title,
|
||||
comments,
|
||||
description,
|
||||
issueType,
|
||||
priority,
|
||||
labels,
|
||||
parent,
|
||||
summary,
|
||||
} = action.params.subActionParams as {
|
||||
title: string;
|
||||
description: string;
|
||||
issueType: string;
|
||||
priority?: string;
|
||||
labels?: string[];
|
||||
parent?: string;
|
||||
comments?: unknown[];
|
||||
summary?: string;
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
summary: summary ?? title,
|
||||
description,
|
||||
issueType,
|
||||
priority,
|
||||
labels,
|
||||
parent,
|
||||
},
|
||||
comments,
|
||||
},
|
||||
comments,
|
||||
},
|
||||
},
|
||||
},
|
||||
] as RuleAlertAction[];
|
||||
}
|
||||
|
||||
if (action.action_type_id === '.resilient') {
|
||||
const { title, comments, description, incidentTypes, severityCode } = action.params
|
||||
.subActionParams as {
|
||||
title: string;
|
||||
description: string;
|
||||
incidentTypes?: number[];
|
||||
severityCode?: number;
|
||||
comments?: unknown[];
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
name: title,
|
||||
description,
|
||||
incidentTypes,
|
||||
severityCode,
|
||||
] as RuleAlertAction[];
|
||||
} else if (action.action_type_id === '.resilient') {
|
||||
const { title, comments, description, incidentTypes, severityCode, name } = action.params
|
||||
.subActionParams as {
|
||||
title: string;
|
||||
description: string;
|
||||
incidentTypes?: number[];
|
||||
severityCode?: number;
|
||||
comments?: unknown[];
|
||||
name?: string;
|
||||
};
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
...action,
|
||||
params: {
|
||||
subAction: 'pushToService',
|
||||
subActionParams: {
|
||||
incident: {
|
||||
name: name ?? title,
|
||||
description,
|
||||
incidentTypes,
|
||||
severityCode,
|
||||
},
|
||||
comments,
|
||||
},
|
||||
comments,
|
||||
},
|
||||
},
|
||||
},
|
||||
] as RuleAlertAction[];
|
||||
] as RuleAlertAction[];
|
||||
}
|
||||
}
|
||||
|
||||
return acc;
|
||||
return [...acc, action];
|
||||
}, [] as RuleAlertAction[]);
|
||||
|
||||
return {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue