diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/index.ts new file mode 100644 index 00000000000000..022a5eee7b9427 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/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 { unmuteAllRuleRequestParamsSchema } from './schemas/latest'; +export type { UnmuteAllRuleRequestParams } from './types/latest'; + +export { unmuteAllRuleRequestParamsSchema as unmuteAllRuleRequestParamsSchemaV1 } from './schemas/v1'; +export type { UnmuteAllRuleRequestParams as UnmuteAllRuleRequestParamsV1 } from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/schemas/latest.ts new file mode 100644 index 00000000000000..25300c97a6d2e1 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/schemas/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 * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/schemas/v1.ts new file mode 100644 index 00000000000000..890ba1925fbefe --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/schemas/v1.ts @@ -0,0 +1,16 @@ +/* + * 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 unmuteAllRuleRequestParamsSchema = schema.object({ + id: schema.string({ + meta: { + description: 'The identifier for the rule.', + }, + }), +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/types/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/types/latest.ts new file mode 100644 index 00000000000000..25300c97a6d2e1 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/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 * from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/types/v1.ts new file mode 100644 index 00000000000000..25638574f3972a --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/unmute_all/types/v1.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 type { TypeOf } from '@kbn/config-schema'; +import { unmuteAllRuleRequestParamsSchemaV1 } from '..'; + +export type UnmuteAllRuleRequestParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/index.ts new file mode 100644 index 00000000000000..3dcd4557188af2 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/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 { unmuteAll } from './unmute_all'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/schemas/index.ts new file mode 100644 index 00000000000000..27354c6d51bef8 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/schemas/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 * from './unmute_all_rule_schemas'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/schemas/unmute_all_rule_schemas.ts b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/schemas/unmute_all_rule_schemas.ts new file mode 100644 index 00000000000000..28be642e9ca49d --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/schemas/unmute_all_rule_schemas.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 unmuteAllRuleParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/types/index.ts new file mode 100644 index 00000000000000..36ee54afdda07a --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/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 * from './unmute_all_rule_types'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/types/unmute_all_rule_types.ts b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/types/unmute_all_rule_types.ts new file mode 100644 index 00000000000000..3e82d8901dc019 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/types/unmute_all_rule_types.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 type { TypeOf } from '@kbn/config-schema'; +import { unmuteAllRuleParamsSchema } from '../schemas'; + +export type UnmuteAllRuleParams = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/unmute_all.test.ts b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/unmute_all.test.ts new file mode 100644 index 00000000000000..531b157a668991 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/unmute_all.test.ts @@ -0,0 +1,76 @@ +/* + * 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 { RulesClientContext } from '../../../../rules_client'; +import { unmuteAll } from './unmute_all'; +import { savedObjectsRepositoryMock } from '@kbn/core-saved-objects-api-server-mocks'; + +jest.mock('../../../../lib/retry_if_conflicts', () => ({ + retryIfConflicts: (_: unknown, id: unknown, asyncFn: () => Promise) => { + return asyncFn(); + }, +})); + +jest.mock('../../../../rules_client/lib', () => ({ + updateMetaAttributes: () => {}, +})); + +jest.mock('../../../../saved_objects', () => ({ + partiallyUpdateRule: async () => {}, +})); + +const loggerErrorMock = jest.fn(); +const getBulkMock = jest.fn(); + +const savedObjectsMock = savedObjectsRepositoryMock.create(); +savedObjectsMock.get = jest.fn().mockReturnValue({ + attributes: { + actions: [], + }, + version: '9.0.0', +}); + +const context = { + logger: { error: loggerErrorMock }, + getActionsClient: () => { + return { + getBulk: getBulkMock, + }; + }, + unsecuredSavedObjectsClient: savedObjectsMock, + authorization: { ensureAuthorized: async () => {} }, + ruleTypeRegistry: { + ensureRuleTypeEnabled: () => {}, + }, + getUserName: async () => {}, +} as unknown as RulesClientContext; + +describe('validate unmuteAll parameters', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should not throw an error for valid params', () => { + const validParams = { + id: 'ble', + }; + + expect(() => unmuteAll(context, validParams)).not.toThrow(); + expect(savedObjectsMock.get).toHaveBeenCalled(); + }); + + it('should throw Boom.badRequest for invalid params', async () => { + const invalidParams = { + id: 22, + }; + + // @ts-expect-error wrong type for testing purposes + await expect(unmuteAll(context, invalidParams)).rejects.toThrowErrorMatchingInlineSnapshot( + `"Error validating unmute all parameters - [id]: expected value of type [string] but got [number]"` + ); + }); +}); diff --git a/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/unmute_all.ts similarity index 67% rename from x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts rename to x-pack/plugins/alerting/server/application/rule/methods/unmute_all/unmute_all.ts index e007633e4012d4..722cfed3700d0c 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/unmute_all/unmute_all.ts @@ -5,19 +5,22 @@ * 2.0. */ -import { RawRule } from '../../types'; -import { WriteOperations, AlertingAuthorizationEntity } from '../../authorization'; -import { retryIfConflicts } from '../../lib/retry_if_conflicts'; -import { partiallyUpdateRule, RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; -import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; -import { RulesClientContext } from '../types'; -import { updateMetaAttributes } from '../lib'; -import { clearUnscheduledSnoozeAttributes } from '../common'; -import { RuleAttributes } from '../../data/rule/types'; +import Boom from '@hapi/boom'; +import { RawRule } from '../../../../types'; +import { WriteOperations, AlertingAuthorizationEntity } from '../../../../authorization'; +import { retryIfConflicts } from '../../../../lib/retry_if_conflicts'; +import { partiallyUpdateRule, RULE_SAVED_OBJECT_TYPE } from '../../../../saved_objects'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; +import { RulesClientContext } from '../../../../rules_client/types'; +import { updateMetaAttributes } from '../../../../rules_client/lib'; +import { clearUnscheduledSnoozeAttributes } from '../../../../rules_client/common'; +import { RuleAttributes } from '../../../../data/rule/types'; +import { UnmuteAllRuleParams } from './types'; +import { unmuteAllRuleParamsSchema } from './schemas'; export async function unmuteAll( context: RulesClientContext, - { id }: { id: string } + { id }: UnmuteAllRuleParams ): Promise { return await retryIfConflicts( context.logger, @@ -26,7 +29,14 @@ export async function unmuteAll( ); } -async function unmuteAllWithOCC(context: RulesClientContext, { id }: { id: string }) { +async function unmuteAllWithOCC(context: RulesClientContext, params: UnmuteAllRuleParams) { + try { + unmuteAllRuleParamsSchema.validate(params); + } catch (error) { + throw Boom.badRequest(`Error validating unmute all parameters - ${error.message}`); + } + + const { id } = params; const { attributes, version } = await context.unsecuredSavedObjectsClient.get( RULE_SAVED_OBJECT_TYPE, id diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index 352eb293fff773..c9ecb0b0ac17cc 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -33,7 +33,7 @@ import { resolveRuleRoute } from './rule/apis/resolve'; import { ruleTypesRoute } from './rule_types'; import { muteAllRuleRoute } from './rule/apis/mute_all/mute_all_rule'; import { muteAlertRoute } from './rule/apis/mute_alert/mute_alert'; -import { unmuteAllRuleRoute } from './unmute_all_rule'; +import { unmuteAllRuleRoute } from './rule/apis/unmute_all'; import { unmuteAlertRoute } from './rule/apis/unmute_alert/unmute_alert_route'; import { updateRuleApiKeyRoute } from './rule/apis/update_api_key/update_rule_api_key_route'; import { bulkEditInternalRulesRoute } from './rule/apis/bulk_edit/bulk_edit_rules_route'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/index.ts new file mode 100644 index 00000000000000..cd6f357ef91309 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/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 { unmuteAllRuleRoute } from './unmute_all_rule'; diff --git a/x-pack/plugins/alerting/server/routes/unmute_all_rule.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.test.ts similarity index 85% rename from x-pack/plugins/alerting/server/routes/unmute_all_rule.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.test.ts index 8671247987bd4c..e597e1b0fdef87 100644 --- a/x-pack/plugins/alerting/server/routes/unmute_all_rule.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.test.ts @@ -7,13 +7,13 @@ import { unmuteAllRuleRoute } from './unmute_all_rule'; 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/errors/rule_type_disabled'; 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/unmute_all_rule.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.ts similarity index 73% rename from x-pack/plugins/alerting/server/routes/unmute_all_rule.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.ts index a6a706a34eafd0..f9ab7d8d8d2846 100644 --- a/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unmute_all/unmute_all_rule.ts @@ -6,18 +6,13 @@ */ import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState, RuleTypeDisabledError } from '../lib'; -import { verifyAccessAndContext } from './lib'; -import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../types'; - -const paramSchema = schema.object({ - id: schema.string({ - meta: { - description: 'The identifier for the rule.', - }, - }), -}); +import { ILicenseState, RuleTypeDisabledError } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; +import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types'; +import { + unmuteAllRuleRequestParamsSchemaV1, + UnmuteAllRuleRequestParamsV1, +} from '../../../../../common/routes/rule/apis/unmute_all'; export const unmuteAllRuleRoute = ( router: IRouter, @@ -33,7 +28,7 @@ export const unmuteAllRuleRoute = ( }, validate: { request: { - params: paramSchema, + params: unmuteAllRuleRequestParamsSchemaV1, }, response: { 204: { @@ -45,9 +40,9 @@ export const unmuteAllRuleRoute = ( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { const rulesClient = (await context.alerting).getRulesClient(); - const { id } = req.params; + const params: UnmuteAllRuleRequestParamsV1 = req.params; try { - await rulesClient.unmuteAll({ id }); + await rulesClient.unmuteAll(params); return res.noContent(); } catch (e) { if (e instanceof RuleTypeDisabledError) { 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 163df75cc0e6b9..c889587469cea8 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -58,8 +58,8 @@ 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 { muteInstance } from '../application/rule/methods/mute_alert/mute_instance'; +import { unmuteAll } from '../application/rule/methods/unmute_all'; import { muteAll } from '../application/rule/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';