From 04c68ad1f6bb966d85a4c40a7f73bc6ee17e5e19 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sat, 9 Nov 2024 17:33:11 +0200 Subject: [PATCH] [ResponseOps][Cases] Register `forwardCompatibility` schema for the Cases SO (#198498) ## Summary Summarize your PR. If it involves visual changes include a screenshot or gif. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine --- .../check_registered_types.test.ts | 2 +- .../cases/model_versions.test.ts | 76 +++++++++---------- .../cases/model_versions.ts | 4 + .../saved_object_types/cases/schemas/index.ts | 10 +++ .../cases/schemas/latest.ts | 8 ++ .../saved_object_types/cases/schemas/v1.ts | 71 +++++++++++++++++ 6 files changed, 131 insertions(+), 40 deletions(-) create mode 100644 x-pack/plugins/cases/server/saved_object_types/cases/schemas/index.ts create mode 100644 x-pack/plugins/cases/server/saved_object_types/cases/schemas/latest.ts create mode 100644 x-pack/plugins/cases/server/saved_object_types/cases/schemas/v1.ts 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 af120096bdb2a..02f7007b51202 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 @@ -73,7 +73,7 @@ describe('checking migration metadata changes on all registered SO types', () => "canvas-element": "cdedc2123eb8a1506b87a56b0bcce60f4ec08bc8", "canvas-workpad": "9d82aafb19586b119e5c9382f938abe28c26ca5c", "canvas-workpad-template": "c077b0087346776bb3542b51e1385d172cb24179", - "cases": "2392189ed338857d4815a4cef6051f9ad124d39d", + "cases": "5433a9f1277f8f17bbc4fd20d33b1fc6d997931e", "cases-comments": "5cb0a421588831c2a950e50f486048b8aabbae25", "cases-configure": "44ed7b8e0f44df39516b8870589b89e32224d2bf", "cases-connector-mappings": "f9d1ac57e484e69506c36a8051e4d61f4a8cfd25", diff --git a/x-pack/plugins/cases/server/saved_object_types/cases/model_versions.test.ts b/x-pack/plugins/cases/server/saved_object_types/cases/model_versions.test.ts index 8520fd9673d31..2c301709ca5c9 100644 --- a/x-pack/plugins/cases/server/saved_object_types/cases/model_versions.test.ts +++ b/x-pack/plugins/cases/server/saved_object_types/cases/model_versions.test.ts @@ -10,51 +10,49 @@ import { modelVersion1 } from './model_versions'; describe('Model versions', () => { describe('1', () => { it('returns the model version correctly', () => { - expect(modelVersion1).toMatchInlineSnapshot(` - Object { - "changes": Array [ - Object { - "addedMappings": Object { - "customFields": Object { - "properties": Object { - "key": Object { - "type": "keyword", - }, - "type": Object { - "type": "keyword", - }, - "value": Object { - "fields": Object { - "boolean": Object { - "ignore_malformed": true, - "type": "boolean", - }, - "date": Object { - "ignore_malformed": true, - "type": "date", - }, - "ip": Object { - "ignore_malformed": true, - "type": "ip", - }, - "number": Object { - "ignore_malformed": true, - "type": "long", - }, - "string": Object { - "type": "text", - }, + expect(modelVersion1.changes).toMatchInlineSnapshot(` + Array [ + Object { + "addedMappings": Object { + "customFields": Object { + "properties": Object { + "key": Object { + "type": "keyword", + }, + "type": Object { + "type": "keyword", + }, + "value": Object { + "fields": Object { + "boolean": Object { + "ignore_malformed": true, + "type": "boolean", + }, + "date": Object { + "ignore_malformed": true, + "type": "date", + }, + "ip": Object { + "ignore_malformed": true, + "type": "ip", + }, + "number": Object { + "ignore_malformed": true, + "type": "long", + }, + "string": Object { + "type": "text", }, - "type": "keyword", }, + "type": "keyword", }, - "type": "nested", }, + "type": "nested", }, - "type": "mappings_addition", }, - ], - } + "type": "mappings_addition", + }, + ] `); }); }); diff --git a/x-pack/plugins/cases/server/saved_object_types/cases/model_versions.ts b/x-pack/plugins/cases/server/saved_object_types/cases/model_versions.ts index 56806e7dec607..7d46789a3b79f 100644 --- a/x-pack/plugins/cases/server/saved_object_types/cases/model_versions.ts +++ b/x-pack/plugins/cases/server/saved_object_types/cases/model_versions.ts @@ -6,6 +6,7 @@ */ import type { SavedObjectsModelVersion } from '@kbn/core-saved-objects-server'; +import { casesSchemaV1 } from './schemas'; /** * Adds custom fields to the cases SO. @@ -54,4 +55,7 @@ export const modelVersion1: SavedObjectsModelVersion = { }, }, ], + schemas: { + forwardCompatibility: casesSchemaV1.extends({}, { unknowns: 'ignore' }), + }, }; diff --git a/x-pack/plugins/cases/server/saved_object_types/cases/schemas/index.ts b/x-pack/plugins/cases/server/saved_object_types/cases/schemas/index.ts new file mode 100644 index 0000000000000..85d9239f72dba --- /dev/null +++ b/x-pack/plugins/cases/server/saved_object_types/cases/schemas/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './latest'; + +export { casesSchema as casesSchemaV1 } from './v1'; diff --git a/x-pack/plugins/cases/server/saved_object_types/cases/schemas/latest.ts b/x-pack/plugins/cases/server/saved_object_types/cases/schemas/latest.ts new file mode 100644 index 0000000000000..25300c97a6d2e --- /dev/null +++ b/x-pack/plugins/cases/server/saved_object_types/cases/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './v1'; diff --git a/x-pack/plugins/cases/server/saved_object_types/cases/schemas/v1.ts b/x-pack/plugins/cases/server/saved_object_types/cases/schemas/v1.ts new file mode 100644 index 0000000000000..1a6bb0a8cdd8c --- /dev/null +++ b/x-pack/plugins/cases/server/saved_object_types/cases/schemas/v1.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 { schema } from '@kbn/config-schema'; + +const UserSchema = schema.object({ + email: schema.nullable(schema.string()), + full_name: schema.nullable(schema.string()), + username: schema.nullable(schema.string()), + profile_uid: schema.nullable(schema.string()), +}); + +const UserProfileSchema = schema.object({ uid: schema.string() }); + +const ConnectorSchema = schema.object({ + name: schema.string(), + type: schema.string(), + fields: schema.arrayOf(schema.object({ key: schema.string(), value: schema.string() })), +}); + +const ExternalServiceSchema = schema.object({ + connector_name: schema.string(), + external_id: schema.string(), + external_title: schema.string(), + external_url: schema.string(), + pushed_at: schema.string(), + pushed_by: UserSchema, +}); + +const SettingsSchema = schema.object({ syncAlerts: schema.boolean() }); + +const CustomFieldsSchema = schema.arrayOf( + schema.object({ + key: schema.string(), + type: schema.string(), + value: schema.nullable(schema.any()), + }) +); + +export const casesSchema = schema.object({ + assignees: schema.arrayOf(UserProfileSchema), + category: schema.maybe(schema.nullable(schema.string())), + closed_at: schema.nullable(schema.string()), + closed_by: schema.nullable(UserSchema), + created_at: schema.string(), + created_by: UserSchema, + connector: ConnectorSchema, + customFields: schema.maybe(schema.nullable(CustomFieldsSchema)), + description: schema.string(), + duration: schema.nullable(schema.number()), + external_service: schema.nullable(ExternalServiceSchema), + owner: schema.string(), + settings: SettingsSchema, + severity: schema.oneOf([ + schema.literal(10), + schema.literal(20), + schema.literal(30), + schema.literal(40), + ]), + status: schema.oneOf([schema.literal(0), schema.literal(10), schema.literal(20)]), + tags: schema.arrayOf(schema.string()), + title: schema.string(), + total_alerts: schema.number(), + total_comments: schema.number(), + updated_at: schema.nullable(schema.string()), + updated_by: schema.nullable(UserSchema), +});