Skip to content

Commit

Permalink
Make osd system index's mappings extendable for plugins
Browse files Browse the repository at this point in the history
Signed-off-by: gaobinlong <gbinlong@amazon.com>
  • Loading branch information
gaobinlong committed Feb 28, 2024
1 parent fe9a4c1 commit acddbc0
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 31 deletions.
2 changes: 2 additions & 0 deletions src/core/server/legacy/legacy_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ export class LegacyService implements CoreService {
setStatus: () => {
throw new Error(`core.savedObjects.setStatus is unsupported in legacy`);
},
addExtendedSavedObjectsMappings:
setupDeps.core.savedObjects.addExtendedSavedObjectsMappings,
},
status: {
isStatusPageAnonymous: setupDeps.core.status.isStatusPageAnonymous,
Expand Down
1 change: 1 addition & 0 deletions src/core/server/plugins/plugin_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
getImportExportObjectLimit: deps.savedObjects.getImportExportObjectLimit,
setRepositoryFactoryProvider: deps.savedObjects.setRepositoryFactoryProvider,
setStatus: deps.savedObjects.setStatus,
addExtendedSavedObjectsMappings: deps.savedObjects.addExtendedSavedObjectsMappings,
},
status: {
core$: deps.status.core$,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import crypto from 'crypto';
import { cloneDeep, mapValues } from 'lodash';
import {
IndexMapping,
SavedObjectsFieldMapping,
SavedObjectsMappingProperties,
SavedObjectsTypeMappingDefinitions,
} from './../../mappings';
Expand All @@ -48,11 +47,15 @@ import {
* @param typeDefinitions - the type definitions to build mapping from.
*/
export function buildActiveMappings(
typeDefinitions: SavedObjectsTypeMappingDefinitions | SavedObjectsMappingProperties
typeDefinitions: SavedObjectsTypeMappingDefinitions | SavedObjectsMappingProperties,
extendedMappings?: SavedObjectsMappingProperties
): IndexMapping {
const mapping = defaultMapping();

const mergedProperties = validateAndMerge(mapping.properties, typeDefinitions);
let mergedProperties = validateAndMerge(mapping.properties, typeDefinitions);
if (extendedMappings) {
mergedProperties = validateAndMerge(mergedProperties, extendedMappings);
}

return cloneDeep({
...mapping,
Expand Down Expand Up @@ -138,16 +141,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: {
Expand Down Expand Up @@ -186,18 +179,6 @@ function defaultMapping(): IndexMapping {
},
},
},
workspaces: {
type: 'keyword',
},
permissions: {
properties: {
read: principals,
write: principals,
management: principals,
library_read: principals,
library_write: principals,
},
},
},
};
}
Expand Down
13 changes: 10 additions & 3 deletions src/core/server/saved_objects/migrations/core/migration_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export interface MigrationOpts {
documentMigrator: VersionedTransformer;
serializer: SavedObjectsSerializer;
convertToAliasScript?: string;
extendedMappingProperties?: SavedObjectsMappingProperties;

/**
* If specified, templates matching the specified pattern will be removed
Expand Down Expand Up @@ -93,7 +94,12 @@ export async function migrationContext(opts: MigrationOpts): Promise<Context> {
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.extendedMappingProperties
);

return {
client,
Expand Down Expand Up @@ -125,10 +131,11 @@ function createSourceContext(source: Index.FullIndexInfo, alias: string) {
function createDestContext(
source: Index.FullIndexInfo,
alias: string,
typeMappingDefinitions: SavedObjectsTypeMappingDefinitions
typeMappingDefinitions: SavedObjectsTypeMappingDefinitions,
extendedMappingProperties?: SavedObjectsMappingProperties
): Index.FullIndexInfo {
const targetMappings = disableUnknownTypeMappingFields(
buildActiveMappings(typeMappingDefinitions),
buildActiveMappings(typeMappingDefinitions, extendedMappingProperties),
source.mappings
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ import { OpenSearchDashboardsConfigType } from 'src/core/server/opensearch_dashb
import { BehaviorSubject } from 'rxjs';

import { Logger } from '../../../logging';
import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings';
import {
IndexMapping,
SavedObjectsMappingProperties,
SavedObjectsTypeMappingDefinitions,
} from '../../mappings';
import { SavedObjectUnsanitizedDoc, SavedObjectsSerializer } from '../../serialization';
import { buildActiveMappings, IndexMigrator, MigrationResult, MigrationStatus } from '../core';
import { DocumentMigrator, VersionedTransformer } from '../core/document_migrator';
Expand All @@ -54,6 +58,7 @@ export interface OpenSearchDashboardsMigratorOptions {
opensearchDashboardsConfig: OpenSearchDashboardsConfigType;
opensearchDashboardsVersion: string;
logger: Logger;
extendedSavedObjectsMappings?: SavedObjectsMappingProperties;
}

export type IOpenSearchDashboardsMigrator = Pick<
Expand Down Expand Up @@ -83,6 +88,7 @@ export class OpenSearchDashboardsMigrator {
status: 'waiting',
});
private readonly activeMappings: IndexMapping;
private readonly extendedMappingProperties?: SavedObjectsMappingProperties;

/**
* Creates an instance of OpenSearchDashboardsMigrator.
Expand All @@ -93,6 +99,7 @@ export class OpenSearchDashboardsMigrator {
opensearchDashboardsConfig,
savedObjectsConfig,
opensearchDashboardsVersion,
extendedSavedObjectsMappings,
logger,
}: OpenSearchDashboardsMigratorOptions) {
this.client = client;
Expand All @@ -101,6 +108,7 @@ export class OpenSearchDashboardsMigrator {
this.typeRegistry = typeRegistry;
this.serializer = new SavedObjectsSerializer(this.typeRegistry);
this.mappingProperties = mergeTypes(this.typeRegistry.getAllTypes());
this.extendedMappingProperties = extendedSavedObjectsMappings;
this.log = logger;
this.documentMigrator = new DocumentMigrator({
opensearchDashboardsVersion,
Expand All @@ -109,7 +117,7 @@ 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, extendedSavedObjectsMappings);
}

/**
Expand Down Expand Up @@ -172,6 +180,7 @@ export class OpenSearchDashboardsMigrator {
index,
log: this.log,
mappingProperties: indexMap[index].typeMappings,
extendedMappingProperties: this.extendedMappingProperties,
pollInterval: this.savedObjectsConfig.pollInterval,
scrollDuration: this.savedObjectsConfig.scrollDuration,
serializer: this.serializer,
Expand Down
15 changes: 14 additions & 1 deletion src/core/server/saved_objects/saved_objects_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
SavedObjectsClient,
SavedObjectsClientProvider,
SavedObjectsClientProviderOptions,
SavedObjectsMappingProperties,
} from './';
import { OpenSearchDashboardsMigrator, IOpenSearchDashboardsMigrator } from './migrations';
import { CoreContext } from '../core_context';
Expand Down Expand Up @@ -183,6 +184,11 @@ export interface SavedObjectsServiceSetup {
* Completely overrides the default status.
*/
setStatus(status$: Observable<ServiceStatus<SavedObjectStatusMeta>>): void;

/**
* Allow a plugin to add extended saved objects mappings
*/
addExtendedSavedObjectsMappings: (mappings: SavedObjectsMappingProperties) => void;
}

/**
Expand Down Expand Up @@ -314,6 +320,7 @@ export class SavedObjectsService
level: ServiceStatusLevels.unavailable,
summary: `waiting`,
});
private extendedSavedObjectsMappings?: SavedObjectsMappingProperties;

constructor(private readonly coreContext: CoreContext) {
this.logger = coreContext.logger.get('savedobjects-service');
Expand Down Expand Up @@ -389,6 +396,9 @@ export class SavedObjectsService
}
this.savedObjectServiceCustomStatus$ = status$;
},
addExtendedSavedObjectsMappings: (mappings: SavedObjectsMappingProperties) => {
this.extendedSavedObjectsMappings = mappings;
},
};
}

Expand All @@ -400,7 +410,7 @@ export class SavedObjectsService
throw new Error('#setup() needs to be run first');
}

this.logger.debug('Starting SavedObjects service');
this.logger.info('Starting SavedObjects service');

if (this.savedObjectServiceCustomStatus$) {
this.savedObjectServiceCustomStatus$
Expand Down Expand Up @@ -435,6 +445,7 @@ export class SavedObjectsService
opensearchDashboardsConfig,
this.config.migration,
opensearch.client,
this.extendedSavedObjectsMappings,
migrationsRetryDelay
);

Expand Down Expand Up @@ -546,6 +557,7 @@ export class SavedObjectsService
opensearchDashboardsConfig: OpenSearchDashboardsConfigType,
savedObjectsConfig: SavedObjectsMigrationConfigType,
client: IClusterClient,
extendedSavedObjectsMappings?: SavedObjectsMappingProperties,
migrationsRetryDelay?: number
): IOpenSearchDashboardsMigrator {
return new OpenSearchDashboardsMigrator({
Expand All @@ -559,6 +571,7 @@ export class SavedObjectsService
this.logger,
migrationsRetryDelay
),
extendedSavedObjectsMappings,
});
}
}
33 changes: 33 additions & 0 deletions src/plugins/workspace/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
Plugin,
Logger,
SavedObjectsClient,
SavedObjectsMappingProperties,
SavedObjectsFieldMapping,
} from '../../../core/server';
import { IWorkspaceClientImpl } from './types';
import { WorkspaceClientWithSavedObject } from './workspace_client';
Expand Down Expand Up @@ -62,6 +64,12 @@ export class WorkspacePlugin implements Plugin<{}, {}> {

await this.client.setup(core);

let extendedSavedObjectsMappings: SavedObjectsMappingProperties = {
workspaces: {
type: 'keyword',
},
};

this.logger.info('Workspace permission control enabled:' + isPermissionControlEnabled);
if (isPermissionControlEnabled) {
this.permissionControl = new SavedObjectsPermissionControl(this.logger);
Expand All @@ -80,8 +88,33 @@ export class WorkspacePlugin implements Plugin<{}, {}> {
WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID,
workspaceSavedObjectsClientWrapper.wrapperFactory
);

const principals: SavedObjectsFieldMapping = {
properties: {
users: {
type: 'keyword',
},
groups: {
type: 'keyword',
},
},
};
extendedSavedObjectsMappings = {
...extendedSavedObjectsMappings,
permissions: {
properties: {
read: principals,
write: principals,
management: principals,
library_read: principals,
library_write: principals,
},
},
};
}

core.savedObjects.addExtendedSavedObjectsMappings(extendedSavedObjectsMappings);

this.proxyWorkspaceTrafficToRealHandler(core);

registerRoutes({
Expand Down

0 comments on commit acddbc0

Please sign in to comment.