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
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import sinon from 'sinon';
import expect from 'expect.js';

import { ensureAllowExplicitIndex } from '../ensure_allow_explicit_index';

const createStubCallWithInternal = responders => (
sinon.spy(async (params) => {
if (responders.length) {
return await responders.shift()(params);
}

throw new Error('Unexpected client.mget call');
})
);

const createStubConfig = () => ({
get: sinon.spy((key) => {
switch (key) {
case 'kibana.index': return '.kibana';
case 'pkg.version': return '0.0.0';
default: throw new Error(`Unexpected config.get('${key}') call`);
}
})
});

describe('ensureAllowExplicitIndex()', () => {
it('attempts an mget with index in request', async () => {
const config = createStubConfig();
const callWithInternalUser = createStubCallWithInternal([
() => ({ ok: true })
]);

const resp = await ensureAllowExplicitIndex(callWithInternalUser, config);
expect(resp).to.be(true);
});

it(`reports "illegal_argument_exception" that mentions "explicit index"`, async () => {
const config = createStubConfig();
const callWithInternalUser = createStubCallWithInternal([
() => ({
error: {
type: 'illegal_argument_exception',
reason: 'explicit index not supported'
}
})
]);

try {
await ensureAllowExplicitIndex(callWithInternalUser, config);
throw new Error('expected ensureAllowExplicitIndex() to throw error');
} catch (error) {
expect(error.message).to.contain('rest.action.multi.allow_explicit_index');
}
});

it('reports unexpected errors', async () => {
const config = createStubConfig();
const callWithInternalUser = createStubCallWithInternal([
() => ({
error: {
type: 'foo',
reason: 'bar'
}
})
]);

try {
await ensureAllowExplicitIndex(callWithInternalUser, config);
throw new Error('expected ensureAllowExplicitIndex() to throw error');
} catch (error) {
expect(error.message).to.contain('[foo]');
expect(error.message).to.contain('bar');
}
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('plugins/elasticsearch', () => {

cluster = { callWithInternalUser: sinon.stub() };
cluster.callWithInternalUser.withArgs('index', sinon.match.any).returns(Promise.resolve());
cluster.callWithInternalUser.withArgs('mget', sinon.match.any).returns(Promise.resolve({ ok: true }));
cluster.callWithInternalUser.withArgs('get', sinon.match.any).returns(Promise.resolve({ found: false }));
cluster.callWithInternalUser.withArgs('search', sinon.match.any).returns(Promise.resolve({ hits: { hits: [] } }));
cluster.callWithInternalUser.withArgs('nodes.info', sinon.match.any).returns(Promise.resolve({
Expand Down
36 changes: 36 additions & 0 deletions src/core_plugins/elasticsearch/lib/ensure_allow_explicit_index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export async function ensureAllowExplicitIndex(callWithInternalUser, config) {
const resp = await callWithInternalUser('mget', {
ignore: [400],
body: {
docs: [
{
_index: config.get('kibana.index'),
_type: 'config',
_id: config.get('pkg.version'),
},
],
},
});

if (!resp.error) {
return true;
}

const error = resp.error || {};
const errorReason = error.reason || '';

const isArgError = error.type === 'illegal_argument_exception';
const isExplicitIndexException = isArgError && errorReason.includes('explicit index');

if (isExplicitIndexException) {
throw new Error(
'Kibana must be able to specify the index within Elasticsearch multi-requests ' +
'(rest.action.multi.allow_explicit_index=true).'
);
}

throw new Error(
'Unable to ensure that rest.action.multi.allow_explicit_index=true: ' +
`[${error.type}] ${errorReason}`
);
}
4 changes: 3 additions & 1 deletion src/core_plugins/elasticsearch/lib/health_check.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import createKibanaIndex from './create_kibana_index';
import kibanaVersion from './kibana_version';
import { ensureEsVersion } from './ensure_es_version';
import { ensureNotTribe } from './ensure_not_tribe';
import { ensureAllowExplicitIndex } from './ensure_allow_explicit_index';

const NoConnections = elasticsearch.errors.NoConnections;
import util from 'util';
Expand Down Expand Up @@ -94,7 +95,8 @@ module.exports = function (plugin, server) {
const healthCheck =
waitForPong(callAdminAsKibanaUser, config.get('elasticsearch.url'))
.then(waitForEsVersion)
.then(ensureNotTribe.bind(this, callAdminAsKibanaUser))
.then(() => ensureNotTribe(callAdminAsKibanaUser))
.then(() => ensureAllowExplicitIndex(callAdminAsKibanaUser, config))
.then(waitForShards)
.then(_.partial(migrateConfig, server))
.then(() => {
Expand Down