From 3e15695d06355867f88659ba0585795d0a1873ce Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 31 Aug 2021 16:38:33 -0700 Subject: [PATCH] [Alerting][8.0] Prepare alerting SOs to sharecapable (#110386) * [Alerting] [8.0] Prepare for making alerting saved objects sharecapable (#109990) * [Alerting] [8.0] Prepare for making alerting saved objects sharecapable * removed v8 check * removed link * added no op migration * fixed name Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> * [Actions] [8.0] Prepare for making action saved objects sharecapable. (#109756) * [Actions] [8.0] Prepare for making action saved objects sharecapable. * added more tests * made it compatible to merge to 7.x * fixed due to comments * fixed tests * added tests * fixed tests * fixed due to comments * added no-opactions migration * fixed test * [Task Manager][8.0] Added migrations to savedObject Ids for "actions:* and "alerting:*" task types (#109180) * [Task Manager][8.0] Added migrations to savedObject Ids for "actions:* and "alerting:*" task types * fixed due to comments * fixed typo * added more tests * added unit test * added func test * added func tests * fixed test Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> * fixed merge * fixed legacy tests * fixed tests * fixed eslint * Update migrations.ts fixed action task * fixed due to comments Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../action_task_params_migrations.test.ts | 8 + .../action_task_params_migrations.ts | 9 + .../saved_objects/actions_migrations.test.ts | 8 + .../saved_objects/actions_migrations.ts | 8 + .../actions/server/saved_objects/index.ts | 6 +- .../alerting/server/saved_objects/index.ts | 3 +- .../server/saved_objects/migrations.test.ts | 8 + .../server/saved_objects/migrations.ts | 7 + .../server/saved_objects/index.ts | 4 +- .../server/saved_objects/migrations.test.ts | 169 +++++++++++++ .../server/saved_objects/migrations.ts | 128 +++++++++- .../tests/alerting/rbac_legacy.ts | 38 ++- .../spaces_only/tests/alerting/create.ts | 2 +- .../es_archives/task_manager_tasks/data.json | 61 +++++ .../task_manager_tasks/mappings.json | 225 ++++++++++++++++++ .../test_suites/task_manager/index.ts | 2 + .../test_suites/task_manager/migrations.ts | 70 ++++++ 17 files changed, 736 insertions(+), 20 deletions(-) create mode 100644 x-pack/plugins/task_manager/server/saved_objects/migrations.test.ts create mode 100644 x-pack/test/functional/es_archives/task_manager_tasks/data.json create mode 100644 x-pack/test/functional/es_archives/task_manager_tasks/mappings.json create mode 100644 x-pack/test/plugin_api_integration/test_suites/task_manager/migrations.ts diff --git a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts index ceea9f3cff18fa..6d7fd940612f3e 100644 --- a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts @@ -356,6 +356,14 @@ describe('successful migrations', () => { }); }); }); + + describe('8.0.0', () => { + test('no op migration for rules SO', () => { + const migration800 = getActionTaskParamsMigrations(encryptedSavedObjectsSetup, [])['8.0.0']; + const actionTaskParam = getMockData(); + expect(migration800(actionTaskParam, context)).toEqual(actionTaskParam); + }); + }); }); describe('handles errors during migrations', () => { diff --git a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts index 3612642160443e..ceb82146a03ebc 100644 --- a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts +++ b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts @@ -48,8 +48,17 @@ export function getActionTaskParamsMigrations( pipeMigrations(getUseSavedObjectReferencesFn(preconfiguredActions)) ); + const migrationActionsTaskParams800 = createEsoMigration( + encryptedSavedObjects, + ( + doc: SavedObjectUnsanitizedDoc + ): doc is SavedObjectUnsanitizedDoc => true, + (doc) => doc // no-op + ); + return { '7.16.0': executeMigrationWithErrorHandling(migrationActionTaskParamsSixteen, '7.16.0'), + '8.0.0': executeMigrationWithErrorHandling(migrationActionsTaskParams800, '8.0.0'), }; } diff --git a/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts index bc0e59279abc19..7dc1426c13a4b7 100644 --- a/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts @@ -118,6 +118,14 @@ describe('successful migrations', () => { }); }); }); + + describe('8.0.0', () => { + test('no op migration for rules SO', () => { + const migration800 = getActionsMigrations(encryptedSavedObjectsSetup)['8.0.0']; + const action = getMockData({}); + expect(migration800(action, context)).toEqual(action); + }); + }); }); describe('handles errors during migrations', () => { diff --git a/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts b/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts index a72565e00ef7b2..7857a9e1f833f9 100644 --- a/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts +++ b/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts @@ -62,10 +62,18 @@ export function getActionsMigrations( pipeMigrations(addisMissingSecretsField) ); + const migrationActions800 = createEsoMigration( + encryptedSavedObjects, + (doc: SavedObjectUnsanitizedDoc): doc is SavedObjectUnsanitizedDoc => + true, + (doc) => doc // no-op + ); + return { '7.10.0': executeMigrationWithErrorHandling(migrationActionsTen, '7.10.0'), '7.11.0': executeMigrationWithErrorHandling(migrationActionsEleven, '7.11.0'), '7.14.0': executeMigrationWithErrorHandling(migrationActionsFourteen, '7.14.0'), + '8.0.0': executeMigrationWithErrorHandling(migrationActions800, '8.0.0'), }; } diff --git a/x-pack/plugins/actions/server/saved_objects/index.ts b/x-pack/plugins/actions/server/saved_objects/index.ts index 71ec92645b2498..14b425d20af135 100644 --- a/x-pack/plugins/actions/server/saved_objects/index.ts +++ b/x-pack/plugins/actions/server/saved_objects/index.ts @@ -35,7 +35,8 @@ export function setupSavedObjects( savedObjects.registerType({ name: ACTION_SAVED_OBJECT_TYPE, hidden: true, - namespaceType: 'single', + namespaceType: 'multiple-isolated', + convertToMultiNamespaceTypeVersion: '8.0.0', mappings: mappings.action as SavedObjectsTypeMappingDefinition, migrations: getActionsMigrations(encryptedSavedObjects), management: { @@ -71,7 +72,8 @@ export function setupSavedObjects( savedObjects.registerType({ name: ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, hidden: true, - namespaceType: 'single', + namespaceType: 'multiple-isolated', + convertToMultiNamespaceTypeVersion: '8.0.0', mappings: mappings.action_task_params as SavedObjectsTypeMappingDefinition, migrations: getActionTaskParamsMigrations(encryptedSavedObjects, preconfiguredActions), excludeOnUpgrade: async ({ readonlyEsClient }) => { diff --git a/x-pack/plugins/alerting/server/saved_objects/index.ts b/x-pack/plugins/alerting/server/saved_objects/index.ts index b1d56a364a3dd4..f1afba147a2f7c 100644 --- a/x-pack/plugins/alerting/server/saved_objects/index.ts +++ b/x-pack/plugins/alerting/server/saved_objects/index.ts @@ -53,7 +53,8 @@ export function setupSavedObjects( savedObjects.registerType({ name: 'alert', hidden: true, - namespaceType: 'single', + namespaceType: 'multiple-isolated', + convertToMultiNamespaceTypeVersion: '8.0.0', migrations: getMigrations(encryptedSavedObjects, isPreconfigured), mappings: mappings.alert as SavedObjectsTypeMappingDefinition, management: { diff --git a/x-pack/plugins/alerting/server/saved_objects/migrations.test.ts b/x-pack/plugins/alerting/server/saved_objects/migrations.test.ts index e460167b40d238..5e850ad3226f80 100644 --- a/x-pack/plugins/alerting/server/saved_objects/migrations.test.ts +++ b/x-pack/plugins/alerting/server/saved_objects/migrations.test.ts @@ -1700,6 +1700,14 @@ describe('successful migrations', () => { }); }); }); + + describe('8.0.0', () => { + test('no op migration for rules SO', () => { + const migration800 = getMigrations(encryptedSavedObjectsSetup, isPreconfigured)['8.0.0']; + const alert = getMockData({}, true); + expect(migration800(alert, migrationContext)).toEqual(alert); + }); + }); }); describe('handles errors during migrations', () => { diff --git a/x-pack/plugins/alerting/server/saved_objects/migrations.ts b/x-pack/plugins/alerting/server/saved_objects/migrations.ts index c0af554cd7a44b..287636c69bb751 100644 --- a/x-pack/plugins/alerting/server/saved_objects/migrations.ts +++ b/x-pack/plugins/alerting/server/saved_objects/migrations.ts @@ -106,6 +106,12 @@ export function getMigrations( pipeMigrations(setLegacyId, getRemovePreconfiguredConnectorsFromReferencesFn(isPreconfigured)) ); + const migrationRules800 = createEsoMigration( + encryptedSavedObjects, + (doc: SavedObjectUnsanitizedDoc): doc is SavedObjectUnsanitizedDoc => true, + (doc) => doc // no-op + ); + return { '7.10.0': executeMigrationWithErrorHandling(migrationWhenRBACWasIntroduced, '7.10.0'), '7.11.0': executeMigrationWithErrorHandling(migrationAlertUpdatedAtAndNotifyWhen, '7.11.0'), @@ -114,6 +120,7 @@ export function getMigrations( '7.14.1': executeMigrationWithErrorHandling(migrationSecurityRules714, '7.14.1'), '7.15.0': executeMigrationWithErrorHandling(migrationSecurityRules715, '7.15.0'), '7.16.0': executeMigrationWithErrorHandling(migrateRules716, '7.16.0'), + '8.0.0': executeMigrationWithErrorHandling(migrationRules800, '8.0.0'), }; } diff --git a/x-pack/plugins/task_manager/server/saved_objects/index.ts b/x-pack/plugins/task_manager/server/saved_objects/index.ts index d2d079c7747b1b..abbd1af73b55a6 100644 --- a/x-pack/plugins/task_manager/server/saved_objects/index.ts +++ b/x-pack/plugins/task_manager/server/saved_objects/index.ts @@ -8,7 +8,7 @@ import type { SavedObjectsServiceSetup, SavedObjectsTypeMappingDefinition } from 'kibana/server'; import { estypes } from '@elastic/elasticsearch'; import mappings from './mappings.json'; -import { migrations } from './migrations'; +import { getMigrations } from './migrations'; import { TaskManagerConfig } from '../config.js'; import { getOldestIdleActionTask } from '../queries/oldest_idle_action_task'; @@ -22,7 +22,7 @@ export function setupSavedObjects( hidden: true, convertToAliasScript: `ctx._id = ctx._source.type + ':' + ctx._id; ctx._source.remove("kibana")`, mappings: mappings.task as SavedObjectsTypeMappingDefinition, - migrations, + migrations: getMigrations(), indexPattern: config.index, excludeOnUpgrade: async ({ readonlyEsClient }) => { const oldestNeededActionParams = await getOldestIdleActionTask( diff --git a/x-pack/plugins/task_manager/server/saved_objects/migrations.test.ts b/x-pack/plugins/task_manager/server/saved_objects/migrations.test.ts new file mode 100644 index 00000000000000..73141479d90816 --- /dev/null +++ b/x-pack/plugins/task_manager/server/saved_objects/migrations.test.ts @@ -0,0 +1,169 @@ +/* + * 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 uuid from 'uuid'; +import { getMigrations } from './migrations'; +import { SavedObjectUnsanitizedDoc } from 'kibana/server'; +import { migrationMocks } from 'src/core/server/mocks'; +import { TaskInstanceWithDeprecatedFields } from '../task'; + +const migrationContext = migrationMocks.createContext(); + +describe('successful migrations', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + describe('7.4.0', () => { + test('extend task instance with updated_at', () => { + const migration740 = getMigrations()['7.4.0']; + const taskInstance = getMockData({}); + expect(migration740(taskInstance, migrationContext).attributes.updated_at).not.toBeNull(); + }); + }); + + describe('7.6.0', () => { + test('rename property Internal to Schedule', () => { + const migration760 = getMigrations()['7.6.0']; + const taskInstance = getMockData({}); + expect(migration760(taskInstance, migrationContext)).toEqual({ + ...taskInstance, + attributes: { + ...taskInstance.attributes, + schedule: taskInstance.attributes.schedule, + }, + }); + }); + }); + + describe('8.0.0', () => { + test('transforms actionsTasksLegacyIdToSavedObjectIds', () => { + const migration800 = getMigrations()['8.0.0']; + const taskInstance = getMockData({ + taskType: 'actions:123456', + params: JSON.stringify({ spaceId: 'user1', actionTaskParamsId: '123456' }), + }); + + expect(migration800(taskInstance, migrationContext)).toEqual({ + ...taskInstance, + attributes: { + ...taskInstance.attributes, + params: '{"spaceId":"user1","actionTaskParamsId":"800f81f8-980e-58ca-b710-d1b0644adea2"}', + }, + }); + }); + + test('it is only applicable for saved objects that live in a custom space', () => { + const migration800 = getMigrations()['8.0.0']; + const taskInstance = getMockData({ + taskType: 'actions:123456', + params: JSON.stringify({ spaceId: 'default', actionTaskParamsId: '123456' }), + }); + + expect(migration800(taskInstance, migrationContext)).toEqual(taskInstance); + }); + + test('it is only applicable for saved objects that live in a custom space even if spaces are disabled', () => { + const migration800 = getMigrations()['8.0.0']; + const taskInstance = getMockData({ + taskType: 'actions:123456', + params: JSON.stringify({ actionTaskParamsId: '123456' }), + }); + + expect(migration800(taskInstance, migrationContext)).toEqual(taskInstance); + }); + + test('transforms alertingTaskLegacyIdToSavedObjectIds', () => { + const migration800 = getMigrations()['8.0.0']; + const taskInstance = getMockData({ + taskType: 'alerting:123456', + params: JSON.stringify({ spaceId: 'user1', alertId: '123456' }), + }); + + expect(migration800(taskInstance, migrationContext)).toEqual({ + ...taskInstance, + attributes: { + ...taskInstance.attributes, + params: '{"spaceId":"user1","alertId":"1a4f9206-e25f-58e6-bad5-3ff21e90648e"}', + }, + }); + }); + + test('skip transformation for defult space scenario', () => { + const migration800 = getMigrations()['8.0.0']; + const taskInstance = getMockData({ + taskType: 'alerting:123456', + params: JSON.stringify({ spaceId: 'default', alertId: '123456' }), + }); + + expect(migration800(taskInstance, migrationContext)).toEqual({ + ...taskInstance, + attributes: { + ...taskInstance.attributes, + params: '{"spaceId":"default","alertId":"123456"}', + }, + }); + }); + }); +}); + +describe('handles errors during migrations', () => { + describe('8.0.0 throws if migration fails', () => { + test('should throw the exception if task instance params format is wrong', () => { + const migration800 = getMigrations()['8.0.0']; + const taskInstance = getMockData({ + taskType: 'alerting:123456', + params: `{ spaceId: 'user1', customId: '123456' }`, + }); + expect(() => { + migration800(taskInstance, migrationContext); + }).toThrowError(); + expect(migrationContext.log.error).toHaveBeenCalledWith( + `savedObject 8.0.0 migration failed for task instance ${taskInstance.id} with error: Unexpected token s in JSON at position 2`, + { + migrations: { + taskInstanceDocument: { + ...taskInstance, + attributes: { + ...taskInstance.attributes, + }, + }, + }, + } + ); + }); + }); +}); + +function getUpdatedAt(): string { + const updatedAt = new Date(); + updatedAt.setHours(updatedAt.getHours() + 2); + return updatedAt.toISOString(); +} + +function getMockData( + overwrites: Record = {} +): SavedObjectUnsanitizedDoc> { + return { + attributes: { + scheduledAt: new Date(), + state: { runs: 0, total_cleaned_up: 0 }, + runAt: new Date(), + startedAt: new Date(), + retryAt: new Date(), + ownerId: '234', + taskType: 'foo', + schedule: { interval: '10s' }, + params: { + bar: true, + }, + ...overwrites, + }, + updated_at: getUpdatedAt(), + id: uuid.v4(), + type: 'task', + }; +} diff --git a/x-pack/plugins/task_manager/server/saved_objects/migrations.ts b/x-pack/plugins/task_manager/server/saved_objects/migrations.ts index 879fca2ae4f6f4..a2ed91dba2737f 100644 --- a/x-pack/plugins/task_manager/server/saved_objects/migrations.ts +++ b/x-pack/plugins/task_manager/server/saved_objects/migrations.ts @@ -5,16 +5,123 @@ * 2.0. */ -import { SavedObjectMigrationMap, SavedObjectUnsanitizedDoc } from '../../../../../src/core/server'; +import { + LogMeta, + SavedObjectMigrationContext, + SavedObjectMigrationFn, + SavedObjectMigrationMap, + SavedObjectsUtils, + SavedObjectUnsanitizedDoc, +} from '../../../../../src/core/server'; import { TaskInstance, TaskInstanceWithDeprecatedFields } from '../task'; -export const migrations: SavedObjectMigrationMap = { - '7.4.0': (doc) => ({ - ...doc, - updated_at: new Date().toISOString(), - }), - '7.6.0': moveIntervalIntoSchedule, -}; +interface TaskInstanceLogMeta extends LogMeta { + migrations: { taskInstanceDocument: SavedObjectUnsanitizedDoc }; +} + +type TaskInstanceMigration = ( + doc: SavedObjectUnsanitizedDoc +) => SavedObjectUnsanitizedDoc; + +export function getMigrations(): SavedObjectMigrationMap { + return { + '7.4.0': executeMigrationWithErrorHandling( + (doc) => ({ + ...doc, + updated_at: new Date().toISOString(), + }), + '7.4.0' + ), + '7.6.0': executeMigrationWithErrorHandling(moveIntervalIntoSchedule, '7.6.0'), + '8.0.0': executeMigrationWithErrorHandling( + pipeMigrations(alertingTaskLegacyIdToSavedObjectIds, actionsTasksLegacyIdToSavedObjectIds), + '8.0.0' + ), + }; +} + +function executeMigrationWithErrorHandling( + migrationFunc: SavedObjectMigrationFn< + TaskInstanceWithDeprecatedFields, + TaskInstanceWithDeprecatedFields + >, + version: string +) { + return ( + doc: SavedObjectUnsanitizedDoc, + context: SavedObjectMigrationContext + ) => { + try { + return migrationFunc(doc, context); + } catch (ex) { + context.log.error( + `savedObject ${version} migration failed for task instance ${doc.id} with error: ${ex.message}`, + { + migrations: { + taskInstanceDocument: doc, + }, + } + ); + throw ex; + } + }; +} + +function alertingTaskLegacyIdToSavedObjectIds( + doc: SavedObjectUnsanitizedDoc +): SavedObjectUnsanitizedDoc { + if (doc.attributes.taskType.startsWith('alerting:')) { + let params: { spaceId?: string; alertId?: string } = {}; + params = JSON.parse((doc.attributes.params as unknown) as string); + + if (params.alertId && params.spaceId && params.spaceId !== 'default') { + const newId = SavedObjectsUtils.getConvertedObjectId(params.spaceId, 'alert', params.alertId); + return { + ...doc, + attributes: { + ...doc.attributes, + params: JSON.stringify({ + ...params, + alertId: newId, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + }) as any, + }, + }; + } + } + + return doc; +} + +function actionsTasksLegacyIdToSavedObjectIds( + doc: SavedObjectUnsanitizedDoc +): SavedObjectUnsanitizedDoc { + if (doc.attributes.taskType.startsWith('actions:')) { + let params: { spaceId?: string; actionTaskParamsId?: string } = {}; + params = JSON.parse((doc.attributes.params as unknown) as string); + + if (params.actionTaskParamsId && params.spaceId && params.spaceId !== 'default') { + const newId = SavedObjectsUtils.getConvertedObjectId( + params.spaceId, + 'action_task_params', + params.actionTaskParamsId + ); + return { + ...doc, + attributes: { + ...doc.attributes, + params: JSON.stringify({ + ...params, + actionTaskParamsId: newId, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + }) as any, + }, + }; + } + } + + return doc; +} function moveIntervalIntoSchedule({ attributes: { interval, ...attributes }, @@ -34,3 +141,8 @@ function moveIntervalIntoSchedule({ }, }; } + +function pipeMigrations(...migrations: TaskInstanceMigration[]): TaskInstanceMigration { + return (doc: SavedObjectUnsanitizedDoc) => + migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc), doc); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/rbac_legacy.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/rbac_legacy.ts index 7bc33538985984..e84eaf2cea04d4 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/rbac_legacy.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/rbac_legacy.ts @@ -10,6 +10,7 @@ import { UserAtSpaceScenarios, Superuser } from '../../scenarios'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { ESTestIndexTool, getUrlPrefix, ObjectRemover, AlertUtils } from '../../../common/lib'; import { setupSpacesAndUsers } from '..'; +import { SavedObjectsUtils } from '../../../../../../src/core/server/saved_objects'; // eslint-disable-next-line import/no-default-export export default function alertTests({ getService }: FtrProviderContext) { @@ -20,13 +21,38 @@ export default function alertTests({ getService }: FtrProviderContext) { const supertestWithoutAuth = getService('supertestWithoutAuth'); const esTestIndexTool = new ESTestIndexTool(es, retry); - const MIGRATED_ACTION_ID = '17f38826-5a8d-4a76-975a-b496e7fffe0b'; + const MIGRATED_ACTION_ID = SavedObjectsUtils.getConvertedObjectId( + 'space1', + 'action', + '17f38826-5a8d-4a76-975a-b496e7fffe0b' + ); + const MIGRATED_ALERT_ID: Record = { - space_1_all_alerts_none_actions: '6ee9630a-a20e-44af-9465-217a3717d2ab', - space_1_all_with_restricted_fixture: '5cc59319-74ee-4edc-8646-a79ea91067cd', - space_1_all: 'd41a6abb-b93b-46df-a80a-926221ea847c', - global_read: '362e362b-a137-4aa2-9434-43e3d0d84a34', - superuser: 'b384be60-ec53-4b26-857e-0253ee55b277', + space_1_all_alerts_none_actions: SavedObjectsUtils.getConvertedObjectId( + 'space1', + 'alert', + '6ee9630a-a20e-44af-9465-217a3717d2ab' + ), + space_1_all_with_restricted_fixture: SavedObjectsUtils.getConvertedObjectId( + 'space1', + 'alert', + '5cc59319-74ee-4edc-8646-a79ea91067cd' + ), + space_1_all: SavedObjectsUtils.getConvertedObjectId( + 'space1', + 'alert', + 'd41a6abb-b93b-46df-a80a-926221ea847c' + ), + global_read: SavedObjectsUtils.getConvertedObjectId( + 'space1', + 'alert', + '362e362b-a137-4aa2-9434-43e3d0d84a34' + ), + superuser: SavedObjectsUtils.getConvertedObjectId( + 'space1', + 'alert', + 'b384be60-ec53-4b26-857e-0253ee55b277' + ), }; describe('alerts', () => { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts index 99a12dc3437de3..f45ad28e2cdc55 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts @@ -193,7 +193,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { const esResponse = await es.get>({ index: '.kibana', - id: `${Spaces.space1.id}:alert:${response.body.id}`, + id: `alert:${response.body.id}`, }); expect(esResponse.statusCode).to.eql(200); const rawActions = (esResponse.body._source as any)?.alert.actions ?? []; diff --git a/x-pack/test/functional/es_archives/task_manager_tasks/data.json b/x-pack/test/functional/es_archives/task_manager_tasks/data.json new file mode 100644 index 00000000000000..b59abd341a7af7 --- /dev/null +++ b/x-pack/test/functional/es_archives/task_manager_tasks/data.json @@ -0,0 +1,61 @@ +{ + "type": "doc", + "value": { + "id": "task:be7e1250-3322-11eb-94c1-db6995e84f6a", + "index": ".kibana_task_manager_1", + "source": { + "migrationVersion": { + "task": "7.16.0" + }, + "references": [ + ], + "task": { + "attempts": 0, + "params": "{\"spaceId\":\"user1\",\"alertId\":\"0359d7fcc04da9878ee9aadbda38ba55\"}", + "retryAt": "2020-11-30T15:43:39.626Z", + "runAt": "2020-11-30T15:43:08.277Z", + "scheduledAt": "2020-11-30T15:43:08.277Z", + "scope": [ + "testing" + ], + "startedAt": null, + "state": "{}", + "status": "idle", + "taskType": "alerting:0359d7fcc04da9878ee9aadbda38ba55" + }, + "type": "task", + "updated_at": "2020-11-30T15:43:08.277Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "task:be7e1250-3322-11eb-94c1-db6995e8389f", + "index": ".kibana_task_manager_1", + "source": { + "migrationVersion": { + "task": "7.16.0" + }, + "references": [ + ], + "task": { + "attempts": 0, + "params": "{\"spaceId\":\"user1\",\"actionTaskParamsId\":\"6e96ac5e648f57523879661ea72525b7\"}", + "retryAt": "2020-11-30T15:43:39.626Z", + "runAt": "2020-11-30T15:43:08.277Z", + "scheduledAt": "2020-11-30T15:43:08.277Z", + "scope": [ + "testing" + ], + "startedAt": null, + "state": "{}", + "status": "idle", + "taskType": "actions:6e96ac5e648f57523879661ea72525b7" + }, + "type": "task", + "updated_at": "2020-11-30T15:43:08.277Z" + } + } +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/task_manager_tasks/mappings.json b/x-pack/test/functional/es_archives/task_manager_tasks/mappings.json new file mode 100644 index 00000000000000..6ec81326d1ca4b --- /dev/null +++ b/x-pack/test/functional/es_archives/task_manager_tasks/mappings.json @@ -0,0 +1,225 @@ +{ + "type": "index", + "value": { + "aliases": { + ".kibana": { + } + }, + "index": ".kibana_1", + "mappings": { + "_meta": { + "migrationMappingPropertyHashes": { + "action": "6e96ac5e648f57523879661ea72525b7", + "action_task_params": "a9d49f184ee89641044be0ca2950fa3a", + "alert": "0359d7fcc04da9878ee9aadbda38ba55", + "api_key_pending_invalidation": "16f515278a295f6245149ad7c5ddedb7", + "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd", + "apm-telemetry": "3d1b76c39bfb2cc8296b024d73854724", + "app_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", + "application_usage_daily": "43b8830d5d0df85a6823d290885fc9fd", + "application_usage_totals": "3d1b76c39bfb2cc8296b024d73854724", + "application_usage_transactional": "3d1b76c39bfb2cc8296b024d73854724", + "search-session": "721df406dbb7e35ac22e4df6c3ad2b2a", + "canvas-element": "7390014e1091044523666d97247392fc", + "canvas-workpad": "b0a1706d356228dbdcb4a17e6b9eb231", + "canvas-workpad-template": "ae2673f678281e2c055d764b153e9715", + "cases": "477f214ff61acc3af26a7b7818e380c1", + "cases-comments": "8a50736330e953bca91747723a319593", + "cases-configure": "387c5f3a3bda7e0ae0dd4e106f914a69", + "cases-user-actions": "32277330ec6b721abe3b846cfd939a71", + "config": "c63748b75f39d0c54de12d12c1ccbc20", + "dashboard": "40554caf09725935e2c02e02563a2d07", + "endpoint:user-artifact": "4a11183eee21e6fbad864f7a30b39ad0", + "endpoint:user-artifact-manifest": "a0d7b04ad405eed54d76e279c3727862", + "enterprise_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", + "epm-packages": "2b83397e3eaaaa8ef15e38813f3721c3", + "event_log_test": "bef808d4a9c27f204ffbda3359233931", + "exception-list": "67f055ab8c10abd7b2ebfd969b836788", + "exception-list-agnostic": "67f055ab8c10abd7b2ebfd969b836788", + "file-upload-telemetry": "0ed4d3e1983d1217a30982630897092e", + "fleet-agent-actions": "9511b565b1cc6441a42033db3d5de8e9", + "fleet-agent-events": "e20a508b6e805189356be381dbfac8db", + "fleet-agents": "cb661e8ede2b640c42c8e5ef99db0683", + "fleet-enrollment-api-keys": "a69ef7ae661dab31561d6c6f052ef2a7", + "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1", + "index-pattern": "45915a1ad866812242df474eb0479052", + "infrastructure-ui-source": "3d1b76c39bfb2cc8296b024d73854724", + "ingest-agent-policies": "8b0733cce189659593659dad8db426f0", + "ingest-outputs": "8854f34453a47e26f86a29f8f3b80b4e", + "ingest-package-policies": "c91ca97b1ff700f0fc64dc6b13d65a85", + "ingest_manager_settings": "02a03095f0e05b7a538fa801b88a217f", + "inventory-view": "3d1b76c39bfb2cc8296b024d73854724", + "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", + "lens": "52346cfec69ff7b47d5f0c12361a2797", + "lens-ui-telemetry": "509bfa5978586998e05f9e303c07a327", + "map": "4a05b35c3a3a58fbc72dd0202dc3487f", + "maps-telemetry": "5ef305b18111b77789afefbd36b66171", + "metrics-explorer-view": "3d1b76c39bfb2cc8296b024d73854724", + "migrationVersion": "4a1746014a75ade3a714e1db5763276f", + "ml-job": "3bb64c31915acf93fc724af137a0891b", + "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9", + "monitoring-telemetry": "2669d5ec15e82391cf58df4294ee9c68", + "namespace": "2f4316de49999235636386fe51dc06c1", + "namespaces": "2f4316de49999235636386fe51dc06c1", + "originId": "2f4316de49999235636386fe51dc06c1", + "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9", + "references": "7997cf5a56cc02bdc9c93361bde732b0", + "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4", + "search": "43012c7ebc4cb57054e0a490e4b43023", + "search-telemetry": "3d1b76c39bfb2cc8296b024d73854724", + "siem-detection-engine-rule-actions": "6569b288c169539db10cb262bf79de18", + "siem-detection-engine-rule-status": "ae783f41c6937db6b7a2ef5c93a9e9b0", + "siem-ui-timeline": "d12c5474364d737d17252acf1dc4585c", + "siem-ui-timeline-note": "8874706eedc49059d4cf0f5094559084", + "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29", + "space": "c5ca8acafa0beaa4d08d014a97b6bc6b", + "tag": "83d55da58f6530f7055415717ec06474", + "telemetry": "36a616f7026dfa617d6655df850fe16d", + "timelion-sheet": "9a2a2748877c7a7b582fef201ab1d4cf", + "tsvb-validation-telemetry": "3a37ef6c8700ae6fc97d5c7da00e9215", + "type": "2f4316de49999235636386fe51dc06c1", + "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", + "updated_at": "00da57df13e94e9d98437d13ace4bfe0", + "upgrade-assistant-reindex-operation": "215107c281839ea9b3ad5f6419819763", + "upgrade-assistant-telemetry": "56702cec857e0a9dacfb696655b4ff7b", + "uptime-dynamic-settings": "3d1b76c39bfb2cc8296b024d73854724", + "url": "c7f66a0df8b1b52f17c28c4adb111105", + "visualization": "f819cf6636b75c9e76ba733a0c6ef355", + "workplace_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724" + } + }, + "dynamic": "strict", + "properties": { + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + ".kibana_task_manager": { + } + }, + "index": ".kibana_task_manager_1", + "mappings": { + "_meta": { + "migrationMappingPropertyHashes": { + "migrationVersion": "4a1746014a75ade3a714e1db5763276f", + "namespace": "2f4316de49999235636386fe51dc06c1", + "namespaces": "2f4316de49999235636386fe51dc06c1", + "originId": "2f4316de49999235636386fe51dc06c1", + "references": "7997cf5a56cc02bdc9c93361bde732b0", + "task": "235412e52d09e7165fac8a67a43ad6b4", + "type": "2f4316de49999235636386fe51dc06c1", + "updated_at": "00da57df13e94e9d98437d13ace4bfe0" + } + }, + "dynamic": "strict", + "properties": { + "migrationVersion": { + "dynamic": "true", + "properties": { + "task": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "references": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + }, + "type": "nested" + }, + "task": { + "properties": { + "attempts": { + "type": "integer" + }, + "ownerId": { + "type": "keyword" + }, + "params": { + "type": "text" + }, + "retryAt": { + "type": "date" + }, + "runAt": { + "type": "date" + }, + "schedule": { + "properties": { + "interval": { + "type": "keyword" + } + } + }, + "scheduledAt": { + "type": "date" + }, + "scope": { + "type": "keyword" + }, + "startedAt": { + "type": "date" + }, + "state": { + "type": "text" + }, + "status": { + "type": "keyword" + }, + "taskType": { + "type": "keyword" + }, + "user": { + "type": "keyword" + } + } + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/index.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/index.ts index bab34312c363f0..b1de32fdcc93ce 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/index.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/index.ts @@ -13,5 +13,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./health_route')); loadTestFile(require.resolve('./task_management')); loadTestFile(require.resolve('./task_management_removed_types')); + + loadTestFile(require.resolve('./migrations')); }); } diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/migrations.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/migrations.ts new file mode 100644 index 00000000000000..caf62a1d364c04 --- /dev/null +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/migrations.ts @@ -0,0 +1,70 @@ +/* + * 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 expect from '@kbn/expect'; +import type { ApiResponse, estypes } from '@elastic/elasticsearch'; +import { TaskInstanceWithDeprecatedFields } from '../../../../plugins/task_manager/server/task'; +import { FtrProviderContext } from '../../../common/ftr_provider_context'; +import { SavedObjectsUtils } from '../../../../../src/core/server/saved_objects'; + +export default function createGetTests({ getService }: FtrProviderContext) { + const es = getService('es'); + const esArchiver = getService('esArchiver'); + const ALERT_ID = '0359d7fcc04da9878ee9aadbda38ba55'; + const ACTION_TASK_PARAMS_ID = '6e96ac5e648f57523879661ea72525b7'; + + describe('migrations', () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/task_manager_tasks'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/task_manager_tasks'); + }); + + it('8.0.0 migrates actions tasks with legacy id to saved object ids', async () => { + // NOTE: We hae to use elastic search directly against the ".kibana" index because alerts do not expose the references which we want to test exists + const response = await es.get<{ task: TaskInstanceWithDeprecatedFields }>({ + index: '.kibana_task_manager', + id: 'task:be7e1250-3322-11eb-94c1-db6995e84f6a', + }); + expect(response.statusCode).to.eql(200); + expect(response.body._source?.task.params).to.eql( + `{"spaceId":"user1","alertId":"${SavedObjectsUtils.getConvertedObjectId( + 'user1', + 'alert', + ALERT_ID + )}"}` + ); + }); + + it('8.0.0 migrates actions tasks from legacy id to saved object ids', async () => { + const searchResult: ApiResponse< + estypes.SearchResponse<{ task: TaskInstanceWithDeprecatedFields }> + > = await es.search({ + index: '.kibana_task_manager', + body: { + query: { + term: { + _id: 'task:be7e1250-3322-11eb-94c1-db6995e8389f', + }, + }, + }, + }); + expect(searchResult.statusCode).to.equal(200); + expect((searchResult.body.hits.total as estypes.SearchTotalHits).value).to.equal(1); + const hit = searchResult.body.hits.hits[0]; + expect(hit!._source!.task.params!).to.equal( + `{"spaceId":"user1","actionTaskParamsId":"${SavedObjectsUtils.getConvertedObjectId( + 'user1', + 'action_task_params', + ACTION_TASK_PARAMS_ID + )}"}` + ); + }); + }); +}