[Alerting] Passing additional rule fields to rule executor (#99819) (#100462)

* Passing additional rule fields to rule executor

* Fixing types check

* Api docs

* Adding enabled and actions

* Api docs

* Encapsulating rule information into RuleConfig type

* Functional tests

* Functional tests

* Adding producer, ruleTypeId and ruleTypeName

* Api docs

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: ymao1 <ying.mao@elastic.co>
This commit is contained in:
Kibana Machine 2021-05-24 12:19:21 -04:00 committed by GitHub
parent 2057412fc6
commit ac96279efe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 483 additions and 52 deletions

View file

@ -404,7 +404,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 79
"lineNumber": 80
},
"deprecated": false,
"children": [
@ -417,7 +417,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 86
"lineNumber": 87
},
"deprecated": false
},
@ -433,7 +433,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 87
"lineNumber": 88
},
"deprecated": false
},
@ -449,7 +449,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 88
"lineNumber": 89
},
"deprecated": false
},
@ -472,7 +472,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 89
"lineNumber": 90
},
"deprecated": false
},
@ -488,7 +488,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 90
"lineNumber": 91
},
"deprecated": false
},
@ -504,7 +504,29 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 91
"lineNumber": 92
},
"deprecated": false
},
{
"parentPluginId": "alerting",
"id": "def-server.AlertExecutorOptions.rule",
"type": "CompoundType",
"tags": [],
"label": "rule",
"description": [],
"signature": [
{
"pluginId": "alerting",
"scope": "common",
"docId": "kibAlertingPluginApi",
"section": "def-common.SanitizedRuleConfig",
"text": "SanitizedRuleConfig"
}
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 93
},
"deprecated": false
},
@ -517,7 +539,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 92
"lineNumber": 94
},
"deprecated": false
},
@ -533,7 +555,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 93
"lineNumber": 95
},
"deprecated": false
},
@ -546,7 +568,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 94
"lineNumber": 96
},
"deprecated": false
},
@ -562,7 +584,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 95
"lineNumber": 97
},
"deprecated": false
},
@ -578,7 +600,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 96
"lineNumber": 98
},
"deprecated": false
},
@ -594,7 +616,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 97
"lineNumber": 99
},
"deprecated": false
}
@ -610,7 +632,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 45
"lineNumber": 46
},
"deprecated": false,
"children": [
@ -633,7 +655,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 46
"lineNumber": 47
},
"deprecated": false,
"returnComment": [],
@ -653,7 +675,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 47
"lineNumber": 48
},
"deprecated": false,
"returnComment": [],
@ -679,7 +701,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 48
"lineNumber": 49
},
"deprecated": false,
"returnComment": [],
@ -697,7 +719,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 49
"lineNumber": 50
},
"deprecated": false,
"returnComment": [],
@ -715,7 +737,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 219
"lineNumber": 221
},
"deprecated": false,
"children": [
@ -737,7 +759,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 220
"lineNumber": 222
},
"deprecated": false
},
@ -759,7 +781,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 221
"lineNumber": 223
},
"deprecated": false
}
@ -786,7 +808,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 69
"lineNumber": 70
},
"deprecated": false,
"children": [
@ -804,7 +826,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 74
"lineNumber": 75
},
"deprecated": false,
"returnComment": [],
@ -846,7 +868,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 113
"lineNumber": 115
},
"deprecated": false,
"children": [
@ -859,7 +881,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 121
"lineNumber": 123
},
"deprecated": false
},
@ -872,7 +894,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 122
"lineNumber": 124
},
"deprecated": false
},
@ -890,7 +912,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 123
"lineNumber": 125
},
"deprecated": false
},
@ -913,7 +935,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 126
"lineNumber": 128
},
"deprecated": false
},
@ -929,7 +951,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 127
"lineNumber": 129
},
"deprecated": false
},
@ -952,7 +974,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 128
"lineNumber": 130
},
"deprecated": false
},
@ -984,7 +1006,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 129
"lineNumber": 131
},
"deprecated": false,
"returnComment": [],
@ -1023,7 +1045,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 140
"lineNumber": 142
},
"deprecated": false
},
@ -1063,7 +1085,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 141
"lineNumber": 143
},
"deprecated": false
},
@ -1079,7 +1101,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 146
"lineNumber": 148
},
"deprecated": false
}
@ -1640,7 +1662,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/server/types.ts",
"lineNumber": 179
"lineNumber": 181
},
"deprecated": false,
"initialIsOpen": false
@ -2047,7 +2069,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 101
"lineNumber": 121
},
"deprecated": false,
"children": [
@ -2060,7 +2082,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 102
"lineNumber": 122
},
"deprecated": false
},
@ -2073,7 +2095,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 103
"lineNumber": 123
},
"deprecated": false
},
@ -2089,7 +2111,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 104
"lineNumber": 124
},
"deprecated": false
},
@ -2105,7 +2127,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 105
"lineNumber": 125
},
"deprecated": false
}
@ -3040,7 +3062,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 86
"lineNumber": 106
},
"deprecated": false,
"children": [
@ -3064,7 +3086,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 87
"lineNumber": 107
},
"deprecated": false
},
@ -3088,7 +3110,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 91
"lineNumber": 111
},
"deprecated": false
},
@ -3112,7 +3134,7 @@
],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 95
"lineNumber": 115
},
"deprecated": false
}
@ -3410,7 +3432,7 @@
"description": [],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 80
"lineNumber": 100
},
"deprecated": false,
"initialIsOpen": false
@ -3883,6 +3905,23 @@
"deprecated": false,
"initialIsOpen": false
},
{
"parentPluginId": "alerting",
"id": "def-common.SanitizedRuleConfig",
"type": "Type",
"tags": [],
"label": "SanitizedRuleConfig",
"description": [],
"signature": [
"Pick<Pick<Alert<never>, \"enabled\" | \"id\" | \"name\" | \"params\" | \"actions\" | \"tags\" | \"muteAll\" | \"alertTypeId\" | \"consumer\" | \"schedule\" | \"scheduledTaskId\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"apiKeyOwner\" | \"throttle\" | \"notifyWhen\" | \"mutedInstanceIds\" | \"executionStatus\">, \"enabled\" | \"name\" | \"actions\" | \"tags\" | \"consumer\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"throttle\" | \"notifyWhen\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }"
],
"source": {
"path": "x-pack/plugins/alerting/common/alert.ts",
"lineNumber": 80
},
"deprecated": false,
"initialIsOpen": false
},
{
"parentPluginId": "alerting",
"id": "def-common.WithoutReservedActionGroups",

View file

@ -77,6 +77,26 @@ export interface Alert<Params extends AlertTypeParams = never> {
export type SanitizedAlert<Params extends AlertTypeParams = never> = Omit<Alert<Params>, 'apiKey'>;
export type SanitizedRuleConfig = Pick<
SanitizedAlert,
| 'name'
| 'tags'
| 'consumer'
| 'enabled'
| 'schedule'
| 'actions'
| 'createdBy'
| 'updatedBy'
| 'createdAt'
| 'updatedAt'
| 'throttle'
| 'notifyWhen'
> & {
producer: string;
ruleTypeId: string;
ruleTypeName: string;
};
export enum HealthStatus {
OK = 'ok',
Warning = 'warn',

View file

@ -100,11 +100,13 @@ describe('Task Runner', () => {
kibanaBaseUrl: 'https://localhost:5601',
};
const mockDate = new Date('2019-02-12T21:01:22.479Z');
const mockedAlertTypeSavedObject: Alert<AlertTypeParams> = {
id: '1',
consumer: 'bar',
createdAt: new Date('2019-02-12T21:01:22.479Z'),
updatedAt: new Date('2019-02-12T21:01:22.479Z'),
createdAt: mockDate,
updatedAt: mockDate,
throttle: null,
muteAll: false,
notifyWhen: 'onActiveAlert',
@ -155,6 +157,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams.actionsPlugin.renderActionParameterTemplates.mockImplementation(
(actionTypeId, actionId, params) => params
);
alertTypeRegistry.get.mockReturnValue(alertType);
});
test('successfully executes the task', async () => {
@ -205,6 +208,45 @@ describe('Task Runner', () => {
expect(call.tags).toEqual(['alert-', '-tags']);
expect(call.createdBy).toBe('alert-creator');
expect(call.updatedBy).toBe('alert-updater');
expect(call.rule).not.toBe(null);
expect(call.rule.name).toBe('alert-name');
expect(call.rule.tags).toEqual(['alert-', '-tags']);
expect(call.rule.consumer).toBe('bar');
expect(call.rule.enabled).toBe(true);
expect(call.rule.schedule).toMatchInlineSnapshot(`
Object {
"interval": "10s",
}
`);
expect(call.rule.createdBy).toBe('alert-creator');
expect(call.rule.updatedBy).toBe('alert-updater');
expect(call.rule.createdAt).toBe(mockDate);
expect(call.rule.updatedAt).toBe(mockDate);
expect(call.rule.notifyWhen).toBe('onActiveAlert');
expect(call.rule.throttle).toBe(null);
expect(call.rule.producer).toBe('alerts');
expect(call.rule.ruleTypeId).toBe('test');
expect(call.rule.ruleTypeName).toBe('My test alert');
expect(call.rule.actions).toMatchInlineSnapshot(`
Array [
Object {
"actionTypeId": "action",
"group": "default",
"id": "1",
"params": Object {
"foo": true,
},
},
Object {
"actionTypeId": "action",
"group": "recovered",
"id": "2",
"params": Object {
"isResolved": true,
},
},
]
`);
expect(call.services.alertInstanceFactory).toBeTruthy();
expect(call.services.scopedClusterClient).toBeTruthy();
expect(call.services).toBeTruthy();

View file

@ -215,6 +215,9 @@ export class TaskRunner<
event: Event
): Promise<AlertTaskState> {
const {
alertTypeId,
consumer,
schedule,
throttle,
notifyWhen,
muteAll,
@ -223,12 +226,17 @@ export class TaskRunner<
tags,
createdBy,
updatedBy,
createdAt,
updatedAt,
enabled,
actions,
} = alert;
const {
params: { alertId },
state: { alertInstances: alertRawInstances = {}, alertTypeState = {}, previousStartedAt },
} = this.taskInstance;
const namespace = this.context.spaceIdToNamespace(spaceId);
const alertType = this.alertTypeRegistry.get(alertTypeId);
const alertInstances = mapValues<
Record<string, RawAlertInstance>,
@ -265,6 +273,23 @@ export class TaskRunner<
tags,
createdBy,
updatedBy,
rule: {
name,
tags,
consumer,
producer: alertType.producer,
ruleTypeId: alert.alertTypeId,
ruleTypeName: alertType.name,
enabled,
schedule,
actions,
createdBy,
updatedBy,
createdAt,
updatedAt,
throttle,
notifyWhen,
},
});
} catch (err) {
event.message = `alert execution failure: ${alertLabel}`;

View file

@ -32,6 +32,7 @@ import {
AlertNotifyWhenType,
WithoutReservedActionGroups,
ActionVariable,
SanitizedRuleConfig,
} from '../common';
import { LicenseType } from '../../licensing/server';
@ -89,6 +90,7 @@ export interface AlertExecutorOptions<
services: AlertServices<InstanceState, InstanceContext, ActionGroupIds>;
params: Params;
state: State;
rule: SanitizedRuleConfig;
spaceId: string;
namespace?: string;
name: string;

View file

@ -37,6 +37,25 @@ const mockOptions = {
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: '',
tags: [],
consumer: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
producer: '',
ruleTypeId: '',
ruleTypeName: '',
},
};
describe('The metric threshold alert type', () => {

View file

@ -44,6 +44,25 @@ describe('rules_notification_alert_type', () => {
previousStartedAt: new Date('2019-12-13T16:40:33.400Z'),
createdBy: 'elastic',
updatedBy: 'elastic',
rule: {
name: 'name',
tags: [],
consumer: 'foo',
producer: 'foo',
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,
},
};
alert = rulesNotificationAlertType({

View file

@ -66,6 +66,25 @@ const getPayload = (
previousStartedAt: new Date('2019-12-13T16:40:33.400Z'),
createdBy: 'elastic',
updatedBy: 'elastic',
rule: {
name: ruleAlert.name,
tags: ruleAlert.tags,
consumer: 'foo',
producer: 'foo',
ruleTypeId: 'ruleType',
ruleTypeName: 'Name of rule',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: 'elastic',
updatedBy: 'elastic',
createdAt: new Date('2019-12-13T16:50:33.400Z'),
updatedAt: new Date('2019-12-13T16:50:33.400Z'),
throttle: null,
notifyWhen: null,
},
});
describe('signal_rule_alert_type', () => {

View file

@ -157,6 +157,25 @@ describe('alertType', () => {
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
});
expect(alertServices.alertInstanceFactory).not.toHaveBeenCalled();
@ -217,6 +236,25 @@ describe('alertType', () => {
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
});
expect(alertServices.alertInstanceFactory).toHaveBeenCalledWith(ConditionMetAlertInstanceId);
@ -274,6 +312,14 @@ describe('alertType', () => {
tags: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
consumer: '',
throttle: null,
notifyWhen: null,
schedule: {
interval: '1h',
},
};
const result = await alertType.executor({
...executorOptions,
@ -344,6 +390,25 @@ describe('alertType', () => {
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
});
const instance: AlertInstanceMock = alertServices.alertInstanceFactory.mock.results[0].value;
@ -402,6 +467,25 @@ describe('alertType', () => {
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
};
const result = await alertType.executor(executorOptions);
@ -498,6 +582,25 @@ describe('alertType', () => {
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
});
const instance: AlertInstanceMock = alertServices.alertInstanceFactory.mock.results[0].value;
@ -563,6 +666,25 @@ describe('alertType', () => {
tags: [],
createdBy: null,
updatedBy: null,
rule: {
name: uuid.v4(),
tags: [],
consumer: '',
producer: '',
ruleTypeId: '',
ruleTypeName: '',
enabled: true,
schedule: {
interval: '1h',
},
actions: [],
createdBy: null,
updatedBy: null,
createdAt: new Date(),
updatedAt: new Date(),
throttle: null,
notifyWhen: null,
},
});
const instance: AlertInstanceMock = alertServices.alertInstanceFactory.mock.results[0].value;

View file

@ -103,10 +103,11 @@ async function alwaysFiringExecutor(alertExecutorOptions: any) {
tags,
createdBy,
updatedBy,
rule,
} = alertExecutorOptions;
let group: string | null = 'default';
let subgroup: string | null = null;
const alertInfo = { alertId, spaceId, namespace, name, tags, createdBy, updatedBy };
const alertInfo = { alertId, spaceId, namespace, name, tags, createdBy, updatedBy, ...rule };
if (params.groupsToScheduleActionsInSeries) {
const index = state.groupInSeriesIndex || 0;

View file

@ -6,6 +6,7 @@
*/
import expect from '@kbn/expect';
import { omit } from 'lodash';
import { UserAtSpaceScenarios, Superuser } from '../../scenarios';
import { FtrProviderContext } from '../../../common/ftr_provider_context';
import {
@ -128,7 +129,11 @@ export default function alertTests({ getService }: FtrProviderContext) {
reference
);
expect(alertSearchResult.hits.total.value).to.eql(1);
expect(alertSearchResult.hits.hits[0]._source).to.eql({
const alertSearchResultWithoutDates = omit(alertSearchResult.hits.hits[0]._source, [
'alertInfo.createdAt',
'alertInfo.updatedAt',
]);
expect(alertSearchResultWithoutDates).to.eql({
source: 'alert:test.always-firing',
reference,
state: {},
@ -138,14 +143,40 @@ export default function alertTests({ getService }: FtrProviderContext) {
},
alertInfo: {
alertId,
consumer: 'alertsFixture',
spaceId: space.id,
namespace: space.id,
name: 'abc',
enabled: true,
notifyWhen: 'onActiveAlert',
schedule: {
interval: '1m',
},
tags: ['tag-A', 'tag-B'],
throttle: '1m',
createdBy: user.fullName,
updatedBy: user.fullName,
actions: response.body.actions.map((action: any) => {
/* eslint-disable @typescript-eslint/naming-convention */
const { connector_type_id, group, id, params } = action;
return {
actionTypeId: connector_type_id,
group,
id,
params,
};
}),
producer: 'alertsFixture',
ruleTypeId: 'test.always-firing',
ruleTypeName: 'Test: Always Firing',
},
});
expect(alertSearchResult.hits.hits[0]._source.alertInfo.createdAt).to.match(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
);
expect(alertSearchResult.hits.hits[0]._source.alertInfo.updatedAt).to.match(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
);
// Ensure only 1 action executed with proper params
const actionSearchResult = await esTestIndexTool.search(
@ -243,7 +274,11 @@ instanceStateValue: true
reference
);
expect(alertSearchResult.hits.total.value).to.eql(1);
expect(alertSearchResult.hits.hits[0]._source).to.eql({
const alertSearchResultWithoutDates = omit(alertSearchResult.hits.hits[0]._source, [
'alertInfo.createdAt',
'alertInfo.updatedAt',
]);
expect(alertSearchResultWithoutDates).to.eql({
source: 'alert:test.always-firing',
reference,
state: {},
@ -253,15 +288,41 @@ instanceStateValue: true
},
alertInfo: {
alertId,
consumer: 'alertsFixture',
spaceId: space.id,
namespace: space.id,
name: 'abc',
enabled: true,
notifyWhen: 'onActiveAlert',
schedule: {
interval: '1m',
},
tags: ['tag-A', 'tag-B'],
throttle: '1m',
createdBy: user.fullName,
updatedBy: user.fullName,
actions: response.body.actions.map((action: any) => {
/* eslint-disable @typescript-eslint/naming-convention */
const { connector_type_id, group, id, params } = action;
return {
actionTypeId: connector_type_id,
group,
id,
params,
};
}),
producer: 'alertsFixture',
ruleTypeId: 'test.always-firing',
ruleTypeName: 'Test: Always Firing',
},
});
expect(alertSearchResult.hits.hits[0]._source.alertInfo.createdAt).to.match(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
);
expect(alertSearchResult.hits.hits[0]._source.alertInfo.updatedAt).to.match(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
);
// Ensure only 1 action executed with proper params
const actionSearchResult = await esTestIndexTool.search(
'action:test.index-record',
@ -348,15 +409,46 @@ instanceStateValue: true
);
expect(alertSearchResult.hits.total.value).to.be.greaterThan(0);
expect(alertSearchResult.hits.hits[0]._source.alertInfo).to.eql({
const alertSearchResultInfoWithoutDates = omit(
alertSearchResult.hits.hits[0]._source.alertInfo,
['createdAt', 'updatedAt']
);
expect(alertSearchResultInfoWithoutDates).to.eql({
alertId,
consumer: 'alertsFixture',
spaceId: space.id,
namespace: space.id,
name: 'def',
enabled: true,
notifyWhen: 'onActiveAlert',
schedule: {
interval: '59s',
},
tags: ['fee', 'fi', 'fo'],
throttle: '1m',
createdBy: user.fullName,
updatedBy: Superuser.fullName,
actions: response2.body.actions.map((action: any) => {
/* eslint-disable @typescript-eslint/naming-convention */
const { connector_type_id, group, id, params } = action;
return {
actionTypeId: connector_type_id,
group,
id,
params,
};
}),
producer: 'alertsFixture',
ruleTypeId: 'test.always-firing',
ruleTypeName: 'Test: Always Firing',
});
expect(alertSearchResult.hits.hits[0]._source.alertInfo.createdAt).to.match(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
);
expect(alertSearchResult.hits.hits[0]._source.alertInfo.updatedAt).to.match(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
);
});
it('should handle custom retry logic when appropriate', async () => {

View file

@ -6,6 +6,7 @@
*/
import expect from '@kbn/expect';
import { omit } from 'lodash';
import { Response as SupertestResponse } from 'supertest';
import { RecoveredActionGroup } from '../../../../../plugins/alerting/common';
import { Space } from '../../../common/types';
@ -95,18 +96,48 @@ export function alertTests({ getService }: FtrProviderContext, space: Space) {
},
alertInfo: {
alertId,
consumer: 'alertsFixture',
spaceId: space.id,
namespace: space.namespace,
name: 'abc',
enabled: true,
notifyWhen: 'onActiveAlert',
schedule: {
interval: '1m',
},
tags: ['tag-A', 'tag-B'],
throttle: '1m',
createdBy: null,
updatedBy: null,
actions: response.body.actions.map((action: any) => {
/* eslint-disable @typescript-eslint/naming-convention */
const { connector_type_id, group, id, params } = action;
return {
actionTypeId: connector_type_id,
group,
id,
params,
};
}),
producer: 'alertsFixture',
ruleTypeId: 'test.always-firing',
ruleTypeName: 'Test: Always Firing',
},
};
if (expected.alertInfo.namespace === undefined) {
delete expected.alertInfo.namespace;
}
expect(alertTestRecord._source).to.eql(expected);
const alertTestRecordWithoutDates = omit(alertTestRecord._source, [
'alertInfo.createdAt',
'alertInfo.updatedAt',
]);
expect(alertTestRecordWithoutDates).to.eql(expected);
expect(alertTestRecord._source.alertInfo.createdAt).to.match(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
);
expect(alertTestRecord._source.alertInfo.updatedAt).to.match(
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
);
const actionTestRecord = (
await esTestIndexTool.waitForDocs('action:test.index-record', reference)
)[0];