Skip to content

Commit

Permalink
[Response Ops][Alerting] Updating AlertsClient to provide feature p…
Browse files Browse the repository at this point in the history
…arity with rule registry lifecycle executor (#160466)

Resolves #160173

## Summary
The rule registry lifecycle executor automatically sets the following
fields in alert docs:
- `event.action` - `open`, `active` or `close` depending on what type of
alert
- `event.kind` - always `signal`
- `tags` - merges rule tags with rule executor reported tags
- `kibana.version`
- `kibana.alert.workflow_status` - set to `open`
- `kibana.alert.time_range`

In addition, the rule registry lifecycle executor provides some helper
functions for the rule executors to get the alert UUID, the alert start
time (if it exists) and the alert document for recovered alerts (used to
set recovered context variables).

This PR augments the framework `AlertsClient` to set the same fields and
to provide the same functionality to the rule executors. When an alert
is reported via the `AlertsClient`, the UUID (either existing or newly
generated) and the start time (for ongoing alerts) is returned back to
the rule executors. When an executor requests the recovered alerts in
order to set context information, the existing alert document is
returned.

## To Verify

Check out [this
commit](dc5beba)
which removes the metric threshold rule from the rule registry lifecycle
executor and onboards it to use the framework alerts client. Create a
metric threshold rule that creates active alerts and recovers alerts.
Inspect the alerts documents to make sure all the fields mentioned above
exist. Compare these documents with alerts created using the lifecycle
executor.

---------

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
ymao1 and kibanamachine authored Jun 29, 2023
1 parent a68a28a commit 50049ac
Show file tree
Hide file tree
Showing 29 changed files with 1,278 additions and 321 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ import {
SPACE_IDS,
TIMESTAMP,
VERSION,
EVENT_ACTION,
EVENT_KIND,
TAGS,
} from '@kbn/rule-data-utils';

export const alertFieldMap = {
Expand Down Expand Up @@ -179,11 +182,26 @@ export const alertFieldMap = {
array: true,
required: false,
},
[EVENT_ACTION]: {
type: 'keyword',
array: false,
required: false,
},
[EVENT_KIND]: {
type: 'keyword',
array: false,
required: false,
},
[SPACE_IDS]: {
type: 'keyword',
array: true,
required: true,
},
[TAGS]: {
type: 'keyword',
array: true,
required: false,
},
[TIMESTAMP]: {
type: 'date',
required: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ import {
ALERT_WORKFLOW_REASON,
ALERT_WORKFLOW_USER,
ECS_VERSION,
EVENT_ACTION,
EVENT_KIND,
TAGS,
} from '@kbn/rule-data-utils';

export const legacyAlertFieldMap = {
Expand Down Expand Up @@ -182,21 +179,6 @@ export const legacyAlertFieldMap = {
array: false,
required: false,
},
[EVENT_ACTION]: {
type: 'keyword',
array: false,
required: false,
},
[EVENT_KIND]: {
type: 'keyword',
array: false,
required: false,
},
[TAGS]: {
type: 'keyword',
array: true,
required: false,
},
} as const;

export type LegacyAlertFieldMap = typeof legacyAlertFieldMap;
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ const AlertRequired = rt.type({
}),
});
const AlertOptional = rt.partial({
event: rt.partial({
action: schemaString,
kind: schemaString,
}),
kibana: rt.partial({
alert: rt.partial({
action_group: schemaString,
Expand Down Expand Up @@ -117,6 +121,7 @@ const AlertOptional = rt.partial({
}),
version: schemaString,
}),
tags: schemaStringArray,
});

// prettier-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@ const LegacyAlertOptional = rt.partial({
ecs: rt.partial({
version: schemaString,
}),
event: rt.partial({
action: schemaString,
kind: schemaString,
}),
kibana: rt.partial({
alert: rt.partial({
risk_score: schemaNumber,
Expand Down Expand Up @@ -113,7 +109,6 @@ const LegacyAlertOptional = rt.partial({
workflow_user: schemaString,
}),
}),
tags: schemaStringArray,
});

// prettier-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,16 @@ describe('mappingFromFieldMap', () => {
'@timestamp': {
type: 'date',
},
event: {
properties: {
action: {
type: 'keyword',
},
kind: {
type: 'keyword',
},
},
},
kibana: {
properties: {
alert: {
Expand Down Expand Up @@ -305,6 +315,9 @@ describe('mappingFromFieldMap', () => {
},
},
},
tags: {
type: 'keyword',
},
},
});
expect(mappingFromFieldMap(legacyAlertFieldMap)).toEqual({
Expand Down Expand Up @@ -355,8 +368,6 @@ describe('mappingFromFieldMap', () => {
},
},
ecs: { properties: { version: { type: 'keyword' } } },
event: { properties: { action: { type: 'keyword' }, kind: { type: 'keyword' } } },
tags: { type: 'keyword' },
},
});
});
Expand Down
18 changes: 18 additions & 0 deletions x-pack/plugins/alerting/server/alert/alert.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,24 @@ describe('getUUID()', () => {
});
});

describe('getStart()', () => {
test('returns null for new alert', () => {
const alert = new Alert<AlertInstanceState, AlertInstanceContext, DefaultActionGroupId>('1');
expect(alert.getStart()).toBeNull();
});

test('returns start time if set in state', () => {
const uuid = 'previous-uuid';
const meta = { uuid };
const state = { foo: true, start: '2023-03-28T12:27:28.159Z', duration: '0' };
const alert = new Alert<AlertInstanceState, AlertInstanceContext, DefaultActionGroupId>('1', {
state,
meta,
});
expect(alert.getStart()).toEqual('2023-03-28T12:27:28.159Z');
});
});

describe('scheduleActions()', () => {
test('makes hasScheduledActions() return true', () => {
const alert = new Alert<AlertInstanceState, AlertInstanceContext, DefaultActionGroupId>('1', {
Expand Down
5 changes: 5 additions & 0 deletions x-pack/plugins/alerting/server/alert/alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export type PublicAlert<
| 'getContext'
| 'getState'
| 'getUuid'
| 'getStart'
| 'hasContext'
| 'replaceState'
| 'scheduleActions'
Expand Down Expand Up @@ -76,6 +77,10 @@ export class Alert<
return this.meta.uuid!;
}

getStart(): string | null {
return this.state.start ? `${this.state.start}` : null;
}

hasScheduledActions() {
return this.scheduledExecutionOptions !== undefined;
}
Expand Down
Loading

0 comments on commit 50049ac

Please sign in to comment.