diff --git a/src/kibana/components/notify/_notifier.js b/src/kibana/components/notify/_notifier.js index 58a4af812ad010..4f49699d0aefaa 100644 --- a/src/kibana/components/notify/_notifier.js +++ b/src/kibana/components/notify/_notifier.js @@ -141,10 +141,16 @@ define(function (require) { */ Notifier.prototype.timed = function (name, fn) { var self = this; + + if (typeof name === 'function') { + fn = name; + name = fn.name; + } + return function WrappedNotifierFunction() { var cntx = this; var args = arguments; - + return self.event(name, function () { return fn.apply(cntx, args); }); diff --git a/src/kibana/components/setup/steps/check_es_version.js b/src/kibana/components/setup/steps/check_es_version.js index f7350bcc4595ac..54534043d4c69d 100644 --- a/src/kibana/components/setup/steps/check_es_version.js +++ b/src/kibana/components/setup/steps/check_es_version.js @@ -1,33 +1,43 @@ define(function (require) { - var _ = require('lodash'); - var versionmath = require('utils/versionmath'); return function CheckEsVersionFn(Private, es, configFile, Notifier, minimumElasticsearchVersion) { - return function checkEsVersion() { - var notify = new Notifier({ location: 'Setup: Elasticsearch version check' }); - var complete = notify.lifecycle('check es version'); + var _ = require('lodash'); + var versionmath = require('utils/versionmath'); + var esBool = require('utils/esBool'); + var notify = new Notifier({ + location: 'Setup: Elasticsearch version check' + }); + + return notify.timed(function checkEsVersion() { var SetupError = Private(require('components/setup/_setup_error')); return es.nodes.info() .then(function (info) { - var versions = _.map(info.nodes, function (v) { - // Remove everything after the -, we don't handle beta/rc ES versions - return v.version.split('-')[0]; + var badNodes = _.filter(info.nodes, function (node) { + // remove client nodes (Logstash) + var isClient = _.get(node, 'attributes.client'); + if (isClient != null && esBool(isClient) === true) { + return false; + } + + // remove nodes that are gte the min version + var v = node.version.split('-')[0]; + return !versionmath.gte(minimumElasticsearchVersion, v); + }); + + if (!badNodes.length) return true; + + var badNodeNames = badNodes.map(function (node) { + return 'Elasticsearch v' + node.version + ' @ ' + node.http_address + ' (' + node.ip + ')'; }); - if (versionmath.is('>=' + minimumElasticsearchVersion, versions)) { - return true; - } - else { - var badNodes = _.map(info.nodes, function (v) { - if (versionmath.is('<' + minimumElasticsearchVersion, [v.version.split('-')[0]])) { - return 'Elasticsearch ' + v.version + ' @ ' + v.transport_address + ' (' + v.ip + ')'; - } - }); - throw SetupError('This version of Kibana requires Elasticsearch ' + minimumElasticsearchVersion + ' or higher on all nodes. ' + - 'I found the following incompatible nodes in your cluster: \n\n' + badNodes.join('\n')); - } - }) - .then(complete, complete.failure); - }; + + throw SetupError( + 'This version of Kibana requires Elasticsearch ' + + minimumElasticsearchVersion + ' or higher on all nodes. ' + + 'I found the following incompatible nodes in your cluster: \n\n' + + badNodeNames.join('\n') + ); + }); + }); }; }); \ No newline at end of file diff --git a/src/kibana/utils/esBool.js b/src/kibana/utils/esBool.js new file mode 100644 index 00000000000000..3a769e0ca1b0de --- /dev/null +++ b/src/kibana/utils/esBool.js @@ -0,0 +1,22 @@ +define(function () { + var map = { + 'false': false, + 'off': false, + 'no': false, + '0': false, + 'true': true, + 'on': true, + 'yes': true, + '1': true + }; + + return function (str) { + var bool = map[String(str)]; + + if (typeof bool !== 'boolean') { + throw new TypeError('"' + str + '" does not map to an esBool'); + } + + return bool; + }; +}); \ No newline at end of file diff --git a/src/kibana/utils/versionmath.js b/src/kibana/utils/versionmath.js index 2643a7160d3af4..a69c89ba5581f3 100644 --- a/src/kibana/utils/versionmath.js +++ b/src/kibana/utils/versionmath.js @@ -18,6 +18,8 @@ define(function (require) { // Sort versions from lowest to highest var sortVersions = function (versions) { + if (!_.isArray(versions)) versions = [versions]; + return _.uniq(versions).sort(function (a, b) { return compare(a, b) ? -1 : 1; }); diff --git a/test/unit/specs/components/setup/check_es_version.js b/test/unit/specs/components/setup/check_es_version.js new file mode 100644 index 00000000000000..aed1457c199025 --- /dev/null +++ b/test/unit/specs/components/setup/check_es_version.js @@ -0,0 +1,75 @@ +define(function (require) { + describe('Setup: Check ES Version', function () { + var _ = require('lodash'); + var sinon = require('test_utils/auto_release_sinon'); + require('test_utils/no_digest_promises').activateForSuite(); + + var checkEsVersion; + var es; + var Promise; + + beforeEach(module('kibana', function ($provide) { + // hard coded to prevent failures when we bump the version + $provide.constant('minimumElasticsearchVersion', '1.4.3'); + })); + + beforeEach(inject(function (Private, $injector) { + checkEsVersion = Private(require('components/setup/steps/check_es_version')); + es = $injector.get('es'); + Promise = $injector.get('Promise'); + })); + + function setNodes(/* ...versions */) { + var versions = _.shuffle(arguments); + var nodes = {}; + var i = 0; + + while (versions.length) { + var name = 'node-' + (++i); + var version = versions.shift(); + + var node = { + version: version, + http_address: 'http_address', + ip: 'ip' + }; + + if (!_.isString(version)) _.assign(node, version); + nodes[name] = node; + } + + sinon.stub(es.nodes, 'info').returns(Promise.resolve({ + nodes: nodes + })); + } + + it('passes with single a node that matches', function () { + setNodes('1.4.3'); + return checkEsVersion(); + }); + + it('passes with multiple nodes that satisfy', function () { + setNodes('1.4.3', '1.4.4', '1.4.3-Beta1'); + return checkEsVersion(); + }); + + it('fails with a single node that is out of date', function () { + setNodes('1.4.4', '1.4.2', '1.4.5'); + return checkEsVersion() + .then(function () { + throw new Error('expected validation to fail'); + }, _.noop); + }); + + it('passes if that single node is a client node', function () { + setNodes( + '1.4.4', + { version: '1.4.2', attributes: { client: 'true' } }, + '1.4.5' + ); + + return checkEsVersion(); + }); + + }); +}); \ No newline at end of file