Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ target
/esvm
.htpasswd
.eslintcache
plugins
/plugins/
data
disabledPlugins
webpackstats.json
Expand Down
2 changes: 1 addition & 1 deletion src/cli_plugin/install/kibana.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 6 additions & 0 deletions src/server/kbn_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'),

Expand Down
15 changes: 15 additions & 0 deletions src/server/plugins/check_enabled.js
Original file line number Diff line number Diff line change
@@ -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;
};
36 changes: 36 additions & 0 deletions src/server/plugins/check_version.js
Original file line number Diff line number Diff line change
@@ -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;
};
23 changes: 10 additions & 13 deletions src/server/plugins/plugin.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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] = [];
Expand All @@ -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() {
Expand Down
32 changes: 22 additions & 10 deletions src/server/plugins/plugin_collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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'));
}
Expand Down
2 changes: 1 addition & 1 deletion src/ui/__tests__/fixtures/plugin_async_foo/package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"name": "plugin_async_foo",
"version": "0.0.0"
"version": "kibana"
}
2 changes: 1 addition & 1 deletion src/ui/__tests__/fixtures/plugin_bar/package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"name": "plugin_bar",
"version": "0.0.0"
"version": "kibana"
}
2 changes: 1 addition & 1 deletion src/ui/__tests__/fixtures/plugin_foo/package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"name": "plugin_foo",
"version": "0.0.0"
"version": "kibana"
}
File renamed without changes.