From 14d707376c65efd62aa22bb3fb95c187cb90d25a Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Fri, 28 Mar 2025 14:51:38 +0200 Subject: [PATCH 01/84] new artifact schema, create rule updates --- .../shared/kbn-alerting-types/rule_types.ts | 10 ++ .../rule/methods/create/create_rule.test.ts | 97 +++++++++++++++++++ .../create/schemas/create_rule_data_schema.ts | 2 + .../methods/create/types/create_rule_data.ts | 1 + .../rule/schemas/artifact_schema.ts | 18 ++++ .../server/application/rule/schemas/index.ts | 1 + 6 files changed, 129 insertions(+) create mode 100644 x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts diff --git a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts index 7f330c46f61ee..6d3b33262dca2 100644 --- a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts +++ b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts @@ -215,6 +215,15 @@ export interface Flapping extends SavedObjectAttributes { statusChangeThreshold: number; } +export interface Dashboard extends SavedObjectAttributes { + id: string; +} + +export interface Artifact extends SavedObjectAttributes { + dashboards?: Dashboard[]; + investigation_guide?: string; // TBD if it will be an object or a string +} + export interface Rule { id: string; enabled: boolean; @@ -251,6 +260,7 @@ export interface Rule { viewInAppRelativeUrl?: string; alertDelay?: AlertDelay | null; flapping?: Flapping | null; + artifacts?: Artifact | null; } export type SanitizedRule = Omit< diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts index ab07a488cf427..cdcb6159c0c08 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts @@ -4483,4 +4483,101 @@ describe('create()', () => { ); }); }); + + describe('artifacts', () => { + test('should create a rule with linked dashboards', async () => { + const dashboards = [ + { + id: '1', + }, + { + id: '2', + }, + ]; + + const data = getMockData({ + name: 'my rule name', + actions: [], + artifacts: { + dashboards, + }, + }); + + unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ + id: '1', + type: RULE_SAVED_OBJECT_TYPE, + attributes: { + enabled: false, + name: 'my rule name', + alertTypeId: '123', + schedule: { interval: 10000 }, + params: { + bar: true, + }, + executionStatus: getRuleExecutionStatusPending(now), + running: false, + createdAt: now, + updatedAt: now, + actions: [], + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ], + }, + }, + references: [ + { + id: '1', + name: 'dashboard_0', + type: 'dashboard', + }, + { + id: '2', + name: 'dashboard_1', + type: 'dashboard', + }, + ], + }); + + const result = await rulesClient.create({ data }); + + expect(unsecuredSavedObjectsClient.create).toHaveBeenCalledWith( + RULE_SAVED_OBJECT_TYPE, + expect.objectContaining({ + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ], + }, + }), + { + id: 'mock-saved-object-id', + references: [ + { + id: '1', + name: 'dashboard_0', + type: 'dashboard', + }, + { + id: '2', + name: 'dashboard_1', + type: 'dashboard', + }, + ], + } + ); + + expect(result.artifacts?.dashboards).toEqual(dashboards); + }); + }); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts index e2cf0da359b0a..666b52a08cb96 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts @@ -14,6 +14,7 @@ import { actionRequestSchema, systemActionRequestSchema, flappingSchema, + artifactSchema, } from '../../../schemas'; export const createRuleDataSchema = schema.object( @@ -39,6 +40,7 @@ export const createRuleDataSchema = schema.object( notifyWhen: schema.maybe(schema.nullable(notifyWhenSchema)), alertDelay: schema.maybe(alertDelaySchema), flapping: schema.maybe(schema.nullable(flappingSchema)), + artifacts: schema.maybe(artifactSchema), }, { unknowns: 'allow' } ); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/types/create_rule_data.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/types/create_rule_data.ts index 0fd75188fd6cb..eea1e19ddda1d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/types/create_rule_data.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/types/create_rule_data.ts @@ -25,4 +25,5 @@ export interface CreateRuleData { notifyWhen?: CreateRuleDataType['notifyWhen']; alertDelay?: CreateRuleDataType['alertDelay']; flapping?: CreateRuleDataType['flapping']; + artifacts?: CreateRuleDataType['artifacts']; } diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts new file mode 100644 index 0000000000000..18a3c2c8d50f5 --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.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 dashboardSchema = schema.arrayOf( + schema.object({ + id: schema.string(), + }) +); + +export const artifactSchema = schema.object({ + dashboards: schema.maybe(dashboardSchema), +}); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts index dc0d310f36535..720e3b3333de8 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts @@ -9,3 +9,4 @@ export * from './rule_schemas'; export * from './action_schemas'; export * from './notify_when_schema'; export * from './flapping_schema'; +export * from './artifact_schema'; From b01099ccd18d0c7b76b8de33ca4308beafd94c1e Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Sat, 29 Mar 2025 01:05:39 +0200 Subject: [PATCH 02/84] more updates to create rule schema --- .../routes/rule/apis/create/schemas/v1.ts | 3 ++- .../routes/rule/apis/create/types/v1.ts | 1 + .../common/routes/rule/response/index.ts | 1 + .../common/routes/rule/response/schemas/v1.ts | 8 ++++++++ .../common/routes/rule/response/types/v1.ts | 1 + .../rule/methods/create/create_rule.ts | 3 ++- .../server/application/rule/schemas/index.ts | 1 - .../application/rule/schemas/rule_schemas.ts | 9 +++++++++ ...ransform_rule_attributes_to_rule_domain.ts | 1 + ...ransform_rule_domain_to_rule_attributes.ts | 2 ++ .../server/application/rule/types/rule.ts | 2 ++ .../transforms/transform_create_body/v1.ts | 1 + .../model_versions/rule_model_versions.ts | 8 ++++++++ .../saved_objects/schemas/raw_rule/index.ts | 1 + .../saved_objects/schemas/raw_rule/latest.ts | 3 ++- .../saved_objects/schemas/raw_rule/v5.ts | 20 +++++++++++++++++++ 16 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/schemas/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/schemas/v1.ts index a297ebf15748a..1ccd361e27f4f 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/schemas/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/schemas/v1.ts @@ -11,7 +11,7 @@ import { createRuleParamsExamplesV1, } from '@kbn/response-ops-rule-params'; import { validateDurationV1, validateHoursV1, validateTimezoneV1 } from '../../../validation'; -import { notifyWhenSchemaV1, alertDelaySchemaV1 } from '../../../response'; +import { notifyWhenSchemaV1, alertDelaySchemaV1, artifactSchemaV1 } from '../../../response'; import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; import { flappingSchemaV1 } from '../../../common'; @@ -189,6 +189,7 @@ export const createBodySchema = schema.object({ notify_when: schema.maybe(schema.nullable(notifyWhenSchemaV1)), alert_delay: schema.maybe(alertDelaySchemaV1), flapping: schema.maybe(schema.nullable(flappingSchemaV1)), + artifacts: schema.maybe(artifactSchemaV1), }); export { createRuleParamsExamplesV1 }; diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/types/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/types/v1.ts index 7256a00f45d40..06f5da49b43cb 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/types/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/types/v1.ts @@ -32,6 +32,7 @@ export interface CreateRuleRequestBody { notify_when?: CreateBodySchema['notify_when']; alert_delay?: CreateBodySchema['alert_delay']; flapping?: CreateBodySchema['flapping']; + artifacts?: CreateBodySchema['artifacts']; } export interface CreateRuleResponse { diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/index.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/index.ts index 1c7632ad28988..e2c60ec319190 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/index.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/index.ts @@ -30,6 +30,7 @@ export { notifyWhenSchema as notifyWhenSchemaV1, scheduleIdsSchema as scheduleIdsSchemaV1, alertDelaySchema as alertDelaySchemaV1, + artifactSchema as artifactSchemaV1, } from './schemas/v1'; export type { diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts index 754b9a0637458..f49a218f65d1c 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts @@ -475,6 +475,13 @@ export const alertDelaySchema = schema.object( } ); +export const dashboardSchema = schema.arrayOf(schema.object({ id: schema.string() })); + +export const artifactSchema = schema.object({ + dashboards: schema.maybe(dashboardSchema), + investigation_guide: schema.maybe(schema.string()), +}); + export const ruleResponseSchema = schema.object({ id: schema.string({ meta: { @@ -639,6 +646,7 @@ export const ruleResponseSchema = schema.object({ ), alert_delay: schema.maybe(alertDelaySchema), flapping: schema.maybe(schema.nullable(flappingSchemaV1)), + artifacts: schema.maybe(artifactSchema), }); export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts index 8b305195610b6..b6f9aed370892 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts @@ -54,4 +54,5 @@ export interface RuleResponse { view_in_app_relative_url?: RuleResponseSchemaType['view_in_app_relative_url']; alert_delay?: RuleResponseSchemaType['alert_delay']; flapping?: RuleResponseSchemaType['flapping']; + artifacts?: RuleResponseSchemaType['artifacts']; } diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts index a4307499a9fbd..d3d63a12e3cb8 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts @@ -199,6 +199,7 @@ export async function createRule( } = await withSpan({ name: 'extractReferences', type: 'rules' }, () => extractReferences(context, ruleType, allActions, validatedRuleTypeParams) ); + // TODO update extractReferences const createTime = Date.now(); const lastRunTimestamp = new Date(); @@ -209,7 +210,7 @@ export async function createRule( const { systemActions, actions: actionToNotUse, ...restData } = data; // Convert domain rule object to ES rule attributes const ruleAttributes = transformRuleDomainToRuleAttributes({ - actionsWithRefs, + actionsWithRefs, // TODO add dashboards with refs rule: { ...restData, // TODO (http-versioning) create a rule domain version of this function diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts index 720e3b3333de8..dc0d310f36535 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts @@ -9,4 +9,3 @@ export * from './rule_schemas'; export * from './action_schemas'; export * from './notify_when_schema'; export * from './flapping_schema'; -export * from './artifact_schema'; diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts index 134f6f2ff896a..4090dcfdbcf09 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts @@ -149,6 +149,13 @@ export const alertDelaySchema = schema.object({ active: schema.number(), }); +export const dashboardSchema = schema.arrayOf(schema.object({ id: schema.string() })); + +export const artifactSchema = schema.object({ + dashboards: schema.maybe(dashboardSchema), + investigation_guide: schema.maybe(schema.string()), +}); + /** * Unsanitized (domain) rule schema, used by internal rules clients */ @@ -189,6 +196,7 @@ export const ruleDomainSchema = schema.object({ alertDelay: schema.maybe(alertDelaySchema), legacyId: schema.maybe(schema.nullable(schema.string())), flapping: schema.maybe(schema.nullable(flappingSchema)), + artifacts: schema.maybe(artifactSchema), }); /** @@ -230,4 +238,5 @@ export const ruleSchema = schema.object({ alertDelay: schema.maybe(alertDelaySchema), legacyId: schema.maybe(schema.nullable(schema.string())), flapping: schema.maybe(schema.nullable(flappingSchema)), + artifacts: schema.maybe(artifactSchema), }); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts index afb0e76bc8526..d8f9940d36168 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts @@ -234,6 +234,7 @@ export const transformRuleAttributesToRuleDomain = { alertDelay?: RuleSchemaType['alertDelay']; legacyId?: RuleSchemaType['legacyId']; flapping?: RuleSchemaType['flapping']; + artifacts?: RuleSchemaType['artifacts']; } export interface RuleDomain { @@ -124,4 +125,5 @@ export interface RuleDomain { alertDelay?: RuleSchemaType['alertDelay']; legacyId?: RuleSchemaType['legacyId']; flapping?: RuleSchemaType['flapping']; + artifacts?: RuleDomainSchemaType['artifacts']; } diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts index d8b646f673a64..f5fcd2bb8c5b2 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts @@ -103,5 +103,6 @@ export const transformCreateBody = ({ ...(createBody.flapping !== undefined ? { flapping: transformCreateBodyFlapping(createBody.flapping) } : {}), + artifacts: createBody.artifacts, }; }; diff --git a/x-pack/platform/plugins/shared/alerting/server/saved_objects/model_versions/rule_model_versions.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/model_versions/rule_model_versions.ts index 1d1ce3f6ad828..081c42ce8d455 100644 --- a/x-pack/platform/plugins/shared/alerting/server/saved_objects/model_versions/rule_model_versions.ts +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/model_versions/rule_model_versions.ts @@ -11,6 +11,7 @@ import { rawRuleSchemaV2, rawRuleSchemaV3, rawRuleSchemaV4, + rawRuleSchemaV5, } from '../schemas/raw_rule'; export const ruleModelVersions: SavedObjectsModelVersionMap = { @@ -42,4 +43,11 @@ export const ruleModelVersions: SavedObjectsModelVersionMap = { create: rawRuleSchemaV4, }, }, + '5': { + changes: [], + schemas: { + forwardCompatibility: rawRuleSchemaV4.extends({}, { unknowns: 'ignore' }), + create: rawRuleSchemaV5, + }, + }, }; diff --git a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/index.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/index.ts index 684e813f7f868..10c7d125b0c59 100644 --- a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/index.ts +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/index.ts @@ -11,3 +11,4 @@ export { rawRuleSchema as rawRuleSchemaV1 } from './v1'; export { rawRuleSchema as rawRuleSchemaV2 } from './v2'; export { rawRuleSchema as rawRuleSchemaV3 } from './v3'; export { rawRuleSchema as rawRuleSchemaV4 } from './v4'; +export { rawRuleSchema as rawRuleSchemaV5 } from './v5'; diff --git a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/latest.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/latest.ts index 35d60b9c39ffb..479245944f3b7 100644 --- a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/latest.ts +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/latest.ts @@ -13,7 +13,8 @@ import type { rawRuleLastRunSchema, } from './v3'; -import type { rawRuleMonitoringSchema, rawRuleSchema } from './v4'; +import type { rawRuleMonitoringSchema } from './v4'; +import type { rawRuleSchema } from './v5'; type Mutable = { -readonly [P in keyof T]: T[P] extends object ? Mutable : T[P] }; diff --git a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts new file mode 100644 index 0000000000000..e20e5aebf4ab1 --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts @@ -0,0 +1,20 @@ +/* + * 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 { rawRuleSchema as rawRuleSchemaV4 } from './v4'; + +export const dashboardSchema = schema.arrayOf(schema.object({ id: schema.string() })); + +export const artifactSchema = schema.object({ + dashboards: schema.maybe(dashboardSchema), + investigation_guide: schema.maybe(schema.string()), +}); + +export const rawRuleSchema = rawRuleSchemaV4.extends({ + artifacts: schema.maybe(artifactSchema), +}); From c2db5d8bbe7a8bcc58b1fea2183b974a42542152 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 31 Mar 2025 00:58:28 +0300 Subject: [PATCH 03/84] save artifacts as references in the rule SO during rule creation --- .../plugins/shared/alerting/common/index.ts | 1 + .../common/routes/rule/response/types/v1.ts | 2 +- .../plugins/shared/alerting/common/rule.ts | 1 + .../rule/methods/create/create_rule.ts | 8 ++-- ...ransform_rule_attributes_to_rule_domain.ts | 28 ++++++++++- .../transform_rule_domain_to_rule.ts | 1 + ...ransform_rule_domain_to_rule_attributes.ts | 6 ++- .../server/application/rule/types/rule.ts | 2 +- .../transform_rule_to_rule_response/v1.ts | 2 + .../rules_client/lib/extract_references.ts | 47 +++++++++++++++++-- .../alerting/server/rules_client/types.ts | 10 ++++ .../saved_objects/schemas/raw_rule/v5.ts | 8 +++- .../plugins/shared/alerting/server/types.ts | 2 + 13 files changed, 104 insertions(+), 14 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/common/index.ts b/x-pack/platform/plugins/shared/alerting/common/index.ts index 049516a18590a..ca6668284e84f 100644 --- a/x-pack/platform/plugins/shared/alerting/common/index.ts +++ b/x-pack/platform/plugins/shared/alerting/common/index.ts @@ -45,6 +45,7 @@ export type { RuleSystemActionKey, SanitizedRuleConfig, RuleMonitoringLastRunMetrics, + Artifact, } from './rule'; export { RuleExecutionStatusValues, diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts index b6f9aed370892..c5be4ea5d0bd9 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts @@ -54,5 +54,5 @@ export interface RuleResponse { view_in_app_relative_url?: RuleResponseSchemaType['view_in_app_relative_url']; alert_delay?: RuleResponseSchemaType['alert_delay']; flapping?: RuleResponseSchemaType['flapping']; - artifacts?: RuleResponseSchemaType['artifacts']; + artifacts?: RuleResponseSchemaType['artifacts']; // DO I NEED TO ADD ARTIFACTS HERE? } diff --git a/x-pack/platform/plugins/shared/alerting/common/rule.ts b/x-pack/platform/plugins/shared/alerting/common/rule.ts index 48d972d6a0035..515bd1d73469f 100644 --- a/x-pack/platform/plugins/shared/alerting/common/rule.ts +++ b/x-pack/platform/plugins/shared/alerting/common/rule.ts @@ -45,6 +45,7 @@ export type { AlertsHealth, AlertingFrameworkHealth, ResolvedSanitizedRule, + Artifact, } from '@kbn/alerting-types'; export { diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts index d3d63a12e3cb8..77a77d92975db 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts @@ -196,10 +196,10 @@ export async function createRule( references, params: updatedParams, actions: actionsWithRefs, + artifacts: artifactsWithRefs, } = await withSpan({ name: 'extractReferences', type: 'rules' }, () => - extractReferences(context, ruleType, allActions, validatedRuleTypeParams) + extractReferences(context, ruleType, allActions, validatedRuleTypeParams, initialData.artifacts) ); - // TODO update extractReferences const createTime = Date.now(); const lastRunTimestamp = new Date(); @@ -210,7 +210,8 @@ export async function createRule( const { systemActions, actions: actionToNotUse, ...restData } = data; // Convert domain rule object to ES rule attributes const ruleAttributes = transformRuleDomainToRuleAttributes({ - actionsWithRefs, // TODO add dashboards with refs + actionsWithRefs, + artifactsWithRefs, rule: { ...restData, // TODO (http-versioning) create a rule domain version of this function @@ -270,6 +271,7 @@ export async function createRule( } // Convert domain rule to rule (Remove certain properties) + // As I understand I need to remove artifacts, need to confirm const rule = transformRuleDomainToRule(ruleDomain, { isPublic: true }); // TODO (http-versioning): Remove this cast, this enables us to move forward diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts index d8f9940d36168..dc81f697d9bc9 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts @@ -5,6 +5,7 @@ * 2.0. */ import { isEmpty } from 'lodash'; +import { omit } from 'lodash'; import type { Logger } from '@kbn/core/server'; import type { SavedObjectReference } from '@kbn/core/server'; import { ruleExecutionStatusValues } from '../constants'; @@ -169,6 +170,31 @@ export const transformRuleAttributesToRuleDomain = { + if (!artifacts) { + return { artifacts: { dashboards: [] } }; + } + return { + ...artifacts, + dashboards: artifacts.dashboards?.map((dashboard) => { + const reference = references.find((ref) => ref.name === dashboard.refId); + if (!reference) { + throw new Error(`Artifact reference "${dashboard.refId}" not found in rule id: ${id}`); + } + return { + ...omit(dashboard, 'refId'), + id: reference.id, + }; + }) + }; + } + + const artifactsWithInjectedRefs = esRule.artifacts ? injectReferencesIntoArtifacts(esRule.artifacts, references || []) : null; // TODO: don't return null const params = injectReferencesIntoParams( id, ruleType, @@ -234,7 +260,7 @@ export const transformRuleAttributesToRuleDomain = ( alertDelay: ruleDomain.alertDelay, legacyId: ruleDomain.legacyId, flapping: ruleDomain.flapping, + artifacts: ruleDomain.artifacts, // shall I return the artifacts here? When I added this here, I got artifacts in the rule creation response (in the POST response) but not in the GET rule response }; if (isPublic) { diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts index a324425f2e012..3bc025b21c888 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts @@ -7,7 +7,7 @@ import type { RawRule } from '../../../types'; import type { RuleDomain } from '../types'; import { getMappedParams } from '../../../rules_client/common'; -import type { DenormalizedAction } from '../../../rules_client'; +import type { DenormalizedAction, DenormalizedArtifacts } from '../../../rules_client'; interface TransformRuleToEsParams { legacyId: RawRule['legacyId']; @@ -18,10 +18,12 @@ interface TransformRuleToEsParams { // TODO dashboards with refs export const transformRuleDomainToRuleAttributes = ({ actionsWithRefs, + artifactsWithRefs, rule, params, }: { actionsWithRefs: DenormalizedAction[]; + artifactsWithRefs: DenormalizedArtifacts; rule: Omit; params: TransformRuleToEsParams; }): RawRule => { @@ -82,6 +84,6 @@ export const transformRuleDomainToRuleAttributes = ({ ...(rule.running !== undefined ? { running: rule.running } : {}), ...(rule.alertDelay !== undefined ? { alertDelay: rule.alertDelay } : {}), ...(rule.flapping !== undefined ? { flapping: rule.flapping } : {}), - artifacts: rule.artifacts, + artifacts: artifactsWithRefs.artifacts, } as RawRule; }; diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/types/rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/types/rule.ts index 47131738e6b2d..ffc2da04008e1 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/types/rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/types/rule.ts @@ -85,7 +85,7 @@ export interface Rule { alertDelay?: RuleSchemaType['alertDelay']; legacyId?: RuleSchemaType['legacyId']; flapping?: RuleSchemaType['flapping']; - artifacts?: RuleSchemaType['artifacts']; + artifacts?: RuleSchemaType['artifacts']; // do I need to remove it from here? } export interface RuleDomain { diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts index de3e99fe092fc..7dd248ac0e3aa 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts @@ -156,4 +156,6 @@ export const transformRuleToRuleResponse = ( : {}), ...(rule.alertDelay !== undefined ? { alert_delay: rule.alertDelay } : {}), ...(rule.flapping !== undefined ? { flapping: transformFlapping(rule.flapping) } : {}), + // do I need to add artifacts here? + artifacts: rule.artifacts, }); diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index 710719ea45298..3147ed2b75487 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -6,11 +6,11 @@ */ import type { SavedObjectReference } from '@kbn/core/server'; -import type { RuleTypeParams } from '../../types'; +import type { RuleTypeParams, Artifact } from '../../types'; import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; import type { DenormalizedAction, NormalizedAlertActionWithGeneratedValues } from '../types'; import { extractedSavedObjectParamReferenceNamePrefix } from '../common/constants'; -import type { RulesClientContext } from '../types'; +import type { RulesClientContext, DenormalizedArtifacts } from '../types'; import { denormalizeActions } from './denormalize_actions'; export async function extractReferences< @@ -20,9 +20,11 @@ export async function extractReferences< context: RulesClientContext, ruleType: UntypedNormalizedRuleType, ruleActions: NormalizedAlertActionWithGeneratedValues[], - ruleParams: Params + ruleParams: Params, + ruleArtifacts?: Artifact ): Promise<{ actions: DenormalizedAction[]; + artifacts: DenormalizedArtifacts; params: ExtractedParams; references: SavedObjectReference[]; }> { @@ -32,6 +34,42 @@ export async function extractReferences< ruleActions ); + // TODO move this to demormalize_artifacts file + const denormalizeArtifacts = (ruleArtifacts: Artifact): { artifacts: DenormalizedArtifacts; references: SavedObjectReference[] } => { + const references: SavedObjectReference[] = []; + const artifacts: DenormalizedArtifacts = { + artifacts: { + dashboards: [] + }, + }; + + if (ruleArtifacts.dashboards) { + ruleArtifacts.dashboards.forEach((dashboard, i) => { + const refName = `dashboard_${i}`; + const dashboardRef = { + id: dashboard.id, + name: refName, // what kind of name do I give here? + type: 'dashboard', + }; + references.push(dashboardRef); + if (!artifacts.artifacts.dashboards) { + artifacts.artifacts.dashboards = []; + } + artifacts.artifacts.dashboards.push({ + refId: refName, + }); + }); + } + + return { + artifacts, + references + }; + }; + const { artifacts, references: artifactReferences } = ruleArtifacts + ? denormalizeArtifacts(ruleArtifacts) + : { artifacts: { artifacts: { dashboards: [] } }, references: [] }; + // Extracts any references using configured reference extractor if available const extractedRefsAndParams = ruleType?.useSavedObjectReferences?.extractReferences ? ruleType.useSavedObjectReferences.extractReferences(ruleParams) @@ -45,10 +83,11 @@ export async function extractReferences< name: `${extractedSavedObjectParamReferenceNamePrefix}${reference.name}`, })); - const references = [...actionReferences, ...paramReferences]; + const references = [...actionReferences, ...paramReferences, ...artifactReferences]; return { actions, + artifacts, params, references, }; diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/types.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/types.ts index 43d80ca674130..0a9cac9821128 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/types.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/types.ts @@ -185,3 +185,13 @@ export type DenormalizedAction = DistributiveOmit< actionRef: string; actionTypeId: string; }; + +interface DashboardItem { + refId: string; +} + +export interface DenormalizedArtifacts { + artifacts: { + dashboards?: DashboardItem[]; + }; +} diff --git a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts index e20e5aebf4ab1..020fde4aa3315 100644 --- a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts @@ -8,10 +8,14 @@ import { schema } from '@kbn/config-schema'; import { rawRuleSchema as rawRuleSchemaV4 } from './v4'; -export const dashboardSchema = schema.arrayOf(schema.object({ id: schema.string() })); +export const rawRuleDashboardSchema = schema.arrayOf( + schema.object({ + refId: schema.string(), + }) +); export const artifactSchema = schema.object({ - dashboards: schema.maybe(dashboardSchema), + dashboards: schema.maybe(rawRuleDashboardSchema), investigation_guide: schema.maybe(schema.string()), }); diff --git a/x-pack/platform/plugins/shared/alerting/server/types.ts b/x-pack/platform/plugins/shared/alerting/server/types.ts index 92f6bb0033106..7c8cd228f8689 100644 --- a/x-pack/platform/plugins/shared/alerting/server/types.ts +++ b/x-pack/platform/plugins/shared/alerting/server/types.ts @@ -50,6 +50,7 @@ import type { SanitizedRuleConfig, SanitizedRule, RuleAlertData, + Artifact, } from '../common'; import type { PublicAlertFactory } from './alert/create_alert_factory'; import type { RulesSettingsFlappingProperties } from '../common/rules_settings'; @@ -58,6 +59,7 @@ import type { GetTimeRangeResult } from './lib/get_time_range'; export type WithoutQueryAndParams = Pick>; export type SpaceIdToNamespaceFunction = (spaceId?: string) => string | undefined; export type { RuleTypeParams }; +export type { Artifact }; /** * @public */ From 387d72cd66e90237959cc60ebca7543d92df6e26 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 31 Mar 2025 13:35:31 +0300 Subject: [PATCH 04/84] remove artifacts from create rule response (transformRuleToRuleResponse) --- .../shared/alerting/common/routes/rule/response/types/v1.ts | 1 - .../server/application/rule/methods/create/create_rule.ts | 1 - .../rule/transforms/transform_rule_domain_to_rule.ts | 2 +- .../rule/transforms/transform_rule_domain_to_rule_attributes.ts | 1 - .../rule/transforms/transform_rule_to_rule_response/v1.ts | 2 -- 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts index c5be4ea5d0bd9..8b305195610b6 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts @@ -54,5 +54,4 @@ export interface RuleResponse { view_in_app_relative_url?: RuleResponseSchemaType['view_in_app_relative_url']; alert_delay?: RuleResponseSchemaType['alert_delay']; flapping?: RuleResponseSchemaType['flapping']; - artifacts?: RuleResponseSchemaType['artifacts']; // DO I NEED TO ADD ARTIFACTS HERE? } diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts index 77a77d92975db..a68abe5aff84c 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts @@ -271,7 +271,6 @@ export async function createRule( } // Convert domain rule to rule (Remove certain properties) - // As I understand I need to remove artifacts, need to confirm const rule = transformRuleDomainToRule(ruleDomain, { isPublic: true }); // TODO (http-versioning): Remove this cast, this enables us to move forward diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.ts index 3eab08f71385c..125d7659d6182 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.ts @@ -54,7 +54,7 @@ export const transformRuleDomainToRule = ( alertDelay: ruleDomain.alertDelay, legacyId: ruleDomain.legacyId, flapping: ruleDomain.flapping, - artifacts: ruleDomain.artifacts, // shall I return the artifacts here? When I added this here, I got artifacts in the rule creation response (in the POST response) but not in the GET rule response + artifacts: ruleDomain.artifacts, }; if (isPublic) { diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts index 3bc025b21c888..ad168ee4cc49e 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts @@ -15,7 +15,6 @@ interface TransformRuleToEsParams { meta?: RawRule['meta']; } -// TODO dashboards with refs export const transformRuleDomainToRuleAttributes = ({ actionsWithRefs, artifactsWithRefs, diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts index 7dd248ac0e3aa..de3e99fe092fc 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts @@ -156,6 +156,4 @@ export const transformRuleToRuleResponse = ( : {}), ...(rule.alertDelay !== undefined ? { alert_delay: rule.alertDelay } : {}), ...(rule.flapping !== undefined ? { flapping: transformFlapping(rule.flapping) } : {}), - // do I need to add artifacts here? - artifacts: rule.artifacts, }); From 186d1d6f4d9e44a960533a30c9e118145d93bd6c Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 31 Mar 2025 14:10:02 +0300 Subject: [PATCH 05/84] remove investigation_guide for now. it will be added later on as v6 in the SO raw rule --- src/platform/packages/shared/kbn-alerting-types/rule_types.ts | 1 - .../shared/alerting/common/routes/rule/response/schemas/v1.ts | 1 - .../alerting/server/application/rule/schemas/rule_schemas.ts | 1 - .../shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts | 1 - 4 files changed, 4 deletions(-) diff --git a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts index 6d3b33262dca2..1e3bb75f8bd50 100644 --- a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts +++ b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts @@ -221,7 +221,6 @@ export interface Dashboard extends SavedObjectAttributes { export interface Artifact extends SavedObjectAttributes { dashboards?: Dashboard[]; - investigation_guide?: string; // TBD if it will be an object or a string } export interface Rule { diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts index f49a218f65d1c..c4f079bba79c3 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts @@ -479,7 +479,6 @@ export const dashboardSchema = schema.arrayOf(schema.object({ id: schema.string( export const artifactSchema = schema.object({ dashboards: schema.maybe(dashboardSchema), - investigation_guide: schema.maybe(schema.string()), }); export const ruleResponseSchema = schema.object({ diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts index 4090dcfdbcf09..4ac2257084ee8 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts @@ -153,7 +153,6 @@ export const dashboardSchema = schema.arrayOf(schema.object({ id: schema.string( export const artifactSchema = schema.object({ dashboards: schema.maybe(dashboardSchema), - investigation_guide: schema.maybe(schema.string()), }); /** diff --git a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts index 020fde4aa3315..5bd3e4f884f19 100644 --- a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts @@ -16,7 +16,6 @@ export const rawRuleDashboardSchema = schema.arrayOf( export const artifactSchema = schema.object({ dashboards: schema.maybe(rawRuleDashboardSchema), - investigation_guide: schema.maybe(schema.string()), }); export const rawRuleSchema = rawRuleSchemaV4.extends({ From a3708dda51110ce1e66881302e45ad72e6c2212a Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 31 Mar 2025 15:21:41 +0300 Subject: [PATCH 06/84] type refactoring --- ...ransform_rule_attributes_to_rule_domain.ts | 29 ++----------------- ...ransform_rule_domain_to_rule_attributes.ts | 2 +- .../server/rules_client/common/index.ts | 6 +++- .../rules_client/common/inject_references.ts | 20 +++++++++++++ .../rules_client/lib/extract_references.ts | 12 ++++---- .../alerting/server/rules_client/types.ts | 4 +-- 6 files changed, 34 insertions(+), 39 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts index dc81f697d9bc9..282ad9b050db7 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts @@ -5,7 +5,6 @@ * 2.0. */ import { isEmpty } from 'lodash'; -import { omit } from 'lodash'; import type { Logger } from '@kbn/core/server'; import type { SavedObjectReference } from '@kbn/core/server'; import { ruleExecutionStatusValues } from '../constants'; @@ -13,7 +12,7 @@ import { getRuleSnoozeEndTime } from '../../../lib'; import type { RuleDomain, Monitoring, RuleParams } from '../types'; import type { PartialRule, RawRule, RawRuleExecutionStatus, SanitizedRule } from '../../../types'; import type { UntypedNormalizedRuleType } from '../../../rule_type_registry'; -import { injectReferencesIntoParams } from '../../../rules_client/common'; +import { injectReferencesIntoParams, injectReferencesIntoArtifacts } from '../../../rules_client/common'; import { getActiveScheduledSnoozes } from '../../../lib/is_rule_snoozed'; import { transformRawActionsToDomainActions, @@ -170,31 +169,7 @@ export const transformRuleAttributesToRuleDomain = { - if (!artifacts) { - return { artifacts: { dashboards: [] } }; - } - return { - ...artifacts, - dashboards: artifacts.dashboards?.map((dashboard) => { - const reference = references.find((ref) => ref.name === dashboard.refId); - if (!reference) { - throw new Error(`Artifact reference "${dashboard.refId}" not found in rule id: ${id}`); - } - return { - ...omit(dashboard, 'refId'), - id: reference.id, - }; - }) - }; - } - - const artifactsWithInjectedRefs = esRule.artifacts ? injectReferencesIntoArtifacts(esRule.artifacts, references || []) : null; // TODO: don't return null + const artifactsWithInjectedRefs = injectReferencesIntoArtifacts(id, esRule.artifacts, references || []); const params = injectReferencesIntoParams( id, ruleType, diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts index ad168ee4cc49e..05f2b1a29facb 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts @@ -83,6 +83,6 @@ export const transformRuleDomainToRuleAttributes = ({ ...(rule.running !== undefined ? { running: rule.running } : {}), ...(rule.alertDelay !== undefined ? { alertDelay: rule.alertDelay } : {}), ...(rule.flapping !== undefined ? { flapping: rule.flapping } : {}), - artifacts: artifactsWithRefs.artifacts, + artifacts: artifactsWithRefs, } as RawRule; }; diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/index.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/index.ts index a695e0a8bd6e9..90db6e99902cb 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/index.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/index.ts @@ -26,7 +26,11 @@ export { apiKeyAsAlertAttributes, apiKeyAsRuleDomainProperties, } from './api_key_as_alert_attributes'; -export { injectReferencesIntoActions, injectReferencesIntoParams } from './inject_references'; +export { + injectReferencesIntoActions, + injectReferencesIntoParams, + injectReferencesIntoArtifacts, +} from './inject_references'; export { parseDate } from './parse_date'; export { includeFieldsRequiredForAuthentication } from './include_fields_required_for_authentication'; export { getAndValidateCommonBulkOptions } from './get_and_validate_common_bulk_options'; diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index 9e956c634ade9..ec4f2901bc469 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -77,3 +77,23 @@ export function injectReferencesIntoParams< ); } } + +export function injectReferencesIntoArtifacts(ruleId: string, artifacts: RawRule['artifacts'], + references: SavedObjectReference[]) { + if (!artifacts) { + return { dashboards: [] }; + } + return { + ...artifacts, + dashboards: artifacts.dashboards?.map((dashboard) => { + const reference = references.find((ref) => ref.name === dashboard.refId); + if (!reference) { + throw new Error(`Artifact reference "${dashboard.refId}" not found in rule id: ${ruleId}`); + } + return { + ...omit(dashboard, 'refId'), + id: reference.id, + }; + }) + }; + } diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index 3147ed2b75487..9966934bea815 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -38,9 +38,7 @@ export async function extractReferences< const denormalizeArtifacts = (ruleArtifacts: Artifact): { artifacts: DenormalizedArtifacts; references: SavedObjectReference[] } => { const references: SavedObjectReference[] = []; const artifacts: DenormalizedArtifacts = { - artifacts: { - dashboards: [] - }, + dashboards: [] }; if (ruleArtifacts.dashboards) { @@ -52,10 +50,10 @@ export async function extractReferences< type: 'dashboard', }; references.push(dashboardRef); - if (!artifacts.artifacts.dashboards) { - artifacts.artifacts.dashboards = []; + if (!artifacts.dashboards) { + artifacts.dashboards = []; } - artifacts.artifacts.dashboards.push({ + artifacts.dashboards.push({ refId: refName, }); }); @@ -68,7 +66,7 @@ export async function extractReferences< }; const { artifacts, references: artifactReferences } = ruleArtifacts ? denormalizeArtifacts(ruleArtifacts) - : { artifacts: { artifacts: { dashboards: [] } }, references: [] }; + : { artifacts: { dashboards: [] }, references: [] }; // Extracts any references using configured reference extractor if available const extractedRefsAndParams = ruleType?.useSavedObjectReferences?.extractReferences diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/types.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/types.ts index 0a9cac9821128..ee9ab1d45f97b 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/types.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/types.ts @@ -191,7 +191,5 @@ interface DashboardItem { } export interface DenormalizedArtifacts { - artifacts: { - dashboards?: DashboardItem[]; - }; + dashboards?: DashboardItem[]; } From c1ab616a8a3d41858f88a4bfebc4937a03167acc Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 31 Mar 2025 15:43:05 +0300 Subject: [PATCH 07/84] move denormalize_artifacts into a new file --- .../rules_client/lib/denormalize_artifacts.ts | 42 +++++++++++++++++++ .../rules_client/lib/extract_references.ts | 35 +--------------- 2 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts new file mode 100644 index 0000000000000..af9ea6c86b079 --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { SavedObjectReference } from '@kbn/core/server'; +import type { Artifact } from '../../types'; +import type { DenormalizedArtifacts } from '../types'; + +export function denormalizeArtifacts(ruleArtifacts: Artifact | undefined): { + artifacts: DenormalizedArtifacts; + references: SavedObjectReference[]; +} { + const references: SavedObjectReference[] = []; + const artifacts: DenormalizedArtifacts = { + dashboards: [], + }; + + if (ruleArtifacts && ruleArtifacts.dashboards) { + ruleArtifacts.dashboards.forEach((dashboard, i) => { + const refName = `dashboard_${i}`; + const dashboardRef = { + id: dashboard.id, + name: refName, + type: 'dashboard', + }; + references.push(dashboardRef); + if (!artifacts.dashboards) { + artifacts.dashboards = []; + } + artifacts.dashboards.push({ + refId: refName, + }); + }); + } + + return { + artifacts, + references, + }; +} diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index 9966934bea815..7352b154bcd83 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -12,6 +12,7 @@ import type { DenormalizedAction, NormalizedAlertActionWithGeneratedValues } fro import { extractedSavedObjectParamReferenceNamePrefix } from '../common/constants'; import type { RulesClientContext, DenormalizedArtifacts } from '../types'; import { denormalizeActions } from './denormalize_actions'; +import { denormalizeArtifacts } from './denormalize_artifacts'; export async function extractReferences< Params extends RuleTypeParams, @@ -34,39 +35,7 @@ export async function extractReferences< ruleActions ); - // TODO move this to demormalize_artifacts file - const denormalizeArtifacts = (ruleArtifacts: Artifact): { artifacts: DenormalizedArtifacts; references: SavedObjectReference[] } => { - const references: SavedObjectReference[] = []; - const artifacts: DenormalizedArtifacts = { - dashboards: [] - }; - - if (ruleArtifacts.dashboards) { - ruleArtifacts.dashboards.forEach((dashboard, i) => { - const refName = `dashboard_${i}`; - const dashboardRef = { - id: dashboard.id, - name: refName, // what kind of name do I give here? - type: 'dashboard', - }; - references.push(dashboardRef); - if (!artifacts.dashboards) { - artifacts.dashboards = []; - } - artifacts.dashboards.push({ - refId: refName, - }); - }); - } - - return { - artifacts, - references - }; - }; - const { artifacts, references: artifactReferences } = ruleArtifacts - ? denormalizeArtifacts(ruleArtifacts) - : { artifacts: { dashboards: [] }, references: [] }; + const { artifacts, references: artifactReferences } = denormalizeArtifacts(ruleArtifacts); // Extracts any references using configured reference extractor if available const extractedRefsAndParams = ruleType?.useSavedObjectReferences?.extractReferences From 21f13f1c2e3c2d7f7ee46d9b5ce385e94217151a Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 31 Mar 2025 21:44:51 +0300 Subject: [PATCH 08/84] fix failing create_rule tests --- .../rule/methods/create/create_rule.test.ts | 81 +++++++++++++++++++ ...ransform_rule_attributes_to_rule_domain.ts | 11 ++- .../rules_client/common/inject_references.ts | 39 ++++----- 3 files changed, 111 insertions(+), 20 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts index cdcb6159c0c08..d2963c25ee2db 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts @@ -432,6 +432,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, "createdBy": "elastic", @@ -482,6 +485,9 @@ describe('create()', () => { "apiKey": null, "apiKeyCreatedByUser": null, "apiKeyOwner": null, + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "bar", "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "elastic", @@ -712,6 +718,9 @@ describe('create()', () => { "apiKey": null, "apiKeyCreatedByUser": null, "apiKeyOwner": null, + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "bar", "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "elastic", @@ -933,6 +942,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -1137,6 +1149,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -1191,6 +1206,9 @@ describe('create()', () => { alertTypeId: '123', apiKey: null, apiKeyOwner: null, + artifacts: { + dashboards: [], + }, apiKeyCreatedByUser: null, consumer: 'bar', createdAt: '2019-02-12T21:01:22.479Z', @@ -1389,6 +1407,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -1449,6 +1470,9 @@ describe('create()', () => { apiKey: null, apiKeyCreatedByUser: null, apiKeyOwner: null, + artifacts: { + dashboards: [], + }, consumer: 'bar', createdAt: '2019-02-12T21:01:22.479Z', createdBy: 'elastic', @@ -1562,6 +1586,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": false, "executionStatus": Object { @@ -1701,6 +1728,9 @@ describe('create()', () => { apiKey: null, apiKeyOwner: null, apiKeyCreatedByUser: null, + artifacts: { + dashboards: [], + }, consumer: 'bar', createdAt: '2019-02-12T21:01:22.479Z', createdBy: 'elastic', @@ -1756,6 +1786,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -1894,6 +1927,9 @@ describe('create()', () => { apiKey: null, apiKeyOwner: null, apiKeyCreatedByUser: null, + artifacts: { + dashboards: [], + }, legacyId: null, consumer: 'bar', createdAt: '2019-02-12T21:01:22.479Z', @@ -1949,6 +1985,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -2077,6 +2116,9 @@ describe('create()', () => { apiKey: null, apiKeyOwner: null, apiKeyCreatedByUser: null, + artifacts: { + dashboards: [], + }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', updatedBy: 'elastic', @@ -2125,6 +2167,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, "createdBy": "elastic", @@ -2221,6 +2266,9 @@ describe('create()', () => { apiKey: null, apiKeyOwner: null, apiKeyCreatedByUser: null, + artifacts: { + dashboards: [], + }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', updatedBy: 'elastic', @@ -2269,6 +2317,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, "createdBy": "elastic", @@ -2365,6 +2416,9 @@ describe('create()', () => { apiKey: null, apiKeyOwner: null, apiKeyCreatedByUser: null, + artifacts: { + dashboards: [], + }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', updatedBy: 'elastic', @@ -2413,6 +2467,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, "createdBy": "elastic", @@ -2531,6 +2588,9 @@ describe('create()', () => { apiKeyOwner: null, apiKey: null, apiKeyCreatedByUser: null, + artifacts: { + dashboards: [], + }, legacyId: null, createdBy: 'elastic', updatedBy: 'elastic', @@ -2600,6 +2660,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, "createdBy": "elastic", @@ -2927,6 +2990,9 @@ describe('create()', () => { params: { bar: true }, apiKey: Buffer.from('123:abc').toString('base64'), apiKeyOwner: 'elastic', + artifacts: { + dashboards: [], + }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', updatedBy: 'elastic', @@ -3028,6 +3094,9 @@ describe('create()', () => { ], legacyId: null, alertTypeId: '123', + artifacts: { + dashboards: [], + }, consumer: 'bar', name: 'abc', params: { bar: true }, @@ -3785,6 +3854,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -4003,6 +4075,9 @@ describe('create()', () => { apiKey: Buffer.from('123:abc').toString('base64'), apiKeyOwner: 'elastic', apiKeyCreatedByUser: true, + artifacts: { + dashboards: [], + }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', updatedBy: 'elastic', @@ -4181,6 +4256,9 @@ describe('create()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -4234,6 +4312,9 @@ describe('create()', () => { apiKey: null, apiKeyOwner: null, apiKeyCreatedByUser: null, + artifacts: { + dashboards: [], + }, consumer: 'bar', createdAt: '2019-02-12T21:01:22.479Z', createdBy: 'elastic', diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts index 282ad9b050db7..ee08b600d6cf7 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts @@ -12,7 +12,10 @@ import { getRuleSnoozeEndTime } from '../../../lib'; import type { RuleDomain, Monitoring, RuleParams } from '../types'; import type { PartialRule, RawRule, RawRuleExecutionStatus, SanitizedRule } from '../../../types'; import type { UntypedNormalizedRuleType } from '../../../rule_type_registry'; -import { injectReferencesIntoParams, injectReferencesIntoArtifacts } from '../../../rules_client/common'; +import { + injectReferencesIntoParams, + injectReferencesIntoArtifacts, +} from '../../../rules_client/common'; import { getActiveScheduledSnoozes } from '../../../lib/is_rule_snoozed'; import { transformRawActionsToDomainActions, @@ -169,7 +172,11 @@ export const transformRuleAttributesToRuleDomain = ( id, ruleType, diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index ec4f2901bc469..bdf232f169367 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -78,22 +78,25 @@ export function injectReferencesIntoParams< } } -export function injectReferencesIntoArtifacts(ruleId: string, artifacts: RawRule['artifacts'], - references: SavedObjectReference[]) { - if (!artifacts) { - return { dashboards: [] }; - } - return { - ...artifacts, - dashboards: artifacts.dashboards?.map((dashboard) => { - const reference = references.find((ref) => ref.name === dashboard.refId); - if (!reference) { - throw new Error(`Artifact reference "${dashboard.refId}" not found in rule id: ${ruleId}`); - } - return { - ...omit(dashboard, 'refId'), - id: reference.id, - }; - }) - }; +export function injectReferencesIntoArtifacts( + ruleId: string, + artifacts: RawRule['artifacts'], + references: SavedObjectReference[] +) { + if (!artifacts) { + return { dashboards: [] }; } + return { + ...artifacts, + dashboards: artifacts.dashboards?.map((dashboard) => { + const reference = references.find((ref) => ref.name === dashboard.refId); + if (!reference) { + throw new Error(`Artifact reference "${dashboard.refId}" not found in rule id: ${ruleId}`); + } + return { + ...omit(dashboard, 'refId'), + id: reference.id, + }; + }), + }; +} From 201a15bfad698465dd6bacc62ccb7d86dd753a76 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 1 Apr 2025 10:48:37 +0300 Subject: [PATCH 09/84] add integration tests for creating a rule with dashboard artifacts --- .../transforms/transform_create_body/v1.ts | 2 +- .../tests/alerting/group1/create.ts | 110 ++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts index f5fcd2bb8c5b2..dc0c707c6b8ad 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts @@ -103,6 +103,6 @@ export const transformCreateBody = ({ ...(createBody.flapping !== undefined ? { flapping: transformCreateBodyFlapping(createBody.flapping) } : {}), - artifacts: createBody.artifacts, + ...(createBody.artifacts ? { artifacts: createBody.artifacts } : {}), }; }; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts index 484880c34737b..5a58256cc1b15 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts @@ -753,5 +753,115 @@ export default function createAlertTests({ getService }: FtrProviderContext) { }); }); }); + + describe('artifacts', () => { + describe('create rule with dashboards artifacts correctly', () => { + it('should not return dashboards artifacts in the rule response', async () => { + const response = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + artifacts: { + dashboards: [{ id: 'dashboard-1' }, { id: 'dashboard-2' }], + }, + }) + ); + expect(response.status).to.eql(200); + objectRemover.add(Spaces.space1.id, response.body.id, 'rule', 'alerting'); + + expect(response.body.artifacts).to.be(undefined); + }); + + it('should store references correctly for dashboard artifacts', async () => { + const { body: createdDashboard } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/content_management/rpc/create`) + .set('kbn-xsrf', 'foo') + .send({ + contentTypeId: 'dashboard', + data: { + kibanaSavedObjectMeta: {}, + title: 'Sample dashboard', + }, + options: { + references: [], + overwrite: true, + }, + version: 2, + }) + .expect(200); + const dashboardId = createdDashboard.result.result.item.id; + const response = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + artifacts: { + dashboards: [ + { + id: dashboardId, + }, + ], + }, + }) + ); + expect(response.status).to.eql(200); + + objectRemover.add(Spaces.space1.id, response.body.id, 'rule', 'alerting'); + + expect(response.body).to.eql({ + id: response.body.id, + name: 'abc', + tags: ['foo'], + actions: [], + enabled: true, + rule_type_id: 'test.noop', + revision: 0, + running: false, + consumer: 'alertsFixture', + params: {}, + created_by: null, + schedule: { interval: '1m' }, + scheduled_task_id: response.body.scheduled_task_id, + updated_by: null, + api_key_owner: null, + api_key_created_by_user: null, + throttle: '1m', + notify_when: 'onThrottleInterval', + mute_all: false, + muted_alert_ids: [], + created_at: response.body.created_at, + updated_at: response.body.updated_at, + execution_status: response.body.execution_status, + ...(response.body.next_run ? { next_run: response.body.next_run } : {}), + ...(response.body.last_run ? { last_run: response.body.last_run } : {}), + }); + + const esResponse = await es.get>( + { + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + id: `alert:${response.body.id}`, + }, + { meta: true } + ); + + const rawDashboards = (esResponse.body._source as any)?.alert.artifacts.dashboards ?? []; + expect(rawDashboards).to.eql([ + { + refId: 'dashboard_0', + }, + ]); + + const references = esResponse.body._source?.references ?? []; + + expect(references.length).to.eql(1); + expect(references[0]).to.eql({ + id: dashboardId, + name: 'dashboard_0', + type: 'dashboard', + }); + }); + }); + }); }); } From b9542c0977c84bb4cbad07d4ba51c72bb73deece Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 1 Apr 2025 20:09:48 +0300 Subject: [PATCH 10/84] return artifacts on the internal find api (TODO: handle transforming refs back to dashboard ids) --- .../rule/apis/find/find_internal_rules_route.ts | 2 +- .../routes/rule/apis/find/find_rules_route.ts | 2 +- .../transforms/transform_find_rules_response/v1.ts | 13 ++++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_internal_rules_route.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_internal_rules_route.ts index 43a68e3dfec2d..ac7d2a2dfae65 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_internal_rules_route.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_internal_rules_route.ts @@ -69,7 +69,7 @@ export const findInternalRulesRoute = ( }); const responseBody: FindRulesResponseV1['body'] = - transformFindRulesResponseV1(findResult, options.fields); + transformFindRulesResponseV1(findResult, options.fields, true); return res.ok({ body: responseBody, diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_rules_route.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_rules_route.ts index 29a4a2da35698..574aa1029619b 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_rules_route.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_rules_route.ts @@ -90,7 +90,7 @@ export const findRulesRoute = ( }); const responseBody: FindRulesResponseV1['body'] = - transformFindRulesResponseV1(findResult, options.fields); + transformFindRulesResponseV1(findResult, options.fields, false); return res.ok({ body: responseBody, diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts index 80729ae13b6c0..b98bc26d6b547 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts @@ -21,7 +21,8 @@ import { export const transformPartialRule = ( rule: Partial>, - fields?: string[] + fields?: string[], + isInternal: boolean = false ): Partial> => { const ruleResponse = { ...(rule.id !== undefined ? { id: rule.id } : {}), @@ -80,6 +81,11 @@ export const transformPartialRule = ( : {}), ...(rule.alertDelay !== undefined ? { alert_delay: rule.alertDelay } : {}), ...(rule.flapping !== undefined ? { flapping: transformFlappingV1(rule.flapping) } : {}), + ...(isInternal + ? rule.artifacts !== undefined + ? { artifacts: rule.artifacts } + : { artifacts: { dashboards: [] } } + : {}), }; type RuleKeys = keyof RuleResponseV1; @@ -100,14 +106,15 @@ export const transformPartialRule = ( export const transformFindRulesResponse = ( result: FindResult, - fields?: string[] + fields?: string[], + isInternal: boolean = false ): FindRulesResponseV1['body'] => { return { page: result.page, per_page: result.perPage, total: result.total, data: result.data.map((rule) => - transformPartialRule(rule as Partial>, fields) + transformPartialRule(rule as Partial>, fields, isInternal) ), }; }; From e30f64194a52478e50ebbdcb18192fcbc15a4e09 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 1 Apr 2025 21:59:20 +0300 Subject: [PATCH 11/84] inject references into artifacts in the find rule api --- .../alerting/server/rules_client/lib/get_alert_from_raw.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts index 3100f922dbe8c..44359f4c0b2c4 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts @@ -24,7 +24,7 @@ import { } from '../../lib'; import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; import { getActiveScheduledSnoozes } from '../../lib/is_rule_snoozed'; -import { injectReferencesIntoParams } from '../common'; +import { injectReferencesIntoArtifacts, injectReferencesIntoParams } from '../common'; import { transformRawActionsToDomainActions, transformRawActionsToDomainSystemActions, @@ -169,6 +169,7 @@ function getPartialRuleFromRaw( omitGeneratedValues, }) : [], + artifacts: injectReferencesIntoArtifacts(opts.id, rawRule.artifacts, opts.references || []), params: injectReferencesIntoParams( opts.id, opts.ruleType, From d84c366983c25f9f1fd83802263b34f2d27784da Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 1 Apr 2025 22:37:01 +0300 Subject: [PATCH 12/84] changes to the update schema --- .../alerting/common/routes/rule/apis/update/schemas/v1.ts | 3 ++- .../rule/apis/update/transforms/transform_update_body/v1.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/schemas/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/schemas/v1.ts index baa1dca0ec5b8..2e9c5cc109d40 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/schemas/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/schemas/v1.ts @@ -9,7 +9,7 @@ import path from 'node:path'; import { schema } from '@kbn/config-schema'; import { ruleParamsSchemaWithDefaultValueV1 } from '@kbn/response-ops-rule-params'; import { validateDurationV1, validateHoursV1, validateTimezoneV1 } from '../../../validation'; -import { notifyWhenSchemaV1, alertDelaySchemaV1 } from '../../../response'; +import { notifyWhenSchemaV1, alertDelaySchemaV1, artifactSchemaV1 } from '../../../response'; import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; import { flappingSchemaV1 } from '../../../common'; @@ -163,6 +163,7 @@ export const updateBodySchema = schema.object({ notify_when: schema.maybe(schema.nullable(notifyWhenSchemaV1)), alert_delay: schema.maybe(alertDelaySchemaV1), flapping: schema.maybe(schema.nullable(flappingSchemaV1)), + artifacts: schema.maybe(artifactSchemaV1), }); export const updateParamsSchema = schema.object({ diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.ts index 48e7d71285be5..00b15ebf4db9a 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.ts @@ -104,5 +104,6 @@ export const transformUpdateBody = ({ ...(updateBody.flapping !== undefined ? { flapping: transformUpdateBodyFlapping(updateBody.flapping) } : {}), + ...(updateBody.artifacts ? { artifacts: updateBody.artifacts } : {}), }; }; From 6f6fc54c8fc95366c55f0175e572bfb68af96b30 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 1 Apr 2025 23:14:46 +0300 Subject: [PATCH 13/84] update artifact references on rule update --- .../alerting/common/routes/rule/apis/update/types/v1.ts | 1 + .../rule/methods/update/schemas/update_rule_data_schema.ts | 2 ++ .../rule/methods/update/types/update_rule_data.ts | 1 + .../server/application/rule/methods/update/update_rule.ts | 5 ++++- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/types/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/types/v1.ts index a06c726628796..2ced261dc9770 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/types/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/types/v1.ts @@ -31,6 +31,7 @@ export interface UpdateRuleRequestBody { notify_when?: UpdateBodySchema['notify_when']; alert_delay?: UpdateBodySchema['alert_delay']; flapping?: UpdateBodySchema['flapping']; + artifacts?: UpdateBodySchema['artifacts']; } export interface UpdateRuleResponse { diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/schemas/update_rule_data_schema.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/schemas/update_rule_data_schema.ts index 9c0bf1666f846..9008893fe2e35 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/schemas/update_rule_data_schema.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/schemas/update_rule_data_schema.ts @@ -14,6 +14,7 @@ import { actionRequestSchema, systemActionRequestSchema, flappingSchema, + artifactSchema, } from '../../../schemas'; export const updateRuleDataSchema = schema.object( @@ -30,6 +31,7 @@ export const updateRuleDataSchema = schema.object( notifyWhen: schema.maybe(schema.nullable(notifyWhenSchema)), alertDelay: schema.maybe(alertDelaySchema), flapping: schema.maybe(schema.nullable(flappingSchema)), + artifacts: schema.maybe(artifactSchema), }, { unknowns: 'allow' } ); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/types/update_rule_data.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/types/update_rule_data.ts index 34ae35ac4c0f9..16d05cdc7ba86 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/types/update_rule_data.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/types/update_rule_data.ts @@ -22,4 +22,5 @@ export interface UpdateRuleData { notifyWhen?: UpdateRuleDataType['notifyWhen']; alertDelay?: UpdateRuleDataType['alertDelay']; flapping?: UpdateRuleDataType['flapping']; + artifacts?: UpdateRuleDataType['artifacts']; } diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts index 8cd814f155ddb..fd3724680c64a 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts @@ -313,11 +313,13 @@ async function updateRuleAttributes({ references: extractedReferences, params: updatedParams, actions: actionsWithRefs, + artifacts: artifactsWithRefs, } = await extractReferences( context, ruleType, allActions as NormalizedAlertActionWithGeneratedValues[], - validatedRuleTypeParams + validatedRuleTypeParams, + updateRuleData.artifacts ); // Increment revision if applicable field has changed @@ -368,6 +370,7 @@ async function updateRuleAttributes({ revision, updatedBy: username, updatedAt: new Date().toISOString(), + artifacts: artifactsWithRefs, }); const mappedParams = getMappedParams(updatedParams); From 5328a034969d12b3f3eda76bdb37dc811f703be7 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 2 Apr 2025 10:09:39 +0000 Subject: [PATCH 14/84] [CI] Auto-commit changed files from 'node scripts/capture_oas_snapshot --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules --include-path /api/actions --include-path /api/security/role --include-path /api/spaces --include-path /api/streams --include-path /api/fleet --include-path /api/dashboards --update' --- oas_docs/bundle.json | 126 ++++++++++++++++++++++++++++++++ oas_docs/bundle.serverless.json | 126 ++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+) diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index 070d45787fff4..9a803e328d51f 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -1094,6 +1094,27 @@ "nullable": true, "type": "string" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" @@ -2173,6 +2194,27 @@ ], "type": "object" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" @@ -2820,6 +2862,27 @@ "nullable": true, "type": "string" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" @@ -3742,6 +3805,27 @@ ], "type": "object" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "flapping": { "additionalProperties": false, "description": "When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced.", @@ -4120,6 +4204,27 @@ "nullable": true, "type": "string" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" @@ -6036,6 +6141,27 @@ "nullable": true, "type": "string" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" diff --git a/oas_docs/bundle.serverless.json b/oas_docs/bundle.serverless.json index acd91ee213f9d..a88bf485bab10 100644 --- a/oas_docs/bundle.serverless.json +++ b/oas_docs/bundle.serverless.json @@ -1094,6 +1094,27 @@ "nullable": true, "type": "string" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" @@ -2173,6 +2194,27 @@ ], "type": "object" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" @@ -2820,6 +2862,27 @@ "nullable": true, "type": "string" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" @@ -3742,6 +3805,27 @@ ], "type": "object" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "flapping": { "additionalProperties": false, "description": "When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced.", @@ -4120,6 +4204,27 @@ "nullable": true, "type": "string" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" @@ -6036,6 +6141,27 @@ "nullable": true, "type": "string" }, + "artifacts": { + "additionalProperties": false, + "properties": { + "dashboards": { + "items": { + "additionalProperties": false, + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, "consumer": { "description": "The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", "type": "string" From 255c1948b917d7244c2bb2bdc6bd202702211f06 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 2 Apr 2025 10:31:40 +0000 Subject: [PATCH 15/84] [CI] Auto-commit changed files from 'make api-docs' --- oas_docs/output/kibana.serverless.yaml | 84 ++++++++++++++++++++++++++ oas_docs/output/kibana.yaml | 84 ++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 35493df93dd41..2564a9c51cd06 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -940,6 +940,20 @@ paths: description: The owner of the API key that is associated with the rule and used to run background tasks. nullable: true type: string + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string @@ -1759,6 +1773,20 @@ paths: type: number required: - active + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string @@ -2289,6 +2317,20 @@ paths: description: The owner of the API key that is associated with the rule and used to run background tasks. nullable: true type: string + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string @@ -2984,6 +3026,20 @@ paths: type: number required: - active + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array flapping: additionalProperties: false description: When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced. @@ -3275,6 +3331,20 @@ paths: description: The owner of the API key that is associated with the rule and used to run background tasks. nullable: true type: string + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string @@ -4664,6 +4734,20 @@ paths: description: The owner of the API key that is associated with the rule and used to run background tasks. nullable: true type: string + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index 72dee54232dbe..54370d515ff7e 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -1327,6 +1327,20 @@ paths: description: The owner of the API key that is associated with the rule and used to run background tasks. nullable: true type: string + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string @@ -2146,6 +2160,20 @@ paths: type: number required: - active + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string @@ -2676,6 +2704,20 @@ paths: description: The owner of the API key that is associated with the rule and used to run background tasks. nullable: true type: string + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string @@ -3371,6 +3413,20 @@ paths: type: number required: - active + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array flapping: additionalProperties: false description: When flapping detection is turned on, alerts that switch quickly between active and recovered states are identified as “flapping” and notifications are reduced. @@ -3662,6 +3718,20 @@ paths: description: The owner of the API key that is associated with the rule and used to run background tasks. nullable: true type: string + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string @@ -5051,6 +5121,20 @@ paths: description: The owner of the API key that is associated with the rule and used to run background tasks. nullable: true type: string + artifacts: + additionalProperties: false + type: object + properties: + dashboards: + items: + additionalProperties: false + type: object + properties: + id: + type: string + required: + - id + type: array consumer: description: 'The name of the application or feature that owns the rule. For example: `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.' type: string From 9860710f3aae582c2a48b04afcd0c7dfbc98e9ef Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 2 Apr 2025 10:51:40 +0000 Subject: [PATCH 16/84] [CI] Auto-commit changed files from 'node scripts/jest_integration -u src/core/server/integration_tests/ci_checks' --- .../ci_checks/saved_objects/check_registered_types.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts index 8bb8eb8949364..5c87f86689866 100644 --- a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts +++ b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts @@ -62,7 +62,7 @@ describe('checking migration metadata changes on all registered SO types', () => "action": "0e6fc0b74c7312a8c11ff6b14437b93a997358b8", "action_task_params": "2e475d8b62e2de50b77f58cda309efb537e1d543", "ad_hoc_run_params": "c7419760e878207231c3c8a25ec4d78360e07bf7", - "alert": "c5a135d2aca71f56103e9ccba00d6675b0586c82", + "alert": "795a00b231c815f3d955637ef23cc48f36548aed", "api_key_pending_invalidation": "8f5554d1984854011b8392d9a6f7ef985bcac03c", "apm-custom-dashboards": "b67128f78160c288bd7efe25b2da6e2afd5e82fc", "apm-indices": "8a2d68d415a4b542b26b0d292034a28ffac6fed4", From 236795d59ef284023a4d6fa3a52d659a3861bae6 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 2 Apr 2025 15:58:05 +0300 Subject: [PATCH 17/84] fix bulk edit --- .../rule/methods/bulk_edit/bulk_edit_rules.test.ts | 4 +++- .../application/rule/methods/bulk_edit/bulk_edit_rules.ts | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts index 2949de3ba3c56..aaa5fbf62f143 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts @@ -161,6 +161,9 @@ describe('bulkEdit()', () => { throttle: null, notifyWhen: null, actions: [], + artifacts: { + dashboards: [], + }, name: 'my rule name', revision: 0, }, @@ -652,7 +655,6 @@ describe('bulkEdit()', () => { }, ], }); - expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( [ { diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts index 49b5fc6285187..8a95464a48a4a 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -545,6 +545,7 @@ async function updateRuleAttributesAndParamsInMemory( references, params: updatedParams, actions: actionsWithRefs, + artifacts: artifactsWithRefs, } = await extractReferences( context, ruleType, @@ -559,6 +560,7 @@ async function updateRuleAttributesAndParamsInMemory( legacyId: rule.attributes.legacyId, paramsWithRefs: updatedParams, }, + artifactsWithRefs, }); const { apiKeyAttributes } = await prepareApiKeys( From 31e64f172b5c6ed42acef78149e616ec9ec1c650 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 2 Apr 2025 17:30:59 +0300 Subject: [PATCH 18/84] fix transform rule domain to attributes tests --- ...orm_rule_domain_to_rule_attributes.test.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.test.ts index 52246dde4f647..9b102bd1a4be9 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.test.ts @@ -19,6 +19,17 @@ describe('transformRuleDomainToRuleAttributes', () => { params: {}, }; + const artifacts = { + dashboards: [ + { + id: 'dashboard-1', + }, + { + id: 'dashboard-2', + }, + ], + }; + const rule: RuleDomain<{}> = { id: 'test', enabled: false, @@ -28,6 +39,7 @@ describe('transformRuleDomainToRuleAttributes', () => { consumer: 'myApp', schedule: { interval: '1m' }, actions: [defaultAction], + artifacts, params: {}, mapped_params: {}, createdBy: 'user', @@ -66,6 +78,13 @@ describe('transformRuleDomainToRuleAttributes', () => { params: {}, }, ], + artifactsWithRefs: { + dashboards: [ + { + refId: 'dashboard_0', + }, + ], + }, params: { legacyId: 'test', paramsWithRefs: {}, @@ -86,6 +105,13 @@ describe('transformRuleDomainToRuleAttributes', () => { "alertTypeId": "myType", "apiKey": "MTIzOmFiYw==", "apiKeyOwner": "user", + "artifacts": Object { + "dashboards": Array [ + Object { + "refId": "dashboard_0", + }, + ], + }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "user", From 523fb3c4f7adc8d076af695ed1a5416bef96e8b1 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 2 Apr 2025 18:11:04 +0300 Subject: [PATCH 19/84] fix update rule failing tests by passing a default artifacts value --- .../rule/methods/update/update_rule.test.ts | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index b1b5c81e19f84..525b2583b8f4b 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -411,6 +411,9 @@ describe('update()', () => { "alertDelay": Object { "active": 5, }, + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "executionStatus": Object { @@ -481,6 +484,9 @@ describe('update()', () => { "apiKey": null, "apiKeyCreatedByUser": null, "apiKeyOwner": null, + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "elastic", @@ -746,6 +752,9 @@ describe('update()', () => { alertTypeId: 'myType', apiKey: null, apiKeyOwner: null, + artifacts: { + dashboards: [], + }, apiKeyCreatedByUser: null, consumer: 'myApp', enabled: true, @@ -800,6 +809,9 @@ describe('update()', () => { "uuid": undefined, }, ], + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "executionStatus": Object { @@ -993,6 +1005,9 @@ describe('update()', () => { alertTypeId: 'myType', apiKey: null, apiKeyOwner: null, + artifacts: { + dashboards: [], + }, apiKeyCreatedByUser: null, consumer: 'myApp', enabled: true, @@ -1029,6 +1044,9 @@ describe('update()', () => { "uuid": undefined, }, ], + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "executionStatus": Object { @@ -1204,6 +1222,9 @@ describe('update()', () => { alertTypeId: 'myType', apiKey: null, apiKeyOwner: null, + artifacts: { + dashboards: [], + }, apiKeyCreatedByUser: null, consumer: 'myApp', enabled: true, @@ -1250,6 +1271,9 @@ describe('update()', () => { "uuid": undefined, }, ], + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "executionStatus": Object { @@ -1352,6 +1376,9 @@ describe('update()', () => { "uuid": undefined, }, ], + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "executionStatus": Object { @@ -1400,6 +1427,9 @@ describe('update()', () => { "apiKey": "MTIzOmFiYw==", "apiKeyCreatedByUser": undefined, "apiKeyOwner": "elastic", + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "elastic", @@ -1532,6 +1562,9 @@ describe('update()', () => { "uuid": undefined, }, ], + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": false, "executionStatus": Object { @@ -1572,6 +1605,9 @@ describe('update()', () => { "apiKey": null, "apiKeyCreatedByUser": null, "apiKeyOwner": null, + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "elastic", @@ -2757,6 +2793,9 @@ describe('update()', () => { alertTypeId: 'myType', apiKey: null, apiKeyOwner: null, + artifacts: { + dashboards: [], + }, apiKeyCreatedByUser: null, consumer: 'myApp', enabled: true, @@ -2793,6 +2832,9 @@ describe('update()', () => { "uuid": undefined, }, ], + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "executionStatus": Object { @@ -3350,6 +3392,9 @@ describe('update()', () => { alertTypeId: 'myType', apiKey: null, apiKeyOwner: null, + artifacts: { + dashboards: [], + }, apiKeyCreatedByUser: null, consumer: 'myApp', enabled: true, @@ -3526,6 +3571,9 @@ describe('update()', () => { }, ], "apiKeyCreatedByUser": true, + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "executionStatus": Object { @@ -3568,6 +3616,9 @@ describe('update()', () => { "apiKey": "MTIzOmFiYw==", "apiKeyCreatedByUser": true, "apiKeyOwner": "elastic", + "artifacts": Object { + "dashboards": Array [], + }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "elastic", @@ -3825,6 +3876,9 @@ describe('update()', () => { alertTypeId: 'myType', apiKey: null, apiKeyOwner: null, + artifacts: { + dashboards: [], + }, apiKeyCreatedByUser: null, consumer: 'myApp', enabled: true, @@ -3861,6 +3915,9 @@ describe('update()', () => { "uuid": undefined, }, ], + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, "executionStatus": Object { From 5cefd1ca4a069612e50a2cb594f526a62f813fd6 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 3 Apr 2025 14:22:57 +0300 Subject: [PATCH 20/84] fix model version --- .../server/saved_objects/model_versions/rule_model_versions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/saved_objects/model_versions/rule_model_versions.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/model_versions/rule_model_versions.ts index 081c42ce8d455..bd1673b06dfea 100644 --- a/x-pack/platform/plugins/shared/alerting/server/saved_objects/model_versions/rule_model_versions.ts +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/model_versions/rule_model_versions.ts @@ -46,7 +46,7 @@ export const ruleModelVersions: SavedObjectsModelVersionMap = { '5': { changes: [], schemas: { - forwardCompatibility: rawRuleSchemaV4.extends({}, { unknowns: 'ignore' }), + forwardCompatibility: rawRuleSchemaV5.extends({}, { unknowns: 'ignore' }), create: rawRuleSchemaV5, }, }, From d39cfceeabe390ca435a1ad79698f9a161a58a82 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 3 Apr 2025 14:25:35 +0300 Subject: [PATCH 21/84] remove leftover comment --- .../shared/alerting/server/application/rule/types/rule.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/types/rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/types/rule.ts index ffc2da04008e1..47131738e6b2d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/types/rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/types/rule.ts @@ -85,7 +85,7 @@ export interface Rule { alertDelay?: RuleSchemaType['alertDelay']; legacyId?: RuleSchemaType['legacyId']; flapping?: RuleSchemaType['flapping']; - artifacts?: RuleSchemaType['artifacts']; // do I need to remove it from here? + artifacts?: RuleSchemaType['artifacts']; } export interface RuleDomain { From 0be0f57582de376238f0e282980b6ad451237df8 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 7 Apr 2025 23:02:42 +0300 Subject: [PATCH 22/84] update_rule unit tests --- .../rule/methods/update/update_rule.test.ts | 173 ++++++++++++++++++ .../rule/methods/update/update_rule.ts | 2 +- 2 files changed, 174 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index 525b2583b8f4b..99c12ec029353 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -4276,4 +4276,177 @@ describe('update()', () => { ).rejects.toMatchInlineSnapshot(`[Error: Unauthorized to execute actions]`); }); }); + + describe('artifacts', () => { + test('updates the artifacts', async () => { + const existingDashboards = [ + { + id: 'dashboard-1', + }, + { + id: 'dashboard-2', + }, + ]; + + const existingRule = { + id: '1', + type: RULE_SAVED_OBJECT_TYPE, + attributes: { + name: 'fakeRuleName', + enabled: true, + tags: ['foo'], + alertTypeId: 'myType', + schedule: { interval: '1m' }, + consumer: 'myApp', + revision: 0, + scheduledTaskId: 'task-123', + params: {}, + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, + muteAll: false, + legacyId: null, + snoozeSchedule: [], + mutedInstanceIds: [], + createdBy: 'elastic', + createdAt: '2019-02-12T21:01:22.479Z', + updatedBy: 'elastic', + updatedAt: '2019-02-12T21:01:22.479Z', + actions: [], + artifacts: { + dashboards: existingDashboards, + }, + }, + references: [ + { + name: 'dashboard_0', + type: 'dashboard', + id: 'dashboard-1', + }, + ], + version: '123', + }; + + unsecuredSavedObjectsClient.get.mockResolvedValue(existingRule); + + unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ + id: '1', + type: RULE_SAVED_OBJECT_TYPE, + attributes: { + enabled: true, + schedule: { interval: '1m' }, + params: { + bar: true, + }, + actions: [], + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + ], + }, + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, + notifyWhen: 'onActiveAlert', + revision: 1, + scheduledTaskId: 'task-123', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + references: [ + { + name: 'dashboard_0', + type: 'dashboard', + id: 'dashboard-1', + }, + ], + }); + + const result = await rulesClient.update({ + id: '1', + data: { + schedule: { interval: '1m' }, + name: 'abc', + tags: ['foo'], + params: { + bar: true, + }, + throttle: null, + notifyWhen: 'onActiveAlert', + actions: [], + systemActions: [], + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + ], + }, + }, + }); + + expect(unsecuredSavedObjectsClient.create).toHaveBeenNthCalledWith( + 1, + RULE_SAVED_OBJECT_TYPE, + expect.objectContaining({ + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + ], + }, + }), + { + id: '1', + overwrite: true, + references: [{ id: 'dashboard-1', name: 'dashboard_0', type: 'dashboard' }], + version: '123', + } + ); + + expect(result?.artifacts).toEqual({ + dashboards: [ + { + id: 'dashboard-1', + }, + ], + }); + + expect(result).toMatchInlineSnapshot(` + Object { + "actions": Array [], + "artifacts": Object { + "dashboards": Array [ + Object { + "id": "dashboard-1", + }, + ], + }, + "createdAt": 2019-02-12T21:01:22.479Z, + "enabled": true, + "executionStatus": Object { + "lastExecutionDate": 2019-02-12T21:01:22.479Z, + "status": "pending", + }, + "id": "1", + "notifyWhen": "onActiveAlert", + "params": Object { + "bar": true, + }, + "revision": 1, + "schedule": Object { + "interval": "1m", + }, + "scheduledTaskId": "task-123", + "systemActions": Array [], + "updatedAt": 2019-02-12T21:01:22.479Z, + } + `); + }); + }); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts index fd3724680c64a..98ec271809e64 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts @@ -362,7 +362,7 @@ async function updateRuleAttributes({ const updatedRuleAttributes = updateMetaAttributes(context, { ...updatedRule, - ...omit(updateRuleData, 'actions', 'systemActions'), + ...omit(updateRuleData, 'actions', 'systemActions', 'artifacts'), ...apiKeyAttributes, params: updatedParams as RawRule['params'], actions: actionsWithRefs, From 98ff4ad4a3beed5947b86b9b6f9007f071e14651 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 8 Apr 2025 15:34:02 +0300 Subject: [PATCH 23/84] fix failing find rule unit tests --- .../rule/methods/find/find_rules.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/find/find_rules.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/find/find_rules.test.ts index 39ccbc4d57fe4..c050dfbc7a52f 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/find/find_rules.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/find/find_rules.test.ts @@ -201,6 +201,9 @@ describe('find()', () => { }, ], "alertTypeId": "myType", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -316,6 +319,9 @@ describe('find()', () => { }, ], "alertTypeId": "myType", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -421,6 +427,9 @@ describe('find()', () => { }, ], "alertTypeId": "myType", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -711,6 +720,9 @@ describe('find()', () => { }, ], "alertTypeId": "myType", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -741,6 +753,9 @@ describe('find()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.000Z, @@ -1018,6 +1033,9 @@ describe('find()', () => { "data": Array [ Object { "actions": Array [], + "artifacts": Object { + "dashboards": Array [], + }, "id": "1", "notifyWhen": undefined, "params": undefined, From de37d9c558e1f1c4b02a4d5baf41d1f32922d09f Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 8 Apr 2025 19:52:21 +0300 Subject: [PATCH 24/84] add find rule tests testing artifacts --- .../rule/methods/find/find_rules.test.ts | 114 ++++++++++++++++++ .../rules_client/lib/get_alert_from_raw.ts | 3 +- 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/find/find_rules.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/find/find_rules.test.ts index c050dfbc7a52f..8196cef2f5a41 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/find/find_rules.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/find/find_rules.test.ts @@ -1202,4 +1202,118 @@ describe('find()', () => { expect(result.data[3]).toEqual(expect.objectContaining({ id: siemRule2.id, migrated: true })); }); }); + + describe('artifacts', () => { + test('finds rules with artifacts', async () => { + unsecuredSavedObjectsClient.find.mockReset(); + + unsecuredSavedObjectsClient.find.mockResolvedValueOnce({ + total: 1, + per_page: 10, + page: 1, + saved_objects: [ + { + id: '1', + type: RULE_SAVED_OBJECT_TYPE, + attributes: { + name: 'fakeRuleName', + alertTypeId: 'myType', + schedule: { interval: '10s' }, + params: { + bar: true, + }, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + executionStatus: { + status: 'pending', + lastExecutionDate: new Date('2019-02-12T21:01:22.479Z'), + }, + notifyWhen: 'onActiveAlert', + actions: [ + { + actionTypeId: 'test-action-id', + group: 'default', + actionRef: 'action_0', + params: { + foo: true, + }, + uuid: 100, + }, + ], + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + ], + }, + }, + score: 1, + references: [ + { + name: 'action_0', + type: 'action', + id: '1', + }, + { + name: 'dashboard_0', + type: 'dashboard', + id: 'dashboard-1', + }, + ], + }, + ], + }); + + const rulesClient = new RulesClient(rulesClientParams); + const result = await rulesClient.find({ options: {} }); + expect(result).toMatchInlineSnapshot(` + Object { + "data": Array [ + Object { + "actions": Array [ + Object { + "actionTypeId": "test-action-id", + "group": "default", + "id": "1", + "params": Object { + "foo": true, + }, + "uuid": 100, + }, + ], + "alertTypeId": "myType", + "artifacts": Object { + "dashboards": Array [ + Object { + "id": "dashboard-1", + }, + ], + }, + "createdAt": 2019-02-12T21:01:22.479Z, + "executionStatus": Object { + "lastExecutionDate": 2019-02-12T21:01:22.000Z, + "status": "pending", + }, + "id": "1", + "name": "fakeRuleName", + "notifyWhen": "onActiveAlert", + "params": Object { + "bar": true, + }, + "schedule": Object { + "interval": "10s", + }, + "snoozeSchedule": Array [], + "systemActions": Array [], + "updatedAt": 2019-02-12T21:01:22.479Z, + }, + ], + "page": 1, + "perPage": 10, + "total": 1, + } + `); + }); + }); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts index 44359f4c0b2c4..6219c3b98fefb 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts @@ -123,6 +123,7 @@ function getPartialRuleFromRaw( snoozeSchedule, lastRun, isSnoozedUntil: DoNotUseIsSnoozedUntil, + artifacts, ...partialRawRule } = rawRule; @@ -169,7 +170,7 @@ function getPartialRuleFromRaw( omitGeneratedValues, }) : [], - artifacts: injectReferencesIntoArtifacts(opts.id, rawRule.artifacts, opts.references || []), + artifacts: injectReferencesIntoArtifacts(opts.id, artifacts, opts.references || []), params: injectReferencesIntoParams( opts.id, opts.ruleType, From 72681f282fe7b765233072823b8328577e68ee67 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 9 Apr 2025 10:37:22 -0400 Subject: [PATCH 25/84] Fix Synthetics deployment agnostic test. --- .../apis/observability/synthetics/enable_default_alerting.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/synthetics/enable_default_alerting.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/synthetics/enable_default_alerting.ts index 231195be88e44..49d694812366c 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/synthetics/enable_default_alerting.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/synthetics/enable_default_alerting.ts @@ -306,6 +306,9 @@ const defaultAlertRules = { throttle: null, apiKeyOwner: 'elastic_admin', apiKeyCreatedByUser: true, + artifacts: { + dashboards: [], + }, createdBy: 'elastic_admin', updatedBy: 'elastic_admin', muteAll: false, From 62376f8f5f146bea70aff4279027cca624dbbefd Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 7 Apr 2025 12:52:03 -0400 Subject: [PATCH 26/84] Fix types. --- .../shared/alerting/server/task_runner/fixtures.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/task_runner/fixtures.ts b/x-pack/platform/plugins/shared/alerting/server/task_runner/fixtures.ts index a71b6685fb464..6c8a42d14406b 100644 --- a/x-pack/platform/plugins/shared/alerting/server/task_runner/fixtures.ts +++ b/x-pack/platform/plugins/shared/alerting/server/task_runner/fixtures.ts @@ -298,6 +298,17 @@ export const mockedRule: SanitizedRule } as SanitizedRuleAction; }), isSnoozedUntil: undefined, + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + refId: 'ref-1', + }, + ], + investigation_guide: { + blob: 'guide-content', + }, + }, }; export const mockTaskInstance = () => ({ From 4c315dc8332fbe41f752253293fc260910a6ae6b Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 8 Apr 2025 08:32:54 -0400 Subject: [PATCH 27/84] Fix more tests. --- .../apis/observability/synthetics/enable_default_alerting.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/synthetics/enable_default_alerting.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/synthetics/enable_default_alerting.ts index 49d694812366c..419006911da9e 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/synthetics/enable_default_alerting.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/synthetics/enable_default_alerting.ts @@ -274,6 +274,9 @@ const defaultAlertRules = { throttle: null, apiKeyOwner: 'any', apiKeyCreatedByUser: true, + artifacts: { + dashboards: [], + }, createdBy: 'any', updatedBy: 'any', muteAll: false, From c67b4eb1379de5ad00fe0908572519ad3cb1bdf4 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 9 Apr 2025 11:48:00 -0400 Subject: [PATCH 28/84] Fix more `find_interna` tests. --- .../group1/tests/alerting/find_internal.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts index 484a34b41dd72..2980ebe1da74d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts @@ -99,6 +99,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { notify_when: 'onThrottleInterval', updated_by: 'elastic', api_key_owner: 'elastic', + artifacts: { dashboards: [] }, mute_all: false, muted_alert_ids: [], execution_status: match.execution_status, @@ -279,6 +280,9 @@ export default function createFindTests({ getService }: FtrProviderContext) { params: {}, created_by: 'elastic', api_key_created_by_user: null, + artifacts: { + dashboards: [], + }, revision: 0, throttle: '1m', updated_by: 'elastic', @@ -370,6 +374,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(omit(matchFirst, 'updatedAt')).to.eql({ id: createdAlert.id, actions: [], + artifacts: { dashboards: [] }, tags: [myTag], snooze_schedule: [], is_snoozed_until: null, @@ -377,6 +382,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(omit(matchSecond, 'updatedAt')).to.eql({ id: createdSecondAlert.id, actions: [], + artifacts: { dashboards: [] }, tags: [myTag], snooze_schedule: [], is_snoozed_until: null, @@ -453,6 +459,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(omit(matchFirst, 'updatedAt')).to.eql({ id: createdAlert.id, actions: [], + artifacts: { dashboards: [] }, tags: [myTag], execution_status: matchFirst.execution_status, snooze_schedule: [], @@ -461,6 +468,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(omit(matchSecond, 'updatedAt')).to.eql({ id: createdSecondAlert.id, actions: [], + artifacts: { dashboards: [] }, tags: [myTag], execution_status: matchSecond.execution_status, snooze_schedule: [], From 6318e5bb7e925eef6f235925900e3b6c940fe10d Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 2 Apr 2025 15:15:14 -0400 Subject: [PATCH 29/84] Fix most unit tests. --- .../methods/schedule/schedule_backfill.test.ts | 1 + .../application/rule/methods/get/get_rule.test.ts | 12 ++++++++++++ .../rule/methods/update/update_rule.test.ts | 4 ++++ .../server/rules_client/tests/resolve.test.ts | 9 +++++++++ .../server/rules_client/tests/test_helpers.ts | 9 +++++++++ 5 files changed, 35 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts index 7bae480ade8e8..a276a345aab6f 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts @@ -426,6 +426,7 @@ describe('scheduleBackfill()', () => { alertTypeId: existingDecryptedRule1.attributes.alertTypeId, apiKey: existingDecryptedRule1.attributes.apiKey, apiKeyCreatedByUser: existingDecryptedRule1.attributes.apiKeyCreatedByUser, + artifacts: { dashboards: [] }, consumer: existingDecryptedRule1.attributes.consumer, createdAt: new Date(existingDecryptedRule1.attributes.createdAt), createdBy: existingDecryptedRule1.attributes.createdBy, diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/get/get_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/get/get_rule.test.ts index 71d32b6b42f1f..2f971a1be1cd9 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/get/get_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/get/get_rule.test.ts @@ -132,6 +132,9 @@ describe('get()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2020-08-20T19:23:38.000Z, @@ -227,6 +230,9 @@ describe('get()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2020-08-20T19:23:38.000Z, @@ -311,6 +317,9 @@ describe('get()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2020-08-20T19:23:38.000Z, @@ -438,6 +447,9 @@ describe('get()', () => { }, ], "alertTypeId": "123", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2020-08-20T19:23:38.000Z, diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index 99c12ec029353..b3405fa1f10da 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -486,6 +486,7 @@ describe('update()', () => { "apiKeyOwner": null, "artifacts": Object { "dashboards": Array [], + "investigation_guide": undefined, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -1429,6 +1430,7 @@ describe('update()', () => { "apiKeyOwner": "elastic", "artifacts": Object { "dashboards": Array [], + "investigation_guide": undefined, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -1607,6 +1609,7 @@ describe('update()', () => { "apiKeyOwner": null, "artifacts": Object { "dashboards": Array [], + "investigation_guide": undefined, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -3618,6 +3621,7 @@ describe('update()', () => { "apiKeyOwner": "elastic", "artifacts": Object { "dashboards": Array [], + "investigation_guide": undefined, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/tests/resolve.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/tests/resolve.test.ts index df21bae6da71b..1e55ceb2a4583 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/tests/resolve.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/tests/resolve.test.ts @@ -138,6 +138,9 @@ describe('resolve()', () => { ], "alertTypeId": "123", "alias_target_id": "2", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.479Z, @@ -322,6 +325,9 @@ describe('resolve()', () => { ], "alertTypeId": "123", "alias_target_id": "2", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.479Z, @@ -517,6 +523,9 @@ describe('resolve()', () => { ], "alertTypeId": "123", "alias_target_id": "2", + "artifacts": Object { + "dashboards": Array [], + }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { "lastExecutionDate": 2019-02-12T21:01:22.479Z, diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/tests/test_helpers.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/tests/test_helpers.ts index 8177f919f80ff..33e091f351aaa 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/tests/test_helpers.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/tests/test_helpers.ts @@ -455,6 +455,9 @@ export const returnedRule2 = { export const returnedRuleForBulkOps1 = { actions: [], alertTypeId: 'fakeType', + artifacts: { + dashboards: [], + }, consumer: 'fakeConsumer', enabled: true, id: 'id1', @@ -481,6 +484,9 @@ export const returnedRuleForBulkOps1 = { export const returnedRuleForBulkOps2 = { actions: [], alertTypeId: 'fakeType', + artifacts: { + dashboards: [], + }, consumer: 'fakeConsumer', enabled: true, id: 'id2', @@ -508,6 +514,9 @@ export const returnedRuleForBulkOps3 = { actions: [], alertTypeId: 'fakeType', apiKeyCreatedByUser: true, + artifacts: { + dashboards: [], + }, consumer: 'fakeConsumer', enabled: true, id: 'id3', From 06aae53db94e3a1c349cf44a8d6da0a5b874e38d Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 9 Apr 2025 15:31:53 -0400 Subject: [PATCH 30/84] Still trying to fix internal find test that is broken despite passing locally. --- .../group1/tests/alerting/find_internal.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts index 2980ebe1da74d..53f49c76558a1 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts @@ -87,6 +87,9 @@ export default function createFindTests({ getService }: FtrProviderContext) { consumer: 'alertsFixture', schedule: { interval: '1m' }, enabled: true, + artifacts: { + dashboards: [], + }, actions: [], params: {}, created_by: 'elastic', @@ -99,7 +102,6 @@ export default function createFindTests({ getService }: FtrProviderContext) { notify_when: 'onThrottleInterval', updated_by: 'elastic', api_key_owner: 'elastic', - artifacts: { dashboards: [] }, mute_all: false, muted_alert_ids: [], execution_status: match.execution_status, From 24394287db6b60aa81b37d92ba12dc095bc9253c Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 9 Apr 2025 15:52:20 -0400 Subject: [PATCH 31/84] Temp debug logging for CI visibility. --- .../group1/tests/alerting/find_internal.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts index 53f49c76558a1..e59415e58fbb2 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts @@ -78,7 +78,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { const match = response.body.data.find((obj: any) => obj.id === createdAlert.id); const activeSnoozes = match.active_snoozes; const hasActiveSnoozes = !!(activeSnoozes || []).filter((obj: any) => obj).length; - expect(match).to.eql({ + const expected = { id: createdAlert.id, name: 'abc', tags: ['foo'], @@ -111,7 +111,11 @@ export default function createFindTests({ getService }: FtrProviderContext) { snooze_schedule: match.snooze_schedule, ...(hasActiveSnoozes && { active_snoozes: activeSnoozes }), is_snoozed_until: null, - }); + }; + + console.log('debug logging match', JSON.stringify(match)); + console.log('debug logging expected', JSON.stringify(expected)); + expect(match).to.eql(expected); expect(Date.parse(match.created_at)).to.be.greaterThan(0); expect(Date.parse(match.updated_at)).to.be.greaterThan(0); break; From e993299194e236039144c8a1af1e11d5f59ac44c Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 9 Apr 2025 15:58:52 -0400 Subject: [PATCH 32/84] Fix unit tests. --- .../backfill/methods/schedule/schedule_backfill.test.ts | 1 + .../application/rule/methods/update/update_rule.test.ts | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts index a276a345aab6f..39ac40a9bba14 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/backfill/methods/schedule/schedule_backfill.test.ts @@ -458,6 +458,7 @@ describe('scheduleBackfill()', () => { alertTypeId: existingDecryptedRule2.attributes.alertTypeId, apiKey: existingDecryptedRule2.attributes.apiKey, apiKeyCreatedByUser: existingDecryptedRule2.attributes.apiKeyCreatedByUser, + artifacts: { dashboards: [] }, consumer: existingDecryptedRule2.attributes.consumer, createdAt: new Date(existingDecryptedRule2.attributes.createdAt), createdBy: existingDecryptedRule2.attributes.createdBy, diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index b3405fa1f10da..99c12ec029353 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -486,7 +486,6 @@ describe('update()', () => { "apiKeyOwner": null, "artifacts": Object { "dashboards": Array [], - "investigation_guide": undefined, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -1430,7 +1429,6 @@ describe('update()', () => { "apiKeyOwner": "elastic", "artifacts": Object { "dashboards": Array [], - "investigation_guide": undefined, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -1609,7 +1607,6 @@ describe('update()', () => { "apiKeyOwner": null, "artifacts": Object { "dashboards": Array [], - "investigation_guide": undefined, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -3621,7 +3618,6 @@ describe('update()', () => { "apiKeyOwner": "elastic", "artifacts": Object { "dashboards": Array [], - "investigation_guide": undefined, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", From 71bc4e66e88518e23dd936f0a68081d2fb6261f4 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 9 Apr 2025 16:27:46 -0400 Subject: [PATCH 33/84] Temporarily allow console.log for debug purposes. --- .../security_and_spaces/group1/tests/alerting/find_internal.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts index e59415e58fbb2..22817c281c8ec 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts @@ -113,7 +113,9 @@ export default function createFindTests({ getService }: FtrProviderContext) { is_snoozed_until: null, }; + // eslint-disable-next-line no-console console.log('debug logging match', JSON.stringify(match)); + // eslint-disable-next-line no-console console.log('debug logging expected', JSON.stringify(expected)); expect(match).to.eql(expected); expect(Date.parse(match.created_at)).to.be.greaterThan(0); From 894deecd2f80ea7c36114ca0cf5efb96246b4f02 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 8 Apr 2025 13:15:58 -0400 Subject: [PATCH 34/84] Add tests for `denormalizeArtifacts`. --- .../lib/denormalize_artifacts.test.ts | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.test.ts diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.test.ts new file mode 100644 index 0000000000000..13c312ba4363b --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.test.ts @@ -0,0 +1,59 @@ +/* + * 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 { denormalizeArtifacts } from './denormalize_artifacts'; + +describe('denormalizeArtifacts', () => { + it('returns empty artifacts and references if no artifacts are provided', () => { + const { artifacts, references } = denormalizeArtifacts(undefined); + expect(artifacts).toEqual({ + dashboards: [], + investigation_guide: undefined, + }); + expect(references).toEqual([]); + }); + + it('returns denormalized artifacts and references', () => { + const ruleArtifacts = { + dashboards: [ + { + id: '123', + }, + { + id: '456', + }, + ], + investigation_guide: { + blob: '## Summary', + }, + }; + const { artifacts, references } = denormalizeArtifacts(ruleArtifacts); + expect(artifacts).toEqual({ + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ], + investigation_guide: ruleArtifacts.investigation_guide, + }); + expect(references).toEqual([ + { + id: '123', + name: 'dashboard_0', + type: 'dashboard', + }, + { + id: '456', + name: 'dashboard_1', + type: 'dashboard', + }, + ]); + }); +}); From eb747f8a1da42ccb2b1d696790a9ef52e65a4233 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 8 Apr 2025 12:33:32 -0400 Subject: [PATCH 35/84] Add unit tests for `injectReferencesIntoArtifacts`. --- .../common/inject_references.test.ts | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts new file mode 100644 index 0000000000000..fb67049369edb --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts @@ -0,0 +1,71 @@ +/* + * 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 { SavedObjectReference } from '@kbn/core/server'; +import { injectReferencesIntoArtifacts } from './inject_references'; + +describe('injectReferencesIntoArtifacts', () => { + it('returns default value if no artifacts are provided', () => { + expect(injectReferencesIntoArtifacts('test-id', undefined, [])).toEqual({ dashboards: [] }); + }); + + it('throws an error if the dashboard reference is not found', () => { + const artifacts = { + dashboards: [ + { + refId: 'dashboard_1', + }, + ], + }; + const refs: SavedObjectReference[] = []; + expect(() => injectReferencesIntoArtifacts('test-id', artifacts, refs)).toThrow( + 'Artifact reference "dashboard_1" not found in rule id: test-id' + ); + }); + + it('returns the artifacts with injected references', () => { + const artifacts = { + dashboards: [ + { + refId: 'dashboard_1', + }, + { + refId: 'dashboard_2', + }, + ], + investigation_guide: { + blob: '## Summary', + }, + }; + const refs: SavedObjectReference[] = [ + { + id: '123', + name: 'dashboard_1', + type: 'dashboard', + }, + { + id: '456', + name: 'dashboard_2', + type: 'dashboard', + }, + ]; + const result = injectReferencesIntoArtifacts('test-id', artifacts, refs); + expect(result).toEqual({ + dashboards: [ + { + id: '123', + }, + { + id: '456', + }, + ], + investigation_guide: { + blob: '## Summary', + }, + }); + }); +}); From 386f11d21bb2731fbf010db0825d8c0cf5561f75 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 9 Apr 2025 18:46:20 -0400 Subject: [PATCH 36/84] Fix issue from downstream port. --- .../server/rules_client/lib/denormalize_artifacts.test.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.test.ts index 13c312ba4363b..b128533fa1f5f 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.test.ts @@ -12,7 +12,6 @@ describe('denormalizeArtifacts', () => { const { artifacts, references } = denormalizeArtifacts(undefined); expect(artifacts).toEqual({ dashboards: [], - investigation_guide: undefined, }); expect(references).toEqual([]); }); @@ -27,9 +26,6 @@ describe('denormalizeArtifacts', () => { id: '456', }, ], - investigation_guide: { - blob: '## Summary', - }, }; const { artifacts, references } = denormalizeArtifacts(ruleArtifacts); expect(artifacts).toEqual({ @@ -41,7 +37,6 @@ describe('denormalizeArtifacts', () => { refId: 'dashboard_1', }, ], - investigation_guide: ruleArtifacts.investigation_guide, }); expect(references).toEqual([ { From f815d8db349ebd79c4fd0b6978ec3d69cbf79606 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 9 Apr 2025 18:46:54 -0400 Subject: [PATCH 37/84] Remove console.log call. --- .../group1/tests/alerting/find_internal.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts index 22817c281c8ec..363a942a23de7 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/find_internal.ts @@ -113,10 +113,6 @@ export default function createFindTests({ getService }: FtrProviderContext) { is_snoozed_until: null, }; - // eslint-disable-next-line no-console - console.log('debug logging match', JSON.stringify(match)); - // eslint-disable-next-line no-console - console.log('debug logging expected', JSON.stringify(expected)); expect(match).to.eql(expected); expect(Date.parse(match.created_at)).to.be.greaterThan(0); expect(Date.parse(match.updated_at)).to.be.greaterThan(0); From a85b1d4002abf7f7491927b4c80491fdc14cf364 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 10 Apr 2025 14:05:59 +0300 Subject: [PATCH 38/84] remove refId and investigation_guide(for now) --- .../plugins/shared/alerting/server/task_runner/fixtures.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/task_runner/fixtures.ts b/x-pack/platform/plugins/shared/alerting/server/task_runner/fixtures.ts index de10f3db84167..a6a0cbdf2a27a 100644 --- a/x-pack/platform/plugins/shared/alerting/server/task_runner/fixtures.ts +++ b/x-pack/platform/plugins/shared/alerting/server/task_runner/fixtures.ts @@ -302,12 +302,8 @@ export const mockedRule: SanitizedRule dashboards: [ { id: 'dashboard-1', - refId: 'ref-1', }, ], - investigation_guide: { - blob: 'guide-content', - }, }, }; From 7264aa8bfd4fb2ab841cc665afdc8524be696213 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 10 Apr 2025 14:28:27 +0300 Subject: [PATCH 39/84] remove investigation_guide reference in the test --- .../server/rules_client/common/inject_references.test.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts index fb67049369edb..3094bd69330a7 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts @@ -37,9 +37,6 @@ describe('injectReferencesIntoArtifacts', () => { refId: 'dashboard_2', }, ], - investigation_guide: { - blob: '## Summary', - }, }; const refs: SavedObjectReference[] = [ { @@ -63,9 +60,6 @@ describe('injectReferencesIntoArtifacts', () => { id: '456', }, ], - investigation_guide: { - blob: '## Summary', - }, }); }); }); From bc647f3af5bbd64e0d1be1d7d515e817dd98ac31 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 10 Apr 2025 15:40:24 +0300 Subject: [PATCH 40/84] unit tests for extract references --- .../lib/extract_references.test.ts | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts new file mode 100644 index 0000000000000..0f1c8469f34e7 --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts @@ -0,0 +1,134 @@ +/* + * 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 { SavedObjectReference } from '@kbn/core/server'; +import { RecoveredActionGroup } from '../../../common'; +import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; +import { extractReferences } from './extract_references'; +import type { RulesClientContext } from '..'; +import { savedObjectsRepositoryMock } from '@kbn/core-saved-objects-api-server-mocks'; + +import { denormalizeArtifacts } from './denormalize_artifacts'; + +jest.mock('./denormalize_artifacts', () => ({ + denormalizeArtifacts: jest.fn(), +})); + +const mockDenormalizeArtifacts = denormalizeArtifacts as jest.Mock; + +const loggerErrorMock = jest.fn(); +const getBulkMock = jest.fn(); + +const ruleType: jest.Mocked = { + id: 'test.rule-type', + name: 'My test rule', + actionGroups: [{ id: 'default', name: 'Default' }, RecoveredActionGroup], + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + recoveryActionGroup: RecoveredActionGroup, + executor: jest.fn(), + producer: 'alerts', + solution: 'stack', + cancelAlertsOnRuleTimeout: true, + ruleTaskTimeout: '5m', + autoRecoverAlerts: true, + doesSetRecoveryContext: true, + validate: { + params: { validate: (params) => params }, + }, + alerts: { + context: 'test', + mappings: { fieldMap: { field: { type: 'keyword', required: false } } }, + shouldWrite: true, + }, + category: 'test', + validLegacyConsumers: [], +}; + +const context = { + logger: { error: loggerErrorMock }, + getActionsClient: () => { + return { + getBulk: getBulkMock, + }; + }, + unsecuredSavedObjectsClient: savedObjectsRepositoryMock.create(), + authorization: { ensureAuthorized: async () => {} }, + ruleTypeRegistry: { + ensureRuleTypeEnabled: () => {}, + }, + getUserName: async () => {}, +} as unknown as RulesClientContext; + +jest.mock('./denormalize_artifacts', () => ({ + denormalizeArtifacts: jest.fn(), +})); + +describe('extractReferences', () => { + it('returns dashboard artifacts and references', async () => { + mockDenormalizeArtifacts.mockReturnValue({ + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ], + }, + references: [ + { + id: '123', + name: 'dashboard_0', + type: 'dashboard', + }, + { + id: '456', + name: 'dashboard_1', + type: 'dashboard', + }, + ], + }); + + const result = await extractReferences( + context, + ruleType, + [], + {}, + { + dashboards: [{ id: '123' }], + } + ); + + expect(mockDenormalizeArtifacts).toHaveBeenCalled(); + expect(result.artifacts).toEqual({ + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ], + }); + + expect(result.references).toEqual([ + { + id: '123', + name: 'dashboard_0', + type: 'dashboard', + }, + { + id: '456', + name: 'dashboard_1', + type: 'dashboard', + }, + ]); + }); +}); From 9fb63b0f1da154193059a488f0e30ad838576c78 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 10 Apr 2025 16:00:14 +0300 Subject: [PATCH 41/84] fix find internal api failing tests --- .../spaces_only/tests/alerting/group1/find_internal.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find_internal.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find_internal.ts index d0608a95651d5..652b5b61d0f60 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find_internal.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find_internal.ts @@ -119,6 +119,9 @@ export default function createFindTests({ getService }: FtrProviderContext) { params: {}, created_by: null, api_key_owner: null, + artifacts: { + dashboards: [], + }, api_key_created_by_user: null, scheduled_task_id: match.scheduled_task_id, updated_by: null, From 97d87ca13e93fedf16c6405d1948605f0a2a5747 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 10 Apr 2025 13:24:35 +0000 Subject: [PATCH 42/84] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../alerting/server/rules_client/lib/extract_references.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts index 0f1c8469f34e7..0a468d6bc5464 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { SavedObjectReference } from '@kbn/core/server'; import { RecoveredActionGroup } from '../../../common'; import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; import { extractReferences } from './extract_references'; From 929defdaf06d093acb3623494e7cef1da69fa46c Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 10 Apr 2025 17:58:13 +0300 Subject: [PATCH 43/84] add integration tests for update rule --- .../tests/alerting/group2/update.ts | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/update.ts index 596e49bed0bcd..962b161c23888 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/update.ts @@ -7,6 +7,9 @@ import expect from '@kbn/expect'; import { RULE_SAVED_OBJECT_TYPE } from '@kbn/alerting-plugin/server'; +import { ALERTING_CASES_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; +import type { SavedObject } from '@kbn/core/server'; +import type { RawRule } from '@kbn/alerting-plugin/server/types'; import { Spaces } from '../../../scenarios'; import { checkAAD, @@ -20,6 +23,7 @@ import type { FtrProviderContext } from '../../../../common/ftr_provider_context // eslint-disable-next-line import/no-default-export export default function createUpdateTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); + const es = getService('es'); describe('update', () => { const objectRemover = new ObjectRemover(supertest); @@ -453,5 +457,76 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { .expect(400); }); }); + + describe('artifacts', () => { + it('should not return dashboards in the response', async () => { + const expectedArtifacts = { + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + ], + }, + }; + + const createResponse = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData(expectedArtifacts)) + .expect(200); + + const esResponse = await es.get>( + { + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + id: `alert:${createResponse.body.id}`, + }, + { meta: true } + ); + + expect((esResponse.body._source as any)?.alert.artifacts.dashboards ?? []).to.eql([ + { + refId: 'dashboard_0', + }, + ]); + + const updateResponse = await supertest + .put(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule/${createResponse.body.id}`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'bcd', + tags: ['foo'], + params: { + foo: true, + }, + schedule: { interval: '12s' }, + actions: [], + throttle: '1m', + notify_when: 'onThrottleInterval', + artifacts: { + dashboards: [{ id: 'dashboard-1' }, { id: 'dashboard-2' }], + }, + }) + .expect(200); + + expect(updateResponse.body.artifacts).to.be(undefined); + + const esUpdateResponse = await es.get>( + { + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + id: `alert:${updateResponse.body.id}`, + }, + { meta: true } + ); + expect((esUpdateResponse.body._source as any)?.alert.artifacts.dashboards ?? {}).to.eql([ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ]); + }); + }); }); } From d47828dc4349f42714a8ef7b75e84288a57a1607 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 10 Apr 2025 18:33:04 +0300 Subject: [PATCH 44/84] add integration tests for artifacts for the pubic find api --- .../spaces_only/tests/alerting/group1/find.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts index 5eb3d75973945..fe0f8e67258ca 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts @@ -336,5 +336,33 @@ export default function createFindTests({ getService }: FtrProviderContext) { }); }); }); + + describe('artifacts', () => { + it('does not return artifacts when present', async () => { + const expectedArtifacts = { + artifacts: { + dashboards: [{ id: 'dashboard-1' }], + }, + }; + + const { body: createdAlert } = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData(expectedArtifacts)) + .expect(200); + + const { id } = createdAlert; + + const response = await supertest.get( + `${getUrlPrefix(Spaces.space1.id)}/api/alerting/rules/_find` + ); + + expect(response.status).to.eql(200); + + const foundAlert = response.body.data.find((obj: any) => obj.id === id); + expect(foundAlert).not.to.be(undefined); + expect(foundAlert.artifacts).to.be(undefined); + }); + }); }); } From 0c9e07290662b814e29d420810b0c3f71f924237 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 10 Apr 2025 23:04:02 +0300 Subject: [PATCH 45/84] proper clean up of rules to fix failing rule tags tests --- .../spaces_only/tests/alerting/group1/find.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts index fe0f8e67258ca..8cd08304f0d70 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/find.ts @@ -351,6 +351,8 @@ export default function createFindTests({ getService }: FtrProviderContext) { .send(getTestRuleData(expectedArtifacts)) .expect(200); + objectRemover.add(Spaces.space1.id, createdAlert.id, 'rule', 'alerting'); + const { id } = createdAlert; const response = await supertest.get( From 5b055ed71f1a2c50fa86cf694d20eac31817cd46 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 14 Apr 2025 15:35:47 +0300 Subject: [PATCH 46/84] use plural for dashboards and artifacts schema --- .../common/routes/rule/apis/create/schemas/v1.ts | 4 ++-- .../common/routes/rule/apis/update/schemas/v1.ts | 4 ++-- .../alerting/common/routes/rule/response/index.ts | 2 +- .../alerting/common/routes/rule/response/schemas/v1.ts | 8 ++++---- .../methods/create/schemas/create_rule_data_schema.ts | 4 ++-- .../methods/update/schemas/update_rule_data_schema.ts | 4 ++-- .../server/application/rule/schemas/artifact_schema.ts | 6 +++--- .../server/application/rule/schemas/rule_schemas.ts | 10 +++++----- .../server/saved_objects/schemas/raw_rule/v5.ts | 8 ++++---- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/schemas/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/schemas/v1.ts index 1ccd361e27f4f..d270fb8a87e25 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/schemas/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/create/schemas/v1.ts @@ -11,7 +11,7 @@ import { createRuleParamsExamplesV1, } from '@kbn/response-ops-rule-params'; import { validateDurationV1, validateHoursV1, validateTimezoneV1 } from '../../../validation'; -import { notifyWhenSchemaV1, alertDelaySchemaV1, artifactSchemaV1 } from '../../../response'; +import { notifyWhenSchemaV1, alertDelaySchemaV1, artifactsSchemaV1 } from '../../../response'; import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; import { flappingSchemaV1 } from '../../../common'; @@ -189,7 +189,7 @@ export const createBodySchema = schema.object({ notify_when: schema.maybe(schema.nullable(notifyWhenSchemaV1)), alert_delay: schema.maybe(alertDelaySchemaV1), flapping: schema.maybe(schema.nullable(flappingSchemaV1)), - artifacts: schema.maybe(artifactSchemaV1), + artifacts: schema.maybe(artifactsSchemaV1), }); export { createRuleParamsExamplesV1 }; diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/schemas/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/schemas/v1.ts index 2e9c5cc109d40..f23340832f102 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/schemas/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/apis/update/schemas/v1.ts @@ -9,7 +9,7 @@ import path from 'node:path'; import { schema } from '@kbn/config-schema'; import { ruleParamsSchemaWithDefaultValueV1 } from '@kbn/response-ops-rule-params'; import { validateDurationV1, validateHoursV1, validateTimezoneV1 } from '../../../validation'; -import { notifyWhenSchemaV1, alertDelaySchemaV1, artifactSchemaV1 } from '../../../response'; +import { notifyWhenSchemaV1, alertDelaySchemaV1, artifactsSchemaV1 } from '../../../response'; import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; import { flappingSchemaV1 } from '../../../common'; @@ -163,7 +163,7 @@ export const updateBodySchema = schema.object({ notify_when: schema.maybe(schema.nullable(notifyWhenSchemaV1)), alert_delay: schema.maybe(alertDelaySchemaV1), flapping: schema.maybe(schema.nullable(flappingSchemaV1)), - artifacts: schema.maybe(artifactSchemaV1), + artifacts: schema.maybe(artifactsSchemaV1), }); export const updateParamsSchema = schema.object({ diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/index.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/index.ts index e2c60ec319190..98fb488fec08e 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/index.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/index.ts @@ -30,7 +30,7 @@ export { notifyWhenSchema as notifyWhenSchemaV1, scheduleIdsSchema as scheduleIdsSchemaV1, alertDelaySchema as alertDelaySchemaV1, - artifactSchema as artifactSchemaV1, + artifactsSchema as artifactsSchemaV1, } from './schemas/v1'; export type { diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts index c4f079bba79c3..5de32c97153c4 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/schemas/v1.ts @@ -475,10 +475,10 @@ export const alertDelaySchema = schema.object( } ); -export const dashboardSchema = schema.arrayOf(schema.object({ id: schema.string() })); +export const dashboardsSchema = schema.arrayOf(schema.object({ id: schema.string() })); -export const artifactSchema = schema.object({ - dashboards: schema.maybe(dashboardSchema), +export const artifactsSchema = schema.object({ + dashboards: schema.maybe(dashboardsSchema), }); export const ruleResponseSchema = schema.object({ @@ -645,7 +645,7 @@ export const ruleResponseSchema = schema.object({ ), alert_delay: schema.maybe(alertDelaySchema), flapping: schema.maybe(schema.nullable(flappingSchemaV1)), - artifacts: schema.maybe(artifactSchema), + artifacts: schema.maybe(artifactsSchema), }); export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts index 666b52a08cb96..e74ad3b8b1bb4 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts @@ -14,7 +14,7 @@ import { actionRequestSchema, systemActionRequestSchema, flappingSchema, - artifactSchema, + artifactsSchema, } from '../../../schemas'; export const createRuleDataSchema = schema.object( @@ -40,7 +40,7 @@ export const createRuleDataSchema = schema.object( notifyWhen: schema.maybe(schema.nullable(notifyWhenSchema)), alertDelay: schema.maybe(alertDelaySchema), flapping: schema.maybe(schema.nullable(flappingSchema)), - artifacts: schema.maybe(artifactSchema), + artifacts: schema.maybe(artifactsSchema), }, { unknowns: 'allow' } ); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/schemas/update_rule_data_schema.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/schemas/update_rule_data_schema.ts index 9008893fe2e35..5c17a317f9341 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/schemas/update_rule_data_schema.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/schemas/update_rule_data_schema.ts @@ -14,7 +14,7 @@ import { actionRequestSchema, systemActionRequestSchema, flappingSchema, - artifactSchema, + artifactsSchema, } from '../../../schemas'; export const updateRuleDataSchema = schema.object( @@ -31,7 +31,7 @@ export const updateRuleDataSchema = schema.object( notifyWhen: schema.maybe(schema.nullable(notifyWhenSchema)), alertDelay: schema.maybe(alertDelaySchema), flapping: schema.maybe(schema.nullable(flappingSchema)), - artifacts: schema.maybe(artifactSchema), + artifacts: schema.maybe(artifactsSchema), }, { unknowns: 'allow' } ); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts index 18a3c2c8d50f5..7a713b3816e11 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts @@ -7,12 +7,12 @@ import { schema } from '@kbn/config-schema'; -export const dashboardSchema = schema.arrayOf( +export const dashboardsSchema = schema.arrayOf( schema.object({ id: schema.string(), }) ); -export const artifactSchema = schema.object({ - dashboards: schema.maybe(dashboardSchema), +export const artifactsSchema = schema.object({ + dashboards: schema.maybe(dashboardsSchema), }); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts index 4ac2257084ee8..a5975ff16ca4a 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts @@ -149,10 +149,10 @@ export const alertDelaySchema = schema.object({ active: schema.number(), }); -export const dashboardSchema = schema.arrayOf(schema.object({ id: schema.string() })); +export const dashboardsSchema = schema.arrayOf(schema.object({ id: schema.string() })); -export const artifactSchema = schema.object({ - dashboards: schema.maybe(dashboardSchema), +export const artifactsSchema = schema.object({ + dashboards: schema.maybe(dashboardsSchema), }); /** @@ -195,7 +195,7 @@ export const ruleDomainSchema = schema.object({ alertDelay: schema.maybe(alertDelaySchema), legacyId: schema.maybe(schema.nullable(schema.string())), flapping: schema.maybe(schema.nullable(flappingSchema)), - artifacts: schema.maybe(artifactSchema), + artifacts: schema.maybe(artifactsSchema), }); /** @@ -237,5 +237,5 @@ export const ruleSchema = schema.object({ alertDelay: schema.maybe(alertDelaySchema), legacyId: schema.maybe(schema.nullable(schema.string())), flapping: schema.maybe(schema.nullable(flappingSchema)), - artifacts: schema.maybe(artifactSchema), + artifacts: schema.maybe(artifactsSchema), }); diff --git a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts index 5bd3e4f884f19..f050f100db02d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v5.ts @@ -8,16 +8,16 @@ import { schema } from '@kbn/config-schema'; import { rawRuleSchema as rawRuleSchemaV4 } from './v4'; -export const rawRuleDashboardSchema = schema.arrayOf( +export const rawRuleDashboardsSchema = schema.arrayOf( schema.object({ refId: schema.string(), }) ); -export const artifactSchema = schema.object({ - dashboards: schema.maybe(rawRuleDashboardSchema), +export const artifactsSchema = schema.object({ + dashboards: schema.maybe(rawRuleDashboardsSchema), }); export const rawRuleSchema = rawRuleSchemaV4.extends({ - artifacts: schema.maybe(artifactSchema), + artifacts: schema.maybe(artifactsSchema), }); From e4427941997c0dd4f79a287261cdfab531ac1f34 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 14 Apr 2025 16:26:52 +0300 Subject: [PATCH 47/84] use plural for the Artifact --- src/platform/packages/shared/kbn-alerting-types/rule_types.ts | 4 ++-- .../server/rules_client/common/inject_references.test.ts | 2 +- .../alerting/server/rules_client/common/inject_references.ts | 2 +- .../alerting/server/rules_client/lib/denormalize_artifacts.ts | 4 ++-- .../alerting/server/rules_client/lib/extract_references.ts | 4 ++-- x-pack/platform/plugins/shared/alerting/server/types.ts | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts index 1e3bb75f8bd50..dbe63e953261e 100644 --- a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts +++ b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts @@ -219,7 +219,7 @@ export interface Dashboard extends SavedObjectAttributes { id: string; } -export interface Artifact extends SavedObjectAttributes { +export interface Artifacts extends SavedObjectAttributes { dashboards?: Dashboard[]; } @@ -259,7 +259,7 @@ export interface Rule { viewInAppRelativeUrl?: string; alertDelay?: AlertDelay | null; flapping?: Flapping | null; - artifacts?: Artifact | null; + artifacts?: Artifacts | null; } export type SanitizedRule = Omit< diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts index 3094bd69330a7..07013aeb25152 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts @@ -23,7 +23,7 @@ describe('injectReferencesIntoArtifacts', () => { }; const refs: SavedObjectReference[] = []; expect(() => injectReferencesIntoArtifacts('test-id', artifacts, refs)).toThrow( - 'Artifact reference "dashboard_1" not found in rule id: test-id' + 'Artifacts reference "dashboard_1" not found in rule id: test-id' ); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index bdf232f169367..17c935b23a1e3 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -91,7 +91,7 @@ export function injectReferencesIntoArtifacts( dashboards: artifacts.dashboards?.map((dashboard) => { const reference = references.find((ref) => ref.name === dashboard.refId); if (!reference) { - throw new Error(`Artifact reference "${dashboard.refId}" not found in rule id: ${ruleId}`); + throw new Error(`Artifacts reference "${dashboard.refId}" not found in rule id: ${ruleId}`); } return { ...omit(dashboard, 'refId'), diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts index af9ea6c86b079..10c40951dd95d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts @@ -5,10 +5,10 @@ * 2.0. */ import type { SavedObjectReference } from '@kbn/core/server'; -import type { Artifact } from '../../types'; +import type { Artifacts } from '../../types'; import type { DenormalizedArtifacts } from '../types'; -export function denormalizeArtifacts(ruleArtifacts: Artifact | undefined): { +export function denormalizeArtifacts(ruleArtifacts: Artifacts | undefined): { artifacts: DenormalizedArtifacts; references: SavedObjectReference[]; } { diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index 7352b154bcd83..ee142196bb3be 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -6,7 +6,7 @@ */ import type { SavedObjectReference } from '@kbn/core/server'; -import type { RuleTypeParams, Artifact } from '../../types'; +import type { RuleTypeParams, Artifacts } from '../../types'; import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; import type { DenormalizedAction, NormalizedAlertActionWithGeneratedValues } from '../types'; import { extractedSavedObjectParamReferenceNamePrefix } from '../common/constants'; @@ -22,7 +22,7 @@ export async function extractReferences< ruleType: UntypedNormalizedRuleType, ruleActions: NormalizedAlertActionWithGeneratedValues[], ruleParams: Params, - ruleArtifacts?: Artifact + ruleArtifacts?: Artifacts ): Promise<{ actions: DenormalizedAction[]; artifacts: DenormalizedArtifacts; diff --git a/x-pack/platform/plugins/shared/alerting/server/types.ts b/x-pack/platform/plugins/shared/alerting/server/types.ts index 6e36b39af17df..02e0bb41e6dbb 100644 --- a/x-pack/platform/plugins/shared/alerting/server/types.ts +++ b/x-pack/platform/plugins/shared/alerting/server/types.ts @@ -59,7 +59,7 @@ import type { GetTimeRangeResult } from './lib/get_time_range'; export type WithoutQueryAndParams = Pick>; export type SpaceIdToNamespaceFunction = (spaceId?: string) => string | undefined; export type { RuleTypeParams }; -export type { Artifact }; +export type { Artifacts }; /** * @public */ From 21506d2f3392189526bd3f35c1583ad57aa70e4a Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 14 Apr 2025 13:50:57 +0000 Subject: [PATCH 48/84] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- x-pack/platform/plugins/shared/alerting/server/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/types.ts b/x-pack/platform/plugins/shared/alerting/server/types.ts index 02e0bb41e6dbb..e45ecf0df6bb6 100644 --- a/x-pack/platform/plugins/shared/alerting/server/types.ts +++ b/x-pack/platform/plugins/shared/alerting/server/types.ts @@ -50,7 +50,6 @@ import type { SanitizedRuleConfig, SanitizedRule, RuleAlertData, - Artifact, } from '../common'; import type { PublicAlertFactory } from './alert/create_alert_factory'; import type { RulesSettingsFlappingProperties } from '../common/rules_settings'; From db1736a03aa99eba1cd0c24fa0c3328c5dfd6b22 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 14 Apr 2025 17:30:49 +0300 Subject: [PATCH 49/84] more fixes --- x-pack/platform/plugins/shared/alerting/common/index.ts | 2 +- x-pack/platform/plugins/shared/alerting/common/rule.ts | 2 +- x-pack/platform/plugins/shared/alerting/server/types.ts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/common/index.ts b/x-pack/platform/plugins/shared/alerting/common/index.ts index ca6668284e84f..a8fa863e3a99c 100644 --- a/x-pack/platform/plugins/shared/alerting/common/index.ts +++ b/x-pack/platform/plugins/shared/alerting/common/index.ts @@ -45,7 +45,7 @@ export type { RuleSystemActionKey, SanitizedRuleConfig, RuleMonitoringLastRunMetrics, - Artifact, + Artifacts, } from './rule'; export { RuleExecutionStatusValues, diff --git a/x-pack/platform/plugins/shared/alerting/common/rule.ts b/x-pack/platform/plugins/shared/alerting/common/rule.ts index 515bd1d73469f..cbf11cfda1819 100644 --- a/x-pack/platform/plugins/shared/alerting/common/rule.ts +++ b/x-pack/platform/plugins/shared/alerting/common/rule.ts @@ -45,7 +45,7 @@ export type { AlertsHealth, AlertingFrameworkHealth, ResolvedSanitizedRule, - Artifact, + Artifacts, } from '@kbn/alerting-types'; export { diff --git a/x-pack/platform/plugins/shared/alerting/server/types.ts b/x-pack/platform/plugins/shared/alerting/server/types.ts index e45ecf0df6bb6..e9269a7bd6979 100644 --- a/x-pack/platform/plugins/shared/alerting/server/types.ts +++ b/x-pack/platform/plugins/shared/alerting/server/types.ts @@ -50,6 +50,7 @@ import type { SanitizedRuleConfig, SanitizedRule, RuleAlertData, + Artifacts, } from '../common'; import type { PublicAlertFactory } from './alert/create_alert_factory'; import type { RulesSettingsFlappingProperties } from '../common/rules_settings'; From d3126da85de2da84ade548ec89118930befcefdb Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Mon, 14 Apr 2025 17:47:55 +0300 Subject: [PATCH 50/84] Update x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts Co-authored-by: Christos Nasikas --- .../alerting/server/rules_client/common/inject_references.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index 17c935b23a1e3..bbbacd811fd44 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -89,7 +89,7 @@ export function injectReferencesIntoArtifacts( return { ...artifacts, dashboards: artifacts.dashboards?.map((dashboard) => { - const reference = references.find((ref) => ref.name === dashboard.refId); + const reference = references.find((ref) => ref.name === dashboard.refId && ref.type === 'dashboard'); if (!reference) { throw new Error(`Artifacts reference "${dashboard.refId}" not found in rule id: ${ruleId}`); } From b92bab3b64b83c4787203f2c44e53b4f52819c23 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 14 Apr 2025 15:14:31 +0000 Subject: [PATCH 51/84] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../alerting/server/rules_client/common/inject_references.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index bbbacd811fd44..c1a8fa2f7bd4a 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -89,7 +89,9 @@ export function injectReferencesIntoArtifacts( return { ...artifacts, dashboards: artifacts.dashboards?.map((dashboard) => { - const reference = references.find((ref) => ref.name === dashboard.refId && ref.type === 'dashboard'); + const reference = references.find( + (ref) => ref.name === dashboard.refId && ref.type === 'dashboard' + ); if (!reference) { throw new Error(`Artifacts reference "${dashboard.refId}" not found in rule id: ${ruleId}`); } From 70c229ebe582e85c49bb16355040caf8807c113b Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 15 Apr 2025 12:31:42 +0300 Subject: [PATCH 52/84] address PR feedback --- .../packages/shared/kbn-alerting-types/rule_types.ts | 4 ++-- .../find/transforms/transform_find_rules_response/v1.ts | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts index dbe63e953261e..2de420ecd4360 100644 --- a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts +++ b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts @@ -215,11 +215,11 @@ export interface Flapping extends SavedObjectAttributes { statusChangeThreshold: number; } -export interface Dashboard extends SavedObjectAttributes { +export interface Dashboard { id: string; } -export interface Artifacts extends SavedObjectAttributes { +export interface Artifacts { dashboards?: Dashboard[]; } diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts index b98bc26d6b547..8941372f3eabe 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts @@ -81,11 +81,7 @@ export const transformPartialRule = ( : {}), ...(rule.alertDelay !== undefined ? { alert_delay: rule.alertDelay } : {}), ...(rule.flapping !== undefined ? { flapping: transformFlappingV1(rule.flapping) } : {}), - ...(isInternal - ? rule.artifacts !== undefined - ? { artifacts: rule.artifacts } - : { artifacts: { dashboards: [] } } - : {}), + ...(isInternal && rule.artifacts !== undefined ? { artifacts: rule.artifacts } : {}), }; type RuleKeys = keyof RuleResponseV1; From 6254e0f7550169eb4cdc2d1692ea21d8f65a3455 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 15 Apr 2025 12:39:37 +0300 Subject: [PATCH 53/84] bulk edit changes --- .../methods/bulk_edit/bulk_edit_rules.test.ts | 201 +++++++++++++++++- .../rule/methods/bulk_edit/bulk_edit_rules.ts | 13 +- .../rules_client/lib/extract_references.ts | 2 +- 3 files changed, 210 insertions(+), 6 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts index aaa5fbf62f143..229e853c32344 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.test.ts @@ -1097,6 +1097,203 @@ describe('bulkEdit()', () => { }); }); + test('should add system and default actions when there are existing artifacts', async () => { + mockCreatePointInTimeFinderAsInternalUser({ + saved_objects: [ + { + ...existingDecryptedRule, + attributes: { + ...existingDecryptedRule.attributes, + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + ], + }, + } as any, + references: [ + { + id: 'dashboard-1', + type: 'dashboard', + name: 'dashboard_0', + }, + ] as any, + }, + ], + }); + + const defaultAction = { + frequency: { + notifyWhen: 'onActiveAlert' as const, + summary: false, + throttle: null, + }, + group: 'default', + id: '1', + params: {}, + }; + + const systemAction = { + id: 'system_action-id', + params: {}, + }; + + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ + saved_objects: [ + { + ...existingRule, + attributes: { + ...existingRule.attributes, + actions: [ + { + frequency: { + notifyWhen: 'onActiveAlert' as const, + summary: false, + throttle: null, + }, + group: 'default', + params: {}, + actionRef: 'action_0', + actionTypeId: 'test-1', + uuid: '222', + }, + { + params: {}, + actionRef: 'system_action:system_action-id', + actionTypeId: 'test-2', + uuid: '222', + }, + ], + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + ], + }, + }, + references: [ + { + name: 'action_0', + type: 'action', + id: '1', + }, + { + name: 'dashboard_0', + type: 'dashboard', + id: 'dashboard-1', + }, + ], + }, + ], + }); + + actionsClient.getBulk.mockResolvedValue([ + { + id: '1', + actionTypeId: 'test-1', + config: {}, + isMissingSecrets: false, + name: 'test default connector', + isPreconfigured: false, + isDeprecated: false, + isSystemAction: false, + }, + { + id: 'system_action-id', + actionTypeId: 'test-2', + config: {}, + isMissingSecrets: false, + name: 'system action connector', + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ]); + + const result = await rulesClient.bulkEdit({ + filter: '', + operations: [ + { + field: 'actions', + operation: 'add', + value: [defaultAction, systemAction], + }, + ], + }); + + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + { + ...existingRule, + attributes: { + ...existingRule.attributes, + actions: [ + { + actionRef: 'action_0', + actionTypeId: 'test-1', + frequency: { notifyWhen: 'onActiveAlert', summary: false, throttle: null }, + group: 'default', + params: {}, + uuid: '105', + }, + { + actionRef: 'system_action:system_action-id', + actionTypeId: 'test-2', + params: {}, + uuid: '106', + }, + ], + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + ], + }, + apiKey: null, + apiKeyOwner: null, + apiKeyCreatedByUser: null, + meta: { versionApiKeyLastmodified: 'v8.2.0' }, + name: 'my rule name', + enabled: false, + updatedAt: '2019-02-12T21:01:22.479Z', + updatedBy: 'elastic', + tags: ['foo'], + revision: 1, + }, + references: [ + { id: '1', name: 'action_0', type: 'action' }, + { id: 'dashboard-1', name: 'dashboard_0', type: 'dashboard' }, + ], + }, + ], + { overwrite: true } + ); + + expect(result.rules[0]).toEqual({ + ...omit(existingRule.attributes, 'legacyId'), + createdAt: new Date(existingRule.attributes.createdAt), + updatedAt: new Date(existingRule.attributes.updatedAt), + executionStatus: { + ...existingRule.attributes.executionStatus, + lastExecutionDate: new Date(existingRule.attributes.executionStatus.lastExecutionDate), + }, + actions: [{ ...defaultAction, actionTypeId: 'test-1', uuid: '222' }], + systemActions: [{ ...systemAction, actionTypeId: 'test-2', uuid: '222' }], + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + ], + }, + id: existingRule.id, + snoozeSchedule: [], + }); + }); + test('should construct the refs correctly and persist the actions correctly', async () => { const defaultAction = { frequency: { @@ -1197,13 +1394,13 @@ describe('bulkEdit()', () => { frequency: { notifyWhen: 'onActiveAlert', summary: false, throttle: null }, group: 'default', params: {}, - uuid: '105', + uuid: '107', }, { actionRef: 'system_action:system_action-id', actionTypeId: 'test-2', params: {}, - uuid: '106', + uuid: '108', }, ]); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts index 8a95464a48a4a..2d6936dadbbbf 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -39,6 +39,7 @@ import { getBulkUnsnooze, verifySnoozeScheduleLimit, injectReferencesIntoActions, + injectReferencesIntoArtifacts, } from '../../../../rules_client/common'; import { alertingAuthorizationFilterOpts, @@ -329,7 +330,6 @@ async function bulkEditRulesOcc( ); } await rulesFinder.close(); - const updatedInterval = rules .filter((rule) => rule.attributes.enabled) .map((rule) => rule.attributes.schedule?.interval) @@ -468,9 +468,15 @@ async function updateRuleAttributesAndParamsInMemory( attributes: rule.attributes as RawRule, }); + const ruleArtifacts = injectReferencesIntoArtifacts( + rule.id, + rule.attributes.artifacts, + rule.references || [] + ); + if (migratedActions.hasLegacyActions) { rule.attributes.actions = migratedActions.resultedActions; - rule.references = migratedActions.resultedReferences; + rule.references = migratedActions.resultedReferences; // TODO check if this will break references that include artifacts } const ruleActions = injectReferencesIntoActions( @@ -550,7 +556,8 @@ async function updateRuleAttributesAndParamsInMemory( context, ruleType, updatedRuleActions as NormalizedAlertActionWithGeneratedValues[], - validatedMutatedAlertTypeParams + validatedMutatedAlertTypeParams, + ruleArtifacts ); const ruleAttributes = transformRuleDomainToRuleAttributes({ diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index ee142196bb3be..f287a47fa8bc6 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -22,7 +22,7 @@ export async function extractReferences< ruleType: UntypedNormalizedRuleType, ruleActions: NormalizedAlertActionWithGeneratedValues[], ruleParams: Params, - ruleArtifacts?: Artifacts + ruleArtifacts: Artifacts ): Promise<{ actions: DenormalizedAction[]; artifacts: DenormalizedArtifacts; From 53fe0322aa912c431cd81b94c51b19168a61f859 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 15 Apr 2025 16:35:39 +0300 Subject: [PATCH 54/84] more updates --- .../server/application/rule/methods/create/create_rule.ts | 3 ++- .../server/application/rule/methods/update/update_rule.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts index a68abe5aff84c..673a346f9b987 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts @@ -191,6 +191,7 @@ export async function createRule( } const allActions = [...data.actions, ...(data.systemActions ?? [])]; + const artifacts = data.artifacts ?? {}; // Extract saved object references for this rule const { references, @@ -198,7 +199,7 @@ export async function createRule( actions: actionsWithRefs, artifacts: artifactsWithRefs, } = await withSpan({ name: 'extractReferences', type: 'rules' }, () => - extractReferences(context, ruleType, allActions, validatedRuleTypeParams, initialData.artifacts) + extractReferences(context, ruleType, allActions, validatedRuleTypeParams, artifacts) ); const createTime = Date.now(); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts index 98ec271809e64..187e4da9e8901 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts @@ -306,6 +306,7 @@ async function updateRuleAttributes({ let updatedRule = { ...originalRule }; const allActions = [...updateRuleData.actions, ...(updateRuleData.systemActions ?? [])]; + const artifacts = updateRuleData.artifacts ?? {}; const ruleType = context.ruleTypeRegistry.get(updatedRule.alertTypeId); // Extract saved object references for this rule @@ -319,7 +320,7 @@ async function updateRuleAttributes({ ruleType, allActions as NormalizedAlertActionWithGeneratedValues[], validatedRuleTypeParams, - updateRuleData.artifacts + artifacts ); // Increment revision if applicable field has changed From a97d0bdf125aea39bf218c62e5b4fc469960dd9e Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 15 Apr 2025 16:46:11 +0300 Subject: [PATCH 55/84] add artifacts as optional to the response type --- .../shared/alerting/common/routes/rule/response/types/v1.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts index 8b305195610b6..b6f9aed370892 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/response/types/v1.ts @@ -54,4 +54,5 @@ export interface RuleResponse { view_in_app_relative_url?: RuleResponseSchemaType['view_in_app_relative_url']; alert_delay?: RuleResponseSchemaType['alert_delay']; flapping?: RuleResponseSchemaType['flapping']; + artifacts?: RuleResponseSchemaType['artifacts']; } From 140b9536ac77b24b24195a9124483f5d294eb6dc Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 15 Apr 2025 17:08:56 +0300 Subject: [PATCH 56/84] update update_rule tests --- .../application/rule/methods/update/update_rule.test.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index 99c12ec029353..dc227646091b7 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -4281,10 +4281,10 @@ describe('update()', () => { test('updates the artifacts', async () => { const existingDashboards = [ { - id: 'dashboard-1', + refId: 'dashboard_0', }, { - id: 'dashboard-2', + refId: 'dashboard_1', }, ]; @@ -4324,6 +4324,11 @@ describe('update()', () => { type: 'dashboard', id: 'dashboard-1', }, + { + name: 'dashboard_1', + type: 'dashboard', + id: 'dashboard-2', + }, ], version: '123', }; From 69bbc53bce9b71920e0397dcc52d79e5ce092d0d Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 15 Apr 2025 17:31:39 +0300 Subject: [PATCH 57/84] add more tests to the update_rule method (link new dashboard) --- .../rule/methods/update/update_rule.test.ts | 222 +++++++++++++++++- 1 file changed, 221 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index dc227646091b7..7d744f163b678 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -4278,7 +4278,7 @@ describe('update()', () => { }); describe('artifacts', () => { - test('updates the artifacts', async () => { + test('remove an existing dashboard', async () => { const existingDashboards = [ { refId: 'dashboard_0', @@ -4453,5 +4453,225 @@ describe('update()', () => { } `); }); + + test('adds a new linked dashboard', async () => { + const existingDashboards = [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ]; + + const existingRule = { + id: '1', + type: RULE_SAVED_OBJECT_TYPE, + attributes: { + name: 'fakeRuleName', + enabled: true, + tags: ['foo'], + alertTypeId: 'myType', + schedule: { interval: '1m' }, + consumer: 'myApp', + revision: 0, + scheduledTaskId: 'task-123', + params: {}, + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, + muteAll: false, + legacyId: null, + snoozeSchedule: [], + mutedInstanceIds: [], + createdBy: 'elastic', + createdAt: '2019-02-12T21:01:22.479Z', + updatedBy: 'elastic', + updatedAt: '2019-02-12T21:01:22.479Z', + actions: [], + artifacts: { + dashboards: existingDashboards, + }, + }, + references: [ + { + name: 'dashboard_0', + type: 'dashboard', + id: 'dashboard-1', + }, + { + name: 'dashboard_1', + type: 'dashboard', + id: 'dashboard-2', + }, + ], + version: '123', + }; + + unsecuredSavedObjectsClient.get.mockResolvedValue(existingRule); + + unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ + id: '1', + type: RULE_SAVED_OBJECT_TYPE, + attributes: { + enabled: true, + schedule: { interval: '1m' }, + params: { + bar: true, + }, + actions: [], + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + { + refId: 'dashboard_2', + }, + ], + }, + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, + notifyWhen: 'onActiveAlert', + revision: 1, + scheduledTaskId: 'task-123', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }, + references: [ + { + name: 'dashboard_0', + type: 'dashboard', + id: 'dashboard-1', + }, + { + name: 'dashboard_1', + type: 'dashboard', + id: 'dashboard-2', + }, + { + name: 'dashboard_2', + type: 'dashboard', + id: 'dashboard-3', + }, + ], + }); + + const result = await rulesClient.update({ + id: '1', + data: { + schedule: { interval: '1m' }, + name: 'abc', + tags: ['foo'], + params: { + bar: true, + }, + throttle: null, + notifyWhen: 'onActiveAlert', + actions: [], + systemActions: [], + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + { + id: 'dashboard-2', + }, + { + id: 'dashboard-3', + }, + ], + }, + }, + }); + + expect(unsecuredSavedObjectsClient.create).toHaveBeenNthCalledWith( + 1, + RULE_SAVED_OBJECT_TYPE, + expect.objectContaining({ + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + { + refId: 'dashboard_2', + }, + ], + }, + }), + { + id: '1', + overwrite: true, + references: [ + { id: 'dashboard-1', name: 'dashboard_0', type: 'dashboard' }, + { id: 'dashboard-2', name: 'dashboard_1', type: 'dashboard' }, + { id: 'dashboard-3', name: 'dashboard_2', type: 'dashboard' }, + ], + version: '123', + } + ); + + expect(result?.artifacts).toEqual({ + dashboards: [ + { + id: 'dashboard-1', + }, + { + id: 'dashboard-2', + }, + { + id: 'dashboard-3', + }, + ], + }); + + expect(result).toMatchInlineSnapshot(` + Object { + "actions": Array [], + "artifacts": Object { + "dashboards": Array [ + Object { + "id": "dashboard-1", + }, + Object { + "id": "dashboard-2", + }, + Object { + "id": "dashboard-3", + }, + ], + }, + "createdAt": 2019-02-12T21:01:22.479Z, + "enabled": true, + "executionStatus": Object { + "lastExecutionDate": 2019-02-12T21:01:22.479Z, + "status": "pending", + }, + "id": "1", + "notifyWhen": "onActiveAlert", + "params": Object { + "bar": true, + }, + "revision": 1, + "schedule": Object { + "interval": "1m", + }, + "scheduledTaskId": "task-123", + "systemActions": Array [], + "updatedAt": 2019-02-12T21:01:22.479Z, + } + `); + }); }); }); From 7a788069fdfcabca5f507bab166c068927475bff Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 15 Apr 2025 11:31:04 -0400 Subject: [PATCH 58/84] Increase limit of inspector bundle size. --- packages/kbn-optimizer/limits.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 6de583177707d..1d3915ec3f6af 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -85,7 +85,7 @@ pageLoadAssetSize: infra: 184320 ingestPipelines: 58003 inputControlVis: 172675 - inspector: 17600 + inspector: 17900 interactiveSetup: 80000 inventory: 27430 kibanaOverview: 56279 From d776aa01ff63e9ea88c334daa9d64571b5462ac7 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 16 Apr 2025 12:45:21 +0300 Subject: [PATCH 59/84] make artifacts optional --- .../application/rule/methods/bulk_edit/bulk_edit_rules.ts | 4 ++-- .../transforms/transform_rule_attributes_to_rule_domain.ts | 4 ++-- .../server/rules_client/common/inject_references.test.ts | 6 +++--- .../server/rules_client/common/inject_references.ts | 4 ++-- .../alerting/server/rules_client/lib/get_alert_from_raw.ts | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts index 2d6936dadbbbf..ff32a4d3026c7 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -470,8 +470,8 @@ async function updateRuleAttributesAndParamsInMemory( const ruleArtifacts = injectReferencesIntoArtifacts( rule.id, - rule.attributes.artifacts, - rule.references || [] + rule.references || [], + rule.attributes.artifacts ); if (migratedActions.hasLegacyActions) { diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts index ee08b600d6cf7..4c7a713577f2e 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts @@ -174,8 +174,8 @@ export const transformRuleAttributesToRuleDomain = ( id, diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts index 07013aeb25152..01ff7540af954 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts @@ -10,7 +10,7 @@ import { injectReferencesIntoArtifacts } from './inject_references'; describe('injectReferencesIntoArtifacts', () => { it('returns default value if no artifacts are provided', () => { - expect(injectReferencesIntoArtifacts('test-id', undefined, [])).toEqual({ dashboards: [] }); + expect(injectReferencesIntoArtifacts('test-id', [], undefined)).toEqual({ dashboards: [] }); }); it('throws an error if the dashboard reference is not found', () => { @@ -22,7 +22,7 @@ describe('injectReferencesIntoArtifacts', () => { ], }; const refs: SavedObjectReference[] = []; - expect(() => injectReferencesIntoArtifacts('test-id', artifacts, refs)).toThrow( + expect(() => injectReferencesIntoArtifacts('test-id', refs, artifacts)).toThrow( 'Artifacts reference "dashboard_1" not found in rule id: test-id' ); }); @@ -50,7 +50,7 @@ describe('injectReferencesIntoArtifacts', () => { type: 'dashboard', }, ]; - const result = injectReferencesIntoArtifacts('test-id', artifacts, refs); + const result = injectReferencesIntoArtifacts('test-id', refs, artifacts); expect(result).toEqual({ dashboards: [ { diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index c1a8fa2f7bd4a..c0d359f4792e3 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -80,8 +80,8 @@ export function injectReferencesIntoParams< export function injectReferencesIntoArtifacts( ruleId: string, - artifacts: RawRule['artifacts'], - references: SavedObjectReference[] + references: SavedObjectReference[], + artifacts?: RawRule['artifacts'] ) { if (!artifacts) { return { dashboards: [] }; diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts index 6219c3b98fefb..2955a40612abd 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts @@ -170,7 +170,7 @@ function getPartialRuleFromRaw( omitGeneratedValues, }) : [], - artifacts: injectReferencesIntoArtifacts(opts.id, artifacts, opts.references || []), + artifacts: injectReferencesIntoArtifacts(opts.id, opts.references || [], artifacts), params: injectReferencesIntoParams( opts.id, opts.ruleType, From 6e24df3ce2f32b8e64b7e504acdd3046c4119e10 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 16 Apr 2025 12:50:09 +0300 Subject: [PATCH 60/84] type return value of injectReferencesIntoArtifacts --- .../alerting/server/rules_client/common/inject_references.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index c0d359f4792e3..360eaf3b34831 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -10,6 +10,7 @@ import { omit } from 'lodash'; import type { SavedObjectReference, SavedObjectAttributes } from '@kbn/core/server'; import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; import type { RawRule, RuleTypeParams } from '../../types'; +import type { RuleDomain } from '../../application/rule/types'; import { preconfiguredConnectorActionRefPrefix, extractedSavedObjectParamReferenceNamePrefix, @@ -82,7 +83,7 @@ export function injectReferencesIntoArtifacts( ruleId: string, references: SavedObjectReference[], artifacts?: RawRule['artifacts'] -) { +): RuleDomain['artifacts'] { if (!artifacts) { return { dashboards: [] }; } From 1e191c4d870d579c3ff93c9f5c0f237c501af7c8 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 16 Apr 2025 13:46:21 +0300 Subject: [PATCH 61/84] add more tests to transform_rule_attributes_to_rule_domain --- ...orm_rule_attributes_to_rule_domain.test.ts | 156 ++++++++++++++---- 1 file changed, 120 insertions(+), 36 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.test.ts index b24cb5d608219..80fa9034c7082 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.test.ts @@ -64,44 +64,44 @@ const isSystemAction = (id: string) => id === 'my-system-action-id'; describe('transformRuleAttributesToRuleDomain', () => { const MOCK_API_KEY = Buffer.from('123:abc').toString('base64'); const logger = loggingSystemMock.create().get(); - const references = [{ name: 'default-action-ref', type: 'action', id: 'default-action-id' }]; - - const rule = { - enabled: false, - tags: ['foo'], - createdBy: 'user', - createdAt: '2019-02-12T21:01:22.479Z', - updatedAt: '2019-02-12T21:01:22.479Z', - legacyId: null, - muteAll: false, - mutedInstanceIds: [], - snoozeSchedule: [], - alertTypeId: 'myType', - schedule: { interval: '1m' }, - consumer: 'myApp', - scheduledTaskId: 'task-123', - executionStatus: { - lastExecutionDate: '2019-02-12T21:01:22.479Z', - status: 'pending' as const, - error: null, - warning: null, - }, - params: {}, - throttle: null, - notifyWhen: null, - actions: [defaultAction, systemAction], - name: 'my rule name', - revision: 0, - updatedBy: 'user', - apiKey: MOCK_API_KEY, - apiKeyOwner: 'user', - flapping: { - lookBackWindow: 20, - statusChangeThreshold: 20, - }, - }; it('transforms the actions correctly', () => { + const references = [{ name: 'default-action-ref', type: 'action', id: 'default-action-id' }]; + + const rule = { + enabled: false, + tags: ['foo'], + createdBy: 'user', + createdAt: '2019-02-12T21:01:22.479Z', + updatedAt: '2019-02-12T21:01:22.479Z', + legacyId: null, + muteAll: false, + mutedInstanceIds: [], + snoozeSchedule: [], + alertTypeId: 'myType', + schedule: { interval: '1m' }, + consumer: 'myApp', + scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending' as const, + error: null, + warning: null, + }, + params: {}, + throttle: null, + notifyWhen: null, + actions: [defaultAction, systemAction], + name: 'my rule name', + revision: 0, + updatedBy: 'user', + apiKey: MOCK_API_KEY, + apiKeyOwner: 'user', + flapping: { + lookBackWindow: 20, + statusChangeThreshold: 20, + }, + }; const res = transformRuleAttributesToRuleDomain( rule, { @@ -153,4 +153,88 @@ describe('transformRuleAttributesToRuleDomain', () => { ] `); }); + + it('transforms the artifacts correctly', () => { + const artifacts = { + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ], + }; + + const actionReferences = [ + { name: 'default-action-ref', type: 'action', id: 'default-action-id' }, + ]; + + const artifactsReferences = [ + { name: 'dashboard_0', type: 'dashboard', id: 'dashboard-1' }, + { name: 'dashboard_1', type: 'dashboard', id: 'dashboard-2' }, + ]; + + const references = [...actionReferences, ...artifactsReferences]; + + const rule = { + enabled: false, + tags: ['foo'], + createdBy: 'user', + createdAt: '2019-02-12T21:01:22.479Z', + updatedAt: '2019-02-12T21:01:22.479Z', + legacyId: null, + muteAll: false, + mutedInstanceIds: [], + snoozeSchedule: [], + alertTypeId: 'myType', + schedule: { interval: '1m' }, + consumer: 'myApp', + scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending' as const, + error: null, + warning: null, + }, + params: {}, + throttle: null, + notifyWhen: null, + actions: [defaultAction, systemAction], + artifacts, + name: 'my rule name', + revision: 0, + updatedBy: 'user', + apiKey: MOCK_API_KEY, + apiKeyOwner: 'user', + flapping: { + lookBackWindow: 20, + statusChangeThreshold: 20, + }, + }; + + const res = transformRuleAttributesToRuleDomain( + rule, + { + id: '1', + logger, + ruleType, + references, + }, + isSystemAction + ); + + expect(res.artifacts).toMatchInlineSnapshot(` + Object { + "dashboards": Array [ + Object { + "id": "dashboard-1", + }, + Object { + "id": "dashboard-2", + }, + ], + } + `); + }); }); From e606da3cc51accaeea2b33590ebafee7f4bc7ef5 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 16 Apr 2025 14:48:28 +0300 Subject: [PATCH 62/84] fix type issues --- .../alerting/server/rules_client/lib/extract_references.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index f287a47fa8bc6..1cd49c9ce6ae8 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -22,7 +22,7 @@ export async function extractReferences< ruleType: UntypedNormalizedRuleType, ruleActions: NormalizedAlertActionWithGeneratedValues[], ruleParams: Params, - ruleArtifacts: Artifacts + ruleArtifacts: Artifacts | undefined ): Promise<{ actions: DenormalizedAction[]; artifacts: DenormalizedArtifacts; From 674db1a38f165b165a90410d6d8e8ee61991d7db Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 16 Apr 2025 15:01:42 +0300 Subject: [PATCH 63/84] return fake artifact along with dashboards --- .../server/rules_client/common/inject_references.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts index 01ff7540af954..53d4fcc051aad 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts @@ -37,6 +37,9 @@ describe('injectReferencesIntoArtifacts', () => { refId: 'dashboard_2', }, ], + investigation_guide: { + blob: 'test', + }, }; const refs: SavedObjectReference[] = [ { @@ -60,6 +63,9 @@ describe('injectReferencesIntoArtifacts', () => { id: '456', }, ], + investigation_guide: { + blob: 'test', + }, }); }); }); From 09260845c32fef31da7a5e4dc3d4c9a4e3932ae9 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 16 Apr 2025 15:17:04 +0300 Subject: [PATCH 64/84] remove the call to the dashboard api --- .../tests/alerting/group1/create.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts index 5a58256cc1b15..8f59d122e67e8 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts @@ -774,23 +774,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { }); it('should store references correctly for dashboard artifacts', async () => { - const { body: createdDashboard } = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/api/content_management/rpc/create`) - .set('kbn-xsrf', 'foo') - .send({ - contentTypeId: 'dashboard', - data: { - kibanaSavedObjectMeta: {}, - title: 'Sample dashboard', - }, - options: { - references: [], - overwrite: true, - }, - version: 2, - }) - .expect(200); - const dashboardId = createdDashboard.result.result.item.id; + const dashboardId = 'dashboard-1'; const response = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) .set('kbn-xsrf', 'foo') From ec63b16320e3776c07d1eea26699cf7350aacfcf Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 16 Apr 2025 12:38:46 -0400 Subject: [PATCH 65/84] Add new `transformRawArtifactsToDomainArtifacts` function. --- ...sform_raw_artifacts_to_domain_artifacts.ts | 19 +++++++++++++++++++ ...ransform_rule_attributes_to_rule_domain.ts | 12 +++++------- .../rules_client/common/inject_references.ts | 6 +++--- .../rules_client/lib/get_alert_from_raw.ts | 5 +++-- 4 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.ts diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.ts new file mode 100644 index 0000000000000..3ac1222c1669e --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.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 type { SavedObjectReference } from '@kbn/core/server'; +import type { RawRule } from '../../../types'; +import type { RuleDomain } from '../types'; +import { injectReferencesIntoArtifacts } from '../../../rules_client/common'; + +export function transformRawArtifactsToDomainArtifacts( + id: string, + rawArtifacts?: RawRule['artifacts'], + references?: SavedObjectReference[] +): RuleDomain['artifacts'] { + return injectReferencesIntoArtifacts(id, rawArtifacts, references || []); +} diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts index ee08b600d6cf7..70489f4377cec 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts @@ -12,15 +12,13 @@ import { getRuleSnoozeEndTime } from '../../../lib'; import type { RuleDomain, Monitoring, RuleParams } from '../types'; import type { PartialRule, RawRule, RawRuleExecutionStatus, SanitizedRule } from '../../../types'; import type { UntypedNormalizedRuleType } from '../../../rule_type_registry'; -import { - injectReferencesIntoParams, - injectReferencesIntoArtifacts, -} from '../../../rules_client/common'; +import { injectReferencesIntoParams } from '../../../rules_client/common'; import { getActiveScheduledSnoozes } from '../../../lib/is_rule_snoozed'; import { transformRawActionsToDomainActions, transformRawActionsToDomainSystemActions, } from './transform_raw_actions_to_domain_actions'; +import { transformRawArtifactsToDomainArtifacts } from './transform_raw_artifacts_to_domain_artifacts'; const INITIAL_LAST_RUN_METRICS = { duration: 0, @@ -172,10 +170,10 @@ export const transformRuleAttributesToRuleDomain = ( id, @@ -242,7 +240,7 @@ export const transformRuleAttributesToRuleDomain = { - const reference = references.find( + const reference = references?.find( (ref) => ref.name === dashboard.refId && ref.type === 'dashboard' ); if (!reference) { diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts index 6219c3b98fefb..d09e57c7fc627 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/get_alert_from_raw.ts @@ -24,12 +24,13 @@ import { } from '../../lib'; import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; import { getActiveScheduledSnoozes } from '../../lib/is_rule_snoozed'; -import { injectReferencesIntoArtifacts, injectReferencesIntoParams } from '../common'; +import { injectReferencesIntoParams } from '../common'; import { transformRawActionsToDomainActions, transformRawActionsToDomainSystemActions, } from '../../application/rule/transforms/transform_raw_actions_to_domain_actions'; import { fieldsToExcludeFromPublicApi } from '../rules_client'; +import { transformRawArtifactsToDomainArtifacts } from '../../application/rule/transforms/transform_raw_artifacts_to_domain_artifacts'; export interface GetAlertFromRawParams { id: string; @@ -170,7 +171,7 @@ function getPartialRuleFromRaw( omitGeneratedValues, }) : [], - artifacts: injectReferencesIntoArtifacts(opts.id, artifacts, opts.references || []), + artifacts: transformRawArtifactsToDomainArtifacts(opts.id, artifacts, opts.references), params: injectReferencesIntoParams( opts.id, opts.ruleType, From 92486e843595e8fb263423debfb047c8f329e8ea Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 16 Apr 2025 12:39:06 -0400 Subject: [PATCH 66/84] Add tests for `transformRawArtifactsToDomainArtifacts`. --- ..._raw_artifacts_to_domain_artifacts.test.ts | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts new file mode 100644 index 0000000000000..8487b670d7fee --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts @@ -0,0 +1,94 @@ +/* + * 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 { SavedObjectReference } from '@kbn/core/server'; +import type { RawRule } from '../../../types'; +import { transformRawArtifactsToDomainArtifacts } from './transform_raw_artifacts_to_domain_artifacts'; + +describe('transformRawArtifactsToDomainArtifacts', () => { + it('should return empty artifacts if rawArtifacts is undefined', () => { + const result = transformRawArtifactsToDomainArtifacts('1', undefined, []); + expect(result).toEqual({ dashboards: [] }); + }); + + it('should return empty object if rawArtifacts is empty', () => { + const result = transformRawArtifactsToDomainArtifacts('1', {}, []); + expect(result).toEqual({}); + }); + + it('should return artifacts with injected references', () => { + const rawArtifacts: RawRule['artifacts'] = { + dashboards: [ + { + refId: 'dashboard-1', + }, + { + refId: 'dashboard-2', + }, + ], + }; + const references: SavedObjectReference[] = [ + { + id: 'dashboard_0', + name: 'dashboard-1', + type: 'dashboard', + }, + { + id: 'dashboard_1', + name: 'dashboard-2', + type: 'dashboard', + }, + ]; + const result = transformRawArtifactsToDomainArtifacts('1', rawArtifacts, references); + expect(result).toEqual({ + dashboards: [ + { + id: 'dashboard_0', + }, + { + id: 'dashboard_1', + }, + ], + }); + }); + + it('should return artifacts with empty dashboards array if no dashboards in rawArtifacts', () => { + const rawArtifacts: RawRule['artifacts'] = {}; + const references: SavedObjectReference[] = []; + const result = transformRawArtifactsToDomainArtifacts('1', rawArtifacts, references); + expect(result).toEqual({}); + }); + + it('should return artifacts with injected references and empty dashboards array if no dashboards in rawArtifacts', () => { + const rawArtifacts: RawRule['artifacts'] = {}; + const references: SavedObjectReference[] = [ + { + id: 'dashboard-1', + name: 'dashboard_0', + type: 'dashboard', + }, + ]; + const result = transformRawArtifactsToDomainArtifacts('1', rawArtifacts, references); + expect(result).toEqual({}); + }); + + it('throws an error if no references found', () => { + const rawArtifacts: RawRule['artifacts'] = { + dashboards: [ + { + refId: 'dashboard-1', + }, + ], + }; + const references: SavedObjectReference[] = []; + expect(() => + transformRawArtifactsToDomainArtifacts('1', rawArtifacts, references) + ).toThrowErrorMatchingInlineSnapshot( + `"Artifacts reference \\"dashboard-1\\" not found in rule id: 1"` + ); + }); +}); From e625e734d3ee1a8975ca4d5a3af6fd4e8a8e6216 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 16 Apr 2025 14:00:24 -0400 Subject: [PATCH 67/84] Make `artifacts` a required parameter of `extractReferences`. --- .../rule/methods/bulk_edit/bulk_edit_rules.ts | 6 ++--- .../common/inject_references.test.ts | 22 ++++++++++++++++--- .../rules_client/lib/denormalize_artifacts.ts | 7 +++--- .../rules_client/lib/extract_references.ts | 2 +- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts index ff32a4d3026c7..8c373118b4f6c 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -470,8 +470,8 @@ async function updateRuleAttributesAndParamsInMemory( const ruleArtifacts = injectReferencesIntoArtifacts( rule.id, - rule.references || [], - rule.attributes.artifacts + rule.attributes.artifacts, + rule.references ); if (migratedActions.hasLegacyActions) { @@ -557,7 +557,7 @@ async function updateRuleAttributesAndParamsInMemory( ruleType, updatedRuleActions as NormalizedAlertActionWithGeneratedValues[], validatedMutatedAlertTypeParams, - ruleArtifacts + ruleArtifacts! ); const ruleAttributes = transformRuleDomainToRuleAttributes({ diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts index 53d4fcc051aad..02ded7aae93a1 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.test.ts @@ -10,7 +10,23 @@ import { injectReferencesIntoArtifacts } from './inject_references'; describe('injectReferencesIntoArtifacts', () => { it('returns default value if no artifacts are provided', () => { - expect(injectReferencesIntoArtifacts('test-id', [], undefined)).toEqual({ dashboards: [] }); + expect(injectReferencesIntoArtifacts('test-id', undefined, [])).toEqual({ dashboards: [] }); + }); + + it('throws an error if references are not provided', () => { + const artifacts = { + dashboards: [ + { + refId: 'dashboard_1', + }, + { + refId: 'dashboard_2', + }, + ], + }; + expect(() => injectReferencesIntoArtifacts('test-id', artifacts)).toThrow( + 'Artifacts reference "dashboard_1" not found in rule id: test-id' + ); }); it('throws an error if the dashboard reference is not found', () => { @@ -22,7 +38,7 @@ describe('injectReferencesIntoArtifacts', () => { ], }; const refs: SavedObjectReference[] = []; - expect(() => injectReferencesIntoArtifacts('test-id', refs, artifacts)).toThrow( + expect(() => injectReferencesIntoArtifacts('test-id', artifacts, refs)).toThrow( 'Artifacts reference "dashboard_1" not found in rule id: test-id' ); }); @@ -53,7 +69,7 @@ describe('injectReferencesIntoArtifacts', () => { type: 'dashboard', }, ]; - const result = injectReferencesIntoArtifacts('test-id', refs, artifacts); + const result = injectReferencesIntoArtifacts('test-id', artifacts, refs); expect(result).toEqual({ dashboards: [ { diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts index 10c40951dd95d..b025b22162c08 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts @@ -26,10 +26,9 @@ export function denormalizeArtifacts(ruleArtifacts: Artifacts | undefined): { type: 'dashboard', }; references.push(dashboardRef); - if (!artifacts.dashboards) { - artifacts.dashboards = []; - } - artifacts.dashboards.push({ + + // `artifacts.dashboards` is always defined + artifacts.dashboards!.push({ refId: refName, }); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index 1cd49c9ce6ae8..f287a47fa8bc6 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -22,7 +22,7 @@ export async function extractReferences< ruleType: UntypedNormalizedRuleType, ruleActions: NormalizedAlertActionWithGeneratedValues[], ruleParams: Params, - ruleArtifacts: Artifacts | undefined + ruleArtifacts: Artifacts ): Promise<{ actions: DenormalizedAction[]; artifacts: DenormalizedArtifacts; From 43e0918d2d41eed9e6cc3689e359eaf0edddd6ba Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 16 Apr 2025 14:23:07 -0400 Subject: [PATCH 68/84] Add additional coverage to update artifacts test. --- .../rule/methods/update/update_rule.test.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index 7d744f163b678..8d5c8b630ce33 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -4389,6 +4389,9 @@ describe('update()', () => { { id: 'dashboard-1', }, + { + id: 'dashboard-3', + }, ], }, }, @@ -4403,13 +4406,19 @@ describe('update()', () => { { refId: 'dashboard_0', }, + { + refId: 'dashboard_1', + }, ], }, }), { id: '1', overwrite: true, - references: [{ id: 'dashboard-1', name: 'dashboard_0', type: 'dashboard' }], + references: [ + { id: 'dashboard-1', name: 'dashboard_0', type: 'dashboard' }, + { id: 'dashboard-3', name: 'dashboard_1', type: 'dashboard' }, + ], version: '123', } ); From c4efff7a8387adac3741d0270781f71b432b9ba0 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Wed, 16 Apr 2025 22:51:10 +0300 Subject: [PATCH 69/84] rename isInternal to includeArtifacts --- .../find/transforms/transform_find_rules_response/v1.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts index 8941372f3eabe..8eb7738ff7dfb 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/transforms/transform_find_rules_response/v1.ts @@ -22,7 +22,7 @@ import { export const transformPartialRule = ( rule: Partial>, fields?: string[], - isInternal: boolean = false + includeArtifacts: boolean = false ): Partial> => { const ruleResponse = { ...(rule.id !== undefined ? { id: rule.id } : {}), @@ -81,7 +81,7 @@ export const transformPartialRule = ( : {}), ...(rule.alertDelay !== undefined ? { alert_delay: rule.alertDelay } : {}), ...(rule.flapping !== undefined ? { flapping: transformFlappingV1(rule.flapping) } : {}), - ...(isInternal && rule.artifacts !== undefined ? { artifacts: rule.artifacts } : {}), + ...(includeArtifacts && rule.artifacts !== undefined ? { artifacts: rule.artifacts } : {}), }; type RuleKeys = keyof RuleResponseV1; @@ -103,14 +103,14 @@ export const transformPartialRule = ( export const transformFindRulesResponse = ( result: FindResult, fields?: string[], - isInternal: boolean = false + includeArtifacts: boolean = false ): FindRulesResponseV1['body'] => { return { page: result.page, per_page: result.perPage, total: result.total, data: result.data.map((rule) => - transformPartialRule(rule as Partial>, fields, isInternal) + transformPartialRule(rule as Partial>, fields, includeArtifacts) ), }; }; From 67f8302e984a2a53191ea8560be6322a397ca21c Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 17 Apr 2025 13:15:39 +0300 Subject: [PATCH 70/84] update_rule tests updates --- .../rule/methods/update/update_rule.test.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index 8d5c8b630ce33..140630c4ae804 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -4389,9 +4389,6 @@ describe('update()', () => { { id: 'dashboard-1', }, - { - id: 'dashboard-3', - }, ], }, }, @@ -4406,19 +4403,13 @@ describe('update()', () => { { refId: 'dashboard_0', }, - { - refId: 'dashboard_1', - }, ], }, }), { id: '1', overwrite: true, - references: [ - { id: 'dashboard-1', name: 'dashboard_0', type: 'dashboard' }, - { id: 'dashboard-3', name: 'dashboard_1', type: 'dashboard' }, - ], + references: [{ id: 'dashboard-1', name: 'dashboard_0', type: 'dashboard' }], version: '123', } ); @@ -4461,6 +4452,8 @@ describe('update()', () => { "updatedAt": 2019-02-12T21:01:22.479Z, } `); + + expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); }); test('adds a new linked dashboard', async () => { @@ -4681,6 +4674,8 @@ describe('update()', () => { "updatedAt": 2019-02-12T21:01:22.479Z, } `); + + expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); }); }); }); From 4e240fd7b5f366d1ba9cb7ce247ddc9a40333022 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 17 Apr 2025 15:55:52 +0300 Subject: [PATCH 71/84] find_rules_route unit tests --- .../rule/apis/find/find_rules_route.test.ts | 217 ++++++++++++++++++ 1 file changed, 217 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_rules_route.test.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_rules_route.test.ts index 27769cf237389..97e9f7826b7df 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_rules_route.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_rules_route.test.ts @@ -581,4 +581,221 @@ describe('findRulesRoute', () => { }, }); }); + + it('should not return artifacts in the response', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + findRulesRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alerting/rules/_find"`); + + const findResult = { + page: 1, + perPage: 1, + total: 0, + data: [ + { + id: '3d534c70-582b-11ec-8995-2b1578a3bc5d', + notifyWhen: 'onActiveAlert' as const, + alertTypeId: '.index-threshold', + name: 'stressing index-threshold 37/200', + consumer: 'alerts', + tags: [], + enabled: true, + throttle: null, + apiKey: null, + apiKeyOwner: '2889684073', + createdBy: 'elastic', + updatedBy: '2889684073', + muteAll: false, + mutedInstanceIds: [], + schedule: { + interval: '1s', + }, + snoozeSchedule: [], + actions: [ + { + actionTypeId: '.server-log', + params: { + message: 'alert 37: {{context.message}}', + }, + group: 'threshold met', + id: '3619a0d0-582b-11ec-8995-2b1578a3bc5d', + uuid: '123-456', + }, + ], + systemActions: [ + { actionTypeId: '.test', id: 'system_action-id', params: {}, uuid: '789' }, + ], + params: { x: 42 }, + updatedAt: new Date('2024-03-21T13:15:00.498Z'), + createdAt: new Date('2024-03-21T13:15:00.498Z'), + scheduledTaskId: '52125fb0-5895-11ec-ae69-bb65d1a71b72', + executionStatus: { + status: 'ok' as const, + lastExecutionDate: new Date('2024-03-21T13:15:00.498Z'), + lastDuration: 1194, + }, + revision: 0, + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + ], + }, + }, + ], + }; + + rulesClient.find.mockResolvedValueOnce(findResult); + + const [context, req, res] = mockHandlerArguments( + { rulesClient }, + { + query: { + per_page: 1, + page: 1, + default_search_operator: 'OR', + }, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Object { + "data": Array [ + Object { + "actions": Array [ + Object { + "connector_type_id": ".server-log", + "group": "threshold met", + "id": "3619a0d0-582b-11ec-8995-2b1578a3bc5d", + "params": Object { + "message": "alert 37: {{context.message}}", + }, + "uuid": "123-456", + }, + Object { + "connector_type_id": ".test", + "id": "system_action-id", + "params": Object {}, + "uuid": "789", + }, + ], + "api_key_owner": "2889684073", + "consumer": "alerts", + "created_at": "2024-03-21T13:15:00.498Z", + "created_by": "elastic", + "enabled": true, + "execution_status": Object { + "last_duration": 1194, + "last_execution_date": "2024-03-21T13:15:00.498Z", + "status": "ok", + }, + "id": "3d534c70-582b-11ec-8995-2b1578a3bc5d", + "mute_all": false, + "muted_alert_ids": Array [], + "name": "stressing index-threshold 37/200", + "notify_when": "onActiveAlert", + "params": Object { + "x": 42, + }, + "revision": 0, + "rule_type_id": ".index-threshold", + "schedule": Object { + "interval": "1s", + }, + "scheduled_task_id": "52125fb0-5895-11ec-ae69-bb65d1a71b72", + "snooze_schedule": Array [], + "tags": Array [], + "throttle": null, + "updated_at": "2024-03-21T13:15:00.498Z", + "updated_by": "2889684073", + }, + ], + "page": 1, + "per_page": 1, + "total": 0, + }, + } + `); + + expect(rulesClient.find).toHaveBeenCalledTimes(1); + expect(rulesClient.find.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "excludeFromPublicApi": true, + "includeSnoozeData": true, + "options": Object { + "defaultSearchOperator": "OR", + "page": 1, + "perPage": 1, + }, + }, + ] + `); + + expect(res.ok).toHaveBeenCalledWith({ + body: { + page: 1, + per_page: 1, + total: 0, + data: [ + { + actions: [ + { + connector_type_id: '.server-log', + group: 'threshold met', + id: '3619a0d0-582b-11ec-8995-2b1578a3bc5d', + params: { + message: 'alert 37: {{context.message}}', + }, + uuid: '123-456', + }, + { + connector_type_id: '.test', + id: 'system_action-id', + params: {}, + uuid: '789', + }, + ], + api_key_owner: '2889684073', + consumer: 'alerts', + created_at: '2024-03-21T13:15:00.498Z', + created_by: 'elastic', + enabled: true, + execution_status: { + last_duration: 1194, + last_execution_date: '2024-03-21T13:15:00.498Z', + status: 'ok', + }, + id: '3d534c70-582b-11ec-8995-2b1578a3bc5d', + mute_all: false, + muted_alert_ids: [], + name: 'stressing index-threshold 37/200', + notify_when: 'onActiveAlert', + params: { + x: 42, + }, + revision: 0, + rule_type_id: '.index-threshold', + schedule: { + interval: '1s', + }, + scheduled_task_id: '52125fb0-5895-11ec-ae69-bb65d1a71b72', + snooze_schedule: [], + tags: [], + throttle: null, + updated_at: '2024-03-21T13:15:00.498Z', + updated_by: '2889684073', + }, + ], + }, + }); + }); }); From e3f236af7d60cee6d93721bbc6673eccb7a0fed2 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 17 Apr 2025 16:29:33 +0300 Subject: [PATCH 72/84] find_internal_rules_route unit tests --- .../find/find_internal_rules_route.test.ts | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_internal_rules_route.test.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_internal_rules_route.test.ts index 53b330a8a2044..b4712c393dfdd 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_internal_rules_route.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/find/find_internal_rules_route.test.ts @@ -111,4 +111,179 @@ describe('findInternalRulesRoute', () => { }, }); }); + + it('returns artifacts in the response', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + findInternalRulesRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/internal/alerting/rules/_find"`); + + const findResult = { + page: 1, + perPage: 1, + total: 0, + data: [ + { + id: '3d534c70-582b-11ec-8995-2b1578a3bc5d', + notifyWhen: 'onActiveAlert' as const, + alertTypeId: '.index-threshold', + name: 'stressing index-threshold 37/200', + consumer: 'alerts', + tags: [], + enabled: true, + throttle: null, + apiKey: null, + apiKeyOwner: '2889684073', + createdBy: 'elastic', + updatedBy: '2889684073', + muteAll: false, + mutedInstanceIds: [], + schedule: { + interval: '1s', + }, + snoozeSchedule: [], + actions: [ + { + actionTypeId: '.server-log', + params: { + message: 'alert 37: {{context.message}}', + }, + group: 'threshold met', + id: '3619a0d0-582b-11ec-8995-2b1578a3bc5d', + uuid: '123-456', + }, + ], + systemActions: [ + { actionTypeId: '.test', id: 'system_action-id', params: {}, uuid: '789' }, + ], + params: { x: 42 }, + updatedAt: new Date('2024-03-21T13:15:00.498Z'), + createdAt: new Date('2024-03-21T13:15:00.498Z'), + scheduledTaskId: '52125fb0-5895-11ec-ae69-bb65d1a71b72', + executionStatus: { + status: 'ok' as const, + lastExecutionDate: new Date('2024-03-21T13:15:00.498Z'), + lastDuration: 1194, + }, + revision: 0, + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + ], + }, + }, + ], + }; + + rulesClient.find.mockResolvedValueOnce(findResult); + + const [context, req, res] = mockHandlerArguments( + { rulesClient }, + { + body: { + per_page: 1, + page: 1, + default_search_operator: 'OR', + rule_type_ids: ['foo'], + consumers: ['bar'], + }, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Object { + "data": Array [ + Object { + "actions": Array [ + Object { + "connector_type_id": ".server-log", + "group": "threshold met", + "id": "3619a0d0-582b-11ec-8995-2b1578a3bc5d", + "params": Object { + "message": "alert 37: {{context.message}}", + }, + "uuid": "123-456", + }, + Object { + "connector_type_id": ".test", + "id": "system_action-id", + "params": Object {}, + "uuid": "789", + }, + ], + "api_key_owner": "2889684073", + "artifacts": Object { + "dashboards": Array [ + Object { + "id": "dashboard-1", + }, + ], + }, + "consumer": "alerts", + "created_at": "2024-03-21T13:15:00.498Z", + "created_by": "elastic", + "enabled": true, + "execution_status": Object { + "last_duration": 1194, + "last_execution_date": "2024-03-21T13:15:00.498Z", + "status": "ok", + }, + "id": "3d534c70-582b-11ec-8995-2b1578a3bc5d", + "mute_all": false, + "muted_alert_ids": Array [], + "name": "stressing index-threshold 37/200", + "notify_when": "onActiveAlert", + "params": Object { + "x": 42, + }, + "revision": 0, + "rule_type_id": ".index-threshold", + "schedule": Object { + "interval": "1s", + }, + "scheduled_task_id": "52125fb0-5895-11ec-ae69-bb65d1a71b72", + "snooze_schedule": Array [], + "tags": Array [], + "throttle": null, + "updated_at": "2024-03-21T13:15:00.498Z", + "updated_by": "2889684073", + }, + ], + "page": 1, + "per_page": 1, + "total": 0, + }, + } + `); + + expect(rulesClient.find).toHaveBeenCalledTimes(1); + + expect(rulesClient.find.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "excludeFromPublicApi": false, + "includeSnoozeData": true, + "options": Object { + "consumers": Array [ + "bar", + ], + "defaultSearchOperator": "OR", + "page": 1, + "perPage": 1, + "ruleTypeIds": Array [ + "foo", + ], + }, + }, + ] + `); + }); }); From 75d463c20d4f2663b179d23d35c8b80f18994be5 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 17 Apr 2025 16:56:23 +0300 Subject: [PATCH 73/84] test that artifacts are mapped correctly --- .../transform_rule_domain_to_rule.test.ts | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.test.ts index e80b526cca349..74f4f1778917e 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_rule_domain_to_rule.test.ts @@ -190,4 +190,91 @@ describe('transformRuleDomainToRule', () => { }, }); }); + + it('should include artifacts', () => { + const ruleWithArtifacts: RuleDomain<{}> = { + id: 'test', + enabled: false, + name: 'my rule name', + tags: ['foo'], + alertTypeId: 'myType', + consumer: 'myApp', + schedule: { interval: '1m' }, + actions: [defaultAction], + systemActions: [systemAction], + params: {}, + mapped_params: {}, + createdBy: 'user', + createdAt: new Date('2019-02-12T21:01:22.479Z'), + updatedAt: new Date('2019-02-12T21:01:22.479Z'), + legacyId: 'legacyId', + muteAll: false, + mutedInstanceIds: [], + snoozeSchedule: [], + scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.479Z'), + status: 'pending' as const, + }, + throttle: null, + notifyWhen: null, + revision: 0, + updatedBy: 'user', + apiKey: MOCK_API_KEY, + apiKeyOwner: 'user', + flapping: { + lookBackWindow: 20, + statusChangeThreshold: 20, + }, + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + ], + }, + }; + const result = transformRuleDomainToRule(ruleWithArtifacts); + + expect(result).toEqual({ + id: 'test', + enabled: false, + name: 'my rule name', + tags: ['foo'], + alertTypeId: 'myType', + consumer: 'myApp', + schedule: { interval: '1m' }, + actions: [defaultAction], + systemActions: [systemAction], + params: {}, + mapped_params: {}, + createdBy: 'user', + createdAt: new Date('2019-02-12T21:01:22.479Z'), + updatedAt: new Date('2019-02-12T21:01:22.479Z'), + muteAll: false, + mutedInstanceIds: [], + snoozeSchedule: [], + scheduledTaskId: 'task-123', + executionStatus: { + lastExecutionDate: new Date('2019-02-12T21:01:22.479Z'), + status: 'pending' as const, + }, + throttle: null, + notifyWhen: null, + revision: 0, + updatedBy: 'user', + apiKeyOwner: 'user', + flapping: { + lookBackWindow: 20, + statusChangeThreshold: 20, + }, + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + ], + }, + }); + }); }); From 51ebefce597cd080b0dd89b70d280fb745813475 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Thu, 17 Apr 2025 18:19:20 +0300 Subject: [PATCH 74/84] import schema from artifacts_schema --- .../schemas/{artifact_schema.ts => artifacts_schema.ts} | 0 .../alerting/server/application/rule/schemas/index.ts | 1 + .../server/application/rule/schemas/rule_schemas.ts | 7 +------ 3 files changed, 2 insertions(+), 6 deletions(-) rename x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/{artifact_schema.ts => artifacts_schema.ts} (100%) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifacts_schema.ts similarity index 100% rename from x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifact_schema.ts rename to x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifacts_schema.ts diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts index dc0d310f36535..e40955d039ca0 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/index.ts @@ -9,3 +9,4 @@ export * from './rule_schemas'; export * from './action_schemas'; export * from './notify_when_schema'; export * from './flapping_schema'; +export * from './artifacts_schema'; diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts index a5975ff16ca4a..80a7be7e8723d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/rule_schemas.ts @@ -18,6 +18,7 @@ import { dateSchema } from './date_schema'; import { notifyWhenSchema } from './notify_when_schema'; import { actionSchema, systemActionSchema } from './action_schemas'; import { flappingSchema } from './flapping_schema'; +import { artifactsSchema } from './artifacts_schema'; export const mappedParamsSchema = schema.recordOf(schema.string(), schema.maybe(schema.any())); @@ -149,12 +150,6 @@ export const alertDelaySchema = schema.object({ active: schema.number(), }); -export const dashboardsSchema = schema.arrayOf(schema.object({ id: schema.string() })); - -export const artifactsSchema = schema.object({ - dashboards: schema.maybe(dashboardsSchema), -}); - /** * Unsanitized (domain) rule schema, used by internal rules clients */ From c5ba626b932beb446f0e4220e3caa4aea1971e2e Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 18 Apr 2025 13:03:47 -0400 Subject: [PATCH 75/84] Fix tests, change return value to always include dashboards array. --- ..._raw_artifacts_to_domain_artifacts.test.ts | 9 ++----- .../rules_client/common/inject_references.ts | 27 ++++++++++--------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts index 8487b670d7fee..7d4004063db9e 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts @@ -15,11 +15,6 @@ describe('transformRawArtifactsToDomainArtifacts', () => { expect(result).toEqual({ dashboards: [] }); }); - it('should return empty object if rawArtifacts is empty', () => { - const result = transformRawArtifactsToDomainArtifacts('1', {}, []); - expect(result).toEqual({}); - }); - it('should return artifacts with injected references', () => { const rawArtifacts: RawRule['artifacts'] = { dashboards: [ @@ -60,7 +55,7 @@ describe('transformRawArtifactsToDomainArtifacts', () => { const rawArtifacts: RawRule['artifacts'] = {}; const references: SavedObjectReference[] = []; const result = transformRawArtifactsToDomainArtifacts('1', rawArtifacts, references); - expect(result).toEqual({}); + expect(result).toEqual({ dashboards: [] }); }); it('should return artifacts with injected references and empty dashboards array if no dashboards in rawArtifacts', () => { @@ -73,7 +68,7 @@ describe('transformRawArtifactsToDomainArtifacts', () => { }, ]; const result = transformRawArtifactsToDomainArtifacts('1', rawArtifacts, references); - expect(result).toEqual({}); + expect(result).toEqual({ dashboards: [] }); }); it('throws an error if no references found', () => { diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index 76a2d90ea0434..eb4ff81908bc9 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -89,17 +89,20 @@ export function injectReferencesIntoArtifacts( } return { ...artifacts, - dashboards: artifacts.dashboards?.map((dashboard) => { - const reference = references?.find( - (ref) => ref.name === dashboard.refId && ref.type === 'dashboard' - ); - if (!reference) { - throw new Error(`Artifacts reference "${dashboard.refId}" not found in rule id: ${ruleId}`); - } - return { - ...omit(dashboard, 'refId'), - id: reference.id, - }; - }), + dashboards: + artifacts.dashboards?.map((dashboard) => { + const reference = references?.find( + (ref) => ref.name === dashboard.refId && ref.type === 'dashboard' + ); + if (!reference) { + throw new Error( + `Artifacts reference "${dashboard.refId}" not found in rule id: ${ruleId}` + ); + } + return { + ...omit(dashboard, 'refId'), + id: reference.id, + }; + }) ?? [], }; } From 6e5ca07c4fa77890c3774267fcb1b87518524f23 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 18 Apr 2025 13:15:08 -0400 Subject: [PATCH 76/84] Change a word. --- .../transform_raw_artifacts_to_domain_artifacts.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts index 7d4004063db9e..4d7ed06ebce7d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.test.ts @@ -10,7 +10,7 @@ import type { RawRule } from '../../../types'; import { transformRawArtifactsToDomainArtifacts } from './transform_raw_artifacts_to_domain_artifacts'; describe('transformRawArtifactsToDomainArtifacts', () => { - it('should return empty artifacts if rawArtifacts is undefined', () => { + it('should return default artifacts if rawArtifacts is undefined', () => { const result = transformRawArtifactsToDomainArtifacts('1', undefined, []); expect(result).toEqual({ dashboards: [] }); }); From 7058cc8441dc22125bfd4a5389824fd2a029f654 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 18 Apr 2025 13:45:52 -0400 Subject: [PATCH 77/84] Use lodash `uniqBy` to deduplicate reference list. --- .../lib/extract_references.test.ts | 78 +++++++++++++++++++ .../rules_client/lib/extract_references.ts | 3 +- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts index 0a468d6bc5464..8d9b31bc730d0 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts @@ -12,12 +12,18 @@ import type { RulesClientContext } from '..'; import { savedObjectsRepositoryMock } from '@kbn/core-saved-objects-api-server-mocks'; import { denormalizeArtifacts } from './denormalize_artifacts'; +import { denormalizeActions } from './denormalize_actions'; jest.mock('./denormalize_artifacts', () => ({ denormalizeArtifacts: jest.fn(), })); +jest.mock('./denormalize_actions', () => ({ + denormalizeActions: jest.fn(), +})); + const mockDenormalizeArtifacts = denormalizeArtifacts as jest.Mock; +const mockDenormalizeActions = denormalizeActions as jest.Mock; const loggerErrorMock = jest.fn(); const getBulkMock = jest.fn(); @@ -69,6 +75,18 @@ jest.mock('./denormalize_artifacts', () => ({ })); describe('extractReferences', () => { + beforeEach(() => { + mockDenormalizeActions.mockReturnValue({ + actions: [], + references: [ + { + id: '123', + name: 'dashboard_0', + type: 'dashboard', + }, + ], + }); + }); it('returns dashboard artifacts and references', async () => { mockDenormalizeArtifacts.mockReturnValue({ artifacts: { @@ -130,4 +148,64 @@ describe('extractReferences', () => { }, ]); }); + + it('deduplicates references before returning', async () => { + mockDenormalizeArtifacts.mockReturnValue({ + artifacts: { + dashboards: [ + { + refId: 'dashboard_0', + }, + { + refId: 'dashboard_1', + }, + ], + }, + references: [ + { + id: '012', + name: 'dashboard_1', + type: 'dashboard', + }, + { + id: '123', + name: 'dashboard_0', + type: 'dashboard', + }, + { + id: '234', + name: 'dashboard_2', + type: 'dashboard', + }, + ], + }); + + const result = await extractReferences( + context, + ruleType, + [], + {}, + { + dashboards: [{ id: '123' }], + } + ); + + expect(result.references).toEqual([ + { + id: '123', + name: 'dashboard_0', + type: 'dashboard', + }, + { + id: '012', + name: 'dashboard_1', + type: 'dashboard', + }, + { + id: '234', + name: 'dashboard_2', + type: 'dashboard', + }, + ]); + }); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index f287a47fa8bc6..bc514361f43fa 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -6,6 +6,7 @@ */ import type { SavedObjectReference } from '@kbn/core/server'; +import { uniqBy } from 'lodash'; import type { RuleTypeParams, Artifacts } from '../../types'; import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; import type { DenormalizedAction, NormalizedAlertActionWithGeneratedValues } from '../types'; @@ -50,7 +51,7 @@ export async function extractReferences< name: `${extractedSavedObjectParamReferenceNamePrefix}${reference.name}`, })); - const references = [...actionReferences, ...paramReferences, ...artifactReferences]; + const references = uniqBy([...actionReferences, ...paramReferences, ...artifactReferences], 'id'); return { actions, From 86e52c16fb3b097fc045c18b8f33a5847c08c273 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 18 Apr 2025 15:02:49 -0400 Subject: [PATCH 78/84] Update test snapshot where there are duplicate SO ref IDs. --- .../application/rule/methods/update/update_rule.test.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index 140630c4ae804..42a61cbd14e91 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -536,11 +536,6 @@ describe('update()', () => { "name": "action_0", "type": "action", }, - Object { - "id": "1", - "name": "action_1", - "type": "action", - }, Object { "id": "2", "name": "action_2", From 3f8cd80fb2e29adbc8eab4a5083939af25ef327f Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 18 Apr 2025 16:13:55 -0400 Subject: [PATCH 79/84] Revert "Update test snapshot where there are duplicate SO ref IDs." This reverts commit 86e52c16fb3b097fc045c18b8f33a5847c08c273. --- .../application/rule/methods/update/update_rule.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index 42a61cbd14e91..140630c4ae804 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -536,6 +536,11 @@ describe('update()', () => { "name": "action_0", "type": "action", }, + Object { + "id": "1", + "name": "action_1", + "type": "action", + }, Object { "id": "2", "name": "action_2", From dba50325b9ebb2a6b9d28a45ba4aff483d1f97da Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Fri, 18 Apr 2025 16:14:16 -0400 Subject: [PATCH 80/84] Revert "Use lodash `uniqBy` to deduplicate reference list." This reverts commit 7058cc8441dc22125bfd4a5389824fd2a029f654. --- .../lib/extract_references.test.ts | 78 ------------------- .../rules_client/lib/extract_references.ts | 3 +- 2 files changed, 1 insertion(+), 80 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts index 8d9b31bc730d0..0a468d6bc5464 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts @@ -12,18 +12,12 @@ import type { RulesClientContext } from '..'; import { savedObjectsRepositoryMock } from '@kbn/core-saved-objects-api-server-mocks'; import { denormalizeArtifacts } from './denormalize_artifacts'; -import { denormalizeActions } from './denormalize_actions'; jest.mock('./denormalize_artifacts', () => ({ denormalizeArtifacts: jest.fn(), })); -jest.mock('./denormalize_actions', () => ({ - denormalizeActions: jest.fn(), -})); - const mockDenormalizeArtifacts = denormalizeArtifacts as jest.Mock; -const mockDenormalizeActions = denormalizeActions as jest.Mock; const loggerErrorMock = jest.fn(); const getBulkMock = jest.fn(); @@ -75,18 +69,6 @@ jest.mock('./denormalize_artifacts', () => ({ })); describe('extractReferences', () => { - beforeEach(() => { - mockDenormalizeActions.mockReturnValue({ - actions: [], - references: [ - { - id: '123', - name: 'dashboard_0', - type: 'dashboard', - }, - ], - }); - }); it('returns dashboard artifacts and references', async () => { mockDenormalizeArtifacts.mockReturnValue({ artifacts: { @@ -148,64 +130,4 @@ describe('extractReferences', () => { }, ]); }); - - it('deduplicates references before returning', async () => { - mockDenormalizeArtifacts.mockReturnValue({ - artifacts: { - dashboards: [ - { - refId: 'dashboard_0', - }, - { - refId: 'dashboard_1', - }, - ], - }, - references: [ - { - id: '012', - name: 'dashboard_1', - type: 'dashboard', - }, - { - id: '123', - name: 'dashboard_0', - type: 'dashboard', - }, - { - id: '234', - name: 'dashboard_2', - type: 'dashboard', - }, - ], - }); - - const result = await extractReferences( - context, - ruleType, - [], - {}, - { - dashboards: [{ id: '123' }], - } - ); - - expect(result.references).toEqual([ - { - id: '123', - name: 'dashboard_0', - type: 'dashboard', - }, - { - id: '012', - name: 'dashboard_1', - type: 'dashboard', - }, - { - id: '234', - name: 'dashboard_2', - type: 'dashboard', - }, - ]); - }); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index bc514361f43fa..f287a47fa8bc6 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -6,7 +6,6 @@ */ import type { SavedObjectReference } from '@kbn/core/server'; -import { uniqBy } from 'lodash'; import type { RuleTypeParams, Artifacts } from '../../types'; import type { UntypedNormalizedRuleType } from '../../rule_type_registry'; import type { DenormalizedAction, NormalizedAlertActionWithGeneratedValues } from '../types'; @@ -51,7 +50,7 @@ export async function extractReferences< name: `${extractedSavedObjectParamReferenceNamePrefix}${reference.name}`, })); - const references = uniqBy([...actionReferences, ...paramReferences, ...artifactReferences], 'id'); + const references = [...actionReferences, ...paramReferences, ...artifactReferences]; return { actions, From e57875e115e73b249421bbbc2a432cd0f2c67186 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 22 Apr 2025 14:57:20 +0300 Subject: [PATCH 81/84] move injectReferencesIntoArtifacts after hasLegacyActions --- .../rule/methods/bulk_edit/bulk_edit_rules.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts index 8c373118b4f6c..fed38bab45ae6 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -468,15 +468,9 @@ async function updateRuleAttributesAndParamsInMemory( attributes: rule.attributes as RawRule, }); - const ruleArtifacts = injectReferencesIntoArtifacts( - rule.id, - rule.attributes.artifacts, - rule.references - ); - if (migratedActions.hasLegacyActions) { rule.attributes.actions = migratedActions.resultedActions; - rule.references = migratedActions.resultedReferences; // TODO check if this will break references that include artifacts + rule.references = migratedActions.resultedReferences; } const ruleActions = injectReferencesIntoActions( @@ -485,6 +479,12 @@ async function updateRuleAttributesAndParamsInMemory( rule.references || [] ); + const ruleArtifacts = injectReferencesIntoArtifacts( + rule.id, + rule.attributes.artifacts, + rule.references + ); + const ruleDomain: RuleDomain = transformRuleAttributesToRuleDomain( rule.attributes, { From 9b44f70d4228f87323d488f4a3daa9988b4d3d25 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 22 Apr 2025 15:51:53 +0300 Subject: [PATCH 82/84] make artifacts required --- .../application/rule/methods/bulk_edit/bulk_edit_rules.ts | 2 +- .../transform_raw_artifacts_to_domain_artifacts.ts | 2 +- .../server/rules_client/common/inject_references.ts | 2 +- .../server/rules_client/lib/denormalize_artifacts.ts | 7 +++---- .../alerting/server/rules_client/lib/extract_references.ts | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts index fed38bab45ae6..1954aa4fc9c89 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -557,7 +557,7 @@ async function updateRuleAttributesAndParamsInMemory( ruleType, updatedRuleActions as NormalizedAlertActionWithGeneratedValues[], validatedMutatedAlertTypeParams, - ruleArtifacts! + ruleArtifacts ?? {}, ); const ruleAttributes = transformRuleDomainToRuleAttributes({ diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.ts index 3ac1222c1669e..e40c71a3814d7 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/transforms/transform_raw_artifacts_to_domain_artifacts.ts @@ -14,6 +14,6 @@ export function transformRawArtifactsToDomainArtifacts( id: string, rawArtifacts?: RawRule['artifacts'], references?: SavedObjectReference[] -): RuleDomain['artifacts'] { +): Required { return injectReferencesIntoArtifacts(id, rawArtifacts, references || []); } diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts index eb4ff81908bc9..4289734f6396f 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/common/inject_references.ts @@ -83,7 +83,7 @@ export function injectReferencesIntoArtifacts( ruleId: string, artifacts?: RawRule['artifacts'], references?: SavedObjectReference[] -): RuleDomain['artifacts'] { +): Required { if (!artifacts) { return { dashboards: [] }; } diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts index b025b22162c08..861a822477780 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/denormalize_artifacts.ts @@ -9,11 +9,11 @@ import type { Artifacts } from '../../types'; import type { DenormalizedArtifacts } from '../types'; export function denormalizeArtifacts(ruleArtifacts: Artifacts | undefined): { - artifacts: DenormalizedArtifacts; + artifacts: Required; references: SavedObjectReference[]; } { const references: SavedObjectReference[] = []; - const artifacts: DenormalizedArtifacts = { + const artifacts: Required = { dashboards: [], }; @@ -27,8 +27,7 @@ export function denormalizeArtifacts(ruleArtifacts: Artifacts | undefined): { }; references.push(dashboardRef); - // `artifacts.dashboards` is always defined - artifacts.dashboards!.push({ + artifacts.dashboards.push({ refId: refName, }); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts index f287a47fa8bc6..ae4322d912e08 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.ts @@ -25,7 +25,7 @@ export async function extractReferences< ruleArtifacts: Artifacts ): Promise<{ actions: DenormalizedAction[]; - artifacts: DenormalizedArtifacts; + artifacts: Required; params: ExtractedParams; references: SavedObjectReference[]; }> { From f3ec10b11996182a6c90f5a698fd9b835bef8cb0 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 22 Apr 2025 20:58:03 +0300 Subject: [PATCH 83/84] fix lint error --- .../application/rule/methods/bulk_edit/bulk_edit_rules.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts index 1954aa4fc9c89..228bddc906e5b 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -557,7 +557,7 @@ async function updateRuleAttributesAndParamsInMemory( ruleType, updatedRuleActions as NormalizedAlertActionWithGeneratedValues[], validatedMutatedAlertTypeParams, - ruleArtifacts ?? {}, + ruleArtifacts ?? {} ); const ruleAttributes = transformRuleDomainToRuleAttributes({ From b159a0b4b5395f71c1d8e1e4489d8bd6fbb29b95 Mon Sep 17 00:00:00 2001 From: Panagiota Mitsopoulou Date: Tue, 22 Apr 2025 22:34:15 +0300 Subject: [PATCH 84/84] do not mock denormalizeArtifacts --- .../lib/extract_references.test.ts | 46 ------------------- 1 file changed, 46 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts index 0a468d6bc5464..a923f91291927 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/extract_references.test.ts @@ -11,14 +11,6 @@ import { extractReferences } from './extract_references'; import type { RulesClientContext } from '..'; import { savedObjectsRepositoryMock } from '@kbn/core-saved-objects-api-server-mocks'; -import { denormalizeArtifacts } from './denormalize_artifacts'; - -jest.mock('./denormalize_artifacts', () => ({ - denormalizeArtifacts: jest.fn(), -})); - -const mockDenormalizeArtifacts = denormalizeArtifacts as jest.Mock; - const loggerErrorMock = jest.fn(); const getBulkMock = jest.fn(); @@ -64,37 +56,8 @@ const context = { getUserName: async () => {}, } as unknown as RulesClientContext; -jest.mock('./denormalize_artifacts', () => ({ - denormalizeArtifacts: jest.fn(), -})); - describe('extractReferences', () => { it('returns dashboard artifacts and references', async () => { - mockDenormalizeArtifacts.mockReturnValue({ - artifacts: { - dashboards: [ - { - refId: 'dashboard_0', - }, - { - refId: 'dashboard_1', - }, - ], - }, - references: [ - { - id: '123', - name: 'dashboard_0', - type: 'dashboard', - }, - { - id: '456', - name: 'dashboard_1', - type: 'dashboard', - }, - ], - }); - const result = await extractReferences( context, ruleType, @@ -105,15 +68,11 @@ describe('extractReferences', () => { } ); - expect(mockDenormalizeArtifacts).toHaveBeenCalled(); expect(result.artifacts).toEqual({ dashboards: [ { refId: 'dashboard_0', }, - { - refId: 'dashboard_1', - }, ], }); @@ -123,11 +82,6 @@ describe('extractReferences', () => { name: 'dashboard_0', type: 'dashboard', }, - { - id: '456', - name: 'dashboard_1', - type: 'dashboard', - }, ]); }); });