-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spaces - New Platform Migration, Step 1 #35429
Changes from all commits
6b53cfb
0de048e
af427e5
1a56ee6
d89f320
d5cae9f
929cf7b
751e4a7
ae7850a
6c75e85
1e4cd95
de35798
a0bd378
4e835a4
5d27c18
661fe99
0ce0e47
d7ca4ba
600a33a
c5a8656
c6afefc
f67ccc6
5ad6039
dbf39e0
68e7f25
69efd88
3abb40e
18bda1b
21febb8
50a2535
4f1821e
167cc74
25627c5
9cf542e
9b56233
f8b974f
a83f2f8
cb81fcd
98f50b6
ff439c0
2aa3513
3cdfce4
f71a9b1
a321570
809f9e4
38b211d
cbd50bb
6b0bb66
3d84577
6c53d66
c6742b3
d3339ee
ed47e3d
0d9b275
885764d
bdabe4b
279b630
52e21e7
957e548
330c316
26163af
6f0ed68
276239a
93aff23
12417a2
256bb55
1492c4a
9f2bfec
c2e8b51
2611e60
2c14650
d6f8d07
9680e4b
dadd607
81d462b
0b8ddde
583bff2
2f0abc9
1cf4cf0
8819aa6
a4dfdb8
feb1f47
7d3cb65
9f73fd2
0498034
d26c61d
b0a977c
3a5cc82
e9f091f
d03eb01
40df9f5
c338803
3d8aeef
4546013
a1260b5
a0d2d70
c245dca
cc85d11
d0e87a5
a04b6ed
174e2c8
dae35da
a9ea28f
1e21cc8
2f22c48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsClientWrapperFactory](./kibana-plugin-server.savedobjectsclientwrapperfactory.md) | ||
|
||
## SavedObjectsClientWrapperFactory type | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
export declare type SavedObjectsClientWrapperFactory<Request = unknown> = (options: SavedObjectsClientWrapperOptions<Request>) => SavedObjectsClientContract; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsClientWrapperOptions](./kibana-plugin-server.savedobjectsclientwrapperoptions.md) > [client](./kibana-plugin-server.savedobjectsclientwrapperoptions.client.md) | ||
|
||
## SavedObjectsClientWrapperOptions.client property | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
client: SavedObjectsClientContract; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsClientWrapperOptions](./kibana-plugin-server.savedobjectsclientwrapperoptions.md) | ||
|
||
## SavedObjectsClientWrapperOptions interface | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
export interface SavedObjectsClientWrapperOptions<Request = unknown> | ||
``` | ||
|
||
## Properties | ||
|
||
| Property | Type | Description | | ||
| --- | --- | --- | | ||
| [client](./kibana-plugin-server.savedobjectsclientwrapperoptions.client.md) | <code>SavedObjectsClientContract</code> | | | ||
| [request](./kibana-plugin-server.savedobjectsclientwrapperoptions.request.md) | <code>Request</code> | | | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsClientWrapperOptions](./kibana-plugin-server.savedobjectsclientwrapperoptions.md) > [request](./kibana-plugin-server.savedobjectsclientwrapperoptions.request.md) | ||
|
||
## SavedObjectsClientWrapperOptions.request property | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
request: Request; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,32 +4,25 @@ | |
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import * as Rx from 'rxjs'; | ||
import { resolve } from 'path'; | ||
|
||
import { SavedObjectsService } from 'src/core/server'; | ||
import { Request, Server } from 'hapi'; | ||
import KbnServer, { Server } from 'src/legacy/server/kbn_server'; | ||
import { createOptionalPlugin } from '../../server/lib/optional_plugin'; | ||
// @ts-ignore | ||
import { AuditLogger } from '../../server/lib/audit_logger'; | ||
// @ts-ignore | ||
import { watchStatusAndLicenseToInitialize } from '../../server/lib/watch_status_and_license_to_initialize'; | ||
import mappings from './mappings.json'; | ||
import { SpacesAuditLogger } from './server/lib/audit_logger'; | ||
import { checkLicense } from './server/lib/check_license'; | ||
import { createDefaultSpace } from './server/lib/create_default_space'; | ||
import { createSpacesService } from './server/lib/create_spaces_service'; | ||
import { wrapError } from './server/lib/errors'; | ||
import { getActiveSpace } from './server/lib/get_active_space'; | ||
import { getSpaceSelectorUrl } from './server/lib/get_space_selector_url'; | ||
import { getSpacesUsageCollector } from './server/lib/get_spaces_usage_collector'; | ||
import { migrateToKibana660 } from './server/lib/migrations'; | ||
import { initSpacesRequestInterceptors } from './server/lib/request_inteceptors'; | ||
import { spacesSavedObjectsClientWrapperFactory } from './server/lib/saved_objects_client/saved_objects_client_wrapper_factory'; | ||
import { SpacesClient } from './server/lib/spaces_client'; | ||
import { createSpacesTutorialContextFactory } from './server/lib/spaces_tutorial_context_factory'; | ||
import { toggleUICapabilities } from './server/lib/toggle_ui_capabilities'; | ||
import { initExternalSpacesApi } from './server/routes/api/external'; | ||
import { initInternalApis } from './server/routes/api/v1'; | ||
|
||
import { plugin } from './server/new_platform'; | ||
import { | ||
SpacesInitializerContext, | ||
SpacesCoreSetup, | ||
SpacesHttpServiceSetup, | ||
} from './server/new_platform/plugin'; | ||
import { initSpacesRequestInterceptors } from './server/lib/request_interceptors'; | ||
import { SecurityPlugin } from '../security'; | ||
export const spaces = (kibana: Record<string, any>) => | ||
new kibana.Plugin({ | ||
id: 'spaces', | ||
|
@@ -95,7 +88,7 @@ export const spaces = (kibana: Record<string, any>) => | |
request: Record<string, any>, | ||
server: Record<string, any> | ||
) { | ||
const spacesClient = server.plugins.spaces.spacesClient.getScopedClient(request); | ||
const spacesClient = await server.plugins.spaces.getScopedSpacesClient(request); | ||
try { | ||
vars.activeSpace = { | ||
valid: true, | ||
|
@@ -117,86 +110,77 @@ export const spaces = (kibana: Record<string, any>) => | |
}, | ||
|
||
async init(server: Server) { | ||
const thisPlugin = this; | ||
const xpackMainPlugin = server.plugins.xpack_main; | ||
|
||
watchStatusAndLicenseToInitialize(xpackMainPlugin, thisPlugin, async () => { | ||
await createDefaultSpace(server); | ||
}); | ||
const kbnServer = (server as unknown) as KbnServer; | ||
const initializerContext = ({ | ||
legacyConfig: server.config(), | ||
config: { | ||
create: () => { | ||
return Rx.of({ | ||
maxSpaces: server.config().get('xpack.spaces.maxSpaces'), | ||
}); | ||
}, | ||
}, | ||
logger: { | ||
get(...contextParts: string[]) { | ||
return kbnServer.newPlatform.coreContext.logger.get( | ||
'plugins', | ||
'spaces', | ||
...contextParts | ||
); | ||
}, | ||
}, | ||
} as unknown) as SpacesInitializerContext; | ||
|
||
// Register a function that is called whenever the xpack info changes, | ||
// to re-compute the license check results for this plugin. | ||
xpackMainPlugin.info | ||
.feature(thisPlugin.id) | ||
.registerLicenseCheckResultsGenerator(checkLicense); | ||
const spacesHttpService: SpacesHttpServiceSetup = { | ||
...kbnServer.newPlatform.setup.core.http, | ||
route: server.route.bind(server), | ||
mshustov marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. optional: as you still pass |
||
}; | ||
|
||
const spacesService = createSpacesService(server); | ||
server.expose('getSpaceId', (request: any) => spacesService.getSpaceId(request)); | ||
const core: SpacesCoreSetup = { | ||
http: spacesHttpService, | ||
elasticsearch: kbnServer.newPlatform.setup.core.elasticsearch, | ||
savedObjects: server.savedObjects, | ||
usage: server.usage, | ||
tutorial: { | ||
addScopedTutorialContextFactory: server.addScopedTutorialContextFactory, | ||
}, | ||
capabilities: { | ||
registerCapabilitiesModifier: server.registerCapabilitiesModifier, | ||
}, | ||
auditLogger: { | ||
create: (pluginId: string) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❤️ |
||
new AuditLogger(server, pluginId, server.config(), server.plugins.xpack_main.info), | ||
}, | ||
}; | ||
|
||
const config = server.config(); | ||
const plugins = { | ||
xpackMain: server.plugins.xpack_main, | ||
// TODO: Spaces has a circular dependency with Security right now. | ||
// Security is not yet available when init runs, so this is wrapped in an optional function for the time being. | ||
security: createOptionalPlugin<SecurityPlugin>( | ||
server.config(), | ||
'xpack.security', | ||
server.plugins, | ||
'security' | ||
), | ||
spaces: this, | ||
}; | ||
|
||
const spacesAuditLogger = new SpacesAuditLogger( | ||
new AuditLogger(server, 'spaces', config, xpackMainPlugin.info) | ||
); | ||
const { spacesService, log } = await plugin(initializerContext).setup(core, plugins); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apologies for being dense, what's the distinction between what we can pass in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Borrowing from @azasypkin's comment here: TL;DR; setup - everything that makes sense and can be used only at the setup stage, constructor - everything that is valid during entire plugin lifetime. Plugin's setup method will receive "setup contracts" (basically what setup method of other plugins or core services returns) from all optional and required dependencies that live outside of the current plugin: either in other plugins (e.g. license or telemetry plugins) or in the core (e.g. elasticsearch or http services). Same applies to stop and start (that will eventually be re-introduced). There is no notion of "plugin constructor" in the core, what core expects is a "initializer" function exported by the plugin that will receive "initializer" context. This context object will include everything that is valid and can be used during entire plugin lifetime (e.g. logger, env, config). Even though technically plugin doesn't have to define any classes, platform team recommends defining plugin as a class that is instantiated within "initializer" function and hence receives "initializer" context as a constructor argument + any other plugin specific stuff (assuming it's not expensive to create during "pre-setup" initialization). |
||
|
||
server.expose('spacesClient', { | ||
getScopedClient: (request: Request) => { | ||
const adminCluster = server.plugins.elasticsearch.getCluster('admin'); | ||
const { callWithRequest, callWithInternalUser } = adminCluster; | ||
const callCluster = callWithRequest.bind(adminCluster, request); | ||
const { savedObjects } = server; | ||
const internalRepository = savedObjects.getSavedObjectsRepository(callWithInternalUser); | ||
const callWithRequestRepository = savedObjects.getSavedObjectsRepository(callCluster); | ||
const authorization = server.plugins.security | ||
? server.plugins.security.authorization | ||
: null; | ||
return new SpacesClient( | ||
spacesAuditLogger, | ||
(message: string) => { | ||
server.log(['spaces', 'debug'], message); | ||
}, | ||
authorization, | ||
callWithRequestRepository, | ||
server.config(), | ||
internalRepository, | ||
request | ||
); | ||
initSpacesRequestInterceptors({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be moved to the "new platform plugin"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm torn on this... the I could also register |
||
config: initializerContext.legacyConfig, | ||
http: core.http, | ||
getHiddenUiAppById: server.getHiddenUiAppById, | ||
onPostAuth: handler => { | ||
server.ext('onPostAuth', handler); | ||
}, | ||
log, | ||
spacesService, | ||
xpackMain: plugins.xpackMain, | ||
}); | ||
|
||
const { | ||
addScopedSavedObjectsClientWrapperFactory, | ||
types, | ||
} = server.savedObjects as SavedObjectsService; | ||
addScopedSavedObjectsClientWrapperFactory( | ||
Number.MAX_SAFE_INTEGER - 1, | ||
spacesSavedObjectsClientWrapperFactory(spacesService, types) | ||
); | ||
|
||
server.addScopedTutorialContextFactory(createSpacesTutorialContextFactory(spacesService)); | ||
|
||
initInternalApis(server); | ||
initExternalSpacesApi(server); | ||
|
||
initSpacesRequestInterceptors(server); | ||
|
||
// Register a function with server to manage the collection of usage stats | ||
server.usage.collectorSet.register(getSpacesUsageCollector(server)); | ||
|
||
server.registerCapabilitiesModifier(async (request, uiCapabilities) => { | ||
const spacesClient = server.plugins.spaces.spacesClient.getScopedClient(request); | ||
try { | ||
const activeSpace = await getActiveSpace( | ||
spacesClient, | ||
request.getBasePath(), | ||
server.config().get('server.basePath') | ||
); | ||
|
||
const features = server.plugins.xpack_main.getFeatures(); | ||
return toggleUICapabilities(features, uiCapabilities, activeSpace); | ||
} catch (e) { | ||
return uiCapabilities; | ||
} | ||
}); | ||
server.expose('getSpaceId', (request: any) => spacesService.getSpaceId(request)); | ||
server.expose('getScopedSpacesClient', spacesService.scopedClient); | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll defer to @restrry or someone else on the platform team whether this is a change they're okay with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with this. also we can use
class-properties
https://github.com/restrry/kibana/blob/146c65cfeefc946a1cea4a9318953de728e76235/packages/kbn-babel-preset/common_preset.js#L32