Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport 5.x - ES Healthcheck v6 mapping compatibility (#12714) #12737

Merged
merged 1 commit into from
Jul 11, 2017
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: 2 additions & 0 deletions src/core_plugins/elasticsearch/lib/__tests__/health_check.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe('plugins/elasticsearch', () => {

cluster = { callWithInternalUser: sinon.stub() };
cluster.callWithInternalUser.withArgs('index', sinon.match.any).returns(Promise.resolve());
cluster.callWithInternalUser.withArgs('create', sinon.match.any).returns(Promise.resolve({ _id: 1, _version: 1 }));
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: [] } }));
Expand All @@ -61,6 +62,7 @@ describe('plugins/elasticsearch', () => {
const get = sinon.stub();
get.withArgs('elasticsearch.url').returns(esUrl);
get.withArgs('kibana.index').returns('.my-kibana');
get.withArgs('pkg.version').returns('1.0.0');

const set = sinon.stub();

Expand Down
32 changes: 14 additions & 18 deletions src/core_plugins/elasticsearch/lib/__tests__/is_upgradeable.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ describe('plugins/elasticsearch', function () {
})
};

function upgradeDoc(_id, _version, bool) {
function upgradeDoc(id, _version, bool) {
describe('', function () {
before(function () { version = _version; });

it(`should return ${bool} for ${_id} <= ${version}`, function () {
expect(isUpgradeable(server, { _id: _id })).to.be(bool);
it(`should return ${bool} for ${id} <= ${version}`, function () {
expect(isUpgradeable(server, { id: id })).to.be(bool);
});

after(function () { version = pkg.version; });
Expand All @@ -42,32 +42,28 @@ describe('plugins/elasticsearch', function () {
upgradeDoc('4.1.0-rc1-SNAPSHOT', '4.1.0-rc1', false);
upgradeDoc('5.0.0-alpha1', '5.0.0', false);

it('should handle missing _id field', function () {
const doc = {
'_index': '.kibana',
'_type': 'config',
'_score': 1,
'_source': {
it('should handle missing id field', function () {
const configSavedObject = {
'type': 'config',
'attributes': {
'buildNum': 1.7976931348623157e+308,
'defaultIndex': '[logstash-]YYYY.MM.DD'
}
};

expect(isUpgradeable(server, doc)).to.be(false);
expect(isUpgradeable(server, configSavedObject)).to.be(false);
});

it('should handle _id of @@version', function () {
const doc = {
'_index': '.kibana',
'_type': 'config',
'_id': '@@version',
'_score': 1,
'_source': {
it('should handle id of @@version', function () {
const configSavedObject = {
'type': 'config',
'id': '@@version',
'attributes': {
'buildNum': 1.7976931348623157e+308,
'defaultIndex': '[logstash-]YYYY.MM.DD'
}
};
expect(isUpgradeable(server, doc)).to.be(false);
expect(isUpgradeable(server, configSavedObject)).to.be(false);
});

});
Expand Down
114 changes: 54 additions & 60 deletions src/core_plugins/elasticsearch/lib/__tests__/upgrade_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe('plugins/elasticsearch', function () {
describe('lib/upgrade_config', function () {
let get;
let server;
let callWithInternalUser;
let savedObjectsClient;
let upgrade;

beforeEach(function () {
Expand All @@ -17,7 +17,9 @@ describe('plugins/elasticsearch', function () {
get.withArgs('pkg.version').returns('4.0.1');
get.withArgs('pkg.buildNum').returns(Math.random());

callWithInternalUser = sinon.stub();
savedObjectsClient = {
create: sinon.stub()
};

server = {
log: sinon.stub(),
Expand All @@ -26,22 +28,15 @@ describe('plugins/elasticsearch', function () {
get: get
};
},
plugins: {
elasticsearch: {
getCluster: sinon.stub().withArgs('admin').returns({
callWithInternalUser: callWithInternalUser
})
}
}
};
upgrade = upgradeConfig(server);
upgrade = upgradeConfig(server, savedObjectsClient);
});

describe('nothing is found', function () {
const response = { hits: { hits:[] } };
const configSavedObjects = { hits: { hits:[] } };

beforeEach(function () {
callWithInternalUser.withArgs('create', sinon.match.any).returns(Promise.resolve());
savedObjectsClient.create.returns(Promise.resolve({ id: 1, version: 1 }));
});

describe('production', function () {
Expand All @@ -52,17 +47,17 @@ describe('plugins/elasticsearch', function () {
});

it('should resolve buildNum to pkg.buildNum config', function () {
return upgrade(response).then(function () {
sinon.assert.calledOnce(callWithInternalUser);
const params = callWithInternalUser.args[0][1];
expect(params.body).to.have.property('buildNum', get('pkg.buildNum'));
return upgrade(configSavedObjects).then(function () {
sinon.assert.calledOnce(savedObjectsClient.create);
const attributes = savedObjectsClient.create.args[0][1];
expect(attributes).to.have.property('buildNum', get('pkg.buildNum'));
});
});

it('should resolve version to pkg.version config', function () {
return upgrade(response).then(function () {
const params = callWithInternalUser.args[0][1];
expect(params).to.have.property('id', get('pkg.version'));
return upgrade(configSavedObjects).then(function () {
const options = savedObjectsClient.create.args[0][2];
expect(options).to.have.property('id', get('pkg.version'));
});
});
});
Expand All @@ -75,68 +70,68 @@ describe('plugins/elasticsearch', function () {
});

it('should resolve buildNum to pkg.buildNum config', function () {
return upgrade(response).then(function () {
const params = callWithInternalUser.args[0][1];
expect(params.body).to.have.property('buildNum', get('pkg.buildNum'));
return upgrade(configSavedObjects).then(function () {
const attributes = savedObjectsClient.create.args[0][1];
expect(attributes).to.have.property('buildNum', get('pkg.buildNum'));
});
});

it('should resolve version to pkg.version config', function () {
return upgrade(response).then(function () {
const params = callWithInternalUser.args[0][1];
expect(params).to.have.property('id', get('pkg.version'));
return upgrade(configSavedObjects).then(function () {
const options = savedObjectsClient.create.args[0][2];
expect(options).to.have.property('id', get('pkg.version'));
});
});
});
});

it('should resolve with undefined if the current version is found', function () {
const response = { hits: { hits: [ { _id: '4.0.1' } ] } };
return upgrade(response).then(function (resp) {
const configSavedObjects = [ { id: '4.0.1' } ];
return upgrade(configSavedObjects).then(function (resp) {
expect(resp).to.be(undefined);
});
});

it('should create new config if the nothing is upgradeable', function () {
get.withArgs('pkg.buildNum').returns(9833);
callWithInternalUser.withArgs('create', sinon.match.any).returns(Promise.resolve());

const response = { hits: { hits: [ { _id: '4.0.1-alpha3' }, { _id: '4.0.1-beta1' }, { _id: '4.0.0-SNAPSHOT1' } ] } };
return upgrade(response).then(function () {
sinon.assert.calledOnce(callWithInternalUser);
const params = callWithInternalUser.args[0][1];
expect(params).to.have.property('body');
expect(params.body).to.have.property('buildNum', 9833);
expect(params).to.have.property('index', '.my-kibana');
expect(params).to.have.property('type', 'config');
expect(params).to.have.property('id', '4.0.1');
savedObjectsClient.create.returns(Promise.resolve({ id: 1, version: 1 }));

const configSavedObjects = [ { id: '4.0.1-alpha3' }, { id: '4.0.1-beta1' }, { id: '4.0.0-SNAPSHOT1' } ];
return upgrade(configSavedObjects).then(function () {
sinon.assert.calledOnce(savedObjectsClient.create);
const savedObjectType = savedObjectsClient.create.args[0][0];
expect(savedObjectType).to.eql('config');
const attributes = savedObjectsClient.create.args[0][1];
expect(attributes).to.have.property('buildNum', 9833);
const options = savedObjectsClient.create.args[0][2];
expect(options).to.have.property('id', '4.0.1');
});
});

it('should update the build number on the new config', function () {
get.withArgs('pkg.buildNum').returns(5801);
callWithInternalUser.withArgs('create', sinon.match.any).returns(Promise.resolve());

const response = { hits: { hits: [ { _id: '4.0.0', _source: { buildNum: 1 } } ] } };

return upgrade(response).then(function () {
sinon.assert.calledOnce(callWithInternalUser);
const params = callWithInternalUser.args[0][1];
expect(params).to.have.property('body');
expect(params.body).to.have.property('buildNum', 5801);
expect(params).to.have.property('index', '.my-kibana');
expect(params).to.have.property('type', 'config');
expect(params).to.have.property('id', '4.0.1');
savedObjectsClient.create.returns(Promise.resolve({ id: 1, version: 1 }));

const configSavedObjects = [ { id: '4.0.0', attributes: { buildNum: 1 } } ];

return upgrade(configSavedObjects).then(function () {
sinon.assert.calledOnce(savedObjectsClient.create);
const attributes = savedObjectsClient.create.args[0][1];
expect(attributes).to.have.property('buildNum', 5801);
const savedObjectType = savedObjectsClient.create.args[0][0];
expect(savedObjectType).to.eql('config');
const options = savedObjectsClient.create.args[0][2];
expect(options).to.have.property('id', '4.0.1');
});
});

it('should log a message for upgrades', function () {
get.withArgs('pkg.buildNum').returns(5801);
callWithInternalUser.withArgs('create', sinon.match.any).returns(Promise.resolve());
savedObjectsClient.create.returns(Promise.resolve({ id: 1, version: 1 }));

const response = { hits: { hits: [ { _id: '4.0.0', _source: { buildNum: 1 } } ] } };
const configSavedObjects = [ { id: '4.0.0', attributes: { buildNum: 1 } } ];

return upgrade(response).then(function () {
return upgrade(configSavedObjects).then(function () {
sinon.assert.calledOnce(server.log);
expect(server.log.args[0][0]).to.eql(['plugin', 'elasticsearch']);
const msg = server.log.args[0][1];
Expand All @@ -148,15 +143,14 @@ describe('plugins/elasticsearch', function () {

it('should copy attributes from old config', function () {
get.withArgs('pkg.buildNum').returns(5801);
callWithInternalUser.withArgs('create', sinon.match.any).returns(Promise.resolve());
savedObjectsClient.create.returns(Promise.resolve({ id: 1, version: 1 }));

const response = { hits: { hits: [ { _id: '4.0.0', _source: { buildNum: 1, defaultIndex: 'logstash-*' } } ] } };
const configSavedObjects = [ { id: '4.0.0', attributes: { buildNum: 1, defaultIndex: 'logstash-*' } } ];

return upgrade(response).then(function () {
sinon.assert.calledOnce(callWithInternalUser);
const params = callWithInternalUser.args[0][1];
expect(params).to.have.property('body');
expect(params.body).to.have.property('defaultIndex', 'logstash-*');
return upgrade(configSavedObjects).then(function () {
sinon.assert.calledOnce(savedObjectsClient.create);
const attributes = savedObjectsClient.create.args[0][1];
expect(attributes).to.have.property('defaultIndex', 'logstash-*');
});
});
});
Expand Down
14 changes: 7 additions & 7 deletions src/core_plugins/elasticsearch/lib/is_upgradeable.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import semver from 'semver';
const rcVersionRegex = /(\d+\.\d+\.\d+)\-rc(\d+)/i;

module.exports = function (server, doc) {
export default function (server, configSavedObject) {
const config = server.config();
if (/alpha|beta|snapshot/i.test(doc._id)) return false;
if (!doc._id) return false;
if (doc._id === config.get('pkg.version')) return false;
if (/alpha|beta|snapshot/i.test(configSavedObject.id)) return false;
if (!configSavedObject.id) return false;
if (configSavedObject.id === config.get('pkg.version')) return false;

let packageRcRelease = Infinity;
let rcRelease = Infinity;
let packageVersion = config.get('pkg.version');
let version = doc._id;
const matches = doc._id.match(rcVersionRegex);
let version = configSavedObject.id;
const matches = configSavedObject.id.match(rcVersionRegex);
const packageMatches = config.get('pkg.version').match(rcVersionRegex);

if (matches) {
Expand All @@ -30,4 +30,4 @@ module.exports = function (server, doc) {
return false;
}
return true;
};
}
30 changes: 12 additions & 18 deletions src/core_plugins/elasticsearch/lib/migrate_config.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import { get } from 'lodash';
import upgrade from './upgrade_config';
import { SavedObjectsClient } from '../../../server/saved_objects';

module.exports = function (server, { mappings }) {
export default async function (server, { mappings }) {
const config = server.config();
const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin');
const options = {
index: config.get('kibana.index'),

const savedObjectsClient = new SavedObjectsClient(config.get('kibana.index'), mappings, callWithInternalUser);
const { saved_objects: configSavedObjects } = await savedObjectsClient.find({
type: 'config',
body: {
size: 1000,
sort: [
{
buildNum: {
order: 'desc',
unmapped_type: get(mappings, 'config.properties.buildNum.type') || 'keyword'
}
}
]
}
};
page: 1,
perPage: 1000,
sortField: 'buildNum',
sortOrder: 'desc'
});

return callWithInternalUser('search', options).then(upgrade(server));
};
return await upgrade(server, savedObjectsClient)(configSavedObjects);
}
Loading