From 492b43e9c4b1db5d97dc982e491f66677b61ce7e Mon Sep 17 00:00:00 2001 From: Elastic Jasper Date: Mon, 19 Sep 2016 13:46:26 -0400 Subject: [PATCH] Backport PR #8283 --------- **Commit 1:** fixes plugin path in .gitignore * Original sha: f74eb9b4cbf740557459fcbaef092268a69ed39f * Authored by Jim Unger on 2016-09-14T18:40:21Z **Commit 2:** Moves version from plugin installer to utils * Original sha: ae492ff0667ed0d8d2ab5f89aaf2113c834d56db * Authored by Jim Unger on 2016-09-14T18:41:19Z **Commit 3:** Adds plugin version check to kibana startup * Original sha: 83d082105430f1b5d8cab8e69582f1b5d7d38b51 * Authored by Jim Unger on 2016-09-14T18:41:40Z **Commit 4:** Changes plugin version to 'kibana' in text fixture * Original sha: 922c04abe65dea7ff362ae4fadbbf45327adb030 * Authored by Jim Unger on 2016-09-14T19:07:09Z **Commit 5:** Merge branch 'master' into check-plugin-version-on-startup * Original sha: 5da33adfdbe73f310a0942dc836d7747e8894e11 * Authored by Jim Unger on 2016-09-15T14:45:01Z **Commit 6:** review changes to check_version * Original sha: 28024105734ab4cf175a7009f8fe26fda34e801b * Authored by Jim Unger on 2016-09-15T16:53:28Z **Commit 7:** reworked logic to remove config when deleting a plugin from plugin_collection * Original sha: 2f52be62ae2f574d36be9aa4d94bf1260c2ba415 * Authored by Jim Unger on 2016-09-15T20:11:43Z **Commit 8:** Adds a kibanaVersion property to the Plugin class * Original sha: e920bca051b51ffc0245ebe2e6427309a080285a * Authored by Jim Unger on 2016-09-15T21:04:41Z **Commit 9:** move enabled check into it's own mixin, and cleaned up how you disable a plugin * Original sha: 049c0297643817eb0804701c71e9cc3832241fb2 * Authored by Jim Unger on 2016-09-16T17:22:47Z --- .gitignore | 2 +- src/cli_plugin/install/kibana.js | 2 +- src/server/kbn_server.js | 6 ++++ src/server/plugins/check_enabled.js | 15 ++++++++ src/server/plugins/check_version.js | 36 +++++++++++++++++++ src/server/plugins/plugin.js | 23 ++++++------ src/server/plugins/plugin_collection.js | 32 +++++++++++------ .../fixtures/plugin_async_foo/package.json | 2 +- .../fixtures/plugin_bar/package.json | 2 +- .../fixtures/plugin_foo/package.json | 2 +- src/{cli_plugin/install => utils}/version.js | 0 11 files changed, 94 insertions(+), 28 deletions(-) create mode 100644 src/server/plugins/check_enabled.js create mode 100644 src/server/plugins/check_version.js rename src/{cli_plugin/install => utils}/version.js (100%) diff --git a/.gitignore b/.gitignore index 73948dcb6c9da..67ff94557672f 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ target /esvm .htpasswd .eslintcache -plugins +/plugins/ data disabledPlugins webpackstats.json diff --git a/src/cli_plugin/install/kibana.js b/src/cli_plugin/install/kibana.js index 86992fadf7a10..53e21d891f3ea 100644 --- a/src/cli_plugin/install/kibana.js +++ b/src/cli_plugin/install/kibana.js @@ -2,7 +2,7 @@ import _ from 'lodash'; import { fromRoot } from '../../utils'; import KbnServer from '../../server/kbn_server'; import readYamlConfig from '../../cli/serve/read_yaml_config'; -import { versionSatisfies, cleanVersion } from './version'; +import { versionSatisfies, cleanVersion } from '../../utils/version'; import { statSync } from 'fs'; export function existingInstall(settings, logger) { diff --git a/src/server/kbn_server.js b/src/server/kbn_server.js index 8ad9d9c0709d8..bcadf43b6bd39 100644 --- a/src/server/kbn_server.js +++ b/src/server/kbn_server.js @@ -28,6 +28,12 @@ module.exports = class KbnServer { // find plugins and set this.plugins require('./plugins/scan'), + // disable the plugins that are disabled through configuration + require('./plugins/check_enabled'), + + // disable the plugins that are incompatible with the current version of Kibana + require('./plugins/check_version'), + // tell the config we are done loading plugins require('./config/complete'), diff --git a/src/server/plugins/check_enabled.js b/src/server/plugins/check_enabled.js new file mode 100644 index 0000000000000..7953165d88007 --- /dev/null +++ b/src/server/plugins/check_enabled.js @@ -0,0 +1,15 @@ +import toPath from 'lodash/internal/toPath'; + +export default async function (kbnServer, server, config) { + const { plugins } = kbnServer; + + for (let plugin of plugins) { + const enabledInConfig = config.get([...toPath(plugin.configPrefix), 'enabled']); + + if (!enabledInConfig) { + plugins.disable(plugin); + } + } + + return; +}; diff --git a/src/server/plugins/check_version.js b/src/server/plugins/check_version.js new file mode 100644 index 0000000000000..bb50b8daac06f --- /dev/null +++ b/src/server/plugins/check_version.js @@ -0,0 +1,36 @@ +import { cleanVersion, versionSatisfies } from '../../utils/version'; +import { get } from 'lodash'; + +function compatibleWithKibana(kbnServer, plugin) { + //core plugins have a version of 'kibana' and are always compatible + if (plugin.kibanaVersion === 'kibana') return true; + + const pluginKibanaVersion = cleanVersion(plugin.kibanaVersion); + const kibanaVersion = cleanVersion(kbnServer.version); + + return versionSatisfies(pluginKibanaVersion, kibanaVersion); +} + +export default async function (kbnServer, server, config) { + //because a plugin pack can contain more than one actual plugin, (for example x-pack) + //we make sure that the warning messages are unique + const warningMessages = new Set(); + const plugins = kbnServer.plugins; + + for (let plugin of plugins) { + const version = plugin.kibanaVersion; + const name = get(plugin, 'pkg.name'); + + if (!compatibleWithKibana(kbnServer, plugin)) { + const message = `Plugin "${name}" was disabled because it expected Kibana version "${version}", and found "${kbnServer.version}".`; + warningMessages.add(message); + plugins.disable(plugin); + } + } + + for (let message of warningMessages) { + server.log(['warning'], message); + } + + return; +}; diff --git a/src/server/plugins/plugin.js b/src/server/plugins/plugin.js index bd44048bd1ad3..976cf41e3b216 100644 --- a/src/server/plugins/plugin.js +++ b/src/server/plugins/plugin.js @@ -1,5 +1,4 @@ import _ from 'lodash'; -import toPath from 'lodash/internal/toPath'; import Joi from 'joi'; import Bluebird, { attempt, fromNode } from 'bluebird'; import { basename, resolve } from 'path'; @@ -59,10 +58,16 @@ module.exports = class Plugin { this.uiExportsSpecs = opts.uiExports || {}; this.requiredIds = opts.require || []; this.version = opts.version || pkg.version; + + // Plugins must specify their version, and by default that version should match + // the version of kibana down to the patch level. If these two versions need + // to diverge, they can specify a kibana.version in the package to indicate the + // version of kibana the plugin is intended to work with. + this.kibanaVersion = opts.kibanaVersion || _.get(pkg, 'kibana.version', this.version); this.externalPreInit = opts.preInit || _.noop; this.externalInit = opts.init || _.noop; this.configPrefix = opts.configPrefix || this.id; - this.getConfigSchema = opts.config || _.noop; + this.getExternalConfigSchema = opts.config || _.noop; this.preInit = _.once(this.preInit); this.init = _.once(this.init); this[extendInitFns] = []; @@ -89,17 +94,9 @@ module.exports = class Plugin { }; } - async readConfig() { - let schema = await this.getConfigSchema(Joi); - let { config } = this.kbnServer; - config.extendSchema(this.configPrefix, schema || defaultConfigSchema); - - if (config.get([...toPath(this.configPrefix), 'enabled'])) { - return true; - } else { - config.removeSchema(this.configPrefix); - return false; - } + async getConfigSchema() { + let schema = await this.getExternalConfigSchema(Joi); + return schema || defaultConfigSchema; } async preInit() { diff --git a/src/server/plugins/plugin_collection.js b/src/server/plugins/plugin_collection.js index 6019fd3baf60b..62fdd3e90d786 100644 --- a/src/server/plugins/plugin_collection.js +++ b/src/server/plugins/plugin_collection.js @@ -2,11 +2,23 @@ import PluginApi from './plugin_api'; import { inspect } from 'util'; import { get, indexBy } from 'lodash'; +import toPath from 'lodash/internal/toPath'; import Collection from '../../utils/collection'; let byIdCache = Symbol('byIdCache'); let pluginApis = Symbol('pluginApis'); +async function addPluginConfig(pluginCollection, plugin) { + const configSchema = await plugin.getConfigSchema(); + let { config } = pluginCollection.kbnServer; + config.extendSchema(plugin.configPrefix, configSchema); +} + +function removePluginConfig(pluginCollection, plugin) { + let { config } = pluginCollection.kbnServer; + config.removeSchema(plugin.configPrefix); +} + module.exports = class Plugins extends Collection { constructor(kbnServer) { @@ -27,21 +39,21 @@ module.exports = class Plugins extends Collection { // clear the byIdCache this[byIdCache] = null; - for (let product of output) { - - if (product instanceof api.Plugin) { - let plugin = product; - this.add(plugin); - - let enabled = await plugin.readConfig(); - if (!enabled) this.delete(plugin); - continue; + for (let plugin of output) { + if (!plugin instanceof api.Plugin) { + throw new TypeError('unexpected plugin export ' + inspect(plugin)); } - throw new TypeError('unexpected plugin export ' + inspect(product)); + await addPluginConfig(this, plugin); + this.add(plugin); } } + async disable(plugin) { + removePluginConfig(this, plugin); + this.delete(plugin); + } + get byId() { return this[byIdCache] || (this[byIdCache] = indexBy([...this], 'id')); } diff --git a/src/ui/__tests__/fixtures/plugin_async_foo/package.json b/src/ui/__tests__/fixtures/plugin_async_foo/package.json index 4ad7dda995ca5..fc1c8d8088f1b 100644 --- a/src/ui/__tests__/fixtures/plugin_async_foo/package.json +++ b/src/ui/__tests__/fixtures/plugin_async_foo/package.json @@ -1,4 +1,4 @@ { "name": "plugin_async_foo", - "version": "0.0.0" + "version": "kibana" } diff --git a/src/ui/__tests__/fixtures/plugin_bar/package.json b/src/ui/__tests__/fixtures/plugin_bar/package.json index bfc5da0182266..f79b807990dca 100644 --- a/src/ui/__tests__/fixtures/plugin_bar/package.json +++ b/src/ui/__tests__/fixtures/plugin_bar/package.json @@ -1,4 +1,4 @@ { "name": "plugin_bar", - "version": "0.0.0" + "version": "kibana" } diff --git a/src/ui/__tests__/fixtures/plugin_foo/package.json b/src/ui/__tests__/fixtures/plugin_foo/package.json index 6a73b89110ae9..c1b7ddd35c9a2 100644 --- a/src/ui/__tests__/fixtures/plugin_foo/package.json +++ b/src/ui/__tests__/fixtures/plugin_foo/package.json @@ -1,4 +1,4 @@ { "name": "plugin_foo", - "version": "0.0.0" + "version": "kibana" } diff --git a/src/cli_plugin/install/version.js b/src/utils/version.js similarity index 100% rename from src/cli_plugin/install/version.js rename to src/utils/version.js