Merge pull request #8334 from elastic/jasper/backport/8283/5.0

[backport] PR #8283 to 5.0
This commit is contained in:
Jim Unger 2016-09-19 12:54:00 -05:00 committed by GitHub
commit c4f6c2d17d
11 changed files with 94 additions and 28 deletions

2
.gitignore vendored
View file

@ -21,7 +21,7 @@ target
/esvm
.htpasswd
.eslintcache
plugins
/plugins/
data
disabledPlugins
webpackstats.json

View file

@ -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) {

View file

@ -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'),

View file

@ -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;
};

View file

@ -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;
};

View file

@ -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() {

View file

@ -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'));
}

View file

@ -1,4 +1,4 @@
{
"name": "plugin_async_foo",
"version": "0.0.0"
"version": "kibana"
}

View file

@ -1,4 +1,4 @@
{
"name": "plugin_bar",
"version": "0.0.0"
"version": "kibana"
}

View file

@ -1,4 +1,4 @@
{
"name": "plugin_foo",
"version": "0.0.0"
"version": "kibana"
}