diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/index.ts new file mode 100644 index 0000000000000..26d14465471cf --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/index.ts @@ -0,0 +1,12 @@ +/* + * 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. + */ + +export { muteAlertParamsSchema } from './schemas/latest'; +export { muteAlertParamsSchema as muteAlertParamsSchemaV1 } from './schemas/v1'; + +export type { MuteAlertRequestParams } from './types/latest'; +export type { MuteAlertRequestParams as MuteAlertRequestParamsV1 } from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/schemas/latest.ts new file mode 100644 index 0000000000000..eee4b4b4e34b3 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/schemas/latest.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ +export { muteAlertParamsSchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/schemas/v1.ts new file mode 100644 index 0000000000000..3cfe34de957e2 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/schemas/v1.ts @@ -0,0 +1,13 @@ +/* + * 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 { schema } from '@kbn/config-schema'; + +export const muteAlertParamsSchema = schema.object({ + rule_id: schema.string(), + alert_id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/types/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/types/latest.ts new file mode 100644 index 0000000000000..0313b54c87630 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/types/latest.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export type { MuteAlertRequestParams } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/types/v1.ts new file mode 100644 index 0000000000000..af3832641d530 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/mute_alert/types/v1.ts @@ -0,0 +1,10 @@ +/* + * 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 type { TypeOf } from '@kbn/config-schema'; +import { muteAlertParamsSchemaV1 } from '..'; + +export type MuteAlertRequestParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/rules_client/methods/mute_instance.ts b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/mute_instance.ts similarity index 61% rename from x-pack/plugins/alerting/server/rules_client/methods/mute_instance.ts rename to x-pack/plugins/alerting/server/application/rule/methods/mute_alert/mute_instance.ts index 5f37988b7b718..8adbdf7ae58c9 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/mute_instance.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/mute_instance.ts @@ -5,28 +5,37 @@ * 2.0. */ -import { Rule } from '../../types'; -import { WriteOperations, AlertingAuthorizationEntity } from '../../authorization'; -import { retryIfConflicts } from '../../lib/retry_if_conflicts'; -import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; -import { MuteOptions } from '../types'; -import { RulesClientContext } from '../types'; -import { updateMeta } from '../lib'; +import Boom from '@hapi/boom'; +import { updateRuleSo } from '../../../../data/rule/methods/update_rule_so'; +import { muteAlertParamsSchema } from './schemas'; +import type { MuteAlertParams } from './types'; +import { Rule } from '../../../../types'; +import { WriteOperations, AlertingAuthorizationEntity } from '../../../../authorization'; +import { retryIfConflicts } from '../../../../lib/retry_if_conflicts'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; +import { RulesClientContext } from '../../../../rules_client/types'; +import { updateMeta } from '../../../../rules_client/lib'; export async function muteInstance( context: RulesClientContext, - { alertId, alertInstanceId }: MuteOptions + params: MuteAlertParams ): Promise { + try { + muteAlertParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Failed to validate params: ${error.message}`); + } + return await retryIfConflicts( context.logger, - `rulesClient.muteInstance('${alertId}')`, - async () => await muteInstanceWithOCC(context, { alertId, alertInstanceId }) + `rulesClient.muteInstance('${params.alertId}')`, + async () => await muteInstanceWithOCC(context, params) ); } async function muteInstanceWithOCC( context: RulesClientContext, - { alertId, alertInstanceId }: MuteOptions + { alertId, alertInstanceId }: MuteAlertParams ) { const { attributes, version } = await context.unsecuredSavedObjectsClient.get( 'alert', @@ -68,15 +77,15 @@ async function muteInstanceWithOCC( const mutedInstanceIds = attributes.mutedInstanceIds || []; if (!attributes.muteAll && !mutedInstanceIds.includes(alertInstanceId)) { mutedInstanceIds.push(alertInstanceId); - await context.unsecuredSavedObjectsClient.update( - 'alert', - alertId, - updateMeta(context, { + await updateRuleSo({ + savedObjectsClient: context.unsecuredSavedObjectsClient, + savedObjectsUpdateOptions: { version }, + id: alertId, + updateRuleAttributes: updateMeta(context, { mutedInstanceIds, updatedBy: await context.getUserName(), updatedAt: new Date().toISOString(), }), - { version } - ); + }); } } diff --git a/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/schemas/index.ts new file mode 100644 index 0000000000000..e7148adf7eefe --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/schemas/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ +export { muteAlertParamsSchema } from './mute_alert_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/schemas/mute_alert_params_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/schemas/mute_alert_params_schema.ts new file mode 100644 index 0000000000000..6c8df8cb907da --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/schemas/mute_alert_params_schema.ts @@ -0,0 +1,12 @@ +/* + * 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 { schema } from '@kbn/config-schema'; + +export const muteAlertParamsSchema = schema.object({ + alertId: schema.string(), + alertInstanceId: schema.string(), +}); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/types/index.ts new file mode 100644 index 0000000000000..8b72247e15649 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/types/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export type { MuteAlertParams } from './mute_alert_params'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/types/mute_alert_params.ts b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/types/mute_alert_params.ts new file mode 100644 index 0000000000000..f94f454f1f78c --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/mute_alert/types/mute_alert_params.ts @@ -0,0 +1,11 @@ +/* + * 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 { TypeOf } from '@kbn/config-schema'; +import { muteAlertParamsSchema } from '../schemas'; + +export type MuteAlertParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index a93803ed6d585..5086cb56279ed 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -32,7 +32,7 @@ import { healthRoute } from './health'; import { resolveRuleRoute } from './resolve_rule'; import { ruleTypesRoute } from './rule_types'; import { muteAllRuleRoute } from './mute_all_rule'; -import { muteAlertRoute } from './mute_alert'; +import { muteAlertRoute } from './rule/apis/mute_alert/mute_alert'; import { unmuteAllRuleRoute } from './unmute_all_rule'; import { unmuteAlertRoute } from './unmute_alert'; import { updateRuleApiKeyRoute } from './update_rule_api_key'; diff --git a/x-pack/plugins/alerting/server/routes/mute_alert.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.test.ts similarity index 87% rename from x-pack/plugins/alerting/server/routes/mute_alert.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.test.ts index ef67a6d2ef3bf..440c040d74ff7 100644 --- a/x-pack/plugins/alerting/server/routes/mute_alert.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.test.ts @@ -7,13 +7,13 @@ import { muteAlertRoute } from './mute_alert'; import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../lib/license_state.mock'; -import { mockHandlerArguments } from './_mock_handler_arguments'; -import { rulesClientMock } from '../rules_client.mock'; -import { RuleTypeDisabledError } from '../lib/errors/rule_type_disabled'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { rulesClientMock } from '../../../../rules_client.mock'; +import { RuleTypeDisabledError } from '../../../../lib'; const rulesClient = rulesClientMock.create(); -jest.mock('../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); diff --git a/x-pack/plugins/alerting/server/routes/mute_alert.ts b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts similarity index 62% rename from x-pack/plugins/alerting/server/routes/mute_alert.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts index 22d9a1670dde5..45a0a37f3164c 100644 --- a/x-pack/plugins/alerting/server/routes/mute_alert.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/mute_alert.ts @@ -4,26 +4,15 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState, RuleTypeDisabledError } from '../lib'; -import { MuteOptions } from '../rules_client'; -import { RewriteRequestCase, verifyAccessAndContext } from './lib'; -import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../types'; - -const paramSchema = schema.object({ - rule_id: schema.string(), - alert_id: schema.string(), -}); - -const rewriteParamsReq: RewriteRequestCase = ({ - rule_id: alertId, - alert_id: alertInstanceId, -}) => ({ - alertId, - alertInstanceId, -}); +import { transformRequestParamsToApplicationV1 } from './transforms'; +import { ILicenseState, RuleTypeDisabledError } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; +import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types'; +import { + muteAlertParamsSchemaV1, + MuteAlertRequestParamsV1, +} from '../../../../../common/routes/rule/apis/mute_alert'; export const muteAlertRoute = ( router: IRouter, @@ -33,15 +22,15 @@ export const muteAlertRoute = ( { path: `${BASE_ALERTING_API_PATH}/rule/{rule_id}/alert/{alert_id}/_mute`, validate: { - params: paramSchema, + params: muteAlertParamsSchemaV1, }, }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { const rulesClient = (await context.alerting).getRulesClient(); - const params = rewriteParamsReq(req.params); + const params: MuteAlertRequestParamsV1 = req.params; try { - await rulesClient.muteInstance(params); + await rulesClient.muteInstance(transformRequestParamsToApplicationV1(params)); return res.noContent(); } catch (e) { if (e instanceof RuleTypeDisabledError) { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/index.ts new file mode 100644 index 0000000000000..21a7250aed4e2 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ +export { transformRequestParamsToApplication } from './transform_request_params_to_application/latest'; +export { transformRequestParamsToApplication as transformRequestParamsToApplicationV1 } from './transform_request_params_to_application/v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/transform_request_params_to_application/latest.ts b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/transform_request_params_to_application/latest.ts new file mode 100644 index 0000000000000..5983069f0d8fd --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/transform_request_params_to_application/latest.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export { transformRequestParamsToApplication } from './v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/transform_request_params_to_application/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/transform_request_params_to_application/v1.ts new file mode 100644 index 0000000000000..37966060dba02 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/mute_alert/transforms/transform_request_params_to_application/v1.ts @@ -0,0 +1,17 @@ +/* + * 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 { MuteAlertParams } from '../../../../../../application/rule/methods/mute_alert/types'; +import { RewriteRequestCase } from '../../../../../lib'; + +export const transformRequestParamsToApplication: RewriteRequestCase = ({ + rule_id: alertId, + alert_id: alertInstanceId, +}) => ({ + alertId, + alertInstanceId, +}); diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 4c1138f23cb39..d7a576ac99d0b 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -5,9 +5,10 @@ * 2.0. */ +import { MuteAlertParams } from '../application/rule/methods/mute_alert/types'; import { SanitizedRule, RuleTypeParams } from '../types'; import { parseDuration } from '../../common/parse_duration'; -import { RulesClientContext, BulkOptions, MuteOptions } from './types'; +import { RulesClientContext, BulkOptions } from './types'; import { clone, CloneArguments } from './methods/clone'; import { createRule, CreateRuleParams } from '../application/rule/methods/create'; import { get, GetParams } from './methods/get'; @@ -52,9 +53,9 @@ import { disable } from './methods/disable'; import { snooze, SnoozeParams } from './methods/snooze'; import { unsnooze, UnsnoozeParams } from './methods/unsnooze'; 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 { muteInstance } from './methods/mute_instance'; import { unmuteInstance } from './methods/unmute_instance'; import { runSoon } from './methods/run_soon'; import { listRuleTypes } from './methods/list_rule_types'; @@ -163,8 +164,8 @@ export class RulesClient { public muteAll = (options: { id: string }) => muteAll(this.context, options); public unmuteAll = (options: { id: string }) => unmuteAll(this.context, options); - public muteInstance = (options: MuteOptions) => muteInstance(this.context, options); - public unmuteInstance = (options: MuteOptions) => unmuteInstance(this.context, options); + public muteInstance = (options: MuteAlertParams) => muteInstance(this.context, options); + public unmuteInstance = (options: MuteAlertParams) => unmuteInstance(this.context, options); public runSoon = (options: { id: string }) => runSoon(this.context, options); diff --git a/x-pack/plugins/alerting/server/rules_client/types.ts b/x-pack/plugins/alerting/server/rules_client/types.ts index c755651f5524d..87ae594976246 100644 --- a/x-pack/plugins/alerting/server/rules_client/types.ts +++ b/x-pack/plugins/alerting/server/rules_client/types.ts @@ -121,6 +121,7 @@ export interface IndexType { [key: string]: unknown; } +// TODO: remove once all mute endpoints have been migrated to RuleMuteAlertOptions export interface MuteOptions extends IndexType { alertId: string; alertInstanceId: string;