[ResponseOps][Flapping] add flapping state to alert context for action parameters (#147136)

Resolves https://github.com/elastic/kibana/issues/146613

## Summary
Makes flapping indicator for an alert available in the context variables
for action mustache templates under `alert.flapping`
Let me know if we want to change this to be something else

### Checklist

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### To verify

- Create a new rule with a connector
- Add the new field Add `{{alert.flapping}}` to the your alert message,
and verify that it is in the alert output.
This commit is contained in:
Alexi Doak 2022-12-14 13:01:56 -05:00 committed by GitHub
parent 1382f48c60
commit b65ded0c8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 0 deletions

View file

@ -134,6 +134,8 @@ Using the https://mustache.github.io/[Mustache] template syntax `{{variable name
`alert.actionGroup`:: The ID of the action group of the alert that scheduled the action.
`alert.actionSubgroup`:: The action subgroup of the alert that scheduled the action.
`alert.actionGroupName`:: The name of the action group of the alert that scheduled the action.
`alert.flapping`:: A flag on the alert that indicates whether the alert status is changing repeatedly.
`kibanaBaseUrl`:: The configured <<server-publicBaseUrl, `server.publicBaseUrl`>>. If not configured, this will be empty.
[role="screenshot"]

View file

@ -208,6 +208,7 @@ export class ExecutionHandler<
alertParams: this.rule.params,
actionParams: action.params,
ruleUrl: this.buildRuleUrl(spaceId),
flapping: alert.getFlapping(),
}),
}),
};

View file

@ -48,6 +48,7 @@ test('skips non string parameters', () => {
alertParams: {
foo: 'test',
},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -82,6 +83,7 @@ test('missing parameters get emptied out', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -111,6 +113,7 @@ test('context parameters are passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -139,6 +142,7 @@ test('state parameters are passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -167,6 +171,7 @@ test('alertId is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -195,6 +200,7 @@ test('alertName is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -223,6 +229,7 @@ test('tags is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -250,6 +257,7 @@ test('undefined tags is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -278,6 +286,7 @@ test('empty tags is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -306,6 +315,7 @@ test('spaceId is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -334,6 +344,7 @@ test('alertInstanceId is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -362,6 +373,7 @@ test('alertActionGroup is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -390,6 +402,7 @@ test('alertActionGroupName is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -418,6 +431,7 @@ test('rule variables are passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -446,6 +460,7 @@ test('rule alert variables are passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -475,6 +490,7 @@ test('date is passed to templates', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
const dateAfter = Date.now();
const dateVariable = new Date(`${result.message}`).valueOf();
@ -505,6 +521,7 @@ test('works recursively', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -537,6 +554,7 @@ test('works recursively with arrays', () => {
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: false,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -548,3 +566,32 @@ test('works recursively with arrays', () => {
}
`);
});
test('flapping is passed to templates', () => {
const actionParams = {
message: 'Value "{{alert.flapping}}" exists',
};
const result = transformActionParams({
actionsPlugin,
actionTypeId,
actionParams,
state: {},
context: {},
alertId: '1',
alertType: 'rule-type-id',
actionId: 'action-id',
alertName: 'alert-name',
tags: ['tag-A', 'tag-B'],
spaceId: 'spaceId-A',
alertInstanceId: '2',
alertActionGroup: 'action-group',
alertActionGroupName: 'Action Group',
alertParams: {},
flapping: true,
});
expect(result).toMatchInlineSnapshot(`
Object {
"message": "Value \\"true\\" exists",
}
`);
});

View file

@ -31,6 +31,7 @@ interface TransformActionParamsOptions {
kibanaBaseUrl?: string;
context: AlertInstanceContext;
ruleUrl?: string;
flapping: boolean;
}
export function transformActionParams({
@ -51,6 +52,7 @@ export function transformActionParams({
kibanaBaseUrl,
alertParams,
ruleUrl,
flapping,
}: TransformActionParamsOptions): RuleActionParams {
// when the list of variables we pass in here changes,
// the UI will need to be updated as well; see:
@ -80,6 +82,7 @@ export function transformActionParams({
id: alertInstanceId,
actionGroup: alertActionGroup,
actionGroupName: alertActionGroupName,
flapping,
},
};
return actionsPlugin.renderActionParameterTemplates(

View file

@ -63,6 +63,10 @@ const expectedTransformResult = [
'The human readable name of the action group of the alert that scheduled actions for the rule.',
name: 'alert.actionGroupName',
},
{
description: 'A flag on the alert that indicates whether the alert is flapping.',
name: 'alert.flapping',
},
{
description: 'The configured server.publicBaseUrl value or empty string if not configured.',
name: 'kibanaBaseUrl',

View file

@ -47,6 +47,7 @@ export enum AlertProvidedActionVariables {
alertActionGroup = 'alert.actionGroup',
alertActionGroupName = 'alert.actionGroupName',
alertActionSubgroup = 'alert.actionSubgroup',
alertFlapping = 'alert.flapping',
}
export enum LegacyAlertProvidedActionVariables {
@ -156,6 +157,14 @@ function getAlwaysProvidedActionVariables(): ActionVariable[] {
),
});
result.push({
name: AlertProvidedActionVariables.alertFlapping,
description: i18n.translate('xpack.triggersActionsUI.actionVariables.alertFlappingLabel', {
defaultMessage:
'A flag on the alert that indicates whether the alert status is changing repeatedly.',
}),
});
result.push({
name: 'kibanaBaseUrl',
description: i18n.translate('xpack.triggersActionsUI.actionVariables.kibanaBaseUrlLabel', {