mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
* Spaces - Client NP Migration, Phase 1 (#40856) * shimming NP for spaces client-side plugin * refresh active space in nav control when updated * fix advanced settings screen * allow npStart from unauthed routes * use NP for deriving space management url * remove security's usage of SpacesManager * remove usages of ui/capabilities * fix tests * implement NP plugin interface * remove hack in favor of convention in migration guide * shim feature catalogue registration * streamline nav control, and handle async loading more gracefully * adding opaqueId * fixes from merge * fix merge from master * fixing merge from master * move _active_space route to NP * moving to the NP feature catalogue registry * moving setup to setup phase * optimizing active space retrieval * reverting test isolation change * Apply suggestions from code review Co-Authored-By: Aleh Zasypkin <aleh.zasypkin@gmail.com> * removing unnecessary PluginInitializerContext * updating advanced settings subtitle * using NP anonymousPaths service * additional nav_control_popover cleanup * additional cleanup * testing out onActiveSpaceChange$ property * make the linter happy * make the type checker happy * fixing types * fix merge from master * spaces LP init should run on all pages, not just the kibana app * address nits * fix infra/logs, and the spaces disabled scenario * fix typescript errors * revert changes to infra plugin * reintroducing activeSpace injected var for legacy plugins * fixing react deprecation warning and unhandled promise rejection * restore activeSpace default var * spaces does not need to check its own enabled status * fix from merge Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> * fix backport merge
206 lines
6.8 KiB
TypeScript
206 lines
6.8 KiB
TypeScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the Elastic License;
|
|
* you may not use this file except in compliance with the Elastic License.
|
|
*/
|
|
|
|
import { Observable } from 'rxjs';
|
|
import { take } from 'rxjs/operators';
|
|
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
|
|
import { HomeServerPluginSetup } from 'src/plugins/home/server';
|
|
import {
|
|
SavedObjectsLegacyService,
|
|
CoreSetup,
|
|
Logger,
|
|
PluginInitializerContext,
|
|
} from '../../../../src/core/server';
|
|
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
|
|
import { PluginSetupContract as SecurityPluginSetup } from '../../security/server';
|
|
import { LicensingPluginSetup } from '../../licensing/server';
|
|
import { XPackMainPlugin } from '../../../legacy/plugins/xpack_main/xpack_main';
|
|
import { createDefaultSpace } from './lib/create_default_space';
|
|
// @ts-ignore
|
|
import { AuditLogger } from '../../../../server/lib/audit_logger';
|
|
import { spacesSavedObjectsClientWrapperFactory } from './lib/saved_objects_client/saved_objects_client_wrapper_factory';
|
|
import { SpacesAuditLogger } from './lib/audit_logger';
|
|
import { createSpacesTutorialContextFactory } from './lib/spaces_tutorial_context_factory';
|
|
import { registerSpacesUsageCollector } from './lib/spaces_usage_collector';
|
|
import { SpacesService } from './spaces_service';
|
|
import { SpacesServiceSetup } from './spaces_service/spaces_service';
|
|
import { ConfigType } from './config';
|
|
import { toggleUICapabilities } from './lib/toggle_ui_capabilities';
|
|
import { initSpacesRequestInterceptors } from './lib/request_interceptors';
|
|
import { initExternalSpacesApi } from './routes/api/external';
|
|
import { initInternalSpacesApi } from './routes/api/internal';
|
|
|
|
/**
|
|
* Describes a set of APIs that is available in the legacy platform only and required by this plugin
|
|
* to function properly.
|
|
*/
|
|
export interface LegacyAPI {
|
|
savedObjects: SavedObjectsLegacyService;
|
|
tutorial: {
|
|
addScopedTutorialContextFactory: (factory: any) => void;
|
|
};
|
|
auditLogger: {
|
|
create: (pluginId: string) => AuditLogger;
|
|
};
|
|
legacyConfig: {
|
|
kibanaIndex: string;
|
|
};
|
|
xpackMain: XPackMainPlugin;
|
|
}
|
|
|
|
export interface PluginsSetup {
|
|
features: FeaturesPluginSetup;
|
|
licensing: LicensingPluginSetup;
|
|
security?: SecurityPluginSetup;
|
|
usageCollection?: UsageCollectionSetup;
|
|
home?: HomeServerPluginSetup;
|
|
}
|
|
|
|
export interface SpacesPluginSetup {
|
|
spacesService: SpacesServiceSetup;
|
|
__legacyCompat: {
|
|
registerLegacyAPI: (legacyAPI: LegacyAPI) => void;
|
|
// TODO: We currently need the legacy plugin to inform this plugin when it is safe to create the default space.
|
|
// The NP does not have the equivilent ES connection/health/comapt checks that the legacy world does.
|
|
// See: https://github.com/elastic/kibana/issues/43456
|
|
createDefaultSpace: () => Promise<void>;
|
|
};
|
|
}
|
|
|
|
export class Plugin {
|
|
private readonly pluginId = 'spaces';
|
|
|
|
private readonly config$: Observable<ConfigType>;
|
|
|
|
private readonly log: Logger;
|
|
|
|
private legacyAPI?: LegacyAPI;
|
|
private readonly getLegacyAPI = () => {
|
|
if (!this.legacyAPI) {
|
|
throw new Error('Legacy API is not registered!');
|
|
}
|
|
return this.legacyAPI;
|
|
};
|
|
|
|
private spacesAuditLogger?: SpacesAuditLogger;
|
|
private readonly getSpacesAuditLogger = () => {
|
|
if (!this.spacesAuditLogger) {
|
|
this.spacesAuditLogger = new SpacesAuditLogger(
|
|
this.getLegacyAPI().auditLogger.create(this.pluginId)
|
|
);
|
|
}
|
|
return this.spacesAuditLogger;
|
|
};
|
|
|
|
constructor(initializerContext: PluginInitializerContext) {
|
|
this.config$ = initializerContext.config.create<ConfigType>();
|
|
this.log = initializerContext.logger.get();
|
|
}
|
|
|
|
public async start() {}
|
|
|
|
public async setup(core: CoreSetup, plugins: PluginsSetup): Promise<SpacesPluginSetup> {
|
|
const service = new SpacesService(this.log, this.getLegacyAPI);
|
|
|
|
const spacesService = await service.setup({
|
|
http: core.http,
|
|
elasticsearch: core.elasticsearch,
|
|
authorization: plugins.security ? plugins.security.authz : null,
|
|
getSpacesAuditLogger: this.getSpacesAuditLogger,
|
|
config$: this.config$,
|
|
});
|
|
|
|
const externalRouter = core.http.createRouter();
|
|
initExternalSpacesApi({
|
|
externalRouter,
|
|
log: this.log,
|
|
getSavedObjects: () => this.getLegacyAPI().savedObjects,
|
|
spacesService,
|
|
});
|
|
|
|
const internalRouter = core.http.createRouter();
|
|
initInternalSpacesApi({
|
|
internalRouter,
|
|
spacesService,
|
|
});
|
|
|
|
initSpacesRequestInterceptors({
|
|
http: core.http,
|
|
log: this.log,
|
|
getLegacyAPI: this.getLegacyAPI,
|
|
spacesService,
|
|
features: plugins.features,
|
|
});
|
|
|
|
core.capabilities.registerSwitcher(async (request, uiCapabilities) => {
|
|
try {
|
|
const activeSpace = await spacesService.getActiveSpace(request);
|
|
const features = plugins.features.getFeatures();
|
|
return toggleUICapabilities(features, uiCapabilities, activeSpace);
|
|
} catch (e) {
|
|
return uiCapabilities;
|
|
}
|
|
});
|
|
|
|
if (plugins.security) {
|
|
plugins.security.registerSpacesService(spacesService);
|
|
}
|
|
|
|
if (plugins.home) {
|
|
plugins.home.tutorials.addScopedTutorialContextFactory(
|
|
createSpacesTutorialContextFactory(spacesService)
|
|
);
|
|
}
|
|
|
|
return {
|
|
spacesService,
|
|
__legacyCompat: {
|
|
registerLegacyAPI: (legacyAPI: LegacyAPI) => {
|
|
this.legacyAPI = legacyAPI;
|
|
this.setupLegacyComponents(
|
|
spacesService,
|
|
plugins.features,
|
|
plugins.licensing,
|
|
plugins.usageCollection
|
|
);
|
|
},
|
|
createDefaultSpace: async () => {
|
|
const esClient = await core.elasticsearch.adminClient$.pipe(take(1)).toPromise();
|
|
return createDefaultSpace({
|
|
esClient,
|
|
savedObjects: this.getLegacyAPI().savedObjects,
|
|
});
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
public stop() {}
|
|
|
|
private setupLegacyComponents(
|
|
spacesService: SpacesServiceSetup,
|
|
featuresSetup: FeaturesPluginSetup,
|
|
licensingSetup: LicensingPluginSetup,
|
|
usageCollectionSetup?: UsageCollectionSetup
|
|
) {
|
|
const legacyAPI = this.getLegacyAPI();
|
|
const { addScopedSavedObjectsClientWrapperFactory, types } = legacyAPI.savedObjects;
|
|
addScopedSavedObjectsClientWrapperFactory(
|
|
Number.MIN_SAFE_INTEGER,
|
|
'spaces',
|
|
spacesSavedObjectsClientWrapperFactory(spacesService, types)
|
|
);
|
|
legacyAPI.tutorial.addScopedTutorialContextFactory(
|
|
createSpacesTutorialContextFactory(spacesService)
|
|
);
|
|
// Register a function with server to manage the collection of usage stats
|
|
registerSpacesUsageCollector(usageCollectionSetup, {
|
|
kibanaIndex: legacyAPI.legacyConfig.kibanaIndex,
|
|
features: featuresSetup,
|
|
licensing: licensingSetup,
|
|
});
|
|
}
|
|
}
|