Skip to content
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

Merged
merged 105 commits into from
Jun 19, 2019
Merged

Conversation

legrego
Copy link
Member

@legrego legrego commented Apr 22, 2019

Summary

The first phase of this Spaces plugin migration to the new platform.
This is only concerned with part of the server side implementation. A client-side PR will follow.

The main goal of this PR is to migrate the onRequest interceptor in order to perform the equivalent of request.setBasePath() in the new platform. This will allow requests outside of the default space to be handled by new platform routes, and is a prerequisite to moving authentication to the new platform.

This PR does not reflect the final state of the spaces plugin. There are design shortcomings that will be addressed in subsequent PRs before the next minor release is cut, as the NP services are evolved and the security plugin is migrated alongside the spaces plugin.

Tasks

  • Create "New Platform" plugin
  • Create interfaces to abstract usage of Hapi server/request
  • Use the NP Elasticsearch service instead of the legacy ES plugin
  • Need NP equivalent of request.setBasePath() and request.getBasePath() in src/core - replace usages in Spaces plugin wherever possible
  • SpacesService.scopedClient() -- currently needs the full request object for subsequent callCluster invocations.
  • Migrate onRequest request interceptor
  • Testing

Not in scope

The following tasks need to be done, but are out of scope for this PR

  • Resolve or enable circular dependency between Spaces and Security
  • Migrate onPostAuth request interceptors to use NP, once available
  • Consolidate plugin services into SpacesService instead of exposing two functions on the server object.
  • Code re-org

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine

This comment has been minimized.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@legrego
Copy link
Member Author

legrego commented Apr 29, 2019

@restrry thanks for agreeing to be my consultant!
Here is what I have so far for the Spaces migration.
I think my most immediate need/question is how we want to migrate request.setBasePath and request.getBasePath to the New Platform. They were introduced for Spaces, and allow callers to transparently get a space-aware base path to Kibana.

@elasticmachine

This comment has been minimized.

@legrego
Copy link
Member Author

legrego commented Apr 29, 2019

Actually, a more complex need is the ability to rewrite the incoming request before it is processed by the rest of the handler chain. We currently rely on the HAPI api and request shape to enable this today.

We re-write requests to drop the space identifier from the URL:

Browser: GET /s/marketing/app/kibana
Spaces interceptor:

  • strip off /s/marketing, store in request.setBasePath()
  • craft new url, omitting /s/marketing from the request.
  • send the updated request through the handler chain for subsequent processing by Kibana.

import { SavedObjectsService } from 'src/legacy/server/saved_objects';
// @ts-ignore
import KbnServer, { Server, KibanaConfig } from 'src/legacy/server/kbn_server';
import { HttpServerInfo } from 'src/core/server/http';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use relative paths when import NP modules, please.
TODO for myself: enhance linting rule to restrict import from NP internals when import declared as an absolute path.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's revert to absolute path import until the problem is resolved #35429 (comment)
also we shouldn't import from module internals, but the root level:

import { HttpServerInfo } from 'src/core/server';

x-pack/plugins/spaces/index.ts Outdated Show resolved Hide resolved
x-pack/plugins/spaces/index.ts Show resolved Hide resolved
x-pack/plugins/spaces/index.ts Outdated Show resolved Hide resolved
x-pack/plugins/spaces/server/routes/api/public/index.ts Outdated Show resolved Hide resolved
x-pack/plugins/spaces/index.ts Outdated Show resolved Hide resolved
x-pack/plugins/spaces/index.ts Outdated Show resolved Hide resolved
x-pack/plugins/spaces/kibana.json Outdated Show resolved Hide resolved
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

x-pack/plugins/spaces/index.ts Outdated Show resolved Hide resolved
x-pack/plugins/spaces/index.ts Outdated Show resolved Hide resolved

const { getSavedObjectsRepository, SavedObjectsClient } = server.savedObjects;
const client = await elasticsearch.dataClient$.pipe(first()).toPromise();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stumbled on this because the defaultSpaceExists check short-circuits the creation of the default space, but I was under the impression that the consumer of this function (which is still in legacy land) needs something to await, so the outcome of this function should still be a promise. If that's not the case, then maybe that simplifies things, but that's where I was getting stuck.

Since this is an async function, even if we return immediately, it'll still be a promise and everything will behave "alright". The biggest drawback that we get from the current implementation being promise based is that we don't get cancellation. If we were to rewrite watchStatusAndLicenseToInitialize to work with observables, we'd be able to cancel it half-way through. Right now, because we break out of the RxJs world, we don't get this...

};
});
}, 30000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These timeouts are pretty long... do you happen to know what's causing the first test to take so long to run?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah they are... I believe it's the call to root.start() which ends up taking a decent amount of time, because it's actually starting a server. I'm not sure why subsequent runs are faster than the first though

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

Copy link
Contributor

@kobelb kobelb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on green CI.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@legrego
Copy link
Member Author

legrego commented Jun 18, 2019

retest

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

config: mockServer.config(),
savedObjects: (mockServer.savedObjects as unknown) as SavedObjectsService,
elasticsearch: ({
dataClient$: Rx.of({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO for myself: core should provide dataClients with mocked ClusterClient interface

basePath = newPath;
});
httpMock.registerOnPreAuth = jest.fn().mockImplementation(async handler => {
const preAuthRequest = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JFYI there is a hapi request mock, which is not exported outside yet. do you think we should provide KibanaRequest mock and export it as well? https://github.com/restrry/kibana/blob/2f22c48dbaec368b3e43a4a30bb50dd369b8e463/src/core/server/http/http_server.mocks.ts#L55

type RequestFacade = KibanaRequest | Legacy.Request;

export interface SpacesServiceSetup {
scopedClient(request: RequestFacade): Promise<SpacesClient>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit misleading. SpacesClient cannot work with KibanaRequest, thus we can scope only to Legacy.Request

@legrego legrego merged commit 7e4e8fe into elastic:master Jun 19, 2019
@legrego legrego deleted the np/spaces-part-1 branch June 19, 2019 14:08
@legrego legrego restored the np/spaces-part-1 branch June 19, 2019 14:09
legrego added a commit to legrego/kibana that referenced this pull request Jun 19, 2019
* crude test updates

* remove custom server typedef

* allow spaces to aquire security plugin after init

* split CoreSetup into CoreSetup and PluginsSetup

* move interfaces to new plugin

* init interceptors in legacy plugin

* fix import

* add placeholder kibana.json

* use NP Elasticsearch service instead of legacy ES Plugin

* cleanup imports

* don't destructure the es client

* introduce request facade

* document reason for getSecurity

* prefer relative imports from src/core

* fix typo in filename: inteceptors --> interceptors

* fix imports; remove stray ts-ignore

* improve typings for spaces client

* rename InterfaceExcept --> Omit

* don't use legacy config in NP

* additional comment

* shim NP config service

* fix merge from master

* revert relative imports into src/core and src/legacy

* shim capabilities modifier into new platform

* removing placeholder kibana.json

* fix prettier problem

* temporary: patch NP 'setUrl'

* migrate onRequest interceptor to NP, without tests

* fix ts error

* testing and deps cleanup for onRequestInterceptor

* replace spaces's usages of request.getBasePath with http.getBasePathFor

* add explicit timeouts for jest interceptor tests

* attempt to fix imports

* use NP logging instead of faked implementation

* revert stray yarn.lock change

* attempt to stablize and fix tests

* update jest config to include src/core/server/mocks

* fix plugin config typings

* add service tests

* fix merge

* allow spaces service to also work with legacy requests

* update interfaces to confirm to new internal/external API convention

* re-enable some post auth interceptor tests

* add explicit timeouts for tests

* prefer modifyUrl instead of manual url modification

* update logger shim to conform to PluginInitializerContext

* remove spaces ConfigClass

* don't weaken type declaration for scoped cluster client calls

* remove legacy server from SpacesCoreSetup

* remove spaces service cache

* remove legacy server as an interceptor dependency

* use modifyUrl on the raw request too

* remove unused import

* cleanup typings

* replace onRequest interceptor with new onPreAuth interceptor

* fix onPostAuth tests

* temporarily copy modifyUrl into spaces plugin

* fix mock export

* fix merge from master

* spaces scopedClient always uses updated ES client and config

* improve typings for usage collector

* rename isLegacyRequest -> isFakeRequest

* use updated NP base path API

* remove commented code

* only expose scoped spaces client

* use OptionalPlugin instead of getSecurity

* update imports of Saved Objects Service to use new src/core/server location

* update core docs
legrego added a commit that referenced this pull request Jun 19, 2019
* crude test updates

* remove custom server typedef

* allow spaces to aquire security plugin after init

* split CoreSetup into CoreSetup and PluginsSetup

* move interfaces to new plugin

* init interceptors in legacy plugin

* fix import

* add placeholder kibana.json

* use NP Elasticsearch service instead of legacy ES Plugin

* cleanup imports

* don't destructure the es client

* introduce request facade

* document reason for getSecurity

* prefer relative imports from src/core

* fix typo in filename: inteceptors --> interceptors

* fix imports; remove stray ts-ignore

* improve typings for spaces client

* rename InterfaceExcept --> Omit

* don't use legacy config in NP

* additional comment

* shim NP config service

* fix merge from master

* revert relative imports into src/core and src/legacy

* shim capabilities modifier into new platform

* removing placeholder kibana.json

* fix prettier problem

* temporary: patch NP 'setUrl'

* migrate onRequest interceptor to NP, without tests

* fix ts error

* testing and deps cleanup for onRequestInterceptor

* replace spaces's usages of request.getBasePath with http.getBasePathFor

* add explicit timeouts for jest interceptor tests

* attempt to fix imports

* use NP logging instead of faked implementation

* revert stray yarn.lock change

* attempt to stablize and fix tests

* update jest config to include src/core/server/mocks

* fix plugin config typings

* add service tests

* fix merge

* allow spaces service to also work with legacy requests

* update interfaces to confirm to new internal/external API convention

* re-enable some post auth interceptor tests

* add explicit timeouts for tests

* prefer modifyUrl instead of manual url modification

* update logger shim to conform to PluginInitializerContext

* remove spaces ConfigClass

* don't weaken type declaration for scoped cluster client calls

* remove legacy server from SpacesCoreSetup

* remove spaces service cache

* remove legacy server as an interceptor dependency

* use modifyUrl on the raw request too

* remove unused import

* cleanup typings

* replace onRequest interceptor with new onPreAuth interceptor

* fix onPostAuth tests

* temporarily copy modifyUrl into spaces plugin

* fix mock export

* fix merge from master

* spaces scopedClient always uses updated ES client and config

* improve typings for usage collector

* rename isLegacyRequest -> isFakeRequest

* use updated NP base path API

* remove commented code

* only expose scoped spaces client

* use OptionalPlugin instead of getSecurity

* update imports of Saved Objects Service to use new src/core/server location

* update core docs
@legrego legrego deleted the np/spaces-part-1 branch June 19, 2019 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore Feature:Security/Spaces Platform Security - Spaces feature release_note:skip Skip the PR/issue when compiling release notes review Team:Security Team focused on: Auth, Users, Roles, Spaces, Audit Logging, and more!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants