From ce430e56f19b13e0807608d36ca94ae347c4d48f Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Tue, 31 Oct 2023 14:54:57 -0500 Subject: [PATCH] [RAM] Add HTTP versioning to resolve, snooze, and unsnooze APIs (#168886) ## Summary **REOPENED version of https://github.com/elastic/kibana/pull/163359, git history got too complicated and triggered too many codeowners** Part of #157883 Converts `_resolve`, `_snooze`, `_unsnooze` to new HTTP versioned model ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../routes/r_rule/response/schemas/v1.ts | 12 +- .../routes/rule/apis/bulk_edit/index.ts | 14 +- .../routes/rule/apis/bulk_edit/schemas/v1.ts | 32 +---- .../routes/rule/apis/bulk_edit/types/v1.ts | 3 +- .../common/routes/rule/apis/create/index.ts | 2 - .../routes/rule/apis/create/schemas/v1.ts | 22 +-- .../common/routes/rule/apis/resolve/index.ts | 14 ++ .../schemas}/latest.ts | 0 .../routes/rule/apis/resolve/schemas/v1.ts | 12 ++ .../resolve/types}/latest.ts | 0 .../routes/rule/apis/resolve/types/v1.ts | 11 ++ .../common/routes/rule/apis/snooze/index.ts | 13 ++ .../routes/rule/apis/snooze/schemas/latest.ts | 8 ++ .../routes/rule/apis/snooze/schemas/v1.ts | 17 +++ .../common/routes/rule/apis/unsnooze/index.ts | 13 ++ .../rule/apis/unsnooze/schemas/latest.ts | 8 ++ .../routes/rule/apis/unsnooze/schemas/v1.ts | 18 +++ .../routes/rule/common/constants/latest.ts | 8 ++ .../rule/{response => common}/constants/v1.ts | 0 .../common/routes/rule/common/index.ts | 38 ++++++ .../bulk_edit/validation => request}/index.ts | 4 +- .../routes/rule/request/schemas/latest.ts | 8 ++ .../common/routes/rule/request/schemas/v1.ts | 19 +++ .../common/routes/rule/response/index.ts | 36 +---- .../common/routes/rule/response/schemas/v1.ts | 20 ++- .../common/routes/rule/validation/index.ts | 3 +- .../validation/validate_notify_when/v1.ts | 2 +- .../validate_snooze_schedule/latest.ts | 8 ++ .../validation/validate_snooze_schedule/v1.ts | 8 +- x-pack/plugins/alerting/common/rule.ts | 5 +- .../r_rule/schemas/r_rule_schema.ts | 12 +- .../types/bulk_edit_rules_options.ts | 2 +- .../application/rule/methods/resolve/index.ts | 9 ++ .../rule/methods/resolve/resolve_rule.ts | 106 +++++++++++++++ .../rule/methods/resolve/schemas/index.ts | 8 ++ .../schemas/resolve_rule_params_schema.ts | 12 ++ .../rule/methods/resolve/types/index.ts | 8 ++ .../methods/resolve/types/resolved_rule.ts | 9 ++ .../application/rule/methods/snooze/index.ts | 9 ++ .../rule/methods/snooze/schemas/index.ts | 9 ++ .../snooze/schemas/snooze_rule_body_schema.ts | 13 ++ .../schemas/snooze_rule_params_schema.ts | 12 ++ .../rule/methods/snooze/snooze_rule.ts} | 78 +++++------ .../rule/methods/snooze/types/index.ts | 8 ++ .../snooze/types/snooze_rule_options.ts | 13 ++ .../rule/methods/unsnooze/index.ts | 9 ++ .../rule/methods/unsnooze/schemas/index.ts | 8 ++ .../schemas/unsnooze_rule_params_schema.ts | 13 ++ .../rule/methods/unsnooze/unsnooze_rule.ts} | 56 ++++---- .../data/r_rule/types/r_rule_attributes.ts | 12 +- .../alerting/server/data/rule/index.ts | 4 + .../server/data/rule/methods/get_rule_so.ts | 22 +++ .../data/rule/methods/resolve_rule_so.ts | 24 ++++ .../plugins/alerting/server/routes/index.ts | 6 +- .../alerting/server/routes/resolve_rule.ts | 91 ------------- .../server/routes/rule/apis/resolve/index.ts | 8 ++ .../apis/resolve/resolve_rule_route.test.ts} | 38 +++--- .../rule/apis/resolve/resolve_rule_route.ts | 52 +++++++ .../rule/apis/resolve/transforms/index.ts | 10 ++ .../transform_resolve_response/latest.ts | 8 ++ .../transform_resolve_response/v1.ts | 18 +++ .../server/routes/rule/apis/snooze/index.ts | 8 ++ .../apis/snooze/snooze_rule_route.test.ts} | 12 +- .../apis/snooze/snooze_rule_route.ts} | 46 ++----- .../rule/apis/snooze/transforms/index.ts | 10 ++ .../transform_snooze_body/latest.ts | 8 ++ .../transforms/transform_snooze_body/v1.ts | 17 +++ .../server/routes/rule/apis/unsnooze/index.ts | 8 ++ .../rule/apis/unsnooze/transforms/index.ts | 10 ++ .../transform_unsnooze_body/latest.ts | 8 ++ .../transforms/transform_unsnooze_body/v1.ts | 10 ++ .../unsnooze/unsnooze_rule_route.test.ts} | 12 +- .../apis/unsnooze/unsnooze_rule_route.ts} | 35 ++--- .../transform_rule_to_rule_response/v1.ts | 1 + .../rules_client/common/snooze_utils.ts | 36 ++--- .../rules_client/lib/get_alert_from_raw.ts | 3 + .../rules_client/lib/get_rule_saved_object.ts | 39 ++++++ .../alerting/server/rules_client/lib/index.ts | 4 + .../lib/resolve_rule_saved_object.ts | 39 ++++++ .../server/rules_client/lib/update_meta.ts | 3 + .../lib/update_meta_attributes.ts | 25 ++++ .../server/rules_client/methods/mute_all.ts | 7 +- .../server/rules_client/methods/resolve.ts | 81 ----------- .../server/rules_client/methods/unmute_all.ts | 7 +- .../server/rules_client/rules_client.ts | 12 +- .../server/rules_client/tests/resolve.test.ts | 127 +++++++----------- x-pack/plugins/alerting/server/types.ts | 3 + x-pack/plugins/alerting/tsconfig.json | 3 +- .../components/notify_badge/notify_badge.tsx | 1 - 89 files changed, 1059 insertions(+), 561 deletions(-) create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/resolve/index.ts rename x-pack/plugins/alerting/common/routes/rule/apis/{bulk_edit/validation/validate_snooze_schedule => resolve/schemas}/latest.ts (100%) create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/resolve/schemas/v1.ts rename x-pack/plugins/alerting/common/routes/rule/{response/constants => apis/resolve/types}/latest.ts (100%) create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/resolve/types/v1.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/snooze/index.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/snooze/schemas/latest.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/snooze/schemas/v1.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/index.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/schemas/latest.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/schemas/v1.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/common/constants/latest.ts rename x-pack/plugins/alerting/common/routes/rule/{response => common}/constants/v1.ts (100%) create mode 100644 x-pack/plugins/alerting/common/routes/rule/common/index.ts rename x-pack/plugins/alerting/common/routes/rule/{apis/bulk_edit/validation => request}/index.ts (59%) create mode 100644 x-pack/plugins/alerting/common/routes/rule/request/schemas/latest.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/request/schemas/v1.ts create mode 100644 x-pack/plugins/alerting/common/routes/rule/validation/validate_snooze_schedule/latest.ts rename x-pack/plugins/alerting/common/routes/rule/{apis/bulk_edit => }/validation/validate_snooze_schedule/v1.ts (74%) create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/resolve/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/resolve/resolve_rule.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/resolve/schemas/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/resolve/schemas/resolve_rule_params_schema.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/resolve/types/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/resolve/types/resolved_rule.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/snooze/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/snooze_rule_body_schema.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/snooze_rule_params_schema.ts rename x-pack/plugins/alerting/server/{rules_client/methods/snooze.ts => application/rule/methods/snooze/snooze_rule.ts} (53%) create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/snooze/types/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/snooze/types/snooze_rule_options.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/unsnooze/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/unsnooze/schemas/index.ts create mode 100644 x-pack/plugins/alerting/server/application/rule/methods/unsnooze/schemas/unsnooze_rule_params_schema.ts rename x-pack/plugins/alerting/server/{rules_client/methods/unsnooze.ts => application/rule/methods/unsnooze/unsnooze_rule.ts} (54%) create mode 100644 x-pack/plugins/alerting/server/data/rule/methods/get_rule_so.ts create mode 100644 x-pack/plugins/alerting/server/data/rule/methods/resolve_rule_so.ts delete mode 100644 x-pack/plugins/alerting/server/routes/resolve_rule.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/resolve/index.ts rename x-pack/plugins/alerting/server/routes/{resolve_rule.test.ts => rule/apis/resolve/resolve_rule_route.test.ts} (75%) create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/index.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/transform_resolve_response/latest.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/transform_resolve_response/v1.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/snooze/index.ts rename x-pack/plugins/alerting/server/routes/{snooze_rule.test.ts => rule/apis/snooze/snooze_rule_route.test.ts} (90%) rename x-pack/plugins/alerting/server/routes/{snooze_rule.ts => rule/apis/snooze/snooze_rule_route.ts} (52%) create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/index.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/transform_snooze_body/latest.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/transform_snooze_body/v1.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/index.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/index.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/transform_unsnooze_body/latest.ts create mode 100644 x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/transform_unsnooze_body/v1.ts rename x-pack/plugins/alerting/server/routes/{unsnooze_rule.test.ts => rule/apis/unsnooze/unsnooze_rule_route.test.ts} (83%) rename x-pack/plugins/alerting/server/routes/{unsnooze_rule.ts => rule/apis/unsnooze/unsnooze_rule_route.ts} (60%) create mode 100644 x-pack/plugins/alerting/server/rules_client/lib/get_rule_saved_object.ts create mode 100644 x-pack/plugins/alerting/server/rules_client/lib/resolve_rule_saved_object.ts create mode 100644 x-pack/plugins/alerting/server/rules_client/lib/update_meta_attributes.ts delete mode 100644 x-pack/plugins/alerting/server/rules_client/methods/resolve.ts diff --git a/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/v1.ts index 0b32b61746ec9..13cb7cb3824f4 100644 --- a/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/r_rule/response/schemas/v1.ts @@ -38,10 +38,10 @@ export const rRuleResponseSchema = schema.object({ byweekday: schema.maybe(schema.arrayOf(schema.oneOf([schema.string(), schema.number()]))), bymonth: schema.maybe(schema.arrayOf(schema.number())), bysetpos: schema.maybe(schema.arrayOf(schema.number())), - bymonthday: schema.arrayOf(schema.number()), - byyearday: schema.arrayOf(schema.number()), - byweekno: schema.arrayOf(schema.number()), - byhour: schema.arrayOf(schema.number()), - byminute: schema.arrayOf(schema.number()), - bysecond: schema.arrayOf(schema.number()), + bymonthday: schema.maybe(schema.arrayOf(schema.number())), + byyearday: schema.maybe(schema.arrayOf(schema.number())), + byweekno: schema.maybe(schema.arrayOf(schema.number())), + byhour: schema.maybe(schema.arrayOf(schema.number())), + byminute: schema.maybe(schema.arrayOf(schema.number())), + bysecond: schema.maybe(schema.arrayOf(schema.number())), }); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/index.ts index 1ae4a238cbf21..801e13088fab6 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/index.ts @@ -5,24 +5,14 @@ * 2.0. */ -export { - ruleSnoozeScheduleSchema, - bulkEditOperationsSchema, - bulkEditRulesRequestBodySchema, -} from './schemas/latest'; -export type { - RuleSnoozeSchedule, - BulkEditRulesRequestBody, - BulkEditRulesResponse, -} from './types/latest'; +export { bulkEditOperationsSchema, bulkEditRulesRequestBodySchema } from './schemas/latest'; +export type { BulkEditRulesRequestBody, BulkEditRulesResponse } from './types/latest'; export { - ruleSnoozeScheduleSchema as ruleSnoozeScheduleSchemaV1, bulkEditOperationsSchema as bulkEditOperationsSchemaV1, bulkEditRulesRequestBodySchema as bulkEditRulesRequestBodySchemaV1, } from './schemas/v1'; export type { - RuleSnoozeSchedule as RuleSnoozeScheduleV1, BulkEditRulesRequestBody as BulkEditRulesRequestBodyV1, BulkEditRulesResponse as BulkEditRulesResponseV1, } from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts index 54e70cde689ac..3a17eaee30974 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/schemas/v1.ts @@ -6,19 +6,10 @@ */ import { schema } from '@kbn/config-schema'; -import { validateDurationV1, validateNotifyWhenV1 } from '../../../validation'; -import { validateSnoozeScheduleV1 } from '../validation'; +import { validateDurationV1 } from '../../../validation'; import { rRuleRequestSchemaV1 } from '../../../../r_rule'; -import { ruleNotifyWhenV1 } from '../../../response'; - -const notifyWhenSchema = schema.oneOf( - [ - schema.literal(ruleNotifyWhenV1.CHANGE), - schema.literal(ruleNotifyWhenV1.ACTIVE), - schema.literal(ruleNotifyWhenV1.THROTTLE), - ], - { validate: validateNotifyWhenV1 } -); +import { notifyWhenSchemaV1, scheduleIdsSchemaV1 } from '../../../response'; +import { ruleSnoozeScheduleSchemaV1 } from '../../../request'; export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); @@ -28,15 +19,6 @@ export const ruleSnoozeScheduleSchema = schema.object({ rRule: rRuleRequestSchemaV1, }); -const ruleSnoozeScheduleSchemaWithValidation = schema.object( - { - id: schema.maybe(schema.string()), - duration: schema.number(), - rRule: rRuleRequestSchemaV1, - }, - { validate: validateSnoozeScheduleV1 } -); - const ruleActionSchema = schema.object({ group: schema.string(), id: schema.string(), @@ -46,7 +28,7 @@ const ruleActionSchema = schema.object({ schema.object({ summary: schema.boolean(), throttle: schema.nullable(schema.string()), - notifyWhen: notifyWhenSchema, + notifyWhen: notifyWhenSchemaV1, }) ), }); @@ -80,17 +62,17 @@ export const bulkEditOperationsSchema = schema.arrayOf( schema.object({ operation: schema.literal('set'), field: schema.literal('notifyWhen'), - value: notifyWhenSchema, + value: notifyWhenSchemaV1, }), schema.object({ operation: schema.oneOf([schema.literal('set')]), field: schema.literal('snoozeSchedule'), - value: ruleSnoozeScheduleSchemaWithValidation, + value: ruleSnoozeScheduleSchemaV1, }), schema.object({ operation: schema.oneOf([schema.literal('delete')]), field: schema.literal('snoozeSchedule'), - value: schema.maybe(scheduleIdsSchema), + value: schema.maybe(scheduleIdsSchemaV1), }), schema.object({ operation: schema.literal('set'), diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/v1.ts index 8f98d1c140746..3070f09964c3c 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/types/v1.ts @@ -6,9 +6,8 @@ */ import type { TypeOf } from '@kbn/config-schema'; import { RuleParamsV1, RuleResponseV1 } from '../../../response'; -import { ruleSnoozeScheduleSchemaV1, bulkEditRulesRequestBodySchemaV1 } from '..'; +import { bulkEditRulesRequestBodySchemaV1 } from '..'; -export type RuleSnoozeSchedule = TypeOf; export type BulkEditRulesRequestBody = TypeOf; interface BulkEditActionSkippedResult { diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/create/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/index.ts index 92ac6d67aece7..b7d96ceed715c 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/create/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/index.ts @@ -6,7 +6,6 @@ */ export { - notifyWhenSchema, actionFrequencySchema, actionAlertsFilterSchema, actionSchema, @@ -23,7 +22,6 @@ export type { } from './types/latest'; export { - notifyWhenSchema as notifyWhenSchemaV1, actionFrequencySchema as actionFrequencySchemaV1, actionAlertsFilterSchema as actionAlertsFilterSchemaV1, actionSchema as actionSchemaV1, diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts index 98d82abf62be4..e471dd3cea530 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts @@ -6,26 +6,12 @@ */ import { schema } from '@kbn/config-schema'; -import { ruleNotifyWhenV1 } from '../../../response'; -import { - validateNotifyWhenV1, - validateDurationV1, - validateHoursV1, - validateTimezoneV1, -} from '../../../validation'; - -export const notifyWhenSchema = schema.oneOf( - [ - schema.literal(ruleNotifyWhenV1.CHANGE), - schema.literal(ruleNotifyWhenV1.ACTIVE), - schema.literal(ruleNotifyWhenV1.THROTTLE), - ], - { validate: validateNotifyWhenV1 } -); +import { validateDurationV1, validateHoursV1, validateTimezoneV1 } from '../../../validation'; +import { notifyWhenSchemaV1 } from '../../../response'; export const actionFrequencySchema = schema.object({ summary: schema.boolean(), - notify_when: notifyWhenSchema, + notify_when: notifyWhenSchemaV1, throttle: schema.nullable(schema.string({ validate: validateDurationV1 })), }); @@ -91,7 +77,7 @@ export const createBodySchema = schema.object({ interval: schema.string({ validate: validateDurationV1 }), }), actions: schema.arrayOf(actionSchema, { defaultValue: [] }), - notify_when: schema.maybe(schema.nullable(notifyWhenSchema)), + notify_when: schema.maybe(schema.nullable(notifyWhenSchemaV1)), }); export const createParamsSchema = schema.object({ diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/resolve/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/resolve/index.ts new file mode 100644 index 0000000000000..140ec00701414 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/resolve/index.ts @@ -0,0 +1,14 @@ +/* + * 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 { resolveParamsSchema } from './schemas/latest'; + +export { resolveParamsSchema as resolveParamsSchemaV1 } from './schemas/v1'; + +export type { ResolveRuleResponse } from './types/latest'; + +export type { ResolveRuleResponse as ResolveRuleResponseV1 } from './types/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/resolve/schemas/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/latest.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/resolve/schemas/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/resolve/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/resolve/schemas/v1.ts new file mode 100644 index 0000000000000..26f23e23af6dc --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/resolve/schemas/v1.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 resolveParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/response/constants/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/resolve/types/latest.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/response/constants/latest.ts rename to x-pack/plugins/alerting/common/routes/rule/apis/resolve/types/latest.ts diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/resolve/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/resolve/types/v1.ts new file mode 100644 index 0000000000000..eb86327c07712 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/resolve/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 { RuleParamsV1, RuleResponseV1 } from '../../../response'; + +export interface ResolveRuleResponse { + body: RuleResponseV1; +} diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/snooze/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/snooze/index.ts new file mode 100644 index 0000000000000..cfd7ad0cbce05 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/snooze/index.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. + */ + +export { snoozeParamsSchema, snoozeBodySchema } from './schemas/latest'; + +export { + snoozeParamsSchema as snoozeParamsSchemaV1, + snoozeBodySchema as snoozeBodySchemaV1, +} from './schemas/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/snooze/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/snooze/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/snooze/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/snooze/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/snooze/schemas/v1.ts new file mode 100644 index 0000000000000..9b12ab9767512 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/snooze/schemas/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 { schema } from '@kbn/config-schema'; +import { ruleSnoozeScheduleSchemaV1 } from '../../../request'; + +export const snoozeParamsSchema = schema.object({ + id: schema.string(), +}); + +export const snoozeBodySchema = schema.object({ + snooze_schedule: ruleSnoozeScheduleSchemaV1, +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/index.ts b/x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/index.ts new file mode 100644 index 0000000000000..1fb769c46d345 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/index.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. + */ + +export { unsnoozeParamsSchema, unsnoozeBodySchema } from './schemas/latest'; + +export { + unsnoozeParamsSchema as unsnoozeParamsSchemaV1, + unsnoozeBodySchema as unsnoozeBodySchemaV1, +} from './schemas/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/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/unsnooze/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/schemas/v1.ts new file mode 100644 index 0000000000000..0da0e1b4ecd0b --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/apis/unsnooze/schemas/v1.ts @@ -0,0 +1,18 @@ +/* + * 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 unsnoozeParamsSchema = schema.object({ + id: schema.string(), +}); + +const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); + +export const unsnoozeBodySchema = schema.object({ + schedule_ids: scheduleIdsSchema, +}); diff --git a/x-pack/plugins/alerting/common/routes/rule/common/constants/latest.ts b/x-pack/plugins/alerting/common/routes/rule/common/constants/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/common/constants/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/response/constants/v1.ts b/x-pack/plugins/alerting/common/routes/rule/common/constants/v1.ts similarity index 100% rename from x-pack/plugins/alerting/common/routes/rule/response/constants/v1.ts rename to x-pack/plugins/alerting/common/routes/rule/common/constants/v1.ts diff --git a/x-pack/plugins/alerting/common/routes/rule/common/index.ts b/x-pack/plugins/alerting/common/routes/rule/common/index.ts new file mode 100644 index 0000000000000..5989a3a993e7a --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/common/index.ts @@ -0,0 +1,38 @@ +/* + * 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 { + ruleNotifyWhen, + ruleLastRunOutcomeValues, + ruleExecutionStatusValues, + ruleExecutionStatusErrorReason, + ruleExecutionStatusWarningReason, +} from './constants/latest'; + +export type { + RuleNotifyWhen, + RuleLastRunOutcomeValues, + RuleExecutionStatusValues, + RuleExecutionStatusErrorReason, + RuleExecutionStatusWarningReason, +} from './constants/latest'; + +export { + ruleNotifyWhen as ruleNotifyWhenV1, + ruleLastRunOutcomeValues as ruleLastRunOutcomeValuesV1, + ruleExecutionStatusValues as ruleExecutionStatusValuesV1, + ruleExecutionStatusErrorReason as ruleExecutionStatusErrorReasonV1, + ruleExecutionStatusWarningReason as ruleExecutionStatusWarningReasonV1, +} from './constants/v1'; + +export type { + RuleNotifyWhen as RuleNotifyWhenV1, + RuleLastRunOutcomeValues as RuleLastRunOutcomeValuesV1, + RuleExecutionStatusValues as RuleExecutionStatusValuesV1, + RuleExecutionStatusErrorReason as RuleExecutionStatusErrorReasonV1, + RuleExecutionStatusWarningReason as RuleExecutionStatusWarningReasonV1, +} from './constants/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/index.ts b/x-pack/plugins/alerting/common/routes/rule/request/index.ts similarity index 59% rename from x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/index.ts rename to x-pack/plugins/alerting/common/routes/rule/request/index.ts index c11ce4f73f42c..bf500b636e7d9 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/request/index.ts @@ -5,6 +5,6 @@ * 2.0. */ -export { validateSnoozeSchedule } from './validate_snooze_schedule/latest'; +export { ruleSnoozeScheduleSchema } from './schemas/latest'; -export { validateSnoozeSchedule as validateSnoozeScheduleV1 } from './validate_snooze_schedule/v1'; +export { ruleSnoozeScheduleSchema as ruleSnoozeScheduleSchemaV1 } from './schemas/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/request/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/rule/request/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/request/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/request/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/request/schemas/v1.ts new file mode 100644 index 0000000000000..af9cf6a3ad3a6 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/request/schemas/v1.ts @@ -0,0 +1,19 @@ +/* + * 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'; +import { rRuleRequestSchemaV1 } from '../../../r_rule'; +import { validateSnoozeScheduleV1 } from '../../validation'; + +export const ruleSnoozeScheduleSchema = schema.object( + { + id: schema.maybe(schema.string()), + duration: schema.number(), + rRule: rRuleRequestSchemaV1, + }, + { validate: validateSnoozeScheduleV1 } +); diff --git a/x-pack/plugins/alerting/common/routes/rule/response/index.ts b/x-pack/plugins/alerting/common/routes/rule/response/index.ts index cdf693c7867eb..ec8734240cc2b 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/index.ts @@ -14,6 +14,8 @@ export { monitoringSchema, ruleResponseSchema, ruleSnoozeScheduleSchema, + notifyWhenSchema, + scheduleIdsSchema, } from './schemas/latest'; export type { @@ -24,22 +26,6 @@ export type { Monitoring, } from './types/latest'; -export { - ruleNotifyWhen, - ruleLastRunOutcomeValues, - ruleExecutionStatusValues, - ruleExecutionStatusErrorReason, - ruleExecutionStatusWarningReason, -} from './constants/latest'; - -export type { - RuleNotifyWhen, - RuleLastRunOutcomeValues, - RuleExecutionStatusValues, - RuleExecutionStatusErrorReason, - RuleExecutionStatusWarningReason, -} from './constants/latest'; - export { ruleParamsSchema as ruleParamsSchemaV1, actionParamsSchema as actionParamsSchemaV1, @@ -49,24 +35,10 @@ export { monitoringSchema as monitoringSchemaV1, ruleResponseSchema as ruleResponseSchemaV1, ruleSnoozeScheduleSchema as ruleSnoozeScheduleSchemaV1, + notifyWhenSchema as notifyWhenSchemaV1, + scheduleIdsSchema as scheduleIdsSchemaV1, } from './schemas/v1'; -export { - ruleNotifyWhen as ruleNotifyWhenV1, - ruleLastRunOutcomeValues as ruleLastRunOutcomeValuesV1, - ruleExecutionStatusValues as ruleExecutionStatusValuesV1, - ruleExecutionStatusErrorReason as ruleExecutionStatusErrorReasonV1, - ruleExecutionStatusWarningReason as ruleExecutionStatusWarningReasonV1, -} from './constants/v1'; - -export type { - RuleNotifyWhen as RuleNotifyWhenV1, - RuleLastRunOutcomeValues as RuleLastRunOutcomeValuesV1, - RuleExecutionStatusValues as RuleExecutionStatusValuesV1, - RuleExecutionStatusErrorReason as RuleExecutionStatusErrorReasonV1, - RuleExecutionStatusWarningReason as RuleExecutionStatusWarningReasonV1, -} from './constants/v1'; - export type { RuleParams as RuleParamsV1, RuleResponse as RuleResponseV1, diff --git a/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts index 1c093314f7a47..fe02146c5ef62 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts @@ -13,17 +13,21 @@ import { ruleExecutionStatusErrorReason as ruleExecutionStatusErrorReasonV1, ruleExecutionStatusWarningReason as ruleExecutionStatusWarningReasonV1, ruleLastRunOutcomeValues as ruleLastRunOutcomeValuesV1, -} from '../constants/v1'; +} from '../../common/constants/v1'; +import { validateNotifyWhenV1 } from '../../validation'; export const ruleParamsSchema = schema.recordOf(schema.string(), schema.maybe(schema.any())); export const actionParamsSchema = schema.recordOf(schema.string(), schema.maybe(schema.any())); export const mappedParamsSchema = schema.recordOf(schema.string(), schema.maybe(schema.any())); -const notifyWhenSchema = schema.oneOf([ - schema.literal(ruleNotifyWhenV1.CHANGE), - schema.literal(ruleNotifyWhenV1.ACTIVE), - schema.literal(ruleNotifyWhenV1.THROTTLE), -]); +export const notifyWhenSchema = schema.oneOf( + [ + schema.literal(ruleNotifyWhenV1.CHANGE), + schema.literal(ruleNotifyWhenV1.ACTIVE), + schema.literal(ruleNotifyWhenV1.THROTTLE), + ], + { validate: validateNotifyWhenV1 } +); const intervalScheduleSchema = schema.object({ interval: schema.string(), @@ -182,9 +186,9 @@ export const monitoringSchema = schema.object({ }); export const ruleSnoozeScheduleSchema = schema.object({ + id: schema.maybe(schema.string()), duration: schema.number(), rRule: rRuleResponseSchemaV1, - id: schema.maybe(schema.string()), skipRecurrences: schema.maybe(schema.arrayOf(schema.string())), }); @@ -221,3 +225,5 @@ export const ruleResponseSchema = schema.object({ running: schema.maybe(schema.nullable(schema.boolean())), view_in_app_relative_url: schema.maybe(schema.nullable(schema.string())), }); + +export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); diff --git a/x-pack/plugins/alerting/common/routes/rule/validation/index.ts b/x-pack/plugins/alerting/common/routes/rule/validation/index.ts index a0322c2256e74..710f15f0d4c9d 100644 --- a/x-pack/plugins/alerting/common/routes/rule/validation/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/validation/index.ts @@ -7,10 +7,11 @@ export { validateDuration } from './validate_duration/latest'; export { validateHours } from './validate_hours/latest'; -export { validateNotifyWhen } from './validate_notify_when/latest'; export { validateTimezone } from './validate_timezone/latest'; +export { validateSnoozeSchedule } from './validate_snooze_schedule/latest'; export { validateDuration as validateDurationV1 } from './validate_duration/v1'; export { validateHours as validateHoursV1 } from './validate_hours/v1'; export { validateNotifyWhen as validateNotifyWhenV1 } from './validate_notify_when/v1'; export { validateTimezone as validateTimezoneV1 } from './validate_timezone/v1'; +export { validateSnoozeSchedule as validateSnoozeScheduleV1 } from './validate_snooze_schedule/v1'; diff --git a/x-pack/plugins/alerting/common/routes/rule/validation/validate_notify_when/v1.ts b/x-pack/plugins/alerting/common/routes/rule/validation/validate_notify_when/v1.ts index e58e5f5ef7cfd..38ccd877c49ae 100644 --- a/x-pack/plugins/alerting/common/routes/rule/validation/validate_notify_when/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/validation/validate_notify_when/v1.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ruleNotifyWhenV1, RuleNotifyWhenV1 } from '../../response'; +import { ruleNotifyWhenV1, RuleNotifyWhenV1 } from '../../common'; export function validateNotifyWhen(notifyWhen: string) { if (Object.values(ruleNotifyWhenV1).includes(notifyWhen as RuleNotifyWhenV1)) { diff --git a/x-pack/plugins/alerting/common/routes/rule/validation/validate_snooze_schedule/latest.ts b/x-pack/plugins/alerting/common/routes/rule/validation/validate_snooze_schedule/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/rule/validation/validate_snooze_schedule/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/bulk_edit/validation/validate_snooze_schedule/v1.ts b/x-pack/plugins/alerting/common/routes/rule/validation/validate_snooze_schedule/v1.ts similarity index 74% rename from x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/v1.ts rename to x-pack/plugins/alerting/common/routes/rule/validation/validate_snooze_schedule/v1.ts index 65460110cd107..4a93f130e8248 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/bulk_edit/validation/validate_snooze_schedule/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/validation/validate_snooze_schedule/v1.ts @@ -5,11 +5,15 @@ * 2.0. */ +import { TypeOf } from '@kbn/config-schema'; import { Frequency } from '@kbn/rrule'; import moment from 'moment'; -import { RuleSnoozeScheduleV1 } from '../..'; +import { rRuleRequestSchema } from '../../../r_rule'; -export const validateSnoozeSchedule = (schedule: RuleSnoozeScheduleV1) => { +export const validateSnoozeSchedule = (schedule: { + rRule: TypeOf; + duration: number; +}) => { const intervalIsDaily = schedule.rRule.freq === Frequency.DAILY; const durationInDays = moment.duration(schedule.duration, 'milliseconds').asDays(); if (intervalIsDaily && schedule.rRule.interval && durationInDays >= schedule.rRule.interval) { diff --git a/x-pack/plugins/alerting/common/rule.ts b/x-pack/plugins/alerting/common/rule.ts index 5a8e1b275ef7e..ff74752df8695 100644 --- a/x-pack/plugins/alerting/common/rule.ts +++ b/x-pack/plugins/alerting/common/rule.ts @@ -191,7 +191,10 @@ export type SanitizedRule = Omit< > & { actions: SanitizedRuleAction[] }; export type ResolvedSanitizedRule = SanitizedRule & - Omit; + Omit & { + outcome: string; + alias_target_id?: string; + }; export type SanitizedRuleConfig = Pick< SanitizedRule, diff --git a/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_schema.ts b/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_schema.ts index 6f8b2f8f4fc7a..5325c571f5d3e 100644 --- a/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_schema.ts +++ b/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_schema.ts @@ -37,10 +37,10 @@ export const rRuleSchema = schema.object({ byweekday: schema.maybe(schema.arrayOf(schema.oneOf([schema.string(), schema.number()]))), bymonth: schema.maybe(schema.arrayOf(schema.number())), bysetpos: schema.maybe(schema.arrayOf(schema.number())), - bymonthday: schema.arrayOf(schema.number()), - byyearday: schema.arrayOf(schema.number()), - byweekno: schema.arrayOf(schema.number()), - byhour: schema.arrayOf(schema.number()), - byminute: schema.arrayOf(schema.number()), - bysecond: schema.arrayOf(schema.number()), + bymonthday: schema.maybe(schema.arrayOf(schema.number())), + byyearday: schema.maybe(schema.arrayOf(schema.number())), + byweekno: schema.maybe(schema.arrayOf(schema.number())), + byhour: schema.maybe(schema.arrayOf(schema.number())), + byminute: schema.maybe(schema.arrayOf(schema.number())), + bysecond: schema.maybe(schema.arrayOf(schema.number())), }); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/bulk_edit_rules_options.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/bulk_edit_rules_options.ts index a74b7fe152069..c099cde044363 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/bulk_edit_rules_options.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/types/bulk_edit_rules_options.ts @@ -45,7 +45,7 @@ export type BulkEditOptionsFilter = BulkEditOptionsCo }; export type BulkEditOptionsIds = BulkEditOptionsCommon & { - ids: string[]; + ids?: string[]; }; export type BulkEditSkipReason = 'RULE_NOT_MODIFIED'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/resolve/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/resolve/index.ts new file mode 100644 index 0000000000000..b8d44beb0610e --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/resolve/index.ts @@ -0,0 +1,9 @@ +/* + * 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 { ResolveParams } from './resolve_rule'; +export { resolveRule } from './resolve_rule'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/resolve/resolve_rule.ts b/x-pack/plugins/alerting/server/application/rule/methods/resolve/resolve_rule.ts new file mode 100644 index 0000000000000..cbde52a44b1fe --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/resolve/resolve_rule.ts @@ -0,0 +1,106 @@ +/* + * 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 Boom from '@hapi/boom'; +import { withSpan } from '@kbn/apm-utils'; +import { AlertConsumers } from '@kbn/rule-data-utils'; +import { resolveRuleSavedObject } from '../../../../rules_client/lib'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; +import { RuleTypeParams } from '../../../../types'; +import { ReadOperations, AlertingAuthorizationEntity } from '../../../../authorization'; +import { RulesClientContext } from '../../../../rules_client/types'; +import { formatLegacyActions } from '../../../../rules_client/lib'; +import { transformRuleAttributesToRuleDomain, transformRuleDomainToRule } from '../../transforms'; +import { Rule } from '../../types'; +import { ruleSchema } from '../../schemas'; +import { resolveRuleParamsSchema } from './schemas'; +import type { ResolvedSanitizedRule } from '../../../../types'; + +export interface ResolveParams { + id: string; + includeSnoozeData?: boolean; +} + +export async function resolveRule( + context: RulesClientContext, + { id, includeSnoozeData = false }: ResolveParams +): // TODO (http-versioning): This should be of type Rule, change this when all rule types are fixed +Promise> { + try { + resolveRuleParamsSchema.validate({ id }); + } catch (error) { + throw Boom.badRequest(`Error validating resolve params - ${error.message}`); + } + const { saved_object: result, ...resolveResponse } = await withSpan( + { name: 'resolveRuleSavedObject', type: 'rules' }, + () => + resolveRuleSavedObject(context, { + ruleId: id, + }) + ); + try { + await context.authorization.ensureAuthorized({ + ruleTypeId: result.attributes.alertTypeId, + consumer: result.attributes.consumer, + operation: ReadOperations.Get, + entity: AlertingAuthorizationEntity.Rule, + }); + } catch (error) { + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.RESOLVE, + savedObject: { type: 'alert', id }, + error, + }) + ); + throw error; + } + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.RESOLVE, + savedObject: { type: 'alert', id }, + }) + ); + + const ruleDomain = transformRuleAttributesToRuleDomain(result.attributes, { + id: result.id, + logger: context.logger, + ruleType: context.ruleTypeRegistry.get(result.attributes.alertTypeId), + references: result.references, + includeSnoozeData, + }); + + const rule = transformRuleDomainToRule(ruleDomain); + + try { + ruleSchema.validate(rule); + } catch (error) { + context.logger.warn(`Error validating resolve data - ${error.message}`); + } + + // format legacy actions for SIEM rules + if (result.attributes.consumer === AlertConsumers.SIEM) { + // @ts-expect-error formatLegacyActions uses common Rule type instead of server; wontfix as this function is deprecated + const [migratedRule] = await formatLegacyActions([rule], { + savedObjectsClient: context.unsecuredSavedObjectsClient, + logger: context.logger, + }); + + return { + ...(migratedRule as Rule), + ...resolveResponse, + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + } as ResolvedSanitizedRule; + } + + return { + ...rule, + ...resolveResponse, + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + } as ResolvedSanitizedRule; +} diff --git a/x-pack/plugins/alerting/server/application/rule/methods/resolve/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/resolve/schemas/index.ts new file mode 100644 index 0000000000000..09bccf1170ab4 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/resolve/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 { resolveRuleParamsSchema } from './resolve_rule_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/resolve/schemas/resolve_rule_params_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/resolve/schemas/resolve_rule_params_schema.ts new file mode 100644 index 0000000000000..a4371befd9f78 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/resolve/schemas/resolve_rule_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 resolveRuleParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/resolve/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/resolve/types/index.ts new file mode 100644 index 0000000000000..a4b7c56caab19 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/resolve/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 './resolved_rule'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/resolve/types/resolved_rule.ts b/x-pack/plugins/alerting/server/application/rule/methods/resolve/types/resolved_rule.ts new file mode 100644 index 0000000000000..d9d0c3f0c5e8f --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/resolve/types/resolved_rule.ts @@ -0,0 +1,9 @@ +/* + * 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 { Rule } from '../../../types'; + +export type ResolvedRule = Rule & { outcome: string; alias_target_id?: string }; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/snooze/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/snooze/index.ts new file mode 100644 index 0000000000000..842e092d40d57 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/snooze/index.ts @@ -0,0 +1,9 @@ +/* + * 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 { SnoozeRuleOptions } from './types'; +export { snoozeRule } from './snooze_rule'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/index.ts new file mode 100644 index 0000000000000..b0744b893bbfb --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/index.ts @@ -0,0 +1,9 @@ +/* + * 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 { snoozeRuleParamsSchema } from './snooze_rule_params_schema'; +export { snoozeRuleBodySchema } from './snooze_rule_body_schema'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/snooze_rule_body_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/snooze_rule_body_schema.ts new file mode 100644 index 0000000000000..180e69fb33ad1 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/snooze_rule_body_schema.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'; +import { ruleSnoozeScheduleSchema as ruleSnoozeScheduleRequestSchema } from '../../../../../../common/routes/rule/request'; + +export const snoozeRuleBodySchema = schema.object({ + snoozeSchedule: ruleSnoozeScheduleRequestSchema, +}); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/snooze_rule_params_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/snooze_rule_params_schema.ts new file mode 100644 index 0000000000000..2bacdb1c116f2 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/snooze/schemas/snooze_rule_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 snoozeRuleParamsSchema = schema.object({ + id: schema.string(), +}); diff --git a/x-pack/plugins/alerting/server/rules_client/methods/snooze.ts b/x-pack/plugins/alerting/server/application/rule/methods/snooze/snooze_rule.ts similarity index 53% rename from x-pack/plugins/alerting/server/rules_client/methods/snooze.ts rename to x-pack/plugins/alerting/server/application/rule/methods/snooze/snooze_rule.ts index 6f1187526b521..b10df195e5b77 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/snooze.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/snooze/snooze_rule.ts @@ -6,26 +6,32 @@ */ import Boom from '@hapi/boom'; -import { RawRule, RuleSnoozeSchedule } from '../../types'; -import { WriteOperations, AlertingAuthorizationEntity } from '../../authorization'; -import { retryIfConflicts } from '../../lib/retry_if_conflicts'; -import { partiallyUpdateAlert } from '../../saved_objects'; -import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; -import { validateSnoozeStartDate } from '../../lib/validate_snooze_date'; -import { RuleMutedError } from '../../lib/errors/rule_muted'; -import { RulesClientContext } from '../types'; -import { getSnoozeAttributes, verifySnoozeAttributeScheduleLimit } from '../common'; -import { updateMeta } from '../lib'; +import { withSpan } from '@kbn/apm-utils'; +import { getRuleSavedObject } from '../../../../rules_client/lib'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; +import { WriteOperations, AlertingAuthorizationEntity } from '../../../../authorization'; +import { retryIfConflicts } from '../../../../lib/retry_if_conflicts'; +import { validateSnoozeStartDate } from '../../../../lib/validate_snooze_date'; +import { RuleMutedError } from '../../../../lib/errors/rule_muted'; +import { RulesClientContext } from '../../../../rules_client/types'; +import { + getSnoozeAttributes, + verifySnoozeAttributeScheduleLimit, +} from '../../../../rules_client/common'; +import { updateRuleSo } from '../../../../data/rule'; +import { updateMetaAttributes } from '../../../../rules_client/lib/update_meta_attributes'; +import { snoozeRuleParamsSchema } from './schemas'; +import type { SnoozeRuleOptions } from './types'; -export interface SnoozeParams { - id: string; - snoozeSchedule: RuleSnoozeSchedule; -} - -export async function snooze( +export async function snoozeRule( context: RulesClientContext, - { id, snoozeSchedule }: SnoozeParams + { id, snoozeSchedule }: SnoozeRuleOptions ): Promise { + try { + snoozeRuleParamsSchema.validate({ id }); + } catch (error) { + throw Boom.badRequest(`Error validating snooze params - ${error.message}`); + } const snoozeDateValidationMsg = validateSnoozeStartDate(snoozeSchedule.rRule.dtstart); if (snoozeDateValidationMsg) { throw new RuleMutedError(snoozeDateValidationMsg); @@ -40,17 +46,14 @@ export async function snooze( async function snoozeWithOCC( context: RulesClientContext, - { - id, - snoozeSchedule, - }: { - id: string; - snoozeSchedule: RuleSnoozeSchedule; - } + { id, snoozeSchedule }: SnoozeRuleOptions ) { - const { attributes, version } = await context.unsecuredSavedObjectsClient.get( - 'alert', - id + const { attributes, version } = await withSpan( + { name: 'getRuleSavedObject', type: 'rules' }, + () => + getRuleSavedObject(context, { + ruleId: id, + }) ); try { @@ -93,17 +96,14 @@ async function snoozeWithOCC( throw Boom.badRequest(error.message); } - const updateAttributes = updateMeta(context, { - ...newAttrs, - updatedBy: await context.getUserName(), - updatedAt: new Date().toISOString(), - }); - const updateOptions = { version }; - - await partiallyUpdateAlert( - context.unsecuredSavedObjectsClient, + await updateRuleSo({ + savedObjectsClient: context.unsecuredSavedObjectsClient, + savedObjectsUpdateOptions: { version }, id, - updateAttributes, - updateOptions - ); + updateRuleAttributes: updateMetaAttributes(context, { + ...newAttrs, + updatedBy: await context.getUserName(), + updatedAt: new Date().toISOString(), + }), + }); } diff --git a/x-pack/plugins/alerting/server/application/rule/methods/snooze/types/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/snooze/types/index.ts new file mode 100644 index 0000000000000..ce69db70c3b8b --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/snooze/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 './snooze_rule_options'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/snooze/types/snooze_rule_options.ts b/x-pack/plugins/alerting/server/application/rule/methods/snooze/types/snooze_rule_options.ts new file mode 100644 index 0000000000000..77d077b6ee0e5 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/snooze/types/snooze_rule_options.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 { TypeOf } from '@kbn/config-schema'; +import { ruleSnoozeScheduleSchema as ruleSnoozeScheduleRequestSchema } from '../../../../../../common/routes/rule/request'; + +export interface SnoozeRuleOptions { + id: string; + snoozeSchedule: TypeOf; +} diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/index.ts new file mode 100644 index 0000000000000..3b897aa4675df --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/index.ts @@ -0,0 +1,9 @@ +/* + * 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 { UnsnoozeParams } from './unsnooze_rule'; +export { unsnoozeRule } from './unsnooze_rule'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/schemas/index.ts new file mode 100644 index 0000000000000..8abf96bb36f04 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/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 { unsnoozeRuleParamsSchema } from './unsnooze_rule_params_schema'; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/schemas/unsnooze_rule_params_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/schemas/unsnooze_rule_params_schema.ts new file mode 100644 index 0000000000000..3f5b26e072519 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/schemas/unsnooze_rule_params_schema.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 unsnoozeRuleParamsSchema = schema.object({ + id: schema.string(), + scheduleIds: schema.maybe(schema.arrayOf(schema.string())), +}); diff --git a/x-pack/plugins/alerting/server/rules_client/methods/unsnooze.ts b/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/unsnooze_rule.ts similarity index 54% rename from x-pack/plugins/alerting/server/rules_client/methods/unsnooze.ts rename to x-pack/plugins/alerting/server/application/rule/methods/unsnooze/unsnooze_rule.ts index 59d0ea62eb3ff..c47b39f28aedb 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/unsnooze.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/unsnooze/unsnooze_rule.ts @@ -5,21 +5,24 @@ * 2.0. */ -import { RawRule } from '../../types'; -import { WriteOperations, AlertingAuthorizationEntity } from '../../authorization'; -import { retryIfConflicts } from '../../lib/retry_if_conflicts'; -import { partiallyUpdateAlert } from '../../saved_objects'; -import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; -import { RulesClientContext } from '../types'; -import { updateMeta } from '../lib'; -import { getUnsnoozeAttributes } from '../common'; +import Boom from '@hapi/boom'; +import { withSpan } from '@kbn/apm-utils'; +import { ruleAuditEvent, RuleAuditAction } from '../../../../rules_client/common/audit_events'; +import { getRuleSavedObject } from '../../../../rules_client/lib'; +import { WriteOperations, AlertingAuthorizationEntity } from '../../../../authorization'; +import { retryIfConflicts } from '../../../../lib/retry_if_conflicts'; +import { RulesClientContext } from '../../../../rules_client/types'; +import { getUnsnoozeAttributes } from '../../../../rules_client/common'; +import { updateRuleSo } from '../../../../data/rule'; +import { updateMetaAttributes } from '../../../../rules_client/lib/update_meta_attributes'; +import { unsnoozeRuleParamsSchema } from './schemas'; export interface UnsnoozeParams { id: string; scheduleIds?: string[]; } -export async function unsnooze( +export async function unsnoozeRule( context: RulesClientContext, { id, scheduleIds }: UnsnoozeParams ): Promise { @@ -31,9 +34,17 @@ export async function unsnooze( } async function unsnoozeWithOCC(context: RulesClientContext, { id, scheduleIds }: UnsnoozeParams) { - const { attributes, version } = await context.unsecuredSavedObjectsClient.get( - 'alert', - id + try { + unsnoozeRuleParamsSchema.validate({ id, scheduleIds }); + } catch (error) { + throw Boom.badRequest(`Error validating unsnooze params - ${error.message}`); + } + const { attributes, version } = await withSpan( + { name: 'getRuleSavedObject', type: 'rules' }, + () => + getRuleSavedObject(context, { + ruleId: id, + }) ); try { @@ -69,17 +80,14 @@ async function unsnoozeWithOCC(context: RulesClientContext, { id, scheduleIds }: context.ruleTypeRegistry.ensureRuleTypeEnabled(attributes.alertTypeId); const newAttrs = getUnsnoozeAttributes(attributes, scheduleIds); - const updateAttributes = updateMeta(context, { - ...newAttrs, - updatedBy: await context.getUserName(), - updatedAt: new Date().toISOString(), - }); - const updateOptions = { version }; - - await partiallyUpdateAlert( - context.unsecuredSavedObjectsClient, + await updateRuleSo({ + savedObjectsClient: context.unsecuredSavedObjectsClient, + savedObjectsUpdateOptions: { version }, id, - updateAttributes, - updateOptions - ); + updateRuleAttributes: updateMetaAttributes(context, { + ...newAttrs, + updatedBy: await context.getUserName(), + updatedAt: new Date().toISOString(), + }), + }); } diff --git a/x-pack/plugins/alerting/server/data/r_rule/types/r_rule_attributes.ts b/x-pack/plugins/alerting/server/data/r_rule/types/r_rule_attributes.ts index e29bc5c7ab7e2..54b2547a71b00 100644 --- a/x-pack/plugins/alerting/server/data/r_rule/types/r_rule_attributes.ts +++ b/x-pack/plugins/alerting/server/data/r_rule/types/r_rule_attributes.ts @@ -20,10 +20,10 @@ export interface RRuleAttributes { byweekday?: Array; bymonth?: number[]; bysetpos?: number[]; - bymonthday: number[]; - byyearday: number[]; - byweekno: number[]; - byhour: number[]; - byminute: number[]; - bysecond: number[]; + bymonthday?: number[]; + byyearday?: number[]; + byweekno?: number[]; + byhour?: number[]; + byminute?: number[]; + bysecond?: number[]; } diff --git a/x-pack/plugins/alerting/server/data/rule/index.ts b/x-pack/plugins/alerting/server/data/rule/index.ts index f926adc23f39c..e61b182b92090 100644 --- a/x-pack/plugins/alerting/server/data/rule/index.ts +++ b/x-pack/plugins/alerting/server/data/rule/index.ts @@ -17,5 +17,9 @@ export { bulkCreateRulesSo } from './methods/bulk_create_rule_so'; export type { BulkCreateRulesSoParams } from './methods/bulk_create_rule_so'; export { bulkDeleteRulesSo } from './methods/bulk_delete_rules_so'; export type { BulkDeleteRulesSoParams } from './methods/bulk_delete_rules_so'; +export { resolveRuleSo } from './methods/resolve_rule_so'; +export type { ResolveRuleSoParams } from './methods/resolve_rule_so'; +export { getRuleSo } from './methods/get_rule_so'; +export type { GetRuleSoParams } from './methods/get_rule_so'; export { bulkDisableRulesSo } from './methods/bulk_disable_rules_so'; export type { BulkDisableRulesSoParams } from './methods/bulk_disable_rules_so'; diff --git a/x-pack/plugins/alerting/server/data/rule/methods/get_rule_so.ts b/x-pack/plugins/alerting/server/data/rule/methods/get_rule_so.ts new file mode 100644 index 0000000000000..c8777afef3f78 --- /dev/null +++ b/x-pack/plugins/alerting/server/data/rule/methods/get_rule_so.ts @@ -0,0 +1,22 @@ +/* + * 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 { SavedObjectsClientContract, SavedObject } from '@kbn/core/server'; +import { SavedObjectsGetOptions } from '@kbn/core-saved-objects-api-server'; +import { RuleAttributes } from '../types'; + +export interface GetRuleSoParams { + savedObjectsClient: SavedObjectsClientContract; + id: string; + savedObjectsGetOptions?: SavedObjectsGetOptions; +} + +export const getRuleSo = (params: GetRuleSoParams): Promise> => { + const { savedObjectsClient, id, savedObjectsGetOptions } = params; + + return savedObjectsClient.get('alert', id, savedObjectsGetOptions); +}; diff --git a/x-pack/plugins/alerting/server/data/rule/methods/resolve_rule_so.ts b/x-pack/plugins/alerting/server/data/rule/methods/resolve_rule_so.ts new file mode 100644 index 0000000000000..b8061cc6e3c3c --- /dev/null +++ b/x-pack/plugins/alerting/server/data/rule/methods/resolve_rule_so.ts @@ -0,0 +1,24 @@ +/* + * 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 { SavedObjectsClientContract, SavedObjectsResolveResponse } from '@kbn/core/server'; +import { SavedObjectsResolveOptions } from '@kbn/core-saved-objects-api-server'; +import { RuleAttributes } from '../types'; + +export interface ResolveRuleSoParams { + savedObjectsClient: SavedObjectsClientContract; + id: string; + savedObjectsResolveOptions?: SavedObjectsResolveOptions; +} + +export const resolveRuleSo = ( + params: ResolveRuleSoParams +): Promise> => { + const { savedObjectsClient, id, savedObjectsResolveOptions } = params; + + return savedObjectsClient.resolve('alert', id, savedObjectsResolveOptions); +}; diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index 93c66c45ce2af..d28854fb3ac6a 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -29,7 +29,7 @@ import { getActionErrorLogRoute } from './get_action_error_log'; import { getRuleExecutionKPIRoute } from './get_rule_execution_kpi'; import { getRuleStateRoute } from './get_rule_state'; import { healthRoute } from './health'; -import { resolveRuleRoute } from './resolve_rule'; +import { resolveRuleRoute } from './rule/apis/resolve'; import { ruleTypesRoute } from './rule_types'; import { muteAllRuleRoute } from './mute_all_rule'; import { muteAlertRoute } from './rule/apis/mute_alert/mute_alert'; @@ -37,8 +37,8 @@ import { unmuteAllRuleRoute } from './unmute_all_rule'; import { unmuteAlertRoute } from './unmute_alert'; import { updateRuleApiKeyRoute } from './update_rule_api_key'; import { bulkEditInternalRulesRoute } from './rule/apis/bulk_edit/bulk_edit_rules_route'; -import { snoozeRuleRoute } from './snooze_rule'; -import { unsnoozeRuleRoute } from './unsnooze_rule'; +import { snoozeRuleRoute } from './rule/apis/snooze'; +import { unsnoozeRuleRoute } from './rule/apis/unsnooze'; import { runSoonRoute } from './run_soon'; import { bulkDeleteRulesRoute } from './rule/apis/bulk_delete/bulk_delete_rules_route'; import { bulkEnableRulesRoute } from './bulk_enable_rules'; diff --git a/x-pack/plugins/alerting/server/routes/resolve_rule.ts b/x-pack/plugins/alerting/server/routes/resolve_rule.ts deleted file mode 100644 index e42dd6795f14a..0000000000000 --- a/x-pack/plugins/alerting/server/routes/resolve_rule.ts +++ /dev/null @@ -1,91 +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 { omit } from 'lodash'; -import { schema } from '@kbn/config-schema'; -import { IRouter } from '@kbn/core/server'; -import { ILicenseState } from '../lib'; -import { - verifyAccessAndContext, - RewriteResponseCase, - rewriteRuleLastRun, - rewriteActionsRes, -} from './lib'; -import { - RuleTypeParams, - AlertingRequestHandlerContext, - INTERNAL_BASE_ALERTING_API_PATH, - ResolvedSanitizedRule, -} from '../types'; - -const paramSchema = schema.object({ - id: schema.string(), -}); - -const rewriteBodyRes: RewriteResponseCase> = ({ - alertTypeId, - createdBy, - updatedBy, - createdAt, - updatedAt, - apiKeyOwner, - apiKeyCreatedByUser, - notifyWhen, - muteAll, - mutedInstanceIds, - executionStatus, - actions, - scheduledTaskId, - lastRun, - nextRun, - ...rest -}) => ({ - ...rest, - rule_type_id: alertTypeId, - created_by: createdBy, - updated_by: updatedBy, - created_at: createdAt, - updated_at: updatedAt, - api_key_owner: apiKeyOwner, - notify_when: notifyWhen, - mute_all: muteAll, - muted_alert_ids: mutedInstanceIds, - scheduled_task_id: scheduledTaskId, - execution_status: executionStatus && { - ...omit(executionStatus, 'lastExecutionDate', 'lastDuration'), - last_execution_date: executionStatus.lastExecutionDate, - last_duration: executionStatus.lastDuration, - }, - actions: rewriteActionsRes(actions), - ...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}), - ...(nextRun ? { next_run: nextRun } : {}), - ...(apiKeyCreatedByUser !== undefined ? { api_key_created_by_user: apiKeyCreatedByUser } : {}), -}); - -export const resolveRuleRoute = ( - router: IRouter, - licenseState: ILicenseState -) => { - router.get( - { - path: `${INTERNAL_BASE_ALERTING_API_PATH}/rule/{id}/_resolve`, - validate: { - params: paramSchema, - }, - }, - router.handleLegacyErrors( - verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = (await context.alerting).getRulesClient(); - const { id } = req.params; - const rule = await rulesClient.resolve({ id, includeSnoozeData: true }); - return res.ok({ - body: rewriteBodyRes(rule), - }); - }) - ) - ); -}; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/index.ts new file mode 100644 index 0000000000000..5b8e8120f92f9 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/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 { resolveRuleRoute } from './resolve_rule_route'; diff --git a/x-pack/plugins/alerting/server/routes/resolve_rule.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts similarity index 75% rename from x-pack/plugins/alerting/server/routes/resolve_rule.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts index 273a7ea7fb8aa..e83cd05b02edd 100644 --- a/x-pack/plugins/alerting/server/routes/resolve_rule.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.test.ts @@ -6,17 +6,17 @@ */ import { pick } from 'lodash'; -import { resolveRuleRoute } from './resolve_rule'; +import { resolveRuleRoute } from './resolve_rule_route'; import { httpServiceMock } from '@kbn/core/server/mocks'; -import { licenseStateMock } from '../lib/license_state.mock'; -import { verifyApiAccess } from '../lib/license_api_access'; -import { mockHandlerArguments } from './_mock_handler_arguments'; -import { rulesClientMock } from '../rules_client.mock'; -import { ResolvedSanitizedRule } from '../types'; -import { AsApiContract } from './lib'; +import { licenseStateMock } from '../../../../lib/license_state.mock'; +import { verifyApiAccess } from '../../../../lib/license_api_access'; +import { mockHandlerArguments } from '../../../_mock_handler_arguments'; +import { rulesClientMock } from '../../../../rules_client.mock'; +import { ResolvedRule } from '../../../../application/rule/methods/resolve/types'; +import { ResolvedSanitizedRule } from '../../../../../common'; const rulesClient = rulesClientMock.create(); -jest.mock('../lib/license_api_access', () => ({ +jest.mock('../../../../lib/license_api_access', () => ({ verifyApiAccess: jest.fn(), })); @@ -25,7 +25,7 @@ beforeEach(() => { }); describe('resolveRuleRoute', () => { - const mockedRule: ResolvedSanitizedRule<{ + const mockedRule: ResolvedRule<{ bar: boolean; }> = { id: '1', @@ -67,7 +67,7 @@ describe('resolveRuleRoute', () => { revision: 0, }; - const resolveResult: AsApiContract> = { + const resolveResult = { ...pick( mockedRule, 'consumer', @@ -86,13 +86,13 @@ describe('resolveRuleRoute', () => { updated_by: mockedRule.updatedBy, api_key_owner: mockedRule.apiKeyOwner, muted_alert_ids: mockedRule.mutedInstanceIds, - created_at: mockedRule.createdAt, - updated_at: mockedRule.updatedAt, + created_at: mockedRule.createdAt.toISOString(), + updated_at: mockedRule.updatedAt.toISOString(), id: mockedRule.id, revision: mockedRule.revision, execution_status: { status: mockedRule.executionStatus.status, - last_execution_date: mockedRule.executionStatus.lastExecutionDate, + last_execution_date: mockedRule.executionStatus.lastExecutionDate.toISOString(), }, actions: [ { @@ -115,7 +115,9 @@ describe('resolveRuleRoute', () => { expect(config.path).toMatchInlineSnapshot(`"/internal/alerting/rule/{id}/_resolve"`); - rulesClient.resolve.mockResolvedValueOnce(mockedRule); + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + rulesClient.resolve.mockResolvedValueOnce(mockedRule as ResolvedSanitizedRule); const [context, req, res] = mockHandlerArguments( { rulesClient }, @@ -142,7 +144,9 @@ describe('resolveRuleRoute', () => { const [, handler] = router.get.mock.calls[0]; - rulesClient.resolve.mockResolvedValueOnce(mockedRule); + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + rulesClient.resolve.mockResolvedValueOnce(mockedRule as ResolvedSanitizedRule); const [context, req, res] = mockHandlerArguments( { rulesClient }, @@ -169,7 +173,9 @@ describe('resolveRuleRoute', () => { const [, handler] = router.get.mock.calls[0]; - rulesClient.resolve.mockResolvedValueOnce(mockedRule); + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + rulesClient.resolve.mockResolvedValueOnce(mockedRule as ResolvedSanitizedRule); const [context, req, res] = mockHandlerArguments( { rulesClient }, diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.ts new file mode 100644 index 0000000000000..2e6f016b5f6ac --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/resolve_rule_route.ts @@ -0,0 +1,52 @@ +/* + * 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 { IRouter } from '@kbn/core/server'; +import { RuleParamsV1 } from '../../../../../common/routes/rule/response'; +import { ResolvedRule } from '../../../../application/rule/methods/resolve/types'; +import { + resolveParamsSchemaV1, + ResolveRuleResponseV1, +} from '../../../../../common/routes/rule/apis/resolve'; +import { ILicenseState } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../../../../types'; +import { transformResolveResponseV1 } from './transforms'; + +export type ResolveRuleRequestParamsV1 = TypeOf; + +export const resolveRuleRoute = ( + router: IRouter, + licenseState: ILicenseState +) => { + router.get( + { + path: `${INTERNAL_BASE_ALERTING_API_PATH}/rule/{id}/_resolve`, + validate: { + params: resolveParamsSchemaV1, + }, + }, + router.handleLegacyErrors( + verifyAccessAndContext(licenseState, async function (context, req, res) { + const rulesClient = (await context.alerting).getRulesClient(); + const params: ResolveRuleRequestParamsV1 = req.params; + const { id } = params; + // TODO (http-versioning): Remove this cast, this enables us to move forward + // without fixing all of other solution types + const rule = (await rulesClient.resolve({ + id, + includeSnoozeData: true, + })) as ResolvedRule; + const response: ResolveRuleResponseV1 = { + body: transformResolveResponseV1(rule), + }; + return res.ok(response); + }) + ) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/index.ts new file mode 100644 index 0000000000000..bda58b81a7238 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/index.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. + */ + +export { transformResolveResponse } from './transform_resolve_response/latest'; + +export { transformResolveResponse as transformResolveResponseV1 } from './transform_resolve_response/v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/transform_resolve_response/latest.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/transform_resolve_response/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/transform_resolve_response/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/server/routes/rule/apis/resolve/transforms/transform_resolve_response/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/transform_resolve_response/v1.ts new file mode 100644 index 0000000000000..060f6892403f4 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/resolve/transforms/transform_resolve_response/v1.ts @@ -0,0 +1,18 @@ +/* + * 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 { ResolvedRule } from '../../../../../../application/rule/methods/resolve/types'; +import { RuleParams } from '../../../../../../application/rule/types'; +import { transformRuleToRuleResponseV1 } from '../../../../transforms'; + +export const transformResolveResponse = ( + rule: ResolvedRule +) => ({ + ...transformRuleToRuleResponseV1(rule), + outcome: rule.outcome, + alias_target_id: rule.alias_target_id, +}); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/snooze/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/index.ts new file mode 100644 index 0000000000000..2554a9040c650 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/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 { snoozeRuleRoute } from './snooze_rule_route'; diff --git a/x-pack/plugins/alerting/server/routes/snooze_rule.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.test.ts similarity index 90% rename from x-pack/plugins/alerting/server/routes/snooze_rule.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.test.ts index ab24103672521..51d1b9a23cda8 100644 --- a/x-pack/plugins/alerting/server/routes/snooze_rule.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.test.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { snoozeRuleRoute } from './snooze_rule'; +import { snoozeRuleRoute } from './snooze_rule_route'; 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/snooze_rule.ts b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.ts similarity index 52% rename from x-pack/plugins/alerting/server/routes/snooze_rule.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.ts index 1ffac168fcd00..93b619b50d82c 100644 --- a/x-pack/plugins/alerting/server/routes/snooze_rule.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/snooze_rule_route.ts @@ -5,36 +5,18 @@ * 2.0. */ +import { TypeOf } from '@kbn/config-schema'; import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState, RuleMutedError } from '../lib'; -import { verifyAccessAndContext, rRuleSchema } from './lib'; -import { SnoozeOptions } from '../rules_client'; -import { AlertingRequestHandlerContext, INTERNAL_ALERTING_SNOOZE_RULE } from '../types'; -import { validateSnoozeSchedule } from '../lib/validate_snooze_schedule'; +import { + snoozeBodySchema, + snoozeParamsSchema, +} from '../../../../../common/routes/rule/apis/snooze'; +import { ILicenseState, RuleMutedError } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; +import { AlertingRequestHandlerContext, INTERNAL_ALERTING_SNOOZE_RULE } from '../../../../types'; +import { transformSnoozeBodyV1 } from './transforms'; -const paramSchema = schema.object({ - id: schema.string(), -}); - -export const snoozeScheduleSchema = schema.object( - { - id: schema.maybe(schema.string()), - duration: schema.number(), - rRule: rRuleSchema, - }, - { validate: validateSnoozeSchedule } -); - -const bodySchema = schema.object({ - snooze_schedule: snoozeScheduleSchema, -}); - -const rewriteBodyReq: (opts: { - snooze_schedule: SnoozeOptions['snoozeSchedule']; -}) => SnoozeOptions = ({ snooze_schedule: snoozeSchedule }) => ({ - snoozeSchedule, -}); +export type SnoozeRuleRequestParamsV1 = TypeOf; export const snoozeRuleRoute = ( router: IRouter, @@ -44,15 +26,15 @@ export const snoozeRuleRoute = ( { path: INTERNAL_ALERTING_SNOOZE_RULE, validate: { - params: paramSchema, - body: bodySchema, + params: snoozeParamsSchema, + body: snoozeBodySchema, }, }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { const rulesClient = (await context.alerting).getRulesClient(); - const params = req.params; - const body = rewriteBodyReq(req.body); + const params: SnoozeRuleRequestParamsV1 = req.params; + const body = transformSnoozeBodyV1(req.body); try { await rulesClient.snooze({ ...params, ...body }); return res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/index.ts new file mode 100644 index 0000000000000..fce05888d26fa --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/index.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. + */ + +export { transformSnoozeBody } from './transform_snooze_body/latest'; + +export { transformSnoozeBody as transformSnoozeBodyV1 } from './transform_snooze_body/v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/transform_snooze_body/latest.ts b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/transform_snooze_body/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/transform_snooze_body/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/server/routes/rule/apis/snooze/transforms/transform_snooze_body/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/transform_snooze_body/v1.ts new file mode 100644 index 0000000000000..ff7c890ef9cbd --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/snooze/transforms/transform_snooze_body/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 { TypeOf } from '@kbn/config-schema'; +import { snoozeBodySchemaV1 } from '../../../../../../../common/routes/rule/apis/snooze'; + +type SnoozeBodySchema = TypeOf; + +export const transformSnoozeBody: (opts: SnoozeBodySchema) => { + snoozeSchedule: SnoozeBodySchema['snooze_schedule']; +} = ({ snooze_schedule: snoozeSchedule }) => ({ + snoozeSchedule, +}); diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/index.ts new file mode 100644 index 0000000000000..5702c1a2da283 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/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 { unsnoozeRuleRoute } from './unsnooze_rule_route'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/index.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/index.ts new file mode 100644 index 0000000000000..1ebc46c14819e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/index.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. + */ + +export { transformUnsnoozeBody } from './transform_unsnooze_body/latest'; + +export { transformUnsnoozeBody as transformUnsnoozeBodyV1 } from './transform_unsnooze_body/v1'; diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/transform_unsnooze_body/latest.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/transform_unsnooze_body/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/transform_unsnooze_body/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/server/routes/rule/apis/unsnooze/transforms/transform_unsnooze_body/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/transform_unsnooze_body/v1.ts new file mode 100644 index 0000000000000..bbaa37cf81f3b --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/transforms/transform_unsnooze_body/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. + */ + +export const transformUnsnoozeBody: (opts: { schedule_ids?: string[] }) => { + scheduleIds?: string[]; +} = ({ schedule_ids: scheduleIds }) => (scheduleIds ? { scheduleIds } : {}); diff --git a/x-pack/plugins/alerting/server/routes/unsnooze_rule.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.test.ts similarity index 83% rename from x-pack/plugins/alerting/server/routes/unsnooze_rule.test.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.test.ts index 12a4c250bef1d..1d69b00eb8486 100644 --- a/x-pack/plugins/alerting/server/routes/unsnooze_rule.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.test.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { unsnoozeRuleRoute } from './unsnooze_rule'; +import { unsnoozeRuleRoute } from './unsnooze_rule_route'; 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/unsnooze_rule.ts b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.ts similarity index 60% rename from x-pack/plugins/alerting/server/routes/unsnooze_rule.ts rename to x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.ts index 5efea85c93ec1..e37b5c0217f0a 100644 --- a/x-pack/plugins/alerting/server/routes/unsnooze_rule.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/unsnooze/unsnooze_rule_route.ts @@ -5,25 +5,18 @@ * 2.0. */ +import { TypeOf } from '@kbn/config-schema'; import { IRouter } from '@kbn/core/server'; -import { schema } from '@kbn/config-schema'; -import { ILicenseState, RuleMutedError } from '../lib'; -import { verifyAccessAndContext, RewriteRequestCase } from './lib'; -import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types'; +import { + unsnoozeBodySchema, + unsnoozeParamsSchema, +} from '../../../../../common/routes/rule/apis/unsnooze'; +import { ILicenseState, RuleMutedError } from '../../../../lib'; +import { verifyAccessAndContext } from '../../../lib'; +import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../../../../types'; +import { transformUnsnoozeBodyV1 } from './transforms'; -const paramSchema = schema.object({ - id: schema.string(), -}); - -export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); - -const bodySchema = schema.object({ - schedule_ids: scheduleIdsSchema, -}); - -const rewriteBodyReq: RewriteRequestCase<{ scheduleIds?: string[] }> = ({ - schedule_ids: scheduleIds, -}) => (scheduleIds ? { scheduleIds } : {}); +export type UnsnoozeRuleRequestParamsV1 = TypeOf; export const unsnoozeRuleRoute = ( router: IRouter, @@ -33,15 +26,15 @@ export const unsnoozeRuleRoute = ( { path: `${INTERNAL_BASE_ALERTING_API_PATH}/rule/{id}/_unsnooze`, validate: { - params: paramSchema, - body: bodySchema, + params: unsnoozeParamsSchema, + body: unsnoozeBodySchema, }, }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { const rulesClient = (await context.alerting).getRulesClient(); - const params = req.params; - const body = rewriteBodyReq(req.body); + const params: UnsnoozeRuleRequestParamsV1 = req.params; + const body = transformUnsnoozeBodyV1(req.body); try { await rulesClient.unsnooze({ ...params, ...body }); return res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts b/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts index e43427fe4470a..74508cec9a640 100644 --- a/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts @@ -82,6 +82,7 @@ export const transformRuleToRuleResponse = ( mute_all: rule.muteAll, ...(rule.notifyWhen !== undefined ? { notify_when: rule.notifyWhen } : {}), muted_alert_ids: rule.mutedInstanceIds, + ...(rule.scheduledTaskId !== undefined ? { scheduled_task_id: rule.scheduledTaskId } : {}), execution_status: { status: rule.executionStatus.status, ...(rule.executionStatus.error ? { error: rule.executionStatus.error } : {}), diff --git a/x-pack/plugins/alerting/server/rules_client/common/snooze_utils.ts b/x-pack/plugins/alerting/server/rules_client/common/snooze_utils.ts index edf61427b8339..1f8cf501f7868 100644 --- a/x-pack/plugins/alerting/server/rules_client/common/snooze_utils.ts +++ b/x-pack/plugins/alerting/server/rules_client/common/snooze_utils.ts @@ -6,18 +6,19 @@ */ import { i18n } from '@kbn/i18n'; -import { RawRule, RuleSnoozeSchedule } from '../../types'; import { + Rule, RuleDomain, RuleParams, RuleSnoozeSchedule as RuleDomainSnoozeSchedule, } from '../../application/rule/types'; +import { RuleAttributes } from '../../data/rule/types'; import { getActiveScheduledSnoozes } from '../../lib/is_rule_snoozed'; -/** - * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types - */ -export function getSnoozeAttributes(attributes: RawRule, snoozeSchedule: RuleSnoozeSchedule) { +export function getSnoozeAttributes( + attributes: RuleAttributes, + snoozeSchedule: RuleDomainSnoozeSchedule +) { // If duration is -1, instead mute all const { id: snoozeId, duration } = snoozeSchedule; @@ -69,10 +70,7 @@ export function getBulkSnooze( }; } -/** - * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types - */ -export function getUnsnoozeAttributes(attributes: RawRule, scheduleIds?: string[]) { +export function getUnsnoozeAttributes(attributes: RuleAttributes, scheduleIds?: string[]) { const snoozeSchedule = scheduleIds ? clearScheduledSnoozesAttributesById(attributes, scheduleIds) : clearCurrentActiveSnoozeAttributes(attributes); @@ -106,10 +104,7 @@ export function getBulkUnsnooze( }; } -/** - * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types - */ -export function clearUnscheduledSnoozeAttributes(attributes: RawRule) { +export function clearUnscheduledSnoozeAttributes(attributes: RuleAttributes) { // Clear any snoozes that have no ID property. These are "simple" snoozes created with the quick UI, e.g. snooze for 3 days starting now return attributes.snoozeSchedule ? attributes.snoozeSchedule.filter((s) => typeof s.id !== 'undefined') @@ -120,10 +115,7 @@ export function clearUnscheduledSnooze(rule: RuleDoma return rule.snoozeSchedule ? rule.snoozeSchedule.filter((s) => typeof s.id !== 'undefined') : []; } -/** - * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types - */ -export function clearScheduledSnoozesAttributesById(attributes: RawRule, ids: string[]) { +export function clearScheduledSnoozesAttributesById(attributes: RuleAttributes, ids: string[]) { return attributes.snoozeSchedule ? attributes.snoozeSchedule.filter((s) => s.id && !ids.includes(s.id)) : []; @@ -136,10 +128,7 @@ export function clearScheduledSnoozesById( return rule.snoozeSchedule ? rule.snoozeSchedule.filter((s) => s.id && !ids.includes(s.id)) : []; } -/** - * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types - */ -export function clearCurrentActiveSnoozeAttributes(attributes: RawRule) { +export function clearCurrentActiveSnoozeAttributes(attributes: RuleAttributes) { // First attempt to cancel a simple (unscheduled) snooze const clearedUnscheduledSnoozes = clearUnscheduledSnoozeAttributes(attributes); // Now clear any scheduled snoozes that are currently active and never recur @@ -193,10 +182,7 @@ export function clearCurrentActiveSnooze(rule: RuleDo return clearedSnoozesAndSkippedRecurringSnoozes; } -/** - * @deprecated TODO (http-versioning): Deprecate this once we fix all RawRule types - */ -export function verifySnoozeAttributeScheduleLimit(attributes: Partial) { +export function verifySnoozeAttributeScheduleLimit(attributes: Partial) { const schedules = attributes.snoozeSchedule?.filter((snooze) => snooze.id); if (schedules && schedules.length > 5) { throw Error( diff --git a/x-pack/plugins/alerting/server/rules_client/lib/get_alert_from_raw.ts b/x-pack/plugins/alerting/server/rules_client/lib/get_alert_from_raw.ts index 2b4dbce71f76a..ddf1e40728b28 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/get_alert_from_raw.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/get_alert_from_raw.ts @@ -37,6 +37,9 @@ export interface GetAlertFromRawParams { omitGeneratedValues?: boolean; } +/** + * @deprecated in favor of transformRuleAttributesToRuleDomain + */ export function getAlertFromRaw( context: RulesClientContext, id: string, diff --git a/x-pack/plugins/alerting/server/rules_client/lib/get_rule_saved_object.ts b/x-pack/plugins/alerting/server/rules_client/lib/get_rule_saved_object.ts new file mode 100644 index 0000000000000..43e0344e259fd --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/lib/get_rule_saved_object.ts @@ -0,0 +1,39 @@ +/* + * 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 { SavedObject } from '@kbn/core/server'; +import { withSpan } from '@kbn/apm-utils'; +import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; +import { RulesClientContext } from '../types'; +import { getRuleSo } from '../../data/rule'; +import { RuleAttributes } from '../../data/rule/types'; + +interface GetRuleSavedObjectParams { + ruleId: string; +} + +export async function getRuleSavedObject( + context: RulesClientContext, + params: GetRuleSavedObjectParams +): Promise> { + const { ruleId } = params; + + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.GET, + outcome: 'unknown', + savedObject: { type: 'alert', id: ruleId }, + }) + ); + + return await withSpan({ name: 'unsecuredSavedObjectsClient.get', type: 'rules' }, () => + getRuleSo({ + id: ruleId, + savedObjectsClient: context.unsecuredSavedObjectsClient, + }) + ); +} diff --git a/x-pack/plugins/alerting/server/rules_client/lib/index.ts b/x-pack/plugins/alerting/server/rules_client/lib/index.ts index ab1f33df01c10..ede7c3034a7f2 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/index.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/index.ts @@ -6,9 +6,13 @@ */ export { createRuleSavedObject } from './create_rule_saved_object'; +export { resolveRuleSavedObject } from './resolve_rule_saved_object'; +export { getRuleSavedObject } from './get_rule_saved_object'; + export { extractReferences } from './extract_references'; export { validateActions } from './validate_actions'; export { updateMeta } from './update_meta'; +export { updateMetaAttributes } from './update_meta_attributes'; export * from './get_alert_from_raw'; export { getAuthorizationFilter } from './get_authorization_filter'; export { checkAuthorizationAndGetTotal } from './check_authorization_and_get_total'; diff --git a/x-pack/plugins/alerting/server/rules_client/lib/resolve_rule_saved_object.ts b/x-pack/plugins/alerting/server/rules_client/lib/resolve_rule_saved_object.ts new file mode 100644 index 0000000000000..101f846ae9ba9 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/lib/resolve_rule_saved_object.ts @@ -0,0 +1,39 @@ +/* + * 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 { SavedObjectsResolveResponse } from '@kbn/core/server'; +import { withSpan } from '@kbn/apm-utils'; +import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; +import { RulesClientContext } from '../types'; +import { resolveRuleSo } from '../../data/rule'; +import { RuleAttributes } from '../../data/rule/types'; + +interface ResolveRuleSavedObjectParams { + ruleId: string; +} + +export async function resolveRuleSavedObject( + context: RulesClientContext, + params: ResolveRuleSavedObjectParams +): Promise> { + const { ruleId } = params; + + context.auditLogger?.log( + ruleAuditEvent({ + action: RuleAuditAction.RESOLVE, + outcome: 'unknown', + savedObject: { type: 'alert', id: ruleId }, + }) + ); + + return await withSpan({ name: 'unsecuredSavedObjectsClient.resolve', type: 'rules' }, () => + resolveRuleSo({ + id: ruleId, + savedObjectsClient: context.unsecuredSavedObjectsClient, + }) + ); +} diff --git a/x-pack/plugins/alerting/server/rules_client/lib/update_meta.ts b/x-pack/plugins/alerting/server/rules_client/lib/update_meta.ts index 5fbe2b275f077..278a6ac267df5 100644 --- a/x-pack/plugins/alerting/server/rules_client/lib/update_meta.ts +++ b/x-pack/plugins/alerting/server/rules_client/lib/update_meta.ts @@ -8,6 +8,9 @@ import { RawRule } from '../../types'; import { RulesClientContext } from '../types'; +/** + * @deprecated Use updateMetaAttributes instead + */ export function updateMeta>( context: RulesClientContext, alertAttributes: T diff --git a/x-pack/plugins/alerting/server/rules_client/lib/update_meta_attributes.ts b/x-pack/plugins/alerting/server/rules_client/lib/update_meta_attributes.ts new file mode 100644 index 0000000000000..716e0a8beacb9 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_client/lib/update_meta_attributes.ts @@ -0,0 +1,25 @@ +/* + * 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 { RuleAttributes } from '../../data/rule/types'; +import { RulesClientContext } from '../types'; + +export function updateMetaAttributes>( + context: RulesClientContext, + alertAttributes: T +): T { + if (alertAttributes.hasOwnProperty('apiKey') || alertAttributes.hasOwnProperty('apiKeyOwner')) { + return { + ...alertAttributes, + meta: { + ...(alertAttributes.meta ?? {}), + versionApiKeyLastmodified: context.kibanaVersion, + }, + }; + } + return alertAttributes; +} diff --git a/x-pack/plugins/alerting/server/rules_client/methods/mute_all.ts b/x-pack/plugins/alerting/server/rules_client/methods/mute_all.ts index ca5584da706a7..72a693aace7ac 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/mute_all.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/mute_all.ts @@ -11,8 +11,9 @@ import { retryIfConflicts } from '../../lib/retry_if_conflicts'; import { partiallyUpdateAlert } from '../../saved_objects'; import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; import { RulesClientContext } from '../types'; -import { updateMeta } from '../lib'; +import { updateMetaAttributes } from '../lib'; import { clearUnscheduledSnoozeAttributes } from '../common'; +import { RuleAttributes } from '../../data/rule/types'; export async function muteAll(context: RulesClientContext, { id }: { id: string }): Promise { return await retryIfConflicts( @@ -60,10 +61,10 @@ async function muteAllWithOCC(context: RulesClientContext, { id }: { id: string context.ruleTypeRegistry.ensureRuleTypeEnabled(attributes.alertTypeId); - const updateAttributes = updateMeta(context, { + const updateAttributes = updateMetaAttributes(context, { muteAll: true, mutedInstanceIds: [], - snoozeSchedule: clearUnscheduledSnoozeAttributes(attributes), + snoozeSchedule: clearUnscheduledSnoozeAttributes(attributes as RuleAttributes), updatedBy: await context.getUserName(), updatedAt: new Date().toISOString(), }); diff --git a/x-pack/plugins/alerting/server/rules_client/methods/resolve.ts b/x-pack/plugins/alerting/server/rules_client/methods/resolve.ts deleted file mode 100644 index a663b9aac56d1..0000000000000 --- a/x-pack/plugins/alerting/server/rules_client/methods/resolve.ts +++ /dev/null @@ -1,81 +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 { AlertConsumers } from '@kbn/rule-data-utils'; - -import { RawRule, RuleTypeParams, ResolvedSanitizedRule } from '../../types'; -import { ReadOperations, AlertingAuthorizationEntity } from '../../authorization'; -import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; -import { getAlertFromRaw } from '../lib/get_alert_from_raw'; -import { RulesClientContext } from '../types'; -import { formatLegacyActions } from '../lib'; - -export interface ResolveParams { - id: string; - includeLegacyId?: boolean; - includeSnoozeData?: boolean; -} - -export async function resolve( - context: RulesClientContext, - { id, includeLegacyId, includeSnoozeData = false }: ResolveParams -): Promise> { - const { saved_object: result, ...resolveResponse } = - await context.unsecuredSavedObjectsClient.resolve('alert', id); - try { - await context.authorization.ensureAuthorized({ - ruleTypeId: result.attributes.alertTypeId, - consumer: result.attributes.consumer, - operation: ReadOperations.Get, - entity: AlertingAuthorizationEntity.Rule, - }); - } catch (error) { - context.auditLogger?.log( - ruleAuditEvent({ - action: RuleAuditAction.RESOLVE, - savedObject: { type: 'alert', id }, - error, - }) - ); - throw error; - } - context.auditLogger?.log( - ruleAuditEvent({ - action: RuleAuditAction.RESOLVE, - savedObject: { type: 'alert', id }, - }) - ); - - const rule = getAlertFromRaw( - context, - result.id, - result.attributes.alertTypeId, - result.attributes, - result.references, - includeLegacyId, - false, - includeSnoozeData - ); - - // format legacy actions for SIEM rules - if (result.attributes.consumer === AlertConsumers.SIEM) { - const [migratedRule] = await formatLegacyActions([rule], { - savedObjectsClient: context.unsecuredSavedObjectsClient, - logger: context.logger, - }); - - return { - ...migratedRule, - ...resolveResponse, - }; - } - - return { - ...rule, - ...resolveResponse, - }; -} diff --git a/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts b/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts index e69f09a219700..52403e2d8f70e 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/unmute_all.ts @@ -11,8 +11,9 @@ import { retryIfConflicts } from '../../lib/retry_if_conflicts'; import { partiallyUpdateAlert } from '../../saved_objects'; import { ruleAuditEvent, RuleAuditAction } from '../common/audit_events'; import { RulesClientContext } from '../types'; -import { updateMeta } from '../lib'; +import { updateMetaAttributes } from '../lib'; import { clearUnscheduledSnoozeAttributes } from '../common'; +import { RuleAttributes } from '../../data/rule/types'; export async function unmuteAll( context: RulesClientContext, @@ -63,10 +64,10 @@ async function unmuteAllWithOCC(context: RulesClientContext, { id }: { id: strin context.ruleTypeRegistry.ensureRuleTypeEnabled(attributes.alertTypeId); - const updateAttributes = updateMeta(context, { + const updateAttributes = updateMetaAttributes(context, { muteAll: false, mutedInstanceIds: [], - snoozeSchedule: clearUnscheduledSnoozeAttributes(attributes), + snoozeSchedule: clearUnscheduledSnoozeAttributes(attributes as RuleAttributes), updatedBy: await context.getUserName(), updatedAt: new Date().toISOString(), }); 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 12212b772ce71..0a2da42d7e424 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -12,8 +12,10 @@ import { parseDuration } from '../../common/parse_duration'; import { RulesClientContext, BulkOptions } from './types'; import { clone, CloneArguments } from './methods/clone'; import { createRule, CreateRuleParams } from '../application/rule/methods/create'; +import { snoozeRule, SnoozeRuleOptions } from '../application/rule/methods/snooze'; +import { unsnoozeRule, UnsnoozeParams } from '../application/rule/methods/unsnooze'; import { get, GetParams } from './methods/get'; -import { resolve, ResolveParams } from './methods/resolve'; +import { resolveRule, ResolveParams } from '../application/rule/methods/resolve'; import { getAlertState, GetAlertStateParams } from './methods/get_alert_state'; import { getAlertSummary, GetAlertSummaryParams } from './methods/get_alert_summary'; import { @@ -54,8 +56,6 @@ import { bulkEnableRules } from './methods/bulk_enable'; import { updateApiKey } from './methods/update_api_key'; import { enable } from './methods/enable'; 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'; @@ -130,7 +130,7 @@ export class RulesClient { public get = (params: GetParams) => get(this.context, params); public resolve = (params: ResolveParams) => - resolve(this.context, params); + resolveRule(this.context, params); public update = (params: UpdateOptions) => update(this.context, params); @@ -162,8 +162,8 @@ export class RulesClient { public enable = (options: { id: string }) => enable(this.context, options); public disable = (options: { id: string }) => disable(this.context, options); - public snooze = (options: SnoozeParams) => snooze(this.context, options); - public unsnooze = (options: UnsnoozeParams) => unsnooze(this.context, options); + public snooze = (options: SnoozeRuleOptions) => snoozeRule(this.context, options); + public unsnooze = (options: UnsnoozeParams) => unsnoozeRule(this.context, options); public clearExpiredSnoozes = (options: { rule: Pick, 'id' | 'snoozeSchedule'>; diff --git a/x-pack/plugins/alerting/server/rules_client/tests/resolve.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/resolve.test.ts index 0cf9e792cc1bf..70c6388c41ff4 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/resolve.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/resolve.test.ts @@ -96,6 +96,11 @@ describe('resolve()', () => { }, ], notifyWhen: 'onActiveAlert', + executionStatus: { + status: 'ok', + last_execution_date: new Date().toISOString(), + last_duration: 10, + }, }, references: [ { @@ -123,82 +128,11 @@ describe('resolve()', () => { "alertTypeId": "123", "alias_target_id": "2", "createdAt": 2019-02-12T21:01:22.479Z, - "id": "1", - "notifyWhen": "onActiveAlert", - "outcome": "aliasMatch", - "params": Object { - "bar": true, + "executionStatus": Object { + "lastExecutionDate": 2019-02-12T21:01:22.479Z, + "status": "ok", }, - "schedule": Object { - "interval": "10s", - }, - "snoozeSchedule": Array [], - "updatedAt": 2019-02-12T21:01:22.479Z, - } - `); - expect(unsecuredSavedObjectsClient.resolve).toHaveBeenCalledTimes(1); - expect(unsecuredSavedObjectsClient.resolve.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alert", - "1", - ] - `); - }); - - test('calls saved objects client with id and includeLegacyId params', async () => { - const rulesClient = new RulesClient(rulesClientParams); - unsecuredSavedObjectsClient.resolve.mockResolvedValueOnce({ - saved_object: { - id: '1', - type: 'alert', - attributes: { - legacyId: 'some-legacy-id', - alertTypeId: '123', - schedule: { interval: '10s' }, - params: { - bar: true, - }, - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - actions: [ - { - group: 'default', - actionRef: 'action_0', - params: { - foo: true, - }, - }, - ], - notifyWhen: 'onActiveAlert', - }, - references: [ - { - name: 'action_0', - type: 'action', - id: '1', - }, - ], - }, - outcome: 'aliasMatch', - alias_target_id: '2', - }); - const result = await rulesClient.resolve({ id: '1', includeLegacyId: true }); - expect(result).toMatchInlineSnapshot(` - Object { - "actions": Array [ - Object { - "group": "default", - "id": "1", - "params": Object { - "foo": true, - }, - }, - ], - "alertTypeId": "123", - "alias_target_id": "2", - "createdAt": 2019-02-12T21:01:22.479Z, "id": "1", - "legacyId": "some-legacy-id", "notifyWhen": "onActiveAlert", "outcome": "aliasMatch", "params": Object { @@ -213,11 +147,12 @@ describe('resolve()', () => { `); expect(unsecuredSavedObjectsClient.resolve).toHaveBeenCalledTimes(1); expect(unsecuredSavedObjectsClient.resolve.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - "alert", - "1", - ] - `); + Array [ + "alert", + "1", + undefined, + ] + `); }); test('calls saved objects client with id and includeSnoozeData params', async () => { @@ -256,6 +191,11 @@ describe('resolve()', () => { }, ], notifyWhen: 'onActiveAlert', + executionStatus: { + status: 'ok', + last_execution_date: new Date().toISOString(), + last_duration: 10, + }, }, references: [ { @@ -323,6 +263,11 @@ describe('resolve()', () => { }, ], notifyWhen: 'onActiveAlert', + executionStatus: { + status: 'ok', + last_execution_date: new Date().toISOString(), + last_duration: 10, + }, }, references: [ { @@ -363,6 +308,10 @@ describe('resolve()', () => { "alertTypeId": "123", "alias_target_id": "2", "createdAt": 2019-02-12T21:01:22.479Z, + "executionStatus": Object { + "lastExecutionDate": 2019-02-12T21:01:22.479Z, + "status": "ok", + }, "id": "1", "notifyWhen": "onActiveAlert", "outcome": "aliasMatch", @@ -400,6 +349,11 @@ describe('resolve()', () => { }, }, ], + executionStatus: { + status: 'ok', + last_execution_date: new Date().toISOString(), + last_duration: 10, + }, }, references: [], }, @@ -505,6 +459,11 @@ describe('resolve()', () => { }, }, ], + executionStatus: { + status: 'ok', + last_execution_date: new Date().toISOString(), + last_duration: 10, + }, }, references: [ { @@ -563,6 +522,11 @@ describe('resolve()', () => { bar: true, }, actions: [], + executionStatus: { + status: 'ok', + last_execution_date: new Date().toISOString(), + last_duration: 10, + }, }, references: [], }, @@ -633,6 +597,11 @@ describe('resolve()', () => { }, ], notifyWhen: 'onActiveAlert', + executionStatus: { + status: 'ok', + last_execution_date: new Date().toISOString(), + last_duration: 10, + }, }, references: [ { diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index 26eed5f254bc9..d5e0b331833d5 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -442,6 +442,9 @@ export interface RawRuleExecutionStatus extends SavedObjectAttributes { }; } +/** + * @deprecated in favor of Rule + */ export interface RawRule extends SavedObjectAttributes { enabled: boolean; name: string; diff --git a/x-pack/plugins/alerting/tsconfig.json b/x-pack/plugins/alerting/tsconfig.json index 987ad98b927cf..9eb0b05f7884c 100644 --- a/x-pack/plugins/alerting/tsconfig.json +++ b/x-pack/plugins/alerting/tsconfig.json @@ -59,7 +59,8 @@ "@kbn/serverless", "@kbn/core-http-router-server-mocks", "@kbn/core-elasticsearch-server", - "@kbn/core-application-common" + "@kbn/core-application-common", + "@kbn/core-saved-objects-api-server" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/notify_badge/notify_badge.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/notify_badge/notify_badge.tsx index 8ddb44d0c6c67..e09892471419b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/notify_badge/notify_badge.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/notify_badge/notify_badge.tsx @@ -199,7 +199,6 @@ export const RulesListNotifyBadge: React.FunctionComponent { - // TODO: Implement scheduled snooze button return (