diff --git a/x-pack/plugins/alerting/server/alert_type_registry.test.ts b/x-pack/plugins/alerting/server/alert_type_registry.test.ts index f4749772c70040d..70441af58b72bdf 100644 --- a/x-pack/plugins/alerting/server/alert_type_registry.test.ts +++ b/x-pack/plugins/alerting/server/alert_type_registry.test.ts @@ -173,6 +173,10 @@ describe('list()', () => { "name": "Test Action Group", }, ], + "actionVariables": Object { + "context": Object {}, + "state": Object {}, + }, "defaultActionGroupId": "testActionGroup", "id": "test", "name": "Test", diff --git a/x-pack/plugins/alerting/server/alert_type_registry.ts b/x-pack/plugins/alerting/server/alert_type_registry.ts index d9045fb986745f9..0635af4ae18d6ce 100644 --- a/x-pack/plugins/alerting/server/alert_type_registry.ts +++ b/x-pack/plugins/alerting/server/alert_type_registry.ts @@ -71,6 +71,14 @@ export class AlertTypeRegistry { name: alertType.name, actionGroups: alertType.actionGroups, defaultActionGroupId: alertType.defaultActionGroupId, + actionVariables: normalizedActionVariables(alertType.actionVariables), })); } } + +function normalizedActionVariables(actionVariables: any) { + return { + context: actionVariables?.context ?? {}, + state: actionVariables?.state ?? {}, + }; +} diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index 635cf0cbd137166..4f352d35d6a2493 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -61,6 +61,10 @@ export interface AlertType { actionGroups: ActionGroup[]; defaultActionGroupId: ActionGroup['id']; executor: ({ services, params, state }: AlertExecutorOptions) => Promise; + actionVariables?: { + context?: Record; + state?: Record; + }; } export interface RawAlertAction extends SavedObjectAttributes { diff --git a/x-pack/plugins/alerting_builtins/server/alert_types/index_threshold/alert_type.test.ts b/x-pack/plugins/alerting_builtins/server/alert_types/index_threshold/alert_type.test.ts index 5034b1ee0cd0180..da577d20c9f80cd 100644 --- a/x-pack/plugins/alerting_builtins/server/alert_types/index_threshold/alert_type.test.ts +++ b/x-pack/plugins/alerting_builtins/server/alert_types/index_threshold/alert_type.test.ts @@ -22,6 +22,21 @@ describe('alertType', () => { expect(alertType.id).toBe('.index-threshold'); expect(alertType.name).toBe('Index Threshold'); expect(alertType.actionGroups).toEqual([{ id: 'threshold met', name: 'Threshold Met' }]); + + const actionVariables = { + context: alertType.actionVariables?.context, + state: alertType.actionVariables?.state, + }; + expect(actionVariables).toMatchInlineSnapshot(` + Object { + "context": Object { + "date": "The date the alert exceeded the threshold.", + "group": "The group that exceeded the threshold.", + "value": "The value that exceeded the threshold.", + }, + "state": undefined, + } + `); }); it('validator succeeds with valid params', async () => { diff --git a/x-pack/plugins/alerting_builtins/server/alert_types/index_threshold/alert_type.ts b/x-pack/plugins/alerting_builtins/server/alert_types/index_threshold/alert_type.ts index 4610e0fbaf0da60..a934b3c71d76756 100644 --- a/x-pack/plugins/alerting_builtins/server/alert_types/index_threshold/alert_type.ts +++ b/x-pack/plugins/alerting_builtins/server/alert_types/index_threshold/alert_type.ts @@ -32,6 +32,27 @@ export function getAlertType(service: Service): AlertType { } ); + const actionVariableContextGroupLabel = i18n.translate( + 'xpack.alertingBuiltins.indexThreshold.actionVariableContextGroupLabel', + { + defaultMessage: 'The group that exceeded the threshold.', + } + ); + + const actionVariableContextDateLabel = i18n.translate( + 'xpack.alertingBuiltins.indexThreshold.actionVariableContextDateLabel', + { + defaultMessage: 'The date the alert exceeded the threshold.', + } + ); + + const actionVariableContextValueLabel = i18n.translate( + 'xpack.alertingBuiltins.indexThreshold.actionVariableContextValueLabel', + { + defaultMessage: 'The value that exceeded the threshold.', + } + ); + return { id: ID, name: alertTypeName, @@ -40,6 +61,13 @@ export function getAlertType(service: Service): AlertType { validate: { params: ParamsSchema, }, + actionVariables: { + context: { + group: actionVariableContextGroupLabel, + date: actionVariableContextDateLabel, + value: actionVariableContextValueLabel, + }, + }, executor, }; diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts index 2e7674f2b3eb7d5..08bab213374ff5a 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts @@ -207,6 +207,14 @@ export default function(kibana: any) { { id: 'other', name: 'Other' }, ], defaultActionGroupId: 'default', + actionVariables: { + state: { + instanceStateValue: 'the instance state value', + }, + context: { + instanceContextValue: 'the instance context value', + }, + }, async executor(alertExecutorOptions: AlertExecutorOptions) { const { services, @@ -419,6 +427,26 @@ export default function(kibana: any) { defaultActionGroupId: 'default', async executor({ services, params, state }: AlertExecutorOptions) {}, }; + const onlyContextVariablesAlertType: AlertType = { + id: 'test.onlyContextVariables', + name: 'Test: Only Context Variables', + actionGroups: [{ id: 'default', name: 'Default' }], + defaultActionGroupId: 'default', + actionVariables: { + context: { aContextVariable: 'this is a context variable' }, + }, + async executor(opts: AlertExecutorOptions) {}, + }; + const onlyStateVariablesAlertType: AlertType = { + id: 'test.onlyStateVariables', + name: 'Test: Only State Variables', + actionGroups: [{ id: 'default', name: 'Default' }], + defaultActionGroupId: 'default', + actionVariables: { + state: { aStateVariable: 'this is a state variable' }, + }, + async executor(opts: AlertExecutorOptions) {}, + }; server.newPlatform.setup.plugins.alerting.registerType(alwaysFiringAlertType); server.newPlatform.setup.plugins.alerting.registerType(cumulativeFiringAlertType); server.newPlatform.setup.plugins.alerting.registerType(neverFiringAlertType); @@ -426,6 +454,8 @@ export default function(kibana: any) { server.newPlatform.setup.plugins.alerting.registerType(validationAlertType); server.newPlatform.setup.plugins.alerting.registerType(authorizationAlertType); server.newPlatform.setup.plugins.alerting.registerType(noopAlertType); + server.newPlatform.setup.plugins.alerting.registerType(onlyContextVariablesAlertType); + server.newPlatform.setup.plugins.alerting.registerType(onlyStateVariablesAlertType); }, }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/list_alert_types.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/list_alert_types.ts index 590de1ea7ce0b72..66df08b878215eb 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/list_alert_types.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/list_alert_types.ts @@ -16,7 +16,6 @@ export default function listAlertTypes({ getService }: FtrProviderContext) { describe('list_alert_types', () => { it('should return 200 with list of alert types', async () => { const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alert/types`); - expect(response.statusCode).to.eql(200); const fixtureAlertType = response.body.find((alertType: any) => alertType.id === 'test.noop'); expect(fixtureAlertType).to.eql({ @@ -24,6 +23,60 @@ export default function listAlertTypes({ getService }: FtrProviderContext) { defaultActionGroupId: 'default', id: 'test.noop', name: 'Test: Noop', + actionVariables: { + state: {}, + context: {}, + }, + }); + }); + + it('should return actionVariables with both context and state', async () => { + const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alert/types`); + expect(response.statusCode).to.eql(200); + + const fixtureAlertType = response.body.find( + (alertType: any) => alertType.id === 'test.always-firing' + ); + + expect(fixtureAlertType.actionVariables).to.eql({ + state: { + instanceStateValue: 'the instance state value', + }, + context: { + instanceContextValue: 'the instance context value', + }, + }); + }); + + it('should return actionVariables with just context', async () => { + const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alert/types`); + expect(response.statusCode).to.eql(200); + + const fixtureAlertType = response.body.find( + (alertType: any) => alertType.id === 'test.onlyContextVariables' + ); + + expect(fixtureAlertType.actionVariables).to.eql({ + state: {}, + context: { + aContextVariable: 'this is a context variable', + }, + }); + }); + + it('should return actionVariables with just state', async () => { + const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alert/types`); + expect(response.statusCode).to.eql(200); + + const fixtureAlertType = response.body.find( + (alertType: any) => alertType.id === 'test.onlyStateVariables' + ); + + expect(fixtureAlertType.actionVariables).to.eql({ + state: { + aStateVariable: 'this is a state variable', + }, + context: {}, }); }); });