diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts index 05fb534f7a11..ca3e68a1d086 100644 --- a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts +++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts @@ -34,6 +34,7 @@ import crypto from 'crypto'; import { cloneDeep, mapValues } from 'lodash'; +import { Config } from 'packages/osd-config/target'; import { IndexMapping, SavedObjectsFieldMapping, @@ -48,11 +49,20 @@ import { * @param typeDefinitions - the type definitions to build mapping from. */ export function buildActiveMappings( - typeDefinitions: SavedObjectsTypeMappingDefinitions | SavedObjectsMappingProperties + typeDefinitions: SavedObjectsTypeMappingDefinitions | SavedObjectsMappingProperties, + opensearchDashboardsRawConfig?: Config ): IndexMapping { const mapping = defaultMapping(); - const mergedProperties = validateAndMerge(mapping.properties, typeDefinitions); + let mergedProperties = validateAndMerge(mapping.properties, typeDefinitions); + + if (opensearchDashboardsRawConfig?.get('workspace.enabled')) { + mergedProperties = validateAndMerge(mapping.properties, { + workspaces: { + type: 'keyword', + }, + }); + } return cloneDeep({ ...mapping, @@ -186,9 +196,6 @@ function defaultMapping(): IndexMapping { }, }, }, - workspaces: { - type: 'keyword', - }, permissions: { properties: { read: principals, diff --git a/src/core/server/saved_objects/migrations/core/migration_context.ts b/src/core/server/saved_objects/migrations/core/migration_context.ts index 82001f7ed4c4..8a1e9b648bce 100644 --- a/src/core/server/saved_objects/migrations/core/migration_context.ts +++ b/src/core/server/saved_objects/migrations/core/migration_context.ts @@ -36,6 +36,7 @@ */ import { Logger } from 'src/core/server/logging'; +import { Config } from 'packages/osd-config/target'; import { MigrationOpenSearchClient } from './migration_opensearch_client'; import { SavedObjectsSerializer } from '../../serialization'; import { @@ -65,6 +66,7 @@ export interface MigrationOpts { * prior to running migrations. For example: 'opensearch_dashboards_index_template*' */ obsoleteIndexTemplatePattern?: string; + opensearchDashboardsRawConfig?: Config; } /** @@ -90,10 +92,15 @@ export interface Context { * and various info needed to migrate the source index. */ export async function migrationContext(opts: MigrationOpts): Promise { - const { log, client } = opts; + const { log, client, opensearchDashboardsRawConfig } = opts; const alias = opts.index; const source = createSourceContext(await Index.fetchInfo(client, alias), alias); - const dest = createDestContext(source, alias, opts.mappingProperties); + const dest = createDestContext( + source, + alias, + opts.mappingProperties, + opensearchDashboardsRawConfig + ); return { client, @@ -125,10 +132,11 @@ function createSourceContext(source: Index.FullIndexInfo, alias: string) { function createDestContext( source: Index.FullIndexInfo, alias: string, - typeMappingDefinitions: SavedObjectsTypeMappingDefinitions + typeMappingDefinitions: SavedObjectsTypeMappingDefinitions, + opensearchDashboardsRawConfig?: Config ): Index.FullIndexInfo { const targetMappings = disableUnknownTypeMappingFields( - buildActiveMappings(typeMappingDefinitions), + buildActiveMappings(typeMappingDefinitions, opensearchDashboardsRawConfig), source.mappings ); diff --git a/src/core/server/saved_objects/migrations/opensearch_dashboards/opensearch_dashboards_migrator.test.ts b/src/core/server/saved_objects/migrations/opensearch_dashboards/opensearch_dashboards_migrator.test.ts index 32a1bc51a554..1b089ddff337 100644 --- a/src/core/server/saved_objects/migrations/opensearch_dashboards/opensearch_dashboards_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/opensearch_dashboards/opensearch_dashboards_migrator.test.ts @@ -37,6 +37,7 @@ import { import { loggingSystemMock } from '../../../logging/logging_system.mock'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsType } from '../../types'; +import { configMock } from '../../../config/mocks'; const createRegistry = (types: Array>) => { const registry = new SavedObjectTypeRegistry(); @@ -147,6 +148,8 @@ type MockedOptions = OpenSearchDashboardsMigratorOptions & { }; const mockOptions = () => { + const rawConfig = configMock.create(); + rawConfig.get.mockReturnValue(true); const options: MockedOptions = { logger: loggingSystemMock.create().get(), opensearchDashboardsVersion: '8.2.3', @@ -186,6 +189,7 @@ const mockOptions = () => { skip: false, }, client: opensearchClientMock.createOpenSearchClient(), + opensearchDashboardsRawConfig: rawConfig, }; return options; }; diff --git a/src/core/server/saved_objects/migrations/opensearch_dashboards/opensearch_dashboards_migrator.ts b/src/core/server/saved_objects/migrations/opensearch_dashboards/opensearch_dashboards_migrator.ts index 284615083af3..46e59f237b18 100644 --- a/src/core/server/saved_objects/migrations/opensearch_dashboards/opensearch_dashboards_migrator.ts +++ b/src/core/server/saved_objects/migrations/opensearch_dashboards/opensearch_dashboards_migrator.ts @@ -35,6 +35,7 @@ import { OpenSearchDashboardsConfigType } from 'src/core/server/opensearch_dashboards_config'; import { BehaviorSubject } from 'rxjs'; +import { Config } from 'packages/osd-config/target'; import { Logger } from '../../../logging'; import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings'; @@ -54,6 +55,7 @@ export interface OpenSearchDashboardsMigratorOptions { opensearchDashboardsConfig: OpenSearchDashboardsConfigType; opensearchDashboardsVersion: string; logger: Logger; + opensearchDashboardsRawConfig: Config; } export type IOpenSearchDashboardsMigrator = Pick< @@ -83,6 +85,7 @@ export class OpenSearchDashboardsMigrator { status: 'waiting', }); private readonly activeMappings: IndexMapping; + private readonly opensearchDashboardsRawConfig: Config; /** * Creates an instance of OpenSearchDashboardsMigrator. @@ -94,6 +97,7 @@ export class OpenSearchDashboardsMigrator { savedObjectsConfig, opensearchDashboardsVersion, logger, + opensearchDashboardsRawConfig, }: OpenSearchDashboardsMigratorOptions) { this.client = client; this.opensearchDashboardsConfig = opensearchDashboardsConfig; @@ -109,7 +113,11 @@ export class OpenSearchDashboardsMigrator { }); // Building the active mappings (and associated md5sums) is an expensive // operation so we cache the result - this.activeMappings = buildActiveMappings(this.mappingProperties); + this.opensearchDashboardsRawConfig = opensearchDashboardsRawConfig; + this.activeMappings = buildActiveMappings( + this.mappingProperties, + this.opensearchDashboardsRawConfig + ); } /** @@ -181,6 +189,7 @@ export class OpenSearchDashboardsMigrator { ? 'opensearch_dashboards_index_template*' : undefined, convertToAliasScript: indexMap[index].script, + opensearchDashboardsRawConfig: this.opensearchDashboardsRawConfig, }); }); diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 64c8b6a5fbc8..2a1cff648fae 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -67,6 +67,7 @@ import { registerRoutes } from './routes'; import { ServiceStatus, ServiceStatusLevels } from '../status'; import { calculateStatus$ } from './status'; import { createMigrationOpenSearchClient } from './migrations/core/'; +import { Config } from '../config'; /** * Saved Objects is OpenSearchDashboards's data persistence mechanism allowing plugins to * use OpenSearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods @@ -315,6 +316,8 @@ export class SavedObjectsService summary: `waiting`, }); + private opensearchDashboardsRawConfig?: Config; + constructor(private readonly coreContext: CoreContext) { this.logger = coreContext.logger.get('savedobjects-service'); } @@ -332,6 +335,10 @@ export class SavedObjectsService .atPath('migrations') .pipe(first()) .toPromise(); + this.opensearchDashboardsRawConfig = await this.coreContext.configService + .getConfig$() + .pipe(first()) + .toPromise(); this.config = new SavedObjectConfig(savedObjectsConfig, savedObjectsMigrationConfig); registerRoutes({ @@ -559,6 +566,7 @@ export class SavedObjectsService this.logger, migrationsRetryDelay ), + opensearchDashboardsRawConfig: this.opensearchDashboardsRawConfig as Config, }); } }