[8.x] [Response Ops][Alerting] Remove rules client from alerting task runner (#194300) (#194858)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Response Ops][Alerting] Remove rules client from alerting task
runner (#194300)](https://github.com/elastic/kibana/pull/194300)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Ying
Mao","email":"ying.mao@elastic.co"},"sourceCommit":{"committedDate":"2024-10-03T15:53:06Z","message":"[Response
Ops][Alerting] Remove rules client from alerting task runner
(#194300)\n\n## Summary\r\n\r\nInitializing the rules client with every
rule execution causes 2\r\nrequests to Elasticsearch, a `POST
/_security/user/_has_privileges`\r\nrequest and a
`GET/.kibana_<version>/_doc/space:<spaceId>` request. We\r\nonly use the
rules client to proxy two methods `getAlertFromRaw`
and\r\n`clearExpiredSnoozes`. Both of these methods can be converted
into\r\nlibrary functions that can be used without the rules client.
This PR\r\nmakes that
conversion.\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine
<elasticmachine@users.noreply.github.com>","sha":"326f81398472e160fec254c05541aa2a588a7f70","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Feature:Alerting","release_note:skip","Team:ResponseOps","v9.0.0","backport:prev-minor","v8.16.0"],"title":"[Response
Ops][Alerting] Remove rules client from alerting task
runner","number":194300,"url":"https://github.com/elastic/kibana/pull/194300","mergeCommit":{"message":"[Response
Ops][Alerting] Remove rules client from alerting task runner
(#194300)\n\n## Summary\r\n\r\nInitializing the rules client with every
rule execution causes 2\r\nrequests to Elasticsearch, a `POST
/_security/user/_has_privileges`\r\nrequest and a
`GET/.kibana_<version>/_doc/space:<spaceId>` request. We\r\nonly use the
rules client to proxy two methods `getAlertFromRaw`
and\r\n`clearExpiredSnoozes`. Both of these methods can be converted
into\r\nlibrary functions that can be used without the rules client.
This PR\r\nmakes that
conversion.\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine
<elasticmachine@users.noreply.github.com>","sha":"326f81398472e160fec254c05541aa2a588a7f70"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194300","number":194300,"mergeCommit":{"message":"[Response
Ops][Alerting] Remove rules client from alerting task runner
(#194300)\n\n## Summary\r\n\r\nInitializing the rules client with every
rule execution causes 2\r\nrequests to Elasticsearch, a `POST
/_security/user/_has_privileges`\r\nrequest and a
`GET/.kibana_<version>/_doc/space:<spaceId>` request. We\r\nonly use the
rules client to proxy two methods `getAlertFromRaw`
and\r\n`clearExpiredSnoozes`. Both of these methods can be converted
into\r\nlibrary functions that can be used without the rules client.
This PR\r\nmakes that
conversion.\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine
<elasticmachine@users.noreply.github.com>","sha":"326f81398472e160fec254c05541aa2a588a7f70"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Ying Mao <ying.mao@elastic.co>
This commit is contained in:
Kibana Machine 2024-10-04 03:37:16 +10:00 committed by GitHub
parent e5fd6778f8
commit 23e1bdf32e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 512 additions and 494 deletions

View file

@ -149,16 +149,18 @@ export async function findRules<Params extends RuleParams = never>(
throw error;
}
const rule = getAlertFromRaw<Params>(
context,
id,
attributes.alertTypeId,
(fields ? pick(attributes, fields) : attributes) as RawRule,
references,
false,
const rule = getAlertFromRaw<Params>({
excludeFromPublicApi,
includeSnoozeData
);
id,
includeLegacyId: false,
includeSnoozeData,
isSystemAction: context.isSystemAction,
logger: context.logger,
rawRule: (fields ? pick(attributes, fields) : attributes) as RawRule,
references,
ruleTypeId: attributes.alertTypeId,
ruleTypeRegistry: context.ruleTypeRegistry,
});
// collect SIEM rule for further formatting legacy actions
if (attributes.consumer === AlertConsumers.SIEM) {

View file

@ -606,7 +606,6 @@ export class AlertingPlugin {
encryptedSavedObjectsClient,
eventLogger: this.eventLogger!,
executionContext: core.executionContext,
getRulesClientWithRequest,
kibanaBaseUrl: this.kibanaBaseUrl,
logger,
maintenanceWindowsService: new MaintenanceWindowsService({

View file

@ -52,10 +52,8 @@ const createRulesClientMock = () => {
bulkDisableRules: jest.fn(),
snooze: jest.fn(),
unsnooze: jest.fn(),
clearExpiredSnoozes: jest.fn(),
runSoon: jest.fn(),
clone: jest.fn(),
getAlertFromRaw: jest.fn(),
getScheduleFrequency: jest.fn(),
bulkUntrackAlerts: jest.fn(),
};

View file

@ -141,13 +141,15 @@ export async function createRuleSavedObject<Params extends RuleTypeParams = neve
return createdAlert as SavedObject<RuleAttributes>;
}
return getAlertFromRaw<Params>(
context,
createdAlert.id,
createdAlert.attributes.alertTypeId,
createdAlert.attributes,
return getAlertFromRaw<Params>({
excludeFromPublicApi: true,
id: createdAlert.id,
includeLegacyId: false,
isSystemAction: context.isSystemAction,
logger: context.logger,
rawRule: createdAlert.attributes,
references,
false,
true
);
ruleTypeId: createdAlert.attributes.alertTypeId,
ruleTypeRegistry: context.ruleTypeRegistry,
});
}

View file

@ -6,7 +6,7 @@
*/
import { omit, isEmpty } from 'lodash';
import { SavedObjectReference } from '@kbn/core/server';
import { Logger, SavedObjectReference } from '@kbn/core/server';
import {
Rule,
PartialRule,
@ -15,6 +15,7 @@ import {
RuleTypeParams,
RuleWithLegacyId,
PartialRuleWithLegacyId,
RuleTypeRegistry,
} from '../../types';
import {
ruleExecutionStatusFromRaw,
@ -24,11 +25,11 @@ import {
import { UntypedNormalizedRuleType } from '../../rule_type_registry';
import { getActiveScheduledSnoozes } from '../../lib/is_rule_snoozed';
import { injectReferencesIntoParams } from '../common';
import { RulesClientContext } from '../types';
import {
transformRawActionsToDomainActions,
transformRawActionsToDomainSystemActions,
} from '../../application/rule/transforms/transform_raw_actions_to_domain_actions';
import { fieldsToExcludeFromPublicApi } from '../rules_client';
export interface GetAlertFromRawParams {
id: string;
@ -41,35 +42,52 @@ export interface GetAlertFromRawParams {
omitGeneratedValues?: boolean;
}
interface GetAlertFromRawOpts {
excludeFromPublicApi?: boolean;
id: string;
includeLegacyId?: boolean;
includeSnoozeData?: boolean;
isSystemAction: (actionId: string) => boolean;
logger: Logger;
omitGeneratedValues?: boolean;
rawRule: RawRule;
references: SavedObjectReference[] | undefined;
ruleTypeId: string;
ruleTypeRegistry: RuleTypeRegistry;
}
type GetPartialRuleFromRawOpts = Omit<GetAlertFromRawOpts, 'ruleTypeRegistry'> & {
ruleType: UntypedNormalizedRuleType;
};
/**
* @deprecated in favor of transformRuleAttributesToRuleDomain
*/
export function getAlertFromRaw<Params extends RuleTypeParams>(
context: RulesClientContext,
id: string,
ruleTypeId: string,
rawRule: RawRule,
references: SavedObjectReference[] | undefined,
includeLegacyId: boolean = false,
excludeFromPublicApi: boolean = false,
includeSnoozeData: boolean = false,
omitGeneratedValues: boolean = true
opts: GetAlertFromRawOpts
): Rule | RuleWithLegacyId {
const ruleType = context.ruleTypeRegistry.get(ruleTypeId);
const {
excludeFromPublicApi = false,
includeLegacyId = false,
includeSnoozeData = false,
omitGeneratedValues = true,
} = opts;
const ruleType = opts.ruleTypeRegistry.get(opts.ruleTypeId);
// In order to support the partial update API of Saved Objects we have to support
// partial updates of an Alert, but when we receive an actual RawRule, it is safe
// to cast the result to an Alert
const res = getPartialRuleFromRaw<Params>(
context,
id,
ruleType,
rawRule,
references,
includeLegacyId,
const res = getPartialRuleFromRaw<Params>({
excludeFromPublicApi,
id: opts.id,
includeLegacyId,
includeSnoozeData,
omitGeneratedValues
);
isSystemAction: opts.isSystemAction,
logger: opts.logger,
omitGeneratedValues,
rawRule: opts.rawRule,
references: opts.references,
ruleTypeId: opts.ruleTypeId,
ruleType,
});
// include to result because it is for internal rules client usage
if (includeLegacyId) {
return res as RuleWithLegacyId;
@ -78,11 +96,18 @@ export function getAlertFromRaw<Params extends RuleTypeParams>(
return omit(res, ['legacyId']) as Rule;
}
export function getPartialRuleFromRaw<Params extends RuleTypeParams>(
context: RulesClientContext,
id: string,
ruleType: UntypedNormalizedRuleType,
{
function getPartialRuleFromRaw<Params extends RuleTypeParams>(
opts: GetPartialRuleFromRawOpts
): PartialRule<Params> | PartialRuleWithLegacyId<Params> {
const {
excludeFromPublicApi = false,
includeLegacyId = false,
includeSnoozeData = false,
omitGeneratedValues = true,
rawRule,
} = opts;
const {
createdAt,
updatedAt,
meta,
@ -99,13 +124,8 @@ export function getPartialRuleFromRaw<Params extends RuleTypeParams>(
lastRun,
isSnoozedUntil: DoNotUseIsSNoozedUntil,
...partialRawRule
}: Partial<RawRule>,
references: SavedObjectReference[] | undefined,
includeLegacyId: boolean = false,
excludeFromPublicApi: boolean = false,
includeSnoozeData: boolean = false,
omitGeneratedValues: boolean = true
): PartialRule<Params> | PartialRuleWithLegacyId<Params> {
} = rawRule;
const snoozeScheduleDates = snoozeSchedule?.map((s) => ({
...s,
rRule: {
@ -125,31 +145,36 @@ export function getPartialRuleFromRaw<Params extends RuleTypeParams>(
const includeMonitoring = monitoring && !excludeFromPublicApi;
const rule: PartialRule<Params> = {
id,
id: opts.id,
notifyWhen,
...omit(partialRawRule, excludeFromPublicApi ? [...context.fieldsToExcludeFromPublicApi] : ''),
...omit(partialRawRule, excludeFromPublicApi ? [...fieldsToExcludeFromPublicApi] : ''),
// we currently only support the Interval Schedule type
// Once we support additional types, this type signature will likely change
schedule: schedule as IntervalSchedule,
actions: actions
? transformRawActionsToDomainActions({
ruleId: id,
ruleId: opts.id,
actions,
references: references || [],
isSystemAction: context.isSystemAction,
references: opts.references || [],
isSystemAction: opts.isSystemAction,
omitGeneratedValues,
})
: [],
systemActions: actions
? transformRawActionsToDomainSystemActions({
ruleId: id,
ruleId: opts.id,
actions,
references: references || [],
isSystemAction: context.isSystemAction,
references: opts.references || [],
isSystemAction: opts.isSystemAction,
omitGeneratedValues,
})
: [],
params: injectReferencesIntoParams(id, ruleType, params, references || []) as Params,
params: injectReferencesIntoParams(
opts.id,
opts.ruleType,
params,
opts.references || []
) as Params,
...(excludeFromPublicApi ? {} : { snoozeSchedule: snoozeScheduleDates ?? [] }),
...(includeSnoozeData && !excludeFromPublicApi
? {
@ -164,10 +189,10 @@ export function getPartialRuleFromRaw<Params extends RuleTypeParams>(
...(createdAt ? { createdAt: new Date(createdAt) } : {}),
...(scheduledTaskId ? { scheduledTaskId } : {}),
...(executionStatus
? { executionStatus: ruleExecutionStatusFromRaw(context.logger, id, executionStatus) }
? { executionStatus: ruleExecutionStatusFromRaw(opts.logger, opts.id, executionStatus) }
: {}),
...(includeMonitoring
? { monitoring: convertMonitoringFromRawAndVerify(context.logger, id, monitoring) }
? { monitoring: convertMonitoringFromRawAndVerify(opts.logger, opts.id, monitoring) }
: {}),
...(nextRun ? { nextRun: new Date(nextRun) } : {}),
...(lastRun
@ -193,7 +218,7 @@ export function getPartialRuleFromRaw<Params extends RuleTypeParams>(
// Need the `rule` object to build a URL
if (!excludeFromPublicApi) {
const viewInAppRelativeUrl =
ruleType.getViewInAppRelativeUrl && ruleType.getViewInAppRelativeUrl({ rule });
opts.ruleType.getViewInAppRelativeUrl && opts.ruleType.getViewInAppRelativeUrl({ rule });
if (viewInAppRelativeUrl) {
rule.viewInAppRelativeUrl = viewInAppRelativeUrl;
}

View file

@ -1,48 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { RuleTypeParams, SanitizedRule } from '../../../common';
import { partiallyUpdateRule } from '../../saved_objects';
import { isSnoozeExpired } from '../../lib';
import { RulesClientContext } from '../types';
import { updateMeta } from '../lib';
export async function clearExpiredSnoozes(
context: RulesClientContext,
{
rule,
version,
}: { rule: Pick<SanitizedRule<RuleTypeParams>, 'id' | 'snoozeSchedule'>; version?: string }
): Promise<void> {
const snoozeSchedule = rule.snoozeSchedule
? rule.snoozeSchedule.filter((s) => {
try {
return !isSnoozeExpired(s);
} catch (e) {
context.logger.error(`Error checking for expiration of snooze ${s.id}: ${e}`);
return true;
}
})
: [];
if (snoozeSchedule.length === rule.snoozeSchedule?.length) return;
const updateAttributes = updateMeta(context, {
snoozeSchedule,
updatedBy: await context.getUserName(),
updatedAt: new Date().toISOString(),
});
const updateOptions = { version, refresh: false };
await partiallyUpdateRule(
context.unsecuredSavedObjectsClient,
rule.id,
updateAttributes,
updateOptions
);
}

View file

@ -57,14 +57,12 @@ import { bulkEnableRules, BulkEnableRulesParams } from '../application/rule/meth
import { enableRule } from '../application/rule/methods/enable_rule/enable_rule';
import { updateRuleApiKey } from '../application/rule/methods/update_api_key/update_rule_api_key';
import { disableRule } from '../application/rule/methods/disable/disable_rule';
import { clearExpiredSnoozes } from './methods/clear_expired_snoozes';
import { muteInstance } from '../application/rule/methods/mute_alert/mute_instance';
import { muteAll } from './methods/mute_all';
import { unmuteAll } from './methods/unmute_all';
import { unmuteInstance } from '../application/rule/methods/unmute_alert/unmute_instance';
import { runSoon } from './methods/run_soon';
import { listRuleTypes } from './methods/list_rule_types';
import { getAlertFromRaw, GetAlertFromRawParams } from './lib/get_alert_from_raw';
import { getScheduleFrequency } from '../application/rule/methods/get_schedule_frequency/get_schedule_frequency';
import {
bulkUntrackAlerts,
@ -84,7 +82,7 @@ export type ConstructorOptions = Omit<
'fieldsToExcludeFromPublicApi' | 'minimumScheduleIntervalInMs'
>;
const fieldsToExcludeFromPublicApi: Array<keyof SanitizedRule> = [
export const fieldsToExcludeFromPublicApi: Array<keyof SanitizedRule> = [
'monitoring',
'mapped_params',
'snoozeSchedule',
@ -174,11 +172,6 @@ export class RulesClient {
public snooze = (options: SnoozeRuleOptions) => snoozeRule(this.context, options);
public unsnooze = (options: UnsnoozeParams) => unsnoozeRule(this.context, options);
public clearExpiredSnoozes = (options: {
rule: Pick<SanitizedRule<RuleTypeParams>, 'id' | 'snoozeSchedule'>;
version?: string;
}) => clearExpiredSnoozes(this.context, options);
public muteAll = (options: { id: string }) => muteAll(this.context, options);
public unmuteAll = (options: { id: string }) => unmuteAll(this.context, options);
public muteInstance = (options: MuteAlertParams) => muteInstance(this.context, options);
@ -214,17 +207,4 @@ export class RulesClient {
public getTags = (params: RuleTagsParams) => getRuleTags(this.context, params);
public getScheduleFrequency = () => getScheduleFrequency(this.context);
public getAlertFromRaw = (params: GetAlertFromRawParams) =>
getAlertFromRaw(
this.context,
params.id,
params.ruleTypeId,
params.rawRule,
params.references,
params.includeLegacyId,
params.excludeFromPublicApi,
params.includeSnoozeData,
params.omitGeneratedValues
);
}

View file

@ -1,261 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import moment from 'moment';
import sinon from 'sinon';
import { RulesClient, ConstructorOptions } from '../rules_client';
import {
savedObjectsClientMock,
loggingSystemMock,
savedObjectsRepositoryMock,
uiSettingsServiceMock,
} from '@kbn/core/server/mocks';
import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks';
import { ruleTypeRegistryMock } from '../../rule_type_registry.mock';
import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock';
import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks';
import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks';
import { AlertingAuthorization } from '../../authorization/alerting_authorization';
import { ActionsAuthorization } from '@kbn/actions-plugin/server';
import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks';
import { getBeforeSetup, mockedDateString } from './lib';
import { eventLoggerMock } from '@kbn/event-log-plugin/server/event_logger.mock';
import { TaskStatus } from '@kbn/task-manager-plugin/server';
import { RuleSnooze } from '../../types';
import { ConnectorAdapterRegistry } from '../../connector_adapters/connector_adapter_registry';
import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects';
import { backfillClientMock } from '../../backfill_client/backfill_client.mock';
jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation', () => ({
bulkMarkApiKeysForInvalidation: jest.fn(),
}));
jest.mock('uuid', () => ({
v4: () => '5f6aa57d-3e22-484e-bae8-cbed868f4d28',
}));
let clock: sinon.SinonFakeTimers;
const taskManager = taskManagerMock.createStart();
const ruleTypeRegistry = ruleTypeRegistryMock.create();
const unsecuredSavedObjectsClient = savedObjectsClientMock.create();
const encryptedSavedObjects = encryptedSavedObjectsMock.createClient();
const authorization = alertingAuthorizationMock.create();
const actionsAuthorization = actionsAuthorizationMock.create();
const auditLogger = auditLoggerMock.create();
const eventLogger = eventLoggerMock.create();
const internalSavedObjectsRepository = savedObjectsRepositoryMock.create();
const kibanaVersion = 'v7.10.0';
const rulesClientParams: jest.Mocked<ConstructorOptions> = {
taskManager,
ruleTypeRegistry,
unsecuredSavedObjectsClient,
authorization: authorization as unknown as AlertingAuthorization,
actionsAuthorization: actionsAuthorization as unknown as ActionsAuthorization,
spaceId: 'default',
namespace: 'default',
maxScheduledPerMinute: 10000,
minimumScheduleInterval: { value: '1m', enforce: false },
getUserName: jest.fn(),
createAPIKey: jest.fn(),
logger: loggingSystemMock.create().get(),
internalSavedObjectsRepository,
encryptedSavedObjectsClient: encryptedSavedObjects,
getActionsClient: jest.fn(),
getEventLogClient: jest.fn(),
kibanaVersion,
auditLogger,
eventLogger,
isAuthenticationTypeAPIKey: jest.fn(),
getAuthenticationAPIKey: jest.fn(),
connectorAdapterRegistry: new ConnectorAdapterRegistry(),
getAlertIndicesAlias: jest.fn(),
alertsService: null,
backfillClient: backfillClientMock.create(),
uiSettings: uiSettingsServiceMock.createStartContract(),
isSystemAction: jest.fn(),
};
describe('clearExpiredSnoozes()', () => {
let rulesClient: RulesClient;
beforeAll(() => {
clock = sinon.useFakeTimers(new Date(mockedDateString));
});
afterAll(() => clock.restore());
beforeEach(() => {
clock.reset();
getBeforeSetup(rulesClientParams, taskManager, ruleTypeRegistry);
(auditLogger.log as jest.Mock).mockClear();
rulesClient = new RulesClient(rulesClientParams);
rulesClientParams.createAPIKey.mockResolvedValue({
apiKeysEnabled: false,
});
});
test('clears expired unscheduled snoozes and leaves unexpired scheduled snoozes', async () => {
const { attributes, id } = setupTestWithSnoozeSchedule([
{
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().subtract(1, 'd').toISOString(),
count: 1,
},
},
{
id: '1',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
]);
await rulesClient.clearExpiredSnoozes({ rule: { ...attributes, id } });
expect(unsecuredSavedObjectsClient.update).toHaveBeenCalledWith(
RULE_SAVED_OBJECT_TYPE,
'1',
{
updatedAt: '2019-02-12T21:01:22.479Z',
updatedBy: 'elastic',
snoozeSchedule: [
{
id: '1',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
],
},
{
refresh: false,
}
);
});
test('clears expired scheduled snoozes and leaves unexpired ones', async () => {
const { attributes, id } = setupTestWithSnoozeSchedule([
{
id: '1',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().subtract(1, 'd').toISOString(),
count: 1,
},
},
{
id: '2',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
]);
await rulesClient.clearExpiredSnoozes({ rule: { ...attributes, id } });
expect(unsecuredSavedObjectsClient.update).toHaveBeenCalledWith(
RULE_SAVED_OBJECT_TYPE,
'1',
{
updatedAt: '2019-02-12T21:01:22.479Z',
updatedBy: 'elastic',
snoozeSchedule: [
{
id: '2',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
],
},
{
refresh: false,
}
);
});
test('does nothing when no snoozes are expired', async () => {
const { attributes, id } = setupTestWithSnoozeSchedule([
{
duration: 1000 * 24 * 60 * 60 * 3, // 3 days
rRule: {
tzid: 'UTC',
dtstart: moment().subtract(1, 'd').toISOString(),
count: 1,
},
},
{
id: '2',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
]);
await rulesClient.clearExpiredSnoozes({ rule: { ...attributes, id } });
expect(unsecuredSavedObjectsClient.update).not.toHaveBeenCalled();
});
});
function setupTestWithSnoozeSchedule(snoozeSchedule: RuleSnooze) {
const rule = {
id: '1',
type: RULE_SAVED_OBJECT_TYPE,
attributes: {
name: 'name',
consumer: 'myApp',
schedule: { interval: '10s' },
alertTypeId: 'myType',
enabled: true,
apiKey: 'MTIzOmFiYw==',
apiKeyOwner: 'elastic',
actions: [
{
group: 'default',
id: '1',
actionTypeId: '1',
actionRef: '1',
params: {
foo: true,
},
},
],
snoozeSchedule,
},
version: '123',
references: [],
};
encryptedSavedObjects.getDecryptedAsInternalUser.mockResolvedValue(rule);
unsecuredSavedObjectsClient.get.mockResolvedValue(rule);
taskManager.schedule.mockResolvedValue({
id: '1',
scheduledAt: new Date(),
attempts: 0,
status: TaskStatus.Idle,
runAt: new Date(),
state: {},
params: {},
taskType: '',
startedAt: null,
retryAt: null,
ownerId: null,
});
return rule;
}

View file

@ -263,6 +263,17 @@ const DefaultAttributesForEsUpdate = {
},
},
},
snoozeSchedule: [
{
duration: 1000,
id: '1',
rRule: {
count: 1,
dtstart: '2019-02-13T21:01:22.479Z',
tzid: 'UTC',
},
},
],
};
const AttributesForEsUpdateWithUnallowedFields = {

View file

@ -79,6 +79,7 @@ const RuleAttributesAllowedForPartialUpdate = [
'monitoring',
'nextRun',
'running',
'snoozeSchedule',
];
// direct, partial update to a rule saved object via ElasticsearchClient

View file

@ -30,7 +30,6 @@ import { usageCountersServiceMock } from '@kbn/usage-collection-plugin/server/us
import { AdHocTaskRunner } from './ad_hoc_task_runner';
import { TaskRunnerContext } from './types';
import { backfillClientMock } from '../backfill_client/backfill_client.mock';
import { rulesClientMock } from '../rules_client.mock';
import { ruleTypeRegistryMock } from '../rule_type_registry.mock';
import {
AlertingEventLogger,
@ -143,7 +142,6 @@ const elasticsearchService = elasticsearchServiceMock.createInternalStart();
const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient();
const internalSavedObjectsRepository = savedObjectsRepositoryMock.create();
const maintenanceWindowsService = maintenanceWindowsServiceMock.create();
const rulesClient = rulesClientMock.create();
const ruleRunMetricsStore = ruleRunMetricsStoreMock.create();
const rulesSettingsService = rulesSettingsServiceMock.create();
const ruleTypeRegistry = ruleTypeRegistryMock.create();
@ -166,7 +164,6 @@ const taskRunnerFactoryInitializerParams: TaskRunnerFactoryInitializerParamsType
eventLogger: eventLoggerMock.create(),
executionContext: executionContextServiceMock.createInternalStartContract(),
maintenanceWindowsService,
getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient),
kibanaBaseUrl: 'https://localhost:5601',
logger,
maxAlerts: 1000,

View file

@ -0,0 +1,250 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import moment from 'moment';
import sinon from 'sinon';
import { Logger } from '@kbn/core/server';
import { elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks';
import { RuleSnooze } from '../../types';
import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects';
import { clearExpiredSnoozes } from './clear_expired_snoozes';
import { ALERTING_CASES_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server';
let clock: sinon.SinonFakeTimers;
const mockLogger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
describe('clearExpiredSnoozes()', () => {
beforeAll(() => {
clock = sinon.useFakeTimers(new Date('2019-02-12T21:01:22.479Z'));
});
afterAll(() => clock.restore());
beforeEach(() => {
jest.clearAllMocks();
clock.reset();
});
test('clears expired unscheduled snoozes and leaves unexpired scheduled snoozes', async () => {
const { attributes, id } = getRule([
{
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().subtract(1, 'd').toISOString(),
count: 1,
},
},
{
id: '1',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
]);
await clearExpiredSnoozes({
esClient,
logger: mockLogger,
rule: { ...attributes, id },
});
expect(esClient.update).toHaveBeenCalledWith({
doc: {
alert: {
snoozeSchedule: [
{
duration: 1000,
id: '1',
rRule: {
count: 1,
dtstart: '2019-02-13T21:01:22.479Z',
tzid: 'UTC',
},
},
],
},
},
id: 'alert:1',
index: ALERTING_CASES_SAVED_OBJECT_INDEX,
});
});
test('clears expired scheduled snoozes and leaves unexpired ones', async () => {
const { attributes, id } = getRule([
{
id: '1',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().subtract(1, 'd').toISOString(),
count: 1,
},
},
{
id: '2',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
]);
await clearExpiredSnoozes({
esClient,
logger: mockLogger,
rule: { ...attributes, id },
});
expect(esClient.update).toHaveBeenCalledWith({
doc: {
alert: {
snoozeSchedule: [
{
id: '2',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
],
},
},
id: 'alert:1',
index: ALERTING_CASES_SAVED_OBJECT_INDEX,
});
});
test('passes version if provided', async () => {
const { attributes, id } = getRule([
{
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().subtract(1, 'd').toISOString(),
count: 1,
},
},
{
id: '1',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
]);
await clearExpiredSnoozes({
esClient,
logger: mockLogger,
rule: { ...attributes, id },
version: 'WzQsMV0=',
});
expect(esClient.update).toHaveBeenCalledWith({
doc: {
alert: {
snoozeSchedule: [
{
id: '1',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
],
},
},
id: 'alert:1',
if_primary_term: 1,
if_seq_no: 4,
index: ALERTING_CASES_SAVED_OBJECT_INDEX,
});
});
test('does nothing when no snoozes are expired', async () => {
const { attributes, id } = getRule([
{
duration: 1000 * 24 * 60 * 60 * 3, // 3 days
rRule: {
tzid: 'UTC',
dtstart: moment().subtract(1, 'd').toISOString(),
count: 1,
},
},
{
id: '2',
duration: 1000,
rRule: {
tzid: 'UTC',
dtstart: moment().add(1, 'd').toISOString(),
count: 1,
},
},
]);
await clearExpiredSnoozes({
esClient,
logger: mockLogger,
rule: { ...attributes, id },
});
expect(esClient.update).not.toHaveBeenCalled();
});
test('does nothing when empty snooze schedule', async () => {
const { attributes, id } = getRule([]);
await clearExpiredSnoozes({
esClient,
logger: mockLogger,
rule: { ...attributes, id },
});
expect(esClient.update).not.toHaveBeenCalled();
});
test('does nothing when undefined snooze schedule', async () => {
const { attributes, id } = getRule(undefined);
await clearExpiredSnoozes({
esClient,
logger: mockLogger,
rule: { ...attributes, id },
});
expect(esClient.update).not.toHaveBeenCalled();
});
});
const getRule = (snoozeSchedule: RuleSnooze | undefined) => ({
id: '1',
type: RULE_SAVED_OBJECT_TYPE,
attributes: {
name: 'name',
consumer: 'myApp',
schedule: { interval: '10s' },
alertTypeId: 'myType',
enabled: true,
apiKey: 'MTIzOmFiYw==',
apiKeyOwner: 'elastic',
actions: [
{
group: 'default',
id: '1',
actionTypeId: '1',
actionRef: '1',
params: {
foo: true,
},
},
],
snoozeSchedule,
},
version: 'WzQsMV0=',
references: [],
});

View file

@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { RuleTypeParams, SanitizedRule } from '@kbn/alerting-types';
import { ElasticsearchClient, Logger } from '@kbn/core/server';
import { isSnoozeExpired } from '../../lib';
import { partiallyUpdateRuleWithEs } from '../../saved_objects';
interface ClearExpiredSnoozesOpts {
esClient: ElasticsearchClient;
logger: Logger;
rule: Pick<SanitizedRule<RuleTypeParams>, 'id' | 'snoozeSchedule'>;
version?: string;
}
export async function clearExpiredSnoozes(opts: ClearExpiredSnoozesOpts): Promise<void> {
const { esClient, logger, rule, version } = opts;
if (!rule.snoozeSchedule || !rule.snoozeSchedule.length) return;
const snoozeSchedule = rule.snoozeSchedule
? rule.snoozeSchedule.filter((s) => {
try {
return !isSnoozeExpired(s);
} catch (e) {
logger.error(`Error checking for expiration of snooze ${s.id}: ${e}`);
return true;
}
})
: [];
if (snoozeSchedule.length === rule.snoozeSchedule?.length) return;
const updateAttributes = { snoozeSchedule };
const updateOptions = { version, refresh: false };
await partiallyUpdateRuleWithEs(esClient, rule.id, updateAttributes, updateOptions);
}

View file

@ -9,3 +9,4 @@ export { partiallyUpdateAdHocRun } from './partially_update_ad_hoc_run';
export { processRunResults } from './process_run_result';
export { withAlertingSpan } from './with_alerting_span';
export { createTaskRunnerLogger } from './task_runner_logger';
export { clearExpiredSnoozes } from './clear_expired_snoozes';

View file

@ -8,6 +8,8 @@
import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks';
import { CoreKibanaRequest, SavedObjectsErrorHelpers } from '@kbn/core/server';
import { schema } from '@kbn/config-schema';
import { Logger } from '@kbn/core/server';
import { loggingSystemMock } from '@kbn/core/server/mocks';
import {
getDecryptedRule,
@ -16,19 +18,22 @@ import {
} from './rule_loader';
import { TaskRunnerContext } from './types';
import { ruleTypeRegistryMock } from '../rule_type_registry.mock';
import { rulesClientMock } from '../rules_client.mock';
import { Rule } from '../types';
import { MONITORING_HISTORY_LIMIT, RuleExecutionStatusErrorReasons } from '../../common';
import { getReasonFromError } from '../lib/error_with_reason';
import { mockedRawRuleSO, mockedRule } from './fixtures';
import { RULE_SAVED_OBJECT_TYPE } from '../saved_objects';
import { getErrorSource, TaskErrorSource } from '@kbn/task-manager-plugin/server/task_running';
import { getAlertFromRaw } from '../rules_client/lib/get_alert_from_raw';
// create mocks
const rulesClient = rulesClientMock.create();
const ruleTypeRegistry = ruleTypeRegistryMock.create();
const encryptedSavedObjects = encryptedSavedObjectsMock.createClient();
const mockBasePathService = { set: jest.fn() };
const mockLogger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
jest.mock('../rules_client/lib/get_alert_from_raw');
const mockGetAlertFromRaw = getAlertFromRaw as jest.MockedFunction<typeof getAlertFromRaw>;
// assign default parameters/data
const apiKey = mockedRawRuleSO.attributes.apiKey!;
@ -49,6 +54,7 @@ describe('rule_loader', () => {
});
const getDefaultValidateRuleParams = (ruleEnabled: boolean = true) => ({
logger: mockLogger,
paramValidator,
ruleId,
spaceId,
@ -70,7 +76,17 @@ describe('rule_loader', () => {
consumer,
})
);
contextMock = getTaskRunnerContext(ruleParams, MONITORING_HISTORY_LIMIT);
mockGetAlertFromRaw.mockReturnValue({
name: ruleName,
alertTypeId: ruleTypeId,
params: ruleParams,
monitoring: {
run: {
history: new Array(MONITORING_HISTORY_LIMIT),
},
},
} as Rule);
contextMock = getTaskRunnerContext();
context = contextMock as unknown as TaskRunnerContext;
});
@ -91,7 +107,6 @@ describe('rule_loader', () => {
expect(result.rule.alertTypeId).toBe(ruleTypeId);
expect(result.rule.name).toBe(ruleName);
expect(result.rule.params).toBe(ruleParams);
expect(result.rulesClient).toBe(rulesClient);
expect(result.validatedParams).toEqual(ruleParams);
expect(result.version).toBe('1');
});
@ -133,7 +148,17 @@ describe('rule_loader', () => {
});
test('test throws when rule params fail validation', async () => {
contextMock = getTaskRunnerContext({ bar: 'foo' }, MONITORING_HISTORY_LIMIT);
mockGetAlertFromRaw.mockReturnValueOnce({
name: ruleName,
alertTypeId: ruleTypeId,
params: { bar: 'foo' },
monitoring: {
run: {
history: new Array(MONITORING_HISTORY_LIMIT),
},
},
} as Rule);
contextMock = getTaskRunnerContext();
context = contextMock as unknown as TaskRunnerContext;
let outcome = 'success';
try {
@ -284,26 +309,10 @@ function mockGetDecrypted(attributes: { apiKey?: string; enabled: boolean; consu
}
// return enough of TaskRunnerContext that rule_loader needs
function getTaskRunnerContext(ruleParameters: unknown, historyElements: number) {
function getTaskRunnerContext() {
return {
spaceIdToNamespace: jest.fn(),
encryptedSavedObjectsClient: encryptedSavedObjects,
basePathService: mockBasePathService,
getRulesClientWithRequest,
};
function getRulesClientWithRequest() {
// only need get() mocked
rulesClient.getAlertFromRaw.mockReturnValue({
name: ruleName,
alertTypeId: ruleTypeId,
params: ruleParameters,
monitoring: {
run: {
history: new Array(historyElements),
},
},
} as Rule);
return rulesClient;
}
}

View file

@ -10,6 +10,7 @@ import {
CoreKibanaRequest,
FakeRawRequest,
Headers,
Logger,
SavedObject,
SavedObjectReference,
SavedObjectsErrorHelpers,
@ -25,6 +26,7 @@ import {
} from '../types';
import { MONITORING_HISTORY_LIMIT, RuleTypeParams } from '../../common';
import { RULE_SAVED_OBJECT_TYPE } from '../saved_objects';
import { getAlertFromRaw } from '../rules_client/lib';
interface RuleData {
rawRule: RawRule;
@ -34,6 +36,7 @@ interface RuleData {
interface ValidateRuleAndCreateFakeRequestParams<Params extends RuleTypeParams> {
context: TaskRunnerContext;
logger: Logger;
paramValidator?: RuleTypeParamsValidator<Params>;
ruleData: RuleData;
ruleId: string;
@ -52,6 +55,7 @@ export function validateRuleAndCreateFakeRequest<Params extends RuleTypeParams>(
): RunRuleParams<Params> {
const {
context,
logger,
paramValidator,
ruleData: { rawRule, references, version },
ruleId,
@ -72,14 +76,16 @@ export function validateRuleAndCreateFakeRequest<Params extends RuleTypeParams>(
}
const fakeRequest = getFakeKibanaRequest(context, spaceId, apiKey);
const rulesClient = context.getRulesClientWithRequest(fakeRequest);
const rule = rulesClient.getAlertFromRaw({
const rule = getAlertFromRaw({
id: ruleId,
ruleTypeId,
includeLegacyId: false,
isSystemAction: (actionId: string) => context.actionsPlugin.isSystemActionConnector(actionId),
logger,
omitGeneratedValues: false,
rawRule,
references,
includeLegacyId: false,
omitGeneratedValues: false,
ruleTypeId,
ruleTypeRegistry,
});
try {
@ -112,7 +118,6 @@ export function validateRuleAndCreateFakeRequest<Params extends RuleTypeParams>(
apiKey,
fakeRequest,
rule,
rulesClient,
validatedParams,
version,
};

View file

@ -40,7 +40,7 @@ import {
} from '@kbn/core/server/mocks';
import { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server';
import { actionsMock, actionsClientMock } from '@kbn/actions-plugin/server/mocks';
import { alertsMock, rulesClientMock } from '../mocks';
import { alertsMock } from '../mocks';
import { eventLoggerMock } from '@kbn/event-log-plugin/server/event_logger.mock';
import { IEventLogger } from '@kbn/event-log-plugin/server';
import { SavedObjectsErrorHelpers } from '@kbn/core/server';
@ -79,6 +79,7 @@ import {
AlertingEventLogger,
ContextOpts,
} from '../lib/alerting_event_logger/alerting_event_logger';
import { getAlertFromRaw } from '../rules_client/lib/get_alert_from_raw';
import { alertingEventLoggerMock } from '../lib/alerting_event_logger/alerting_event_logger.mock';
import { SharePluginStart } from '@kbn/share-plugin/server';
import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks';
@ -109,6 +110,9 @@ jest.mock('../lib/wrap_scoped_cluster_client', () => ({
jest.mock('../lib/alerting_event_logger/alerting_event_logger');
jest.mock('../monitoring/rule_result_service');
jest.mock('../rules_client/lib/get_alert_from_raw');
const mockGetAlertFromRaw = getAlertFromRaw as jest.MockedFunction<typeof getAlertFromRaw>;
jest.spyOn(getExecutorServicesModule, 'getExecutorServices');
let fakeTimer: sinon.SinonFakeTimers;
@ -145,7 +149,6 @@ describe('Task Runner', () => {
const backfillClient = backfillClientMock.create();
const services = alertsMock.createRuleExecutorServices();
const actionsClient = actionsClientMock.create();
const rulesClient = rulesClientMock.create();
const ruleTypeRegistry = ruleTypeRegistryMock.create();
const savedObjectsService = savedObjectsServiceMock.createInternalStartContract();
const elasticsearchService = elasticsearchServiceMock.createInternalStart();
@ -180,7 +183,6 @@ describe('Task Runner', () => {
encryptedSavedObjectsClient,
eventLogger: eventLoggerMock.create(),
executionContext: executionContextServiceMock.createInternalStartContract(),
getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient),
kibanaBaseUrl: 'https://localhost:5601',
logger,
maintenanceWindowsService,
@ -232,7 +234,6 @@ describe('Task Runner', () => {
});
savedObjectsService.getScopedClient.mockReturnValue(services.savedObjectsClient);
elasticsearchService.client.asScoped.mockReturnValue(services.scopedClusterClient);
taskRunnerFactoryInitializerParams.getRulesClientWithRequest.mockReturnValue(rulesClient);
taskRunnerFactoryInitializerParams.actionsPlugin.getActionsClientWithRequest.mockResolvedValue(
actionsClient
);
@ -286,7 +287,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
expect(runnerResult).toEqual(generateRunnerResult({ state: true, history: [true] }));
@ -395,7 +396,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
expect(enqueueFunction).toHaveBeenCalledTimes(1);
@ -486,7 +487,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
muteAll: true,
});
@ -621,7 +622,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
muteAll,
snoozeSchedule: snoozeSchedule != null ? JSON.parse(snoozeSchedule) : [],
@ -683,7 +684,7 @@ describe('Task Runner', () => {
internalSavedObjectsRepository,
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
@ -755,7 +756,7 @@ describe('Task Runner', () => {
internalSavedObjectsRepository,
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
@ -818,7 +819,7 @@ describe('Task Runner', () => {
internalSavedObjectsRepository,
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
@ -888,7 +889,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
mutedInstanceIds: ['2'],
});
@ -981,7 +982,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
notifyWhen: 'onThrottleInterval',
throttle: '1d',
@ -1030,7 +1031,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
mutedInstanceIds: ['2'],
notifyWhen: 'onActionGroupChange',
@ -1091,7 +1092,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
notifyWhen: 'onActionGroupChange',
});
@ -1162,7 +1163,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
notifyWhen: 'onActionGroupChange',
});
@ -1227,7 +1228,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
expect(
@ -1344,7 +1345,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
expect(runnerResult.state.alertInstances).toEqual(
@ -1483,7 +1484,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
expect(runnerResult.state.alertInstances).toEqual(
@ -1596,7 +1597,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
actions: [
{
@ -1685,7 +1686,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
actions: [
{
@ -1748,7 +1749,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
actions: [
{
@ -1839,7 +1840,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
expect(runnerResult.state.alertInstances).toEqual(
@ -1899,7 +1900,7 @@ describe('Task Runner', () => {
inMemoryMetrics,
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
@ -1942,7 +1943,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
@ -2060,7 +2061,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
@ -2127,7 +2128,7 @@ describe('Task Runner', () => {
});
test('reschedules for smaller interval if es connectivity error encountered and schedule interval is greater than connectivity retry', async () => {
rulesClient.getAlertFromRaw.mockImplementation(() => {
mockGetAlertFromRaw.mockImplementation(() => {
throw SavedObjectsErrorHelpers.createGenericNotFoundEsUnavailableError(
RULE_SAVED_OBJECT_TYPE,
'1'
@ -2229,7 +2230,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
notifyWhen: 'onActionGroupChange',
actions: [],
@ -2340,7 +2341,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
notifyWhen: 'onActionGroupChange',
actions: [],
@ -2418,7 +2419,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
notifyWhen: 'onActionGroupChange',
actions: [],
@ -2490,7 +2491,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
notifyWhen: 'onActionGroupChange',
actions: [],
@ -2568,7 +2569,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
notifyWhen: 'onActionGroupChange',
actions: [],
@ -2621,7 +2622,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
expect(runnerResult).toEqual(generateRunnerResult({ state: true, history: [true] }));
@ -2692,7 +2693,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
expect(runnerResult).toEqual(generateRunnerResult({ state: true, history: [true] }));
@ -2709,7 +2710,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(mockedRawRuleSO);
ruleType.executor.mockImplementation(
async ({
@ -2742,7 +2743,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
await taskRunner.run();
@ -2782,7 +2783,7 @@ describe('Task Runner', () => {
inMemoryMetrics,
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue({
...mockedRawRuleSO,
attributes: { ...mockedRawRuleSO.attributes, schedule: { interval: '50s' } },
@ -2804,7 +2805,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
ruleType.executor.mockImplementation(
@ -2845,7 +2846,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
for (let i = 0; i < 300; i++) {
@ -2914,7 +2915,7 @@ describe('Task Runner', () => {
},
];
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
actions: mockActions as RuleAction[],
});
@ -3054,7 +3055,7 @@ describe('Task Runner', () => {
}
);
rulesClient.getAlertFromRaw.mockReturnValue({
mockGetAlertFromRaw.mockReturnValue({
...(mockedRuleTypeSavedObject as Rule),
actions: [
{
@ -3189,7 +3190,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
@ -3272,7 +3273,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalled();
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
expect(runnerResult.state.alertInstances).toEqual({});
@ -3299,7 +3300,7 @@ describe('Task Runner', () => {
});
test('reports error to eventLogger when ruleResultService.addLastRunError adds an error', async () => {
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const taskRunner = new TaskRunner({
@ -3343,7 +3344,7 @@ describe('Task Runner', () => {
});
test('returns user error if all the errors reported by getLastRunResults are user error', async () => {
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const taskRunner = new TaskRunner({
@ -3393,7 +3394,7 @@ describe('Task Runner', () => {
context: taskRunnerFactoryInitializerParams,
inMemoryMetrics,
});
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(mockedRawRuleSO);
const runnerResult = await taskRunner.run();

View file

@ -66,7 +66,12 @@ import { RuleRunningHandler } from './rule_running_handler';
import { RuleResultService } from '../monitoring/rule_result_service';
import { RuleTypeRunner } from './rule_type_runner';
import { initializeAlertsClient } from '../alerts_client';
import { createTaskRunnerLogger, withAlertingSpan, processRunResults } from './lib';
import {
createTaskRunnerLogger,
withAlertingSpan,
processRunResults,
clearExpiredSnoozes,
} from './lib';
const FALLBACK_RETRY_INTERVAL = '5m';
const CONNECTIVITY_RETRY_INTERVAL = '5m';
@ -503,6 +508,7 @@ export class TaskRunner<
paramValidator: this.ruleType.validate.params,
ruleId,
spaceId,
logger: this.logger,
context: this.context,
ruleTypeRegistry: this.ruleTypeRegistry,
});
@ -522,7 +528,9 @@ export class TaskRunner<
(async () => {
try {
await runRuleParams.rulesClient.clearExpiredSnoozes({
await clearExpiredSnoozes({
esClient: this.context.elasticsearch.client.asInternalUser,
logger: this.logger,
rule: runRuleParams.rule,
version: runRuleParams.version,
});

View file

@ -34,7 +34,7 @@ import {
} from '@kbn/core/server/mocks';
import { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server';
import { actionsMock, actionsClientMock } from '@kbn/actions-plugin/server/mocks';
import { alertsMock, rulesClientMock } from '../mocks';
import { alertsMock } from '../mocks';
import { eventLoggerMock } from '@kbn/event-log-plugin/server/event_logger.mock';
import { IEventLogger } from '@kbn/event-log-plugin/server';
import { ruleTypeRegistryMock } from '../rule_type_registry.mock';
@ -52,6 +52,7 @@ import {
DATE_1970_5_MIN,
mockedRawRuleSO,
} from './fixtures';
import { getAlertFromRaw } from '../rules_client/lib/get_alert_from_raw';
import { dataPluginMock } from '@kbn/data-plugin/server/mocks';
import { AlertingEventLogger } from '../lib/alerting_event_logger/alerting_event_logger';
import { alertingEventLoggerMock } from '../lib/alerting_event_logger/alerting_event_logger.mock';
@ -118,6 +119,9 @@ jest.mock('../lib/wrap_scoped_cluster_client', () => ({
jest.mock('../lib/alerting_event_logger/alerting_event_logger');
jest.mock('../rules_client/lib/get_alert_from_raw');
const mockGetAlertFromRaw = getAlertFromRaw as jest.MockedFunction<typeof getAlertFromRaw>;
let fakeTimer: sinon.SinonFakeTimers;
const logger: ReturnType<typeof loggingSystemMock.createLogger> = loggingSystemMock.createLogger();
const taskRunnerLogger = createTaskRunnerLogger({ logger, tags: ['1', 'test'] });
@ -167,7 +171,6 @@ describe('Task Runner', () => {
const services = alertsMock.createRuleExecutorServices();
const actionsClient = actionsClientMock.create();
const rulesSettingsService = rulesSettingsServiceMock.create();
const rulesClient = rulesClientMock.create();
const ruleTypeRegistry = ruleTypeRegistryMock.create();
const savedObjectsService = savedObjectsServiceMock.createInternalStartContract();
const elasticsearchService = elasticsearchServiceMock.createInternalStart();
@ -207,7 +210,6 @@ describe('Task Runner', () => {
encryptedSavedObjectsClient,
eventLogger: eventLoggerMock.create(),
executionContext: executionContextServiceMock.createInternalStartContract(),
getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient),
kibanaBaseUrl: 'https://localhost:5601',
logger,
maintenanceWindowsService,
@ -238,7 +240,6 @@ describe('Task Runner', () => {
});
savedObjectsService.getScopedClient.mockReturnValue(services.savedObjectsClient);
elasticsearchService.client.asScoped.mockReturnValue(services.scopedClusterClient);
taskRunnerFactoryInitializerParams.getRulesClientWithRequest.mockReturnValue(rulesClient);
taskRunnerFactoryInitializerParams.actionsPlugin.getActionsClientWithRequest.mockResolvedValue(
actionsClient
);
@ -321,7 +322,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
@ -433,7 +434,7 @@ describe('Task Runner', () => {
inMemoryMetrics,
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
const runnerResult = await taskRunner.run();
expect(runnerResult).toEqual(generateRunnerResult({ state: true, history: [true] }));
@ -579,7 +580,7 @@ describe('Task Runner', () => {
inMemoryMetrics,
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
@ -677,7 +678,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();
@ -771,7 +772,7 @@ describe('Task Runner', () => {
});
expect(AlertingEventLogger).toHaveBeenCalledTimes(1);
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue(mockedRawRuleSO);
await taskRunner.run();

View file

@ -32,12 +32,13 @@ import {
} from '@kbn/core/server/mocks';
import { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server';
import { actionsMock, actionsClientMock } from '@kbn/actions-plugin/server/mocks';
import { alertsMock, rulesClientMock } from '../mocks';
import { alertsMock } from '../mocks';
import { eventLoggerMock } from '@kbn/event-log-plugin/server/event_logger.mock';
import { IEventLogger } from '@kbn/event-log-plugin/server';
import { ruleTypeRegistryMock } from '../rule_type_registry.mock';
import { dataPluginMock } from '@kbn/data-plugin/server/mocks';
import { inMemoryMetricsMock } from '../monitoring/in_memory_metrics.mock';
import { getAlertFromRaw } from '../rules_client/lib/get_alert_from_raw';
import {
AlertingEventLogger,
ContextOpts,
@ -75,6 +76,9 @@ jest.mock('../lib/wrap_scoped_cluster_client', () => ({
jest.mock('../lib/alerting_event_logger/alerting_event_logger');
jest.mock('../rules_client/lib/get_alert_from_raw');
const mockGetAlertFromRaw = getAlertFromRaw as jest.MockedFunction<typeof getAlertFromRaw>;
let fakeTimer: sinon.SinonFakeTimers;
const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract();
@ -112,7 +116,6 @@ describe('Task Runner Cancel', () => {
const internalSavedObjectsRepository = savedObjectsRepositoryMock.create();
const backfillClient = backfillClientMock.create();
const actionsClient = actionsClientMock.create();
const rulesClient = rulesClientMock.create();
const ruleTypeRegistry = ruleTypeRegistryMock.create();
const savedObjectsService = savedObjectsServiceMock.createInternalStartContract();
const elasticsearchService = elasticsearchServiceMock.createInternalStart();
@ -142,7 +145,6 @@ describe('Task Runner Cancel', () => {
encryptedSavedObjectsClient,
eventLogger: eventLoggerMock.create(),
executionContext: executionContextServiceMock.createInternalStartContract(),
getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient),
kibanaBaseUrl: 'https://localhost:5601',
logger,
maintenanceWindowsService,
@ -172,7 +174,6 @@ describe('Task Runner Cancel', () => {
});
savedObjectsService.getScopedClient.mockReturnValue(services.savedObjectsClient);
elasticsearchService.client.asScoped.mockReturnValue(services.scopedClusterClient);
taskRunnerFactoryInitializerParams.getRulesClientWithRequest.mockReturnValue(rulesClient);
taskRunnerFactoryInitializerParams.actionsPlugin.getActionsClientWithRequest.mockResolvedValue(
actionsClient
);
@ -187,7 +188,7 @@ describe('Task Runner Cancel', () => {
flappingSettings: DEFAULT_FLAPPING_SETTINGS,
queryDelaySettings: DEFAULT_QUERY_DELAY_SETTINGS,
});
rulesClient.getAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
mockGetAlertFromRaw.mockReturnValue(mockedRuleTypeSavedObject as Rule);
maintenanceWindowsService.getMaintenanceWindows.mockReturnValue({
maintenanceWindows: [],
maintenanceWindowsWithoutScopedQueryIds: [],

View file

@ -18,7 +18,6 @@ import {
uiSettingsServiceMock,
} from '@kbn/core/server/mocks';
import { actionsMock } from '@kbn/actions-plugin/server/mocks';
import { rulesClientMock } from '../mocks';
import { eventLoggerMock } from '@kbn/event-log-plugin/server/event_logger.mock';
import { UntypedNormalizedRuleType } from '../rule_type_registry';
import { ruleTypeRegistryMock } from '../rule_type_registry.mock';
@ -101,7 +100,6 @@ describe('Task Runner Factory', () => {
afterAll(() => fakeTimer.restore());
const encryptedSavedObjectsPlugin = encryptedSavedObjectsMock.createStart();
const rulesClient = rulesClientMock.create();
const connectorAdapterRegistry = new ConnectorAdapterRegistry();
const taskRunnerFactoryInitializerParams: jest.Mocked<TaskRunnerContext> = {
@ -118,7 +116,6 @@ describe('Task Runner Factory', () => {
encryptedSavedObjectsClient: encryptedSavedObjectsPlugin.getClient(),
eventLogger: eventLoggerMock.create(),
executionContext,
getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient),
kibanaBaseUrl: 'https://localhost:5601',
logger: loggingSystemMock.create().get(),
maintenanceWindowsService,

View file

@ -46,7 +46,6 @@ import { NormalizedRuleType } from '../rule_type_registry';
import {
CombinedSummarizedAlerts,
RawRule,
RulesClientApi,
RuleTypeRegistry,
SpaceIdToNamespaceFunction,
} from '../types';
@ -74,7 +73,6 @@ export interface RunRuleParams<Params extends RuleTypeParams> {
apiKey: RawRule['apiKey'];
fakeRequest: KibanaRequest;
rule: SanitizedRule<Params>;
rulesClient: RulesClientApi;
validatedParams: Params;
version: string | undefined;
}
@ -169,7 +167,6 @@ export interface TaskRunnerContext {
encryptedSavedObjectsClient: EncryptedSavedObjectsClient;
eventLogger: IEventLogger;
executionContext: ExecutionContextStart;
getRulesClientWithRequest(request: KibanaRequest): RulesClientApi;
kibanaBaseUrl: string | undefined;
logger: Logger;
maintenanceWindowsService: MaintenanceWindowsService;