diff --git a/src/core/server/opensearch_dashboards_config.ts b/src/core/server/opensearch_dashboards_config.ts index 107d02ea3377..71ffbea535b6 100644 --- a/src/core/server/opensearch_dashboards_config.ts +++ b/src/core/server/opensearch_dashboards_config.ts @@ -90,6 +90,9 @@ export const config = { defaultValue: 'https://survey.opensearch.org', }), }), + permission: schema.object({ + enabled: schema.boolean({ defaultValue: false }), + }), }), deprecations, }; 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..4d92c09a0d9b 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 @@ -48,10 +48,37 @@ import { * @param typeDefinitions - the type definitions to build mapping from. */ export function buildActiveMappings( - typeDefinitions: SavedObjectsTypeMappingDefinitions | SavedObjectsMappingProperties + typeDefinitions: SavedObjectsTypeMappingDefinitions | SavedObjectsMappingProperties, + permissionControlEnabled?: boolean ): IndexMapping { const mapping = defaultMapping(); + // if permission control is enabled, the permissions field should be added to the mapping + if (permissionControlEnabled) { + const principals: SavedObjectsFieldMapping = { + properties: { + users: { + type: 'keyword', + }, + groups: { + type: 'keyword', + }, + }, + }; + mapping.properties = { + ...mapping.properties, + permissions: { + properties: { + read: principals, + write: principals, + management: principals, + library_read: principals, + library_write: principals, + }, + }, + }; + } + const mergedProperties = validateAndMerge(mapping.properties, typeDefinitions); return cloneDeep({ @@ -138,16 +165,6 @@ function findChangedProp(actual: any, expected: any) { * @returns {IndexMapping} */ function defaultMapping(): IndexMapping { - const principals: SavedObjectsFieldMapping = { - properties: { - users: { - type: 'keyword', - }, - groups: { - type: 'keyword', - }, - }, - }; return { dynamic: 'strict', properties: { @@ -189,15 +206,6 @@ function defaultMapping(): IndexMapping { workspaces: { type: 'keyword', }, - permissions: { - properties: { - read: principals, - write: principals, - management: principals, - library_read: principals, - library_write: 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..47d708aa13f7 100644 --- a/src/core/server/saved_objects/migrations/core/migration_context.ts +++ b/src/core/server/saved_objects/migrations/core/migration_context.ts @@ -59,6 +59,7 @@ export interface MigrationOpts { documentMigrator: VersionedTransformer; serializer: SavedObjectsSerializer; convertToAliasScript?: string; + permissionControlEnabled?: boolean; /** * If specified, templates matching the specified pattern will be removed @@ -93,7 +94,12 @@ export async function migrationContext(opts: MigrationOpts): Promise { const { log, client } = 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, + opts.permissionControlEnabled + ); return { client, @@ -125,10 +131,11 @@ function createSourceContext(source: Index.FullIndexInfo, alias: string) { function createDestContext( source: Index.FullIndexInfo, alias: string, - typeMappingDefinitions: SavedObjectsTypeMappingDefinitions + typeMappingDefinitions: SavedObjectsTypeMappingDefinitions, + permissionControlEnabled?: boolean ): Index.FullIndexInfo { const targetMappings = disableUnknownTypeMappingFields( - buildActiveMappings(typeMappingDefinitions), + buildActiveMappings(typeMappingDefinitions, permissionControlEnabled), source.mappings ); 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..db4ddb057a25 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 @@ -43,14 +43,14 @@ import { buildActiveMappings, IndexMigrator, MigrationResult, MigrationStatus } import { DocumentMigrator, VersionedTransformer } from '../core/document_migrator'; import { MigrationOpenSearchClient } from '../core/'; import { createIndexMap } from '../core/build_index_map'; -import { SavedObjectsMigrationConfigType } from '../../saved_objects_config'; +import { SavedObjectConfig, SavedObjectsMigrationConfigType } from '../../saved_objects_config'; import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsType } from '../../types'; export interface OpenSearchDashboardsMigratorOptions { client: MigrationOpenSearchClient; typeRegistry: ISavedObjectTypeRegistry; - savedObjectsConfig: SavedObjectsMigrationConfigType; + savedObjectsConfig: SavedObjectConfig; opensearchDashboardsConfig: OpenSearchDashboardsConfigType; opensearchDashboardsVersion: string; logger: Logger; @@ -71,7 +71,7 @@ export interface OpenSearchDashboardsMigratorStatus { */ export class OpenSearchDashboardsMigrator { private readonly client: MigrationOpenSearchClient; - private readonly savedObjectsConfig: SavedObjectsMigrationConfigType; + private readonly savedObjectsConfig: SavedObjectConfig; private readonly documentMigrator: VersionedTransformer; private readonly opensearchDashboardsConfig: OpenSearchDashboardsConfigType; private readonly log: Logger; @@ -109,7 +109,10 @@ 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.activeMappings = buildActiveMappings( + this.mappingProperties, + this.savedObjectsConfig.permissionControlEnabled + ); } /** @@ -166,14 +169,14 @@ export class OpenSearchDashboardsMigrator { const migrators = Object.keys(indexMap).map((index) => { return new IndexMigrator({ - batchSize: this.savedObjectsConfig.batchSize, + batchSize: this.savedObjectsConfig.migration.batchSize, client: this.client, documentMigrator: this.documentMigrator, index, log: this.log, mappingProperties: indexMap[index].typeMappings, - pollInterval: this.savedObjectsConfig.pollInterval, - scrollDuration: this.savedObjectsConfig.scrollDuration, + pollInterval: this.savedObjectsConfig.migration.pollInterval, + scrollDuration: this.savedObjectsConfig.migration.scrollDuration, serializer: this.serializer, // Only necessary for the migrator of the opensearch-dashboards index. obsoleteIndexTemplatePattern: @@ -181,6 +184,7 @@ export class OpenSearchDashboardsMigrator { ? 'opensearch_dashboards_index_template*' : undefined, convertToAliasScript: indexMap[index].script, + permissionControlEnabled: this.savedObjectsConfig.permissionControlEnabled, }); }); diff --git a/src/core/server/saved_objects/saved_objects_config.ts b/src/core/server/saved_objects/saved_objects_config.ts index 291350bf93a6..a3db2af6c0ea 100644 --- a/src/core/server/saved_objects/saved_objects_config.ts +++ b/src/core/server/saved_objects/saved_objects_config.ts @@ -49,12 +49,16 @@ export const savedObjectsConfig = { schema: schema.object({ maxImportPayloadBytes: schema.byteSize({ defaultValue: 26214400 }), maxImportExportSize: schema.byteSize({ defaultValue: 10000 }), + permission: schema.object({ + enabled: schema.boolean({ defaultValue: false }), + }), }), }; export class SavedObjectConfig { public maxImportPayloadBytes: number; public maxImportExportSize: number; + public permissionControlEnabled: boolean; public migration: SavedObjectsMigrationConfigType; @@ -65,5 +69,6 @@ export class SavedObjectConfig { this.maxImportPayloadBytes = rawConfig.maxImportPayloadBytes.getValueInBytes(); this.maxImportExportSize = rawConfig.maxImportExportSize.getValueInBytes(); this.migration = rawMigrationConfig; + this.permissionControlEnabled = rawConfig.permission.enabled; } } diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 64c8b6a5fbc8..f785ae4b82bf 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -433,7 +433,7 @@ export class SavedObjectsService const migrator = this.createMigrator( opensearchDashboardsConfig, - this.config.migration, + this.config, opensearch.client, migrationsRetryDelay ); @@ -544,7 +544,7 @@ export class SavedObjectsService private createMigrator( opensearchDashboardsConfig: OpenSearchDashboardsConfigType, - savedObjectsConfig: SavedObjectsMigrationConfigType, + savedObjectsConfig: SavedObjectConfig, client: IClusterClient, migrationsRetryDelay?: number ): IOpenSearchDashboardsMigrator {