[Response Ops][Alerting] Removing top level rule fields passed into executors (#144270)

* Removing top level fields passed into executors

* Updating stack rules

* Updating other rules

* Fixing types

* Fixing functional test

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Ying Mao 2022-11-04 09:20:54 -04:00 committed by GitHub
parent cb2f4ba9d9
commit 3b59a90671
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 123 additions and 158 deletions

View file

@ -29,7 +29,7 @@ describe('ActionContext', () => {
hits: [],
link: 'link-mock',
};
const context = addMessages({ name: '[rule-name]' }, base, params);
const context = addMessages('[rule-name]', base, params);
expect(context.title).toMatchInlineSnapshot(`"rule '[rule-name]' matched query"`);
expect(context.message).toEqual(
`rule '[rule-name]' is active:
@ -60,7 +60,7 @@ describe('ActionContext', () => {
hits: [],
link: 'link-mock',
};
const context = addMessages({ name: '[rule-name]' }, base, params, true);
const context = addMessages('[rule-name]', base, params, true);
expect(context.title).toMatchInlineSnapshot(`"rule '[rule-name]' recovered"`);
expect(context.message).toEqual(
`rule '[rule-name]' is recovered:
@ -91,7 +91,7 @@ describe('ActionContext', () => {
hits: [],
link: 'link-mock',
};
const context = addMessages({ name: '[rule-name]' }, base, params);
const context = addMessages('[rule-name]', base, params);
expect(context.title).toMatchInlineSnapshot(`"rule '[rule-name]' matched query"`);
expect(context.message).toEqual(
`rule '[rule-name]' is active:

View file

@ -7,13 +7,10 @@
import { i18n } from '@kbn/i18n';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { RuleExecutorOptions, AlertInstanceContext } from '@kbn/alerting-plugin/server';
import { AlertInstanceContext } from '@kbn/alerting-plugin/server';
import { OnlyEsQueryRuleParams, OnlySearchSourceRuleParams } from './types';
// rule type context provided to actions
type RuleInfo = Pick<RuleExecutorOptions, 'name'>;
export interface ActionContext extends EsQueryRuleActionContext {
// a short pre-constructed message which may be used in an action field
title: string;
@ -36,7 +33,7 @@ export interface EsQueryRuleActionContext extends AlertInstanceContext {
}
export function addMessages(
ruleInfo: RuleInfo,
ruleName: string,
baseContext: EsQueryRuleActionContext,
params: OnlyEsQueryRuleParams | OnlySearchSourceRuleParams,
isRecovered: boolean = false
@ -44,7 +41,7 @@ export function addMessages(
const title = i18n.translate('xpack.stackAlerts.esQuery.alertTypeContextSubjectTitle', {
defaultMessage: `rule '{name}' {verb}`,
values: {
name: ruleInfo.name,
name: ruleName,
verb: isRecovered ? 'recovered' : 'matched query',
},
});
@ -58,7 +55,7 @@ export function addMessages(
- Timestamp: {date}
- Link: {link}`,
values: {
name: ruleInfo.name,
name: ruleName,
value: baseContext.value,
conditions: baseContext.conditions,
window,

View file

@ -20,7 +20,14 @@ import { isEsQueryRule } from './util';
export async function executor(core: CoreSetup, options: ExecutorOptions<EsQueryRuleParams>) {
const esQueryRule = isEsQueryRule(options.params.searchType);
const { alertId: ruleId, name, services, params, state, spaceId, logger } = options;
const {
rule: { id: ruleId, name },
services,
params,
state,
spaceId,
logger,
} = options;
const { alertFactory, scopedClusterClient, searchSourceClient } = services;
const currentTimestamp = new Date().toISOString();
const publicBaseUrl = core.http.basePath.publicBaseUrl ?? '';
@ -75,7 +82,7 @@ export async function executor(core: CoreSetup, options: ExecutorOptions<EsQuery
conditions: getContextConditionsDescription(params.thresholdComparator, params.threshold),
} as EsQueryRuleActionContext;
const actionContext = addMessages(options, baseActiveContext, params);
const actionContext = addMessages(name, baseActiveContext, params);
const alertInstance = alertFactory.create(ConditionMetAlertInstanceId);
alertInstance
// store the params we would need to recreate the query that led to this alert instance
@ -107,7 +114,7 @@ export async function executor(core: CoreSetup, options: ExecutorOptions<EsQuery
true
),
} as EsQueryRuleActionContext;
const recoveryContext = addMessages(options, baseRecoveryContext, params, true);
const recoveryContext = addMessages(name, baseRecoveryContext, params, true);
alert.setContext(recoveryContext);
}

View file

@ -640,7 +640,6 @@ async function invokeExecutor({
state?: EsQueryRuleState;
}) {
return await ruleType.executor({
alertId: uuid.v4(),
executionId: uuid.v4(),
startedAt: new Date(),
previousStartedAt: new Date(),
@ -655,11 +654,8 @@ async function invokeExecutor({
...state,
},
spaceId: uuid.v4(),
name: uuid.v4(),
tags: [],
createdBy: null,
updatedBy: null,
rule: {
id: uuid.v4(),
name: uuid.v4(),
tags: [],
consumer: '',

View file

@ -143,7 +143,7 @@ export const getGeoContainmentExecutor = (): GeoContainmentAlertType['executor']
startedAt: windowEnd,
services,
params,
alertId,
rule: { id: ruleId },
state,
logger,
}): Promise<GeoContainmentState> {
@ -155,7 +155,7 @@ export const getGeoContainmentExecutor = (): GeoContainmentAlertType['executor']
params.geoField,
services.scopedClusterClient.asCurrentUser,
logger,
alertId,
ruleId,
params.boundaryNameField,
params.boundaryIndexQuery
);
@ -170,7 +170,7 @@ export const getGeoContainmentExecutor = (): GeoContainmentAlertType['executor']
// Start collecting data only on the first cycle
let currentIntervalResults: estypes.SearchResponse<unknown> | undefined;
if (!windowStart) {
logger.debug(`alert ${GEO_CONTAINMENT_ID}:${alertId} alert initialized. Collecting data`);
logger.debug(`alert ${GEO_CONTAINMENT_ID}:${ruleId} alert initialized. Collecting data`);
// Consider making first time window configurable?
const START_TIME_WINDOW = 1;
const tempPreviousEndTime = new Date(windowEnd);

View file

@ -518,7 +518,7 @@ describe('geo_containment', () => {
boundaryIndexId: 'testBoundaryIndexId',
boundaryGeoField: 'testBoundaryGeoField',
};
const alertId = 'testAlertId';
const ruleId = 'testAlertId';
const geoContainmentState = {
shapesFilters: {
testShape: 'thisIsAShape',
@ -567,7 +567,10 @@ describe('geo_containment', () => {
// @ts-ignore
services: alertServicesWithSearchMock,
params: geoContainmentParams,
alertId,
// @ts-ignore
rule: {
id: ruleId,
},
// @ts-ignore
state: {},
});
@ -587,7 +590,10 @@ describe('geo_containment', () => {
// @ts-ignore
services: alertServicesWithSearchMock,
params: geoContainmentParams,
alertId,
// @ts-ignore
rule: {
id: ruleId,
},
state: geoContainmentState,
});
if (executionResult && executionResult.shapesFilters) {
@ -606,7 +612,10 @@ describe('geo_containment', () => {
// @ts-ignore
services: alertServicesWithSearchMock,
params: geoContainmentParams,
alertId,
// @ts-ignore
rule: {
id: ruleId,
},
state: geoContainmentState,
});
if (executionResult && executionResult.shapesFilters) {
@ -642,7 +651,10 @@ describe('geo_containment', () => {
// @ts-ignore
services: alertServicesWithSearchMock,
params: geoContainmentParams,
alertId,
// @ts-ignore
rule: {
id: ruleId,
},
state: geoContainmentState,
});
if (executionResult && executionResult.prevLocationMap) {

View file

@ -28,7 +28,7 @@ describe('ActionContext', () => {
value: 42,
conditions: 'count greater than 4',
};
const context = addMessages({ name: '[rule-name]' }, base, params);
const context = addMessages('[rule-name]', base, params);
expect(context.title).toMatchInlineSnapshot(`"alert [rule-name] group [group] met threshold"`);
expect(context.message).toEqual(
`alert '[rule-name]' is active for group '[group]':
@ -59,7 +59,7 @@ describe('ActionContext', () => {
value: 42,
conditions: 'avg([aggField]) greater than 4.2',
};
const context = addMessages({ name: '[rule-name]' }, base, params);
const context = addMessages('[rule-name]', base, params);
expect(context.title).toMatchInlineSnapshot(`"alert [rule-name] group [group] met threshold"`);
expect(context.message).toEqual(
`alert '[rule-name]' is active for group '[group]':
@ -89,7 +89,7 @@ describe('ActionContext', () => {
value: 4,
conditions: 'count between 4 and 5',
};
const context = addMessages({ name: '[rule-name]' }, base, params);
const context = addMessages('[rule-name]', base, params);
expect(context.title).toMatchInlineSnapshot(`"alert [rule-name] group [group] met threshold"`);
expect(context.message).toEqual(
`alert '[rule-name]' is active for group '[group]':
@ -119,7 +119,7 @@ describe('ActionContext', () => {
value: 'unknown',
conditions: 'count between 4 and 5',
};
const context = addMessages({ name: '[rule-name]' }, base, params);
const context = addMessages('[rule-name]', base, params);
expect(context.title).toMatchInlineSnapshot(`"alert [rule-name] group [group] met threshold"`);
expect(context.message).toEqual(
`alert '[rule-name]' is active for group '[group]':

View file

@ -6,13 +6,10 @@
*/
import { i18n } from '@kbn/i18n';
import { RuleExecutorOptions, AlertInstanceContext } from '@kbn/alerting-plugin/server';
import { AlertInstanceContext } from '@kbn/alerting-plugin/server';
import { Params } from './rule_type_params';
// rule type context provided to actions
type RuleInfo = Pick<RuleExecutorOptions, 'name'>;
export interface ActionContext extends BaseActionContext {
// a short pre-constructed message which may be used in an action field
title: string;
@ -79,20 +76,20 @@ const RECOVERY_MESSAGE = (name: string, context: BaseActionContext, window: stri
});
export function addMessages(
ruleInfo: RuleInfo,
ruleName: string,
baseContext: BaseActionContext,
params: Params,
isRecoveryMessage?: boolean
): ActionContext {
const title = isRecoveryMessage
? RECOVERY_TITLE(ruleInfo.name, baseContext.group)
: DEFAULT_TITLE(ruleInfo.name, baseContext.group);
? RECOVERY_TITLE(ruleName, baseContext.group)
: DEFAULT_TITLE(ruleName, baseContext.group);
const window = `${params.timeWindowSize}${params.timeWindowUnit}`;
const message = isRecoveryMessage
? RECOVERY_MESSAGE(ruleInfo.name, baseContext, window)
: DEFAULT_MESSAGE(ruleInfo.name, baseContext, window);
? RECOVERY_MESSAGE(ruleName, baseContext, window)
: DEFAULT_MESSAGE(ruleName, baseContext, window);
return { ...baseContext, title, message };
}

View file

@ -183,7 +183,6 @@ describe('ruleType', () => {
};
await ruleType.executor({
alertId: uuid.v4(),
executionId: uuid.v4(),
startedAt: new Date(),
previousStartedAt: new Date(),
@ -197,11 +196,8 @@ describe('ruleType', () => {
latestTimestamp: undefined,
},
spaceId: uuid.v4(),
name: uuid.v4(),
tags: [],
createdBy: null,
updatedBy: null,
rule: {
id: uuid.v4(),
name: uuid.v4(),
tags: [],
consumer: '',
@ -250,7 +246,6 @@ describe('ruleType', () => {
};
await ruleType.executor({
alertId: uuid.v4(),
executionId: uuid.v4(),
startedAt: new Date(),
previousStartedAt: new Date(),
@ -264,11 +259,8 @@ describe('ruleType', () => {
latestTimestamp: undefined,
},
spaceId: uuid.v4(),
name: uuid.v4(),
tags: [],
createdBy: null,
updatedBy: null,
rule: {
id: uuid.v4(),
name: uuid.v4(),
tags: [],
consumer: '',
@ -317,7 +309,6 @@ describe('ruleType', () => {
};
await ruleType.executor({
alertId: uuid.v4(),
executionId: uuid.v4(),
startedAt: new Date(),
previousStartedAt: new Date(),
@ -331,11 +322,8 @@ describe('ruleType', () => {
latestTimestamp: undefined,
},
spaceId: uuid.v4(),
name: uuid.v4(),
tags: [],
createdBy: null,
updatedBy: null,
rule: {
id: uuid.v4(),
name: uuid.v4(),
tags: [],
consumer: '',
@ -383,7 +371,6 @@ describe('ruleType', () => {
};
await ruleType.executor({
alertId: uuid.v4(),
executionId: uuid.v4(),
startedAt: new Date(),
previousStartedAt: new Date(),
@ -397,11 +384,8 @@ describe('ruleType', () => {
latestTimestamp: undefined,
},
spaceId: uuid.v4(),
name: uuid.v4(),
tags: [],
createdBy: null,
updatedBy: null,
rule: {
id: uuid.v4(),
name: uuid.v4(),
tags: [],
consumer: '',

View file

@ -134,7 +134,12 @@ export function getRuleType(
async function executor(
options: RuleExecutorOptions<Params, {}, {}, ActionContext, typeof ActionGroupId>
) {
const { alertId: ruleId, name, services, params, logger } = options;
const {
rule: { id: ruleId, name },
services,
params,
logger,
} = options;
const { alertFactory, scopedClusterClient } = services;
const alertLimit = alertFactory.alertLimit.getValue();
@ -229,7 +234,7 @@ export function getRuleType(
value,
conditions: humanFn,
};
const actionContext = addMessages(options, baseContext, params);
const actionContext = addMessages(name, baseContext, params);
const alert = alertFactory.create(alertId);
alert.scheduleActions(ActionGroupId, actionContext);
logger.debug(`scheduled actionGroup: ${JSON.stringify(actionContext)}`);
@ -249,7 +254,7 @@ export function getRuleType(
params.thresholdComparator
)} ${params.threshold.join(' and ')}`,
};
const recoveryContext = addMessages(options, baseContext, params, true);
const recoveryContext = addMessages(name, baseContext, params, true);
recoveredAlert.setContext(recoveryContext);
}
}