kibana/src/plugin_discovery
Tiago Costa 45a67701f2
Upgrade to NodeJS 10 (#25157)
* feat(NA): upgrade node js version on file configs.

* chore(NA): migrate configs and 3rd party dependencies to work on node js 10.x

* fix(NA): add missing async function declaration.

* chore(NA): updated elastic/good package to work with node10

* chore(NA): update lockfiles.

* fix(NA): add missing dep.

* fix(NA): types for node 10.

* test(NA): fix error return type for node10.

* fix(NA): kbn-pm webpack config to unlazy a require using lazy-cache. fix(NA): build to work with node 10.

* test(NA): jest integration test for kbn-pluin-helpers.

* test(NA): fix jest tests for kbn-es.

* fix(NA): use ostmpdir instead of a tmp folder inside the fixtures.

* fix(NA): change afterEach on kbn es decompress test.

* fix(NA): change afterEach on kbn es decompress test.

* fix(NA): readd mock-fs for the tests that still use it on kbn-es and that works on node10.

* fix(NA): readd mock-fs for the tests that still use it on kbn-es and that works on node10.

* refact(NA): rewrite tests using mock-fs and completely remove this dependency.

* fix(NA): failing test implementation using jest mock in order to replace mock-fs.

* fix(NA): update jest snapshots to match new ones generated one node 10.

* fix(NA): cli/cluster mock to spyOn off method instead off spyOn removeListener as this was changed on Node 10.

* fix(NA): tests for cluster_manager to also spyOn off and on instead of addListener and removeListener

* test(NA): fix management advance settings image field test flow.

* fix(NA): apply missing types for src/core/server/plugins/discovery/plugins_discovery.ts.

* test(NA): updated 2 missing snapshots for KuiCodeEditor on kbn-ui-framework.

* refact(NA): fix eslint errors.

* refact(NA): fix ts code with tslint fix. chore(NA): update jest snapshots.

* chore(NA): migrate kbn config schema peer dependency to last used joi version to avoid warning on bootstrap.

* fix(NA): tslint errors.

* chore(NA): upgrade types node to the last version.

* fix(NA): missing utf8 input format encoding when reading a file.

* chore(NA): upgrade to node 10.14.1

* fix(NA): Buffer api usage to avoid deprecation warnings.
2018-12-10 17:41:51 +00:00
..
__tests__ Fix misspellings (#19981) 2018-06-26 20:17:41 -07:00
plugin_config [config] transform plugin deprecations before checking for unused settings (#21294) 2018-11-01 14:59:56 -05:00
plugin_exports Apache 2.0 license headers (#19383) 2018-05-28 20:06:30 -07:00
plugin_pack Introduce support for the server-side new platform plugins. (#25473) 2018-12-04 20:57:14 +01:00
plugin_spec Upgrade to NodeJS 10 (#25157) 2018-12-10 17:41:51 +00:00
errors.js Apache 2.0 license headers (#19383) 2018-05-28 20:06:30 -07:00
find_plugin_specs.js Make core logging independent from the legacy Kibana. (#21831) 2018-08-15 20:49:21 +02:00
index.js Apache 2.0 license headers (#19383) 2018-05-28 20:06:30 -07:00
README.md [common] fix paths. 2018-12-03 13:03:14 +01:00

Plugin Discovery

The plugin discovery module defines the core plugin loading logic used by the Kibana server. It exports functions for

findPluginSpecs(settings, [config])

Finds PluginSpec objects

params

  • settings: the same settings object accepted by KbnServer
  • [config]: Optional - a Config service. Using this param causes findPluginSpecs() to modify config's schema to support the configuration for each discovered PluginSpec. If you can, please use the Config service produced by extendedConfig$ rather than passing in an existing service so that findPluginSpecs() is side-effect free.

return value

findPluginSpecs() returns an object of Observables which produce values at different parts of the process. Since the Observables are all aware of their own dependencies you can subscribe to any combination (within the same tick) and only the necessary plugin logic will be executed.

If you never subscribe to any of the Observables then plugin discovery won't actually run.

  • pack$: emits every PluginPack found
  • invalidDirectoryError$: Observable<Error>: emits InvalidDirectoryErrors caused by settings.plugins.scanDirs values that don't point to actual directories. findPluginSpecs() will not abort when this error is encountered.
  • invalidPackError$: Observable<Error>: emits InvalidPackErrors caused by children of settings.plugins.scanDirs or settings.plugins.paths values which don't meet the requirements of a PluginPack (probably missing a package.json). findPluginSpecs() will not abort when this error is encountered.
  • deprecation$: Observable<string>: emits deprecation warnings that are produces when reading each PluginPack's configuration
  • extendedConfig$: Observable<Config>: emits the Config service that was passed to findPluginSpecs() (or created internally if none was passed) after it has been extended with the configuration from each plugin
  • spec$: Observable<PluginSpec>: emits every enabled PluginSpec defined by the discovered PluginPacks
  • disabledSpec$: Observable<PluginSpec>: emits every disabled PluginSpec defined by the discovered PluginPacks
  • invalidVersionSpec$: Observable<PluginSpec>: emits every PluginSpec who's required kibana version does not match the version exposed by config.get('pkg.version')

example

Just get the plugin specs, only fail if there is an uncaught error of some sort:

const { pack$ } = findPluginSpecs(settings);
const packs = await pack$.pipe(toArray()).toPromise()

Just log the deprecation messages:

const { deprecation$ } = findPluginSpecs(settings);
for (const warning of await deprecation$.pipe(toArray()).toPromise()) {
  console.log('DEPRECATION:', warning)
}

Get the packs but fail if any packs are invalid:

const { pack$, invalidDirectoryError$ } = findPluginSpecs(settings);
const packs = await Rx.merge(
  pack$.pipe(toArray()),

  // if we ever get an InvalidDirectoryError, throw it
  // into the stream so that all streams are unsubscribed,
  // the discovery process is aborted, and the promise rejects
  invalidDirectoryError$.pipe(
    map(error => { throw error })
  ),
).toPromise()

Handle everything

const {
  pack$,
  invalidDirectoryError$,
  invalidPackError$,
  deprecation$,
  extendedConfig$,
  spec$,
  disabledSpecs$,
  invalidVersionSpec$,
} = findPluginSpecs(settings);

Rx.merge(
  pack$.pipe(
    tap(pluginPack => console.log('Found plugin pack', pluginPack))
  ),

  invalidDirectoryError$.pipe(
    tap(error => console.log('Invalid directory error', error))
  ),

  invalidPackError$.pipe(
    tap(error => console.log('Invalid plugin pack error', error))
  ),

  deprecation$.pipe(
    tap(msg => console.log('DEPRECATION:', msg))
  ),

  extendedConfig$.pipe(
    tap(config => console.log('config service extended by plugins', config))
  ),

  spec$.pipe(
    tap(pluginSpec => console.log('enabled plugin spec found', spec))
  ),

  disabledSpec$.pipe(
    tap(pluginSpec => console.log('disabled plugin spec found', spec))
  ),

  invalidVersionSpec$.pipe(
    tap(pluginSpec => console.log('plugin spec with invalid version found', spec))
  ),
)
.toPromise()
.then(() => {
  console.log('plugin discovery complete')
})
.catch((error) => {
  console.log('plugin discovery failed', error)
})

reduceExportSpecs(pluginSpecs, reducers, [defaults={}])

Reduces every value exported by the PluginSpecs to produce a single value. If an exported value is an array each item in the array will be reduced individually. If the exported value is undefined it will be ignored. The reducer is called with the signature:

reducer(
  // the result of the previous reducer call, or `defaults`
  acc: any,
  // the exported value, found at `uiExports[type]` or `uiExports[type][i]`
  // in the PluginSpec config.
  spec: any,
  // the key in `uiExports` where this export was found
  type: string,
  // the PluginSpec which exported this spec
  pluginSpec: PluginSpec
)

new PluginPack(options) class

Only exported so that PluginPack instances can be created in tests and used in place of on-disk plugin fixtures. Use findPluginSpecs(), or the cached result of a call to findPluginSpecs() (like kbnServer.pluginSpecs) any time you might need access to PluginPack objects in distributed code.

params

  • options.path: absolute path to where this plugin pack was found, this is normally a direct child of ./src/legacy/core_plugins or ./plugins
  • options.pkg: the parsed package.json for this pack, used for defaults in PluginSpec objects defined by this pack
  • options.provider: the default export of the pack, a function which is called with the PluginSpec class which should return one or more PluginSpec objects.