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

Split legacy plugin discovery, expose SavedObjects scopedClient, wrappers, repository #48882

Merged
merged 21 commits into from
Nov 27, 2019

Conversation

rudolf
Copy link
Contributor

@rudolf rudolf commented Oct 22, 2019

Summary

  1. Split legacy plugin discovery out of LegacyService setup
  2. Expose the following SavedObjects API's:
export interface SavedObjectsServiceSetup {
  /**
   * Set a default factory for creating Saved Objects clients. Only one client
   * factory can be set, subsequent calls to this method will fail.
   */
  setClientFactory: (customClientFactory: SavedObjectsClientFactory<KibanaRequest>) => void;

  /**
   * Add a client wrapper with the given priority.
   */
  addClientWrapper: (
    priority: number,
    id: string,
    factory: SavedObjectsClientWrapperFactory<KibanaRequest>
  ) => void;

  /**
   * Creates a {@link ISavedObjectsRepository | Saved Objects repository} that
   * uses the credentials from the passed in request to authenticate with
   * Elasticsearch.
   */
  scopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository;

  /**
   * Creates a {@link ISavedObjectsRepository | Saved Objects repository} that
   * uses the internal Kibana user for authenticating with Elasticsearch.
   *
   * For a client that uses the credentials and associated privileges of the
   * incoming request see the Saved Objects client exposed from the
   * {@link RequestHandlerContext}.
   */
  internalRepository: (extraTypes?: string[]) => ISavedObjectsRepository;
}
export interface SavedObjectsServiceStart {
  /**
   * Creates a {@link SavedObjectsClientContract | Saved Objects client} that
   * uses the credentials from the passed in request to authenticate with
   * Elasticsearch. Any middleware
   *
   * A client that is already scoped to the incoming request is also exposed
   * from the route handler context see {@link RequestHandlerContext}.
   */
  scopedClient: (
    req: KibanaRequest,
    options?: SavedObjectsClientProviderOptions
  ) => SavedObjectsClientContract;
}

Checklist

Use strikethroughs to remove checklist items you don't feel are applicable to this PR.

For maintainers

@rudolf rudolf added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:New Platform v7.6.0 labels Oct 22, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@rudolf rudolf marked this pull request as ready for review October 22, 2019 13:43
@rudolf rudolf requested a review from a team as a code owner October 22, 2019 13:43
@rudolf rudolf added release_note:skip Skip the PR/issue when compiling release notes v8.0.0 labels Oct 22, 2019
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@joshdover joshdover left a comment

Choose a reason for hiding this comment

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

This internalClient does not expose a way to use "fake credentials" to get a scoped client. I know we need this for a few background workers that do work on behalf of a user, using cached credentials (eg. Reporting, Upgrade Assistant). Are you planning on doing this as a separate change?

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@rudolf
Copy link
Contributor Author

rudolf commented Nov 1, 2019

After speaking to security, uptime and APM it seems like the existing usage in legacy was incorrect and really should be using scoped saved objects clients. So it doesn't appear like there's any valid dependencies on a SavedObjectsSetup.internalClient. I'll keep this PR and use it to expose a scoped client, scoped repository and internal repository.

@joshdover
Copy link
Contributor

Is this still ready for review? It seems it still exposes the internalClient?

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@elasticmachine
Copy link
Contributor

💔 Build Failed

export interface PluginsServiceStartDeps {} // eslint-disable-line @typescript-eslint/no-empty-interface
export type PluginsServiceStartDeps = InternalCoreStart;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not totally convinced we want exact type equivalence here ?

In https://github.com/elastic/kibana/pull/51438/files#diff-725c498a267472754f01cff2baa3901b I explicitly defined the properties

- export interface PluginsServiceStartDeps {} // eslint-disable-line @typescript-eslint/no-empty-interface
+ export interface PluginsServiceStartDeps {
+   capabilities: InternalCoreStart['capabilities'];
+ }

But I'm not sure which one is preferable? I'm guessing we may not necessarily want alls internal core in the service deps? wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it needs to be exactly equivalent, but I don't see the advantage to a more minimal typing, especially since the plugin service will probably require almost every API except the legacy ones which we'll remove later. The more strictly we type it, the more boilerplate it takes to introduce a new API. Although it makes dependencies explicit, I don't think having several layers of slightly different types makes the code more readable, gives us better guarantees or reduced bugs.

Copy link
Contributor

Choose a reason for hiding this comment

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

Reduced boilerplate is a very valid argument

Comment on lines +61 to +66
* When plugins access the Saved Objects client, a new client is created using
* the factory provided to `setClientFactory` and wrapped by all wrappers
* registered through `addClientWrapper`. To create a factory or wrapper,
* plugins will have to construct a Saved Objects client. First create a
* repository by calling `scopedRepository` or `internalRepository` and then
* use this repository as the argument to the {@link SavedObjectsClient}
Copy link
Contributor

Choose a reason for hiding this comment

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

Honest question, is the setClientFactory isolated per-plugin, or is this the responsibility or a single plugin to define it for everyone? What is the actual expected usage of this setter?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These extension points to Saved Objects are there to support the x-pack security plugins: security, encrypted saved objects and spaces and they apply globally, to all plugins that use the saved objects client. This makes the documentation hard to write, cause it's there to solve a very specific problem.

There's broad consensus that this factory and the client wrappers aren't the most elegant architecture, but the way it worked in legacy did the job so we won't try to improve this until after 8.0.0. The security team might have some upcoming requirements that require something more like middleware than just composing clients over each other, but there's no concrete plans yet.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if we're there yet, but if we are sure that this pattern will be replaced, we should mark the setClientFactory and addClientWrapper methods @deprecated.

Copy link
Contributor

Choose a reason for hiding this comment

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

A public API that allows only to be called once sure seems like fragile :) But this will do the job until proper revision.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

src/core/server/saved_objects/saved_objects_service.ts Outdated Show resolved Hide resolved
src/core/server/saved_objects/saved_objects_service.ts Outdated Show resolved Hide resolved
src/core/server/saved_objects/saved_objects_service.ts Outdated Show resolved Hide resolved
Comment on lines +61 to +66
* When plugins access the Saved Objects client, a new client is created using
* the factory provided to `setClientFactory` and wrapped by all wrappers
* registered through `addClientWrapper`. To create a factory or wrapper,
* plugins will have to construct a Saved Objects client. First create a
* repository by calling `scopedRepository` or `internalRepository` and then
* use this repository as the argument to the {@link SavedObjectsClient}
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if we're there yet, but if we are sure that this pattern will be replaced, we should mark the setClientFactory and addClientWrapper methods @deprecated.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@rudolf rudolf merged commit f29af12 into elastic:master Nov 27, 2019
@rudolf rudolf deleted the saved-object-setup-client branch November 27, 2019 15:47
mbondyra added a commit to mbondyra/kibana that referenced this pull request Nov 28, 2019
…ra/kibana into IS-46410_remove-@kbn/ui-framework

* 'IS-46410_remove-@kbn/ui-framework' of github.com:mbondyra/kibana: (49 commits)
  [ML] Re-activate after method in transform test (elastic#51815)
  [SIEM] [Detection Engine] Add edit on rule creation (elastic#51670)
  De-angularize visLegend (elastic#50613)
  [SIEM][Detection Engine] Change security model to use SIEM permissions
  [Monitoring] Sass cleanup (elastic#51100)
  Move errors and validate index pattern ⇒ NP (elastic#51805)
  fixes pagination tests (elastic#51822)
  Split legacy plugin discovery, expose SavedObjects scopedClient, wrappers, repository (elastic#48882)
  [SIEM][Detection Engine] Adds ecs threat properties to rules (elastic#51782)
  [Lens] Remove client-side reference to server source code (elastic#51763)
  Fix infinite redirect loop when multiple cookies are sent (elastic#50452)
  fixes drag and drop in tests (elastic#51806)
  [Console] Proxy fallback (elastic#50185)
  Query String(Bar) Input - cleanup (elastic#51598)
  shim visualizations plugin (elastic#50624)
  Expressions service fixes: better error and loading states handling (elastic#51183)
  fixes url state tests (elastic#51746)
  fixes browser field tests (elastic#51738)
  [ML] Fix anomaly detection test suite (elastic#51712)
  [SIEM] Fix Timeline drag and drop behavior (elastic#51558)
  ...
jloleysens added a commit to jloleysens/kibana that referenced this pull request Nov 28, 2019
…license-management

* 'master' of github.com:elastic/kibana: (48 commits)
  Enable alerting and actions plugin by default (elastic#51254)
  Fix error returned when creating an alert with ES security disabled (elastic#51639)
  [Discover] Improve Percy functional tests (elastic#51699)
  fixes timeline data providers tests (elastic#51862)
  [Dependencies]: upgrade react to latest v16.12.0 (elastic#51145)
  Allow routes to define some payload config values (elastic#50783)
  Move saved queries service + language switcher ⇒ NP (elastic#51812)
  [ML] Re-activate after method in transform test (elastic#51815)
  [SIEM] [Detection Engine] Add edit on rule creation (elastic#51670)
  De-angularize visLegend (elastic#50613)
  [SIEM][Detection Engine] Change security model to use SIEM permissions
  [Monitoring] Sass cleanup (elastic#51100)
  Move errors and validate index pattern ⇒ NP (elastic#51805)
  fixes pagination tests (elastic#51822)
  Split legacy plugin discovery, expose SavedObjects scopedClient, wrappers, repository (elastic#48882)
  [SIEM][Detection Engine] Adds ecs threat properties to rules (elastic#51782)
  [Lens] Remove client-side reference to server source code (elastic#51763)
  Fix infinite redirect loop when multiple cookies are sent (elastic#50452)
  fixes drag and drop in tests (elastic#51806)
  [Console] Proxy fallback (elastic#50185)
  ...
rudolf added a commit to rudolf/kibana that referenced this pull request Dec 2, 2019
…pers, repository (elastic#48882)

* Split legacy plugin discovery, expose internal SavedObjectsClient

* Expose internal SavedObjectsClient to plugins

* Add more documentation

* Expose client wrappers, repository, scoped client from SavedObjects

* Remove unused onBeforeWrite

* Refactor Service / Repository for testability

* Bind exposed clientProvider methods

* Fix eArchiver's KibanaMigrator

* Cleanup

* Use APICaller type

* Expose SavedObjectsServiceStart to plugins

* API documentation

* Rename API methods to be verbs
rudolf added a commit that referenced this pull request Dec 2, 2019
…pers, repository (#48882) (#51978)

* Split legacy plugin discovery, expose internal SavedObjectsClient

* Expose internal SavedObjectsClient to plugins

* Add more documentation

* Expose client wrappers, repository, scoped client from SavedObjects

* Remove unused onBeforeWrite

* Refactor Service / Repository for testability

* Bind exposed clientProvider methods

* Fix eArchiver's KibanaMigrator

* Cleanup

* Use APICaller type

* Expose SavedObjectsServiceStart to plugins

* API documentation

* Rename API methods to be verbs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.6.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants