diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index b39401efa960..a59f35f9d603 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -1111,6 +1111,19 @@ "type": "object" }, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -2210,7 +2223,21 @@ ], "type": "object" }, + "maxItems": 10, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "maxLength": 1000, + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -2879,6 +2906,19 @@ "type": "object" }, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -3821,7 +3861,21 @@ ], "type": "object" }, + "maxItems": 10, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "maxLength": 1000, + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -4221,6 +4275,19 @@ "type": "object" }, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -6158,6 +6225,19 @@ "type": "object" }, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" diff --git a/oas_docs/bundle.serverless.json b/oas_docs/bundle.serverless.json index 838fa496f3e4..9ad3fe11bdb4 100644 --- a/oas_docs/bundle.serverless.json +++ b/oas_docs/bundle.serverless.json @@ -1111,6 +1111,19 @@ "type": "object" }, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -2210,7 +2223,21 @@ ], "type": "object" }, + "maxItems": 10, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "maxLength": 1000, + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -2879,6 +2906,19 @@ "type": "object" }, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -3821,7 +3861,21 @@ ], "type": "object" }, + "maxItems": 10, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "maxLength": 1000, + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -4221,6 +4275,19 @@ "type": "object" }, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" @@ -6158,6 +6225,19 @@ "type": "object" }, "type": "array" + }, + "investigation_guide": { + "additionalProperties": false, + "properties": { + "blob": { + "description": "User-created content that describes alert causes and remdiation.", + "type": "string" + } + }, + "required": [ + "blob" + ], + "type": "object" } }, "type": "object" diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 46e51a53aeed..769c9d319a59 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -953,6 +953,15 @@ paths: required: - id type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + description: User-created content that describes alert causes and remdiation. + type: string + required: + - blob 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 @@ -1785,7 +1794,17 @@ paths: type: string required: - id + maxItems: 10 type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + maxLength: 1000 + type: string + required: + - blob 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 @@ -2330,6 +2349,15 @@ paths: required: - id type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + description: User-created content that describes alert causes and remdiation. + type: string + required: + - blob 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 @@ -3038,7 +3066,17 @@ paths: type: string required: - id + maxItems: 10 type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + maxLength: 1000 + type: string + required: + - blob 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. @@ -3344,6 +3382,15 @@ paths: required: - id type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + description: User-created content that describes alert causes and remdiation. + type: string + required: + - blob 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 @@ -4747,6 +4794,15 @@ paths: required: - id type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + description: User-created content that describes alert causes and remdiation. + type: string + required: + - blob 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 7cbbd5afe048..12cc5baee4b5 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -1347,6 +1347,15 @@ paths: required: - id type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + description: User-created content that describes alert causes and remdiation. + type: string + required: + - blob 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 @@ -2179,7 +2188,17 @@ paths: type: string required: - id + maxItems: 10 type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + maxLength: 1000 + type: string + required: + - blob 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 @@ -2724,6 +2743,15 @@ paths: required: - id type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + description: User-created content that describes alert causes and remdiation. + type: string + required: + - blob 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 @@ -3432,7 +3460,17 @@ paths: type: string required: - id + maxItems: 10 type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + maxLength: 1000 + type: string + required: + - blob 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. @@ -3738,6 +3776,15 @@ paths: required: - id type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + description: User-created content that describes alert causes and remdiation. + type: string + required: + - blob 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 @@ -5141,6 +5188,15 @@ paths: required: - id type: array + investigation_guide: + additionalProperties: false + type: object + properties: + blob: + description: User-created content that describes alert causes and remdiation. + type: string + required: + - blob 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/packages/kbn-check-mappings-update-cli/current_fields.json b/packages/kbn-check-mappings-update-cli/current_fields.json index 65725783b6ba..fa63eee1e843 100644 --- a/packages/kbn-check-mappings-update-cli/current_fields.json +++ b/packages/kbn-check-mappings-update-cli/current_fields.json @@ -21,6 +21,9 @@ "actions.actionTypeId", "actions.group", "alertTypeId", + "artifacts", + "artifacts.investigation_guide", + "artifacts.investigation_guide.blob", "consumer", "createdAt", "createdBy", diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index a5ad489b5428..063f0e3f6f85 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -71,6 +71,17 @@ "alertTypeId": { "type": "keyword" }, + "artifacts": { + "properties": { + "investigation_guide": { + "properties": { + "blob": { + "type": "text" + } + } + } + } + }, "consumer": { "type": "keyword" }, 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 ceee1d0f04b8..0a15e2497216 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": "696d997e420024a8cf973da94d905c8756e1177c", "action_task_params": "cd91a48515202852ebf1fed0d999cd96f6b2823e", "ad_hoc_run_params": "690b8991f48c73a04e6a8cf41fd4967a42f8e552", - "alert": "1dcfa1391ca9e31e9b71e4e1785fb1f5da3f9c96", + "alert": "581f322afd6784aebdb80f872b825a928533d364", "api_key_pending_invalidation": "cef0693ec88475a0e1f43614cfa6ca43c24d0338", "apm-custom-dashboards": "9b08d5d5222131c6981a70144b1d61648757a613", "apm-indices": "b844821e9675768b1cb78f6d91ff336ed09d4739", 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 2de420ecd436..da650bbdec15 100644 --- a/src/platform/packages/shared/kbn-alerting-types/rule_types.ts +++ b/src/platform/packages/shared/kbn-alerting-types/rule_types.ts @@ -221,6 +221,9 @@ export interface Dashboard { export interface Artifacts { dashboards?: Dashboard[]; + investigation_guide?: { + blob: string; + }; } export interface Rule { 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 d270fb8a87e2..0190b6c0ec62 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,8 @@ import { createRuleParamsExamplesV1, } from '@kbn/response-ops-rule-params'; import { validateDurationV1, validateHoursV1, validateTimezoneV1 } from '../../../validation'; -import { notifyWhenSchemaV1, alertDelaySchemaV1, artifactsSchemaV1 } from '../../../response'; +import { notifyWhenSchemaV1, alertDelaySchemaV1 } from '../../../response'; +import { artifactsSchemaV1 } from '../../../request'; import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; import { flappingSchemaV1 } from '../../../common'; 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 f23340832f10..d22461de8f20 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,9 +9,10 @@ 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, artifactsSchemaV1 } from '../../../response'; +import { notifyWhenSchemaV1, alertDelaySchemaV1 } from '../../../response'; import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; import { flappingSchemaV1 } from '../../../common'; +import { artifactsSchemaV1 } from '../../../request'; export const updateRuleParamsExamples = () => path.join(__dirname, 'examples_update_rule.yaml'); diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/request/index.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/request/index.ts index bf500b636e7d..9de3f60bb5ab 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/request/index.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/request/index.ts @@ -8,3 +8,4 @@ export { ruleSnoozeScheduleSchema } from './schemas/latest'; export { ruleSnoozeScheduleSchema as ruleSnoozeScheduleSchemaV1 } from './schemas/v1'; +export { artifactsSchema as artifactsSchemaV1 } from './schemas/v1'; diff --git a/x-pack/platform/plugins/shared/alerting/common/routes/rule/request/schemas/v1.ts b/x-pack/platform/plugins/shared/alerting/common/routes/rule/request/schemas/v1.ts index c48fb291054b..45fe7ce1ac86 100644 --- a/x-pack/platform/plugins/shared/alerting/common/routes/rule/request/schemas/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/common/routes/rule/request/schemas/v1.ts @@ -9,6 +9,24 @@ import { schema } from '@kbn/config-schema'; import { rRuleRequestSchemaV1 } from '../../../r_rule'; import { validateSnoozeScheduleV1 } from '../../validation'; +export const MAX_ARTIFACTS_DASHBOARDS_LENGTH = 10; +export const MAX_ARTIFACTS_INVESTIGATION_GUIDE_LENGTH = 1000; + +export const dashboardsSchema = schema.arrayOf(schema.object({ id: schema.string() }), { + maxSize: MAX_ARTIFACTS_DASHBOARDS_LENGTH, +}); + +export const investigationGuideSchema = schema.object({ + blob: schema.string({ + maxLength: MAX_ARTIFACTS_INVESTIGATION_GUIDE_LENGTH, // with validation + }), +}); + +export const artifactsSchema = schema.object({ + dashboards: schema.maybe(dashboardsSchema), + investigation_guide: schema.maybe(investigationGuideSchema), +}); + export const ruleSnoozeScheduleSchema = schema.object( { id: schema.maybe( 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 5de32c97153c..d4b435dacab6 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 @@ -477,8 +477,17 @@ export const alertDelaySchema = schema.object( export const dashboardsSchema = schema.arrayOf(schema.object({ id: schema.string() })); +export const investigationGuideSchema = schema.object({ + blob: schema.string({ + meta: { + description: 'User-created content that describes alert causes and remdiation.', + }, + }), +}); + export const artifactsSchema = schema.object({ dashboards: schema.maybe(dashboardsSchema), + investigation_guide: schema.maybe(investigationGuideSchema), }); export const ruleResponseSchema = schema.object({ diff --git a/x-pack/platform/plugins/shared/alerting/common/saved_objects/rules/mappings.ts b/x-pack/platform/plugins/shared/alerting/common/saved_objects/rules/mappings.ts index 82de4efdb10f..a693a792f224 100644 --- a/x-pack/platform/plugins/shared/alerting/common/saved_objects/rules/mappings.ts +++ b/x-pack/platform/plugins/shared/alerting/common/saved_objects/rules/mappings.ts @@ -10,6 +10,17 @@ import type { SavedObjectsTypeMappingDefinition } from '@kbn/core/server'; export const alertMappings: SavedObjectsTypeMappingDefinition = { dynamic: false, properties: { + artifacts: { + properties: { + investigation_guide: { + properties: { + blob: { + type: 'text', + }, + }, + }, + }, + }, enabled: { type: 'boolean', }, 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 0b8e72f02b5a..953c91585c72 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 @@ -438,7 +438,7 @@ describe('scheduleBackfill()', () => { alertTypeId: existingDecryptedRule1.attributes.alertTypeId, apiKey: existingDecryptedRule1.attributes.apiKey, apiKeyCreatedByUser: existingDecryptedRule1.attributes.apiKeyCreatedByUser, - artifacts: { dashboards: [] }, + artifacts: { dashboards: [], investigation_guide: { blob: '' } }, consumer: existingDecryptedRule1.attributes.consumer, createdAt: new Date(existingDecryptedRule1.attributes.createdAt), createdBy: existingDecryptedRule1.attributes.createdBy, @@ -470,7 +470,7 @@ describe('scheduleBackfill()', () => { alertTypeId: existingDecryptedRule2.attributes.alertTypeId, apiKey: existingDecryptedRule2.attributes.apiKey, apiKeyCreatedByUser: existingDecryptedRule2.attributes.apiKeyCreatedByUser, - artifacts: { dashboards: [] }, + artifacts: { dashboards: [], investigation_guide: { blob: '' } }, 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/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 229e853c3234..d74d20c12a1c 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 @@ -163,6 +163,7 @@ describe('bulkEdit()', () => { actions: [], artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, name: 'my rule name', revision: 0, @@ -1251,6 +1252,7 @@ describe('bulkEdit()', () => { refId: 'dashboard_0', }, ], + investigation_guide: { blob: '' }, }, apiKey: null, apiKeyOwner: null, @@ -1288,6 +1290,7 @@ describe('bulkEdit()', () => { id: 'dashboard-1', }, ], + investigation_guide: { blob: '' }, }, id: existingRule.id, snoozeSchedule: [], 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 d2963c25ee2d..aea73f1b46e7 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 @@ -345,7 +345,7 @@ describe('create()', () => { }); }); - test('creates an rule', async () => { + test('creates a rule', async () => { const data = getMockData(); const createdAttributes = { ...data, @@ -434,6 +434,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, @@ -487,6 +490,9 @@ describe('create()', () => { "apiKeyOwner": null, "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "bar", "createdAt": "2019-02-12T21:01:22.479Z", @@ -720,6 +726,9 @@ describe('create()', () => { "apiKeyOwner": null, "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "bar", "createdAt": "2019-02-12T21:01:22.479Z", @@ -944,6 +953,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -1151,6 +1163,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -1208,6 +1223,7 @@ describe('create()', () => { apiKeyOwner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, apiKeyCreatedByUser: null, consumer: 'bar', @@ -1409,6 +1425,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -1472,6 +1491,7 @@ describe('create()', () => { apiKeyOwner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, consumer: 'bar', createdAt: '2019-02-12T21:01:22.479Z', @@ -1588,6 +1608,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": false, @@ -1730,6 +1753,7 @@ describe('create()', () => { apiKeyCreatedByUser: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, consumer: 'bar', createdAt: '2019-02-12T21:01:22.479Z', @@ -1788,6 +1812,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -1929,6 +1956,7 @@ describe('create()', () => { apiKeyCreatedByUser: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, legacyId: null, consumer: 'bar', @@ -1987,6 +2015,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -2118,6 +2149,7 @@ describe('create()', () => { apiKeyCreatedByUser: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', @@ -2169,6 +2201,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, @@ -2268,6 +2303,7 @@ describe('create()', () => { apiKeyCreatedByUser: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', @@ -2319,6 +2355,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, @@ -2418,6 +2457,9 @@ describe('create()', () => { apiKeyCreatedByUser: null, artifacts: { dashboards: [], + investigation_guide: { + blob: '', + }, }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', @@ -2469,6 +2511,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, @@ -2590,6 +2635,9 @@ describe('create()', () => { apiKeyCreatedByUser: null, artifacts: { dashboards: [], + investigation_guide: { + blob: '', + }, }, legacyId: null, createdBy: 'elastic', @@ -2662,6 +2710,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "bar", "createdAt": 2019-02-12T21:01:22.479Z, @@ -2992,6 +3043,9 @@ describe('create()', () => { apiKeyOwner: 'elastic', artifacts: { dashboards: [], + investigation_guide: { + blob: '', + }, }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', @@ -3096,6 +3150,9 @@ describe('create()', () => { alertTypeId: '123', artifacts: { dashboards: [], + investigation_guide: { + blob: '', + }, }, consumer: 'bar', name: 'abc', @@ -3856,6 +3913,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -4077,6 +4137,9 @@ describe('create()', () => { apiKeyCreatedByUser: true, artifacts: { dashboards: [], + investigation_guide: { + blob: '', + }, }, createdBy: 'elastic', createdAt: '2019-02-12T21:01:22.479Z', @@ -4258,6 +4321,9 @@ describe('create()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -4314,6 +4380,9 @@ describe('create()', () => { apiKeyCreatedByUser: null, artifacts: { dashboards: [], + investigation_guide: { + blob: '', + }, }, consumer: 'bar', createdAt: '2019-02-12T21:01:22.479Z', @@ -4639,6 +4708,9 @@ describe('create()', () => { refId: 'dashboard_1', }, ], + investigation_guide: { + blob: '', + }, }, }), { @@ -4660,5 +4732,66 @@ describe('create()', () => { expect(result.artifacts?.dashboards).toEqual(dashboards); }); + + test('should create a rule with an investigation guide', async () => { + const expectedBlob = `# Summary +This is an example of *Markdown* content. +This is the type of text _investigation guides_ will contain.`; + const investigationGuide = { + investigation_guide: { + blob: expectedBlob, + }, + }; + const data = getMockData({ + name: 'investigation guide test rule', + actions: [], + artifacts: { + ...investigationGuide, + }, + }); + + unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ + id: 'ig123', + type: RULE_SAVED_OBJECT_TYPE, + attributes: { + enabled: false, + name: 'investigation guide test rule', + alertTypeId: '123', + schedule: { interval: 10000 }, + params: { + bar: true, + }, + executionStatus: getRuleExecutionStatusPending(now), + running: false, + createdAt: now, + updatedAt: now, + actions: [], + artifacts: { + ...investigationGuide, + }, + }, + references: [], + }); + + const result = await rulesClient.create({ data }); + + expect(unsecuredSavedObjectsClient.create).toHaveBeenCalledWith( + RULE_SAVED_OBJECT_TYPE, + expect.objectContaining({ + artifacts: { + dashboards: [], + investigation_guide: { + blob: expectedBlob, + }, + }, + }), + { + id: 'mock-saved-object-id', + references: [], + } + ); + + expect(result.artifacts?.investigation_guide).toEqual(investigationGuide.investigation_guide); + }); }); }); 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 a85a0e5056db..04d92897d37c 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 @@ -202,6 +202,9 @@ describe('find()', () => { "alertTypeId": "myType", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -320,6 +323,9 @@ describe('find()', () => { "alertTypeId": "myType", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -428,6 +434,9 @@ describe('find()', () => { "alertTypeId": "myType", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -719,6 +728,9 @@ describe('find()', () => { "alertTypeId": "myType", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -752,6 +764,9 @@ describe('find()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -1030,6 +1045,9 @@ describe('find()', () => { "actions": Array [], "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "id": "1", "notifyWhen": undefined, @@ -1284,6 +1302,9 @@ describe('find()', () => { "id": "dashboard-1", }, ], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { 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 2f971a1be1cd..6b4a726cab9c 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 @@ -134,6 +134,9 @@ describe('get()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -232,6 +235,9 @@ describe('get()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -319,6 +325,9 @@ describe('get()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -449,6 +458,9 @@ describe('get()', () => { "alertTypeId": "123", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { 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 140630c4ae80..0e2d4e2bb3ad 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 @@ -413,6 +413,9 @@ describe('update()', () => { }, "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -486,6 +489,9 @@ describe('update()', () => { "apiKeyOwner": null, "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -754,6 +760,7 @@ describe('update()', () => { apiKeyOwner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, apiKeyCreatedByUser: null, consumer: 'myApp', @@ -811,6 +818,9 @@ describe('update()', () => { ], "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -1007,6 +1017,7 @@ describe('update()', () => { apiKeyOwner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, apiKeyCreatedByUser: null, consumer: 'myApp', @@ -1046,6 +1057,9 @@ describe('update()', () => { ], "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -1224,6 +1238,7 @@ describe('update()', () => { apiKeyOwner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, apiKeyCreatedByUser: null, consumer: 'myApp', @@ -1273,6 +1288,9 @@ describe('update()', () => { ], "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -1378,6 +1396,9 @@ describe('update()', () => { ], "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -1429,6 +1450,9 @@ describe('update()', () => { "apiKeyOwner": "elastic", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -1564,6 +1588,9 @@ describe('update()', () => { ], "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": false, @@ -1607,6 +1634,9 @@ describe('update()', () => { "apiKeyOwner": null, "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -2795,6 +2825,7 @@ describe('update()', () => { apiKeyOwner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, apiKeyCreatedByUser: null, consumer: 'myApp', @@ -2834,6 +2865,9 @@ describe('update()', () => { ], "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -3394,6 +3428,7 @@ describe('update()', () => { apiKeyOwner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, apiKeyCreatedByUser: null, consumer: 'myApp', @@ -3573,6 +3608,9 @@ describe('update()', () => { "apiKeyCreatedByUser": true, "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -3618,6 +3656,9 @@ describe('update()', () => { "apiKeyOwner": "elastic", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "consumer": "myApp", "createdAt": "2019-02-12T21:01:22.479Z", @@ -3878,6 +3919,7 @@ describe('update()', () => { apiKeyOwner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, apiKeyCreatedByUser: null, consumer: 'myApp', @@ -3917,6 +3959,9 @@ describe('update()', () => { ], "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -4316,6 +4361,7 @@ describe('update()', () => { actions: [], artifacts: { dashboards: existingDashboards, + investigation_guide: { blob: '' }, }, }, references: [ @@ -4351,6 +4397,7 @@ describe('update()', () => { refId: 'dashboard_0', }, ], + investigation_guide: { blob: '' }, }, executionStatus: { lastExecutionDate: '2019-02-12T21:01:22.479Z', @@ -4390,6 +4437,7 @@ describe('update()', () => { id: 'dashboard-1', }, ], + investigation_guide: { blob: '' }, }, }, }); @@ -4404,6 +4452,7 @@ describe('update()', () => { refId: 'dashboard_0', }, ], + investigation_guide: { blob: '' }, }, }), { @@ -4420,6 +4469,7 @@ describe('update()', () => { id: 'dashboard-1', }, ], + investigation_guide: { blob: '' }, }); expect(result).toMatchInlineSnapshot(` @@ -4431,6 +4481,9 @@ describe('update()', () => { "id": "dashboard-1", }, ], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -4494,6 +4547,7 @@ describe('update()', () => { actions: [], artifacts: { dashboards: existingDashboards, + investigation_guide: { blob: '' }, }, }, references: [ @@ -4610,6 +4664,7 @@ describe('update()', () => { refId: 'dashboard_2', }, ], + investigation_guide: { blob: '' }, }, }), { @@ -4636,6 +4691,7 @@ describe('update()', () => { id: 'dashboard-3', }, ], + investigation_guide: { blob: '' }, }); expect(result).toMatchInlineSnapshot(` @@ -4653,6 +4709,9 @@ describe('update()', () => { "id": "dashboard-3", }, ], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "enabled": true, @@ -4677,5 +4736,163 @@ describe('update()', () => { expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); }); + + test('gives updated investigation guide to saved objects client', async () => { + actionsClient.getBulk.mockReset(); + actionsClient.getBulk.mockResolvedValue([ + { + id: '1', + actionTypeId: 'test', + config: { + from: 'me@me.com', + hasAuth: false, + host: 'hello', + port: 22, + secure: null, + service: null, + }, + isMissingSecrets: false, + name: 'email connector', + isPreconfigured: false, + isDeprecated: false, + isSystemAction: false, + }, + { + id: '2', + actionTypeId: 'test2', + config: { + from: 'me@me.com', + hasAuth: false, + host: 'hello', + port: 22, + secure: null, + service: null, + }, + isMissingSecrets: false, + name: 'email connector', + isPreconfigured: false, + isDeprecated: false, + isSystemAction: false, + }, + ]); + unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ + id: '1', + type: RULE_SAVED_OBJECT_TYPE, + attributes: { + enabled: true, + schedule: { interval: '1m' }, + params: { + bar: true, + }, + actions: [ + { + group: 'default', + actionRef: 'action_0', + actionTypeId: 'test', + params: { + foo: true, + }, + }, + { + group: 'default', + actionRef: 'action_1', + actionTypeId: 'test', + params: { + foo: true, + }, + }, + { + group: 'default', + actionRef: 'action_2', + actionTypeId: 'test2', + params: { + foo: true, + }, + }, + ], + notifyWhen: 'onActiveAlert', + revision: 1, + scheduledTaskId: 'task-123', + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + alertDelay: { + active: 5, + }, + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + }, + }, + references: [ + { + name: 'action_0', + type: 'action', + id: '1', + }, + { + name: 'action_1', + type: 'action', + id: '1', + }, + { + name: 'action_2', + type: 'action', + id: '2', + }, + ], + }); + + const result = await rulesClient.update({ + id: '1', + data: { + schedule: { interval: '1m' }, + name: 'abc', + tags: ['foo'], + params: { + bar: true, + risk_score: 40, + severity: 'low', + }, + throttle: null, + notifyWhen: 'onActiveAlert', + artifacts: { + investigation_guide: { blob: 'new blob' }, + }, + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + }, + { + group: 'default', + id: '1', + params: { + foo: true, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, + }, + ], + alertDelay: { + active: 10, + }, + }, + }); + + expect(unsecuredSavedObjectsClient.create).toHaveBeenCalledTimes(1); + expect( + (unsecuredSavedObjectsClient.create.mock.calls[0][1] as RuleDomain).artifacts + ?.investigation_guide?.blob + ).toEqual('new blob'); + expect(result.artifacts).toBeDefined(); + }); }); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifacts_schema.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifacts_schema.ts index 7a713b3816e1..b942f66290a4 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifacts_schema.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/schemas/artifacts_schema.ts @@ -7,6 +7,10 @@ import { schema } from '@kbn/config-schema'; +export const investigationGuideSchema = schema.object({ + blob: schema.string(), +}); + export const dashboardsSchema = schema.arrayOf( schema.object({ id: schema.string(), @@ -15,4 +19,5 @@ export const dashboardsSchema = schema.arrayOf( export const artifactsSchema = schema.object({ dashboards: schema.maybe(dashboardsSchema), + investigation_guide: schema.maybe(investigationGuideSchema), }); 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 4d7ed06ebce7..e894d333f22d 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 @@ -12,7 +12,7 @@ import { transformRawArtifactsToDomainArtifacts } from './transform_raw_artifact describe('transformRawArtifactsToDomainArtifacts', () => { it('should return default artifacts if rawArtifacts is undefined', () => { const result = transformRawArtifactsToDomainArtifacts('1', undefined, []); - expect(result).toEqual({ dashboards: [] }); + expect(result).toEqual({ dashboards: [], investigation_guide: { blob: '' } }); }); it('should return artifacts with injected references', () => { @@ -48,6 +48,7 @@ describe('transformRawArtifactsToDomainArtifacts', () => { id: 'dashboard_1', }, ], + investigation_guide: { blob: '' }, }); }); @@ -55,7 +56,7 @@ describe('transformRawArtifactsToDomainArtifacts', () => { const rawArtifacts: RawRule['artifacts'] = {}; const references: SavedObjectReference[] = []; const result = transformRawArtifactsToDomainArtifacts('1', rawArtifacts, references); - expect(result).toEqual({ dashboards: [] }); + expect(result).toEqual({ dashboards: [], investigation_guide: { blob: '' } }); }); it('should return artifacts with injected references and empty dashboards array if no dashboards in rawArtifacts', () => { @@ -68,7 +69,7 @@ describe('transformRawArtifactsToDomainArtifacts', () => { }, ]; const result = transformRawArtifactsToDomainArtifacts('1', rawArtifacts, references); - expect(result).toEqual({ dashboards: [] }); + expect(result).toEqual({ dashboards: [], investigation_guide: { blob: '' } }); }); it('throws an error if no references found', () => { 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 80fa9034c708..bf1c05376fd6 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 @@ -234,6 +234,9 @@ describe('transformRuleAttributesToRuleDomain', () => { "id": "dashboard-2", }, ], + "investigation_guide": Object { + "blob": "", + }, } `); }); 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 02ded7aae93a..dd2a88db4b5e 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,19 @@ 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: [], + investigation_guide: { blob: '' }, + }); + }); + + it('includes investigation guide fields', () => { + expect( + injectReferencesIntoArtifacts('test-id', { investigation_guide: { blob: '# Summary' } }, []) + ).toEqual({ + dashboards: [], + investigation_guide: { blob: '# Summary' }, + }); }); it('throws an error if references are not provided', () => { 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 4289734f6396..3171880ca20f 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 @@ -85,10 +85,13 @@ export function injectReferencesIntoArtifacts( references?: SavedObjectReference[] ): Required { if (!artifacts) { - return { dashboards: [] }; + return { dashboards: [], investigation_guide: { blob: '' } }; } return { ...artifacts, + investigation_guide: { + blob: artifacts.investigation_guide?.blob ?? '', + }, dashboards: artifacts.dashboards?.map((dashboard) => { const reference = references?.find( 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 b128533fa1f5..ea1daba41d96 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,6 +12,7 @@ describe('denormalizeArtifacts', () => { const { artifacts, references } = denormalizeArtifacts(undefined); expect(artifacts).toEqual({ dashboards: [], + investigation_guide: { blob: '' }, }); expect(references).toEqual([]); }); @@ -26,6 +27,9 @@ describe('denormalizeArtifacts', () => { id: '456', }, ], + investigation_guide: { + blob: '## Summary', + }, }; const { artifacts, references } = denormalizeArtifacts(ruleArtifacts); expect(artifacts).toEqual({ @@ -37,6 +41,7 @@ describe('denormalizeArtifacts', () => { refId: 'dashboard_1', }, ], + investigation_guide: ruleArtifacts.investigation_guide, }); expect(references).toEqual([ { 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 861a82247778..f20794d49abc 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 @@ -15,8 +15,14 @@ export function denormalizeArtifacts(ruleArtifacts: Artifacts | undefined): { const references: SavedObjectReference[] = []; const artifacts: Required = { dashboards: [], + investigation_guide: { blob: '' }, }; + if (ruleArtifacts && ruleArtifacts.investigation_guide) { + artifacts.investigation_guide = { + blob: ruleArtifacts.investigation_guide.blob, + }; + } if (ruleArtifacts && ruleArtifacts.dashboards) { ruleArtifacts.dashboards.forEach((dashboard, i) => { const refName = `dashboard_${i}`; 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 a923f9129192..7eaefe4b59df 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 @@ -74,6 +74,7 @@ describe('extractReferences', () => { refId: 'dashboard_0', }, ], + investigation_guide: { blob: '' }, }); expect(result.references).toEqual([ 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 1e55ceb2a458..798ddaffe6a8 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 @@ -140,6 +140,9 @@ describe('resolve()', () => { "alias_target_id": "2", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -327,6 +330,9 @@ describe('resolve()', () => { "alias_target_id": "2", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { @@ -525,6 +531,9 @@ describe('resolve()', () => { "alias_target_id": "2", "artifacts": Object { "dashboards": Array [], + "investigation_guide": Object { + "blob": "", + }, }, "createdAt": 2019-02-12T21:01:22.479Z, "executionStatus": Object { 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 33e091f351aa..14eeb10fa7ab 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 @@ -457,6 +457,7 @@ export const returnedRuleForBulkOps1 = { alertTypeId: 'fakeType', artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, consumer: 'fakeConsumer', enabled: true, @@ -486,6 +487,7 @@ export const returnedRuleForBulkOps2 = { alertTypeId: 'fakeType', artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, consumer: 'fakeConsumer', enabled: true, @@ -516,6 +518,7 @@ export const returnedRuleForBulkOps3 = { apiKeyCreatedByUser: true, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, consumer: 'fakeConsumer', enabled: true, 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 db098cb9ead8..b00bafeca43c 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,6 +191,11 @@ interface DashboardItem { refId: string; } +interface InvestigationGuide { + blob: string; +} + export interface DenormalizedArtifacts { dashboards?: DashboardItem[]; + investigation_guide?: InvestigationGuide; } 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 bd1673b06dfe..2562c4cdddad 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 @@ -12,6 +12,7 @@ import { rawRuleSchemaV3, rawRuleSchemaV4, rawRuleSchemaV5, + rawRuleSchemaV6, } from '../schemas/raw_rule'; export const ruleModelVersions: SavedObjectsModelVersionMap = { @@ -50,4 +51,28 @@ export const ruleModelVersions: SavedObjectsModelVersionMap = { create: rawRuleSchemaV5, }, }, + '6': { + changes: [ + { + type: 'mappings_addition', + addedMappings: { + artifacts: { + properties: { + investigation_guide: { + properties: { + blob: { + type: 'text', + }, + }, + }, + }, + }, + }, + }, + ], + schemas: { + forwardCompatibility: rawRuleSchemaV6.extends({}, { unknowns: 'ignore' }), + create: rawRuleSchemaV6, + }, + }, }; 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 10c7d125b0c5..1d1438ad01be 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 @@ -12,3 +12,4 @@ export { rawRuleSchema as rawRuleSchemaV2 } from './v2'; export { rawRuleSchema as rawRuleSchemaV3 } from './v3'; export { rawRuleSchema as rawRuleSchemaV4 } from './v4'; export { rawRuleSchema as rawRuleSchemaV5 } from './v5'; +export { rawRuleSchema as rawRuleSchemaV6 } from './v6'; 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 479245944f3b..0c97e5f6f9fd 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 @@ -14,7 +14,7 @@ import type { } from './v3'; import type { rawRuleMonitoringSchema } from './v4'; -import type { rawRuleSchema } from './v5'; +import type { rawRuleSchema } from './v6'; 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/v6.ts b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v6.ts new file mode 100644 index 000000000000..bf54088f5428 --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/server/saved_objects/schemas/raw_rule/v6.ts @@ -0,0 +1,21 @@ +/* + * 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 rawRuleSchemaV5, artifactsSchema as artifactsSchemaV5 } from './v5'; + +export const rawRuleInvestigationGuideSchema = schema.object({ + blob: schema.string(), +}); + +export const artifactsSchema = artifactsSchemaV5.extends({ + investigation_guide: schema.maybe(rawRuleInvestigationGuideSchema), +}); + +export const rawRuleSchema = rawRuleSchemaV5.extends({ + artifacts: schema.maybe(artifactsSchema), +}); 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 a6a0cbdf2a27..e196506520da 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 @@ -304,6 +304,9 @@ export const mockedRule: SanitizedRule id: 'dashboard-1', }, ], + investigation_guide: { + blob: '## Summary', + }, }, }; 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 363a942a23de..089f637ea4d9 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 @@ -85,11 +85,12 @@ export default function createFindTests({ getService }: FtrProviderContext) { rule_type_id: 'test.noop', running: match.running ?? false, consumer: 'alertsFixture', - schedule: { interval: '1m' }, - enabled: true, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, + schedule: { interval: '1m' }, + enabled: true, actions: [], params: {}, created_by: 'elastic', @@ -286,6 +287,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { api_key_created_by_user: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, revision: 0, throttle: '1m', @@ -378,7 +380,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(omit(matchFirst, 'updatedAt')).to.eql({ id: createdAlert.id, actions: [], - artifacts: { dashboards: [] }, + artifacts: { dashboards: [], investigation_guide: { blob: '' } }, tags: [myTag], snooze_schedule: [], is_snoozed_until: null, @@ -386,7 +388,10 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(omit(matchSecond, 'updatedAt')).to.eql({ id: createdSecondAlert.id, actions: [], - artifacts: { dashboards: [] }, + artifacts: { + dashboards: [], + investigation_guide: { blob: '' }, + }, tags: [myTag], snooze_schedule: [], is_snoozed_until: null, @@ -463,7 +468,10 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(omit(matchFirst, 'updatedAt')).to.eql({ id: createdAlert.id, actions: [], - artifacts: { dashboards: [] }, + artifacts: { + dashboards: [], + investigation_guide: { blob: '' }, + }, tags: [myTag], execution_status: matchFirst.execution_status, snooze_schedule: [], @@ -472,7 +480,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(omit(matchSecond, 'updatedAt')).to.eql({ id: createdSecondAlert.id, actions: [], - artifacts: { dashboards: [] }, + artifacts: { dashboards: [], investigation_guide: { blob: '' } }, tags: [myTag], execution_status: matchSecond.execution_status, snooze_schedule: [], diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/resolve.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/resolve.ts index f20200e2d32a..fec0816e4f2e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/resolve.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/alerting/resolve.ts @@ -104,6 +104,10 @@ export default ({ getService }: FtrProviderContext) => { id: '456', }, ], + + investigation_guide: { + blob: '# Summary', + }, }, }) ) @@ -126,6 +130,9 @@ export default ({ getService }: FtrProviderContext) => { id: '456', }, ], + investigation_guide: { + blob: '# Summary', + }, }); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group5/tests/alerting/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group5/tests/alerting/get.ts index 9f0f3fa94cb3..c75b966af08c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group5/tests/alerting/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group5/tests/alerting/get.ts @@ -83,6 +83,7 @@ const getTestUtils = ( ? { artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, } : {}), @@ -399,6 +400,7 @@ const getTestUtils = ( id: 'dashboard-2', }, ], + investigation_guide: { blob: '# Summary' }, }, } : {}), @@ -428,6 +430,7 @@ const getTestUtils = ( id: 'dashboard-2', }, ], + investigation_guide: { blob: '# Summary' }, }); } }); 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 3da0f2517ed2..6e589669a8bc 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 @@ -10,8 +10,12 @@ import type { SavedObject } from '@kbn/core/server'; import type { RawRule } from '@kbn/alerting-plugin/server/types'; import { RuleNotifyWhen } from '@kbn/alerting-plugin/server/types'; import { ALERTING_CASES_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; -import { omit } from 'lodash'; import { RULE_SAVED_OBJECT_TYPE } from '@kbn/alerting-plugin/server'; +import { + MAX_ARTIFACTS_DASHBOARDS_LENGTH, + MAX_ARTIFACTS_INVESTIGATION_GUIDE_LENGTH, +} from '@kbn/alerting-plugin/common/routes/rule/request/schemas/v1'; +import { omit } from 'lodash'; import { Spaces } from '../../../scenarios'; import type { TaskManagerDoc } from '../../../../common/lib'; import { @@ -766,6 +770,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { getTestRuleData({ artifacts: { dashboards: [{ id: 'dashboard-1' }, { id: 'dashboard-2' }], + investigation_guide: { blob: 'Sample investigation guide' }, }, }) ); @@ -788,6 +793,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { id: dashboardId, }, ], + investigation_guide: { blob: 'Sample investigation guide' }, }, }) ); @@ -848,6 +854,83 @@ export default function createAlertTests({ getService }: FtrProviderContext) { }); }); }); + describe('create rule with investigation guide artifacts', () => { + it('should not return investigation guide 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: { + investigation_guide: { blob: 'Sample investigation guide' }, + }, + }) + ) + .expect(200); + objectRemover.add(Spaces.space1.id, response.body.id, 'rule', 'alerting'); + + expect(response.body.artifacts).to.be(undefined); + }); + + it('should store investigation guide in the artifacts field', async () => { + const expectedArtifacts = { + artifacts: { + investigation_guide: { blob: 'Sample investigation guide' }, + }, + }; + const createResponse = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData(expectedArtifacts)) + .expect(200); + objectRemover.add(Spaces.space1.id, createResponse.body.id, 'rule', 'alerting'); + + const esResponse = await es.get>( + { + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + id: `alert:${createResponse.body.id}`, + }, + { meta: true } + ); + + const rawInvestigationGuide = + (esResponse.body._source as any)?.alert.artifacts.investigation_guide ?? {}; + + expect(rawInvestigationGuide).to.eql(expectedArtifacts.artifacts.investigation_guide); + }); + + it('should deny creating a rule with an investigation guide that exceeds size limits', () => + supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + artifacts: { + investigation_guide: { + // purposefully exceed limit + blob: 'a'.repeat(MAX_ARTIFACTS_INVESTIGATION_GUIDE_LENGTH + 1), + }, + }, + }) + ) + .expect(400)); + + it('should deny creating a rule that exceeds dashboard length limits', () => + supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + artifacts: { + dashboards: Array.from( + { length: MAX_ARTIFACTS_DASHBOARDS_LENGTH + 1 }, + (_, idx) => ({ id: `dashboard-${idx}` }) + ), + }, + }) + ) + .expect(400)); + }); }); }); } 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 8cd08304f0d7..bf2cea506968 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 @@ -341,10 +341,10 @@ export default function createFindTests({ getService }: FtrProviderContext) { it('does not return artifacts when present', async () => { const expectedArtifacts = { artifacts: { + investigation_guide: { blob: 'Sample investigation guide' }, dashboards: [{ id: 'dashboard-1' }], }, }; - const { body: createdAlert } = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) .set('kbn-xsrf', 'foo') 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 652b5b61d0f6..7add3aa5a7fc 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 @@ -121,6 +121,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { api_key_owner: null, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, api_key_created_by_user: null, scheduled_task_id: match.scheduled_task_id, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/get.ts index aecb182015fc..fdc1d5260f2f 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/get.ts @@ -55,6 +55,7 @@ const getTestUtils = ( ? { artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, } : {}), @@ -139,6 +140,9 @@ const getTestUtils = ( id: 'dashboard-2', }, ], + investigation_guide: { + blob: '# Summary', + }, }, } : {}), @@ -166,6 +170,9 @@ const getTestUtils = ( id: 'dashboard-2', }, ], + investigation_guide: { + blob: '# Summary', + }, }); } }); 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 962b161c2388..876791873ab6 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 @@ -10,6 +10,10 @@ 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 { + MAX_ARTIFACTS_DASHBOARDS_LENGTH, + MAX_ARTIFACTS_INVESTIGATION_GUIDE_LENGTH, +} from '@kbn/alerting-plugin/common/routes/rule/request/schemas/v1'; import { Spaces } from '../../../scenarios'; import { checkAAD, @@ -467,6 +471,9 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { id: 'dashboard-1', }, ], + investigation_guide: { + blob: '## Summary', + }, }, }; @@ -505,6 +512,9 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { notify_when: 'onThrottleInterval', artifacts: { dashboards: [{ id: 'dashboard-1' }, { id: 'dashboard-2' }], + investigation_guide: { + blob: '## Summary', + }, }, }) .expect(200); @@ -526,6 +536,64 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { refId: 'dashboard_1', }, ]); + expect((esUpdateResponse.body._source as any)?.alert.artifacts.investigation_guide).to.eql({ + blob: '## Summary', + }); + }); + + it('should not allow updating of dashboards with > dashboard length limit', async () => { + // create a rule + const createResponse = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData()) + .expect(200); + + await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule/${createResponse.body.id}`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + artifacts: { + // push more dashboards than allowed + dashboards: Array.from( + { length: MAX_ARTIFACTS_DASHBOARDS_LENGTH + 1 }, + (_, idx) => ({ id: `dashboard-${idx}` }) + ), + }, + }) + ) + .expect(400); + }); + + it('should not allow updating investigation_guide with length > limit', async () => { + // create a rule + const createResponse = await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send(getTestRuleData()) + .expect(200); + + const longInvestigationGuideBlob = 'a'.repeat(MAX_ARTIFACTS_INVESTIGATION_GUIDE_LENGTH + 1); + await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule/${createResponse.body.id}`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + artifacts: { + dashboards: [ + { + id: 'dashboard-1', + }, + ], + // push a longer `investigation_guide` than allowed + investigation_guide: { + blob: longInvestigationGuideBlob, + }, + }, + }) + ) + .expect(400); }); }); }); 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 419006911da9..5981bc897461 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 @@ -276,6 +276,7 @@ const defaultAlertRules = { apiKeyCreatedByUser: true, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, createdBy: 'any', updatedBy: 'any', @@ -311,6 +312,7 @@ const defaultAlertRules = { apiKeyCreatedByUser: true, artifacts: { dashboards: [], + investigation_guide: { blob: '' }, }, createdBy: 'elastic_admin', updatedBy: 'elastic_admin',