Skip to content

Commit

Permalink
[Ingest Manager] Fix for comparing versions with -SNAPSHOT suffix (#8…
Browse files Browse the repository at this point in the history
…0742) (#80911)

* remove -SNAPSHOT from kibana version

* add integration tests with -SNAPSHOT version of kibana

* update isAgentUpgradeable to compare version numbers only

* continue to send the kibana version with snapshot suffix to agent

* cleanup code into one function

* fix test to check for snapshot before adding suffix
  • Loading branch information
neptunian authored Oct 16, 2020
1 parent 727b625 commit 39d668c
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,35 @@ describe('Ingest Manager - isAgentUpgradeable', () => {
true
);
});
it('returns false if agent reports upgradeable, with agent snapshot version === kibana version', () => {
expect(
isAgentUpgradeable(getAgent({ version: '7.9.0-SNAPSHOT', upgradeable: true }), '7.9.0')
).toBe(false);
});
it('returns false if agent reports upgradeable, with agent version === kibana snapshot version', () => {
expect(
isAgentUpgradeable(getAgent({ version: '7.9.0', upgradeable: true }), '7.9.0-SNAPSHOT')
).toBe(false);
});
it('returns true if agent reports upgradeable, with agent snapshot version < kibana snapshot version', () => {
expect(
isAgentUpgradeable(
getAgent({ version: '7.9.0-SNAPSHOT', upgradeable: true }),
'8.0.0-SNAPSHOT'
)
).toBe(true);
});
it('returns false if agent reports upgradeable, with agent snapshot version === kibana snapshot version', () => {
expect(
isAgentUpgradeable(
getAgent({ version: '8.0.0-SNAPSHOT', upgradeable: true }),
'8.0.0-SNAPSHOT'
)
).toBe(false);
});
it('returns true if agent reports upgradeable, with agent version < kibana snapshot version', () => {
expect(
isAgentUpgradeable(getAgent({ version: '7.9.0', upgradeable: true }), '8.0.0-SNAPSHOT')
).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ export function isAgentUpgradeable(agent: Agent, kibanaVersion: string) {
return false;
}
if (agent.unenrollment_started_at || agent.unenrolled_at) return false;
const kibanaVersionParsed = semver.parse(kibanaVersion);
const agentVersionParsed = semver.parse(agentVersion);
if (!agentVersionParsed || !kibanaVersionParsed) return false;
if (!agent.local_metadata.elastic.agent.upgradeable) return false;
return semver.lt(agentVersionParsed, kibanaVersionParsed);

// make sure versions are only the number before comparison
const agentVersionNumber = semver.coerce(agentVersion);
if (!agentVersionNumber) throw new Error('agent version is invalid');
const kibanaVersionNumber = semver.coerce(kibanaVersion);
if (!kibanaVersionNumber) throw new Error('kibana version is invalid');
return semver.lt(agentVersionNumber, kibanaVersionNumber);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import { RequestHandler } from 'src/core/server';
import { TypeOf } from '@kbn/config-schema';
import semver from 'semver';
import {
AgentSOAttributes,
PostAgentUpgradeResponse,
Expand All @@ -26,17 +27,18 @@ export const postAgentUpgradeHandler: RequestHandler<
> = async (context, request, response) => {
const soClient = context.core.savedObjects.client;
const { version, source_uri: sourceUri } = request.body;

// temporarily only allow upgrading to the same version as the installed kibana version
const kibanaVersion = appContextService.getKibanaVersion();
if (kibanaVersion !== version) {
try {
checkVersionIsSame(version, kibanaVersion);
} catch (err) {
return response.customError({
statusCode: 400,
body: {
message: `cannot upgrade agent to ${version} because it is different than the installed kibana version ${kibanaVersion}`,
message: err.message,
},
});
}

const agentSO = await soClient.get<AgentSOAttributes>(
AGENT_SAVED_OBJECT_TYPE,
request.params.agentId
Expand Down Expand Up @@ -82,14 +84,14 @@ export const postBulkAgentsUpgradeHandler: RequestHandler<
> = async (context, request, response) => {
const soClient = context.core.savedObjects.client;
const { version, source_uri: sourceUri, agents } = request.body;

// temporarily only allow upgrading to the same version as the installed kibana version
const kibanaVersion = appContextService.getKibanaVersion();
if (kibanaVersion !== version) {
try {
checkVersionIsSame(version, kibanaVersion);
} catch (err) {
return response.customError({
statusCode: 400,
body: {
message: `cannot upgrade agent to ${version} because it is different than the installed kibana version ${kibanaVersion}`,
message: err.message,
},
});
}
Expand All @@ -115,3 +117,17 @@ export const postBulkAgentsUpgradeHandler: RequestHandler<
return defaultIngestErrorHandler({ error, response });
}
};

export const checkVersionIsSame = (version: string, kibanaVersion: string) => {
// get version number only in case "-SNAPSHOT" is in it
const kibanaVersionNumber = semver.coerce(kibanaVersion)?.version;
if (!kibanaVersionNumber) throw new Error(`kibanaVersion ${kibanaVersionNumber} is not valid`);
const versionToUpgradeNumber = semver.coerce(version)?.version;
if (!versionToUpgradeNumber)
throw new Error(`version to upgrade ${versionToUpgradeNumber} is not valid`);
// temporarily only allow upgrading to the same version as the installed kibana version
if (kibanaVersionNumber !== versionToUpgradeNumber)
throw new Error(
`cannot upgrade agent to ${versionToUpgradeNumber} because it is different than the installed kibana version ${kibanaVersionNumber}`
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import { setupIngest } from './services';
import { skipIfNoDockerRegistry } from '../../../helpers';
import { AGENT_SAVED_OBJECT_TYPE } from '../../../../../plugins/ingest_manager/common';

const makeSnapshotVersion = (version: string) => {
return version.endsWith('-SNAPSHOT') ? version : `${version}-SNAPSHOT`;
};

export default function (providerContext: FtrProviderContext) {
const { getService } = providerContext;
const supertest = getService('supertest');
Expand Down Expand Up @@ -48,6 +52,43 @@ export default function (providerContext: FtrProviderContext) {
const res = await supertest.get(`/api/fleet/agents/agent1`).set('kbn-xsrf', 'xxx');
expect(typeof res.body.item.upgrade_started_at).to.be('string');
});
it('should respond 400 if upgrading agent with version the same as snapshot version', async () => {
const kibanaVersion = await kibanaServer.version.get();
const kibanaVersionSnapshot = makeSnapshotVersion(kibanaVersion);
await kibanaServer.savedObjects.update({
id: 'agent1',
type: AGENT_SAVED_OBJECT_TYPE,
attributes: {
local_metadata: { elastic: { agent: { upgradeable: true, version: kibanaVersion } } },
},
});
await supertest
.post(`/api/fleet/agents/agent1/upgrade`)
.set('kbn-xsrf', 'xxx')
.send({
version: kibanaVersionSnapshot,
})
.expect(400);
});
it('should respond 200 if upgrading agent with version less than kibana snapshot version', async () => {
const kibanaVersion = await kibanaServer.version.get();
const kibanaVersionSnapshot = makeSnapshotVersion(kibanaVersion);

await kibanaServer.savedObjects.update({
id: 'agent1',
type: AGENT_SAVED_OBJECT_TYPE,
attributes: {
local_metadata: { elastic: { agent: { upgradeable: true, version: '0.0.0' } } },
},
});
await supertest
.post(`/api/fleet/agents/agent1/upgrade`)
.set('kbn-xsrf', 'xxx')
.send({
version: kibanaVersionSnapshot,
})
.expect(200);
});
it('should respond 200 to upgrade agent and update the agent SO without source_uri', async () => {
const kibanaVersion = await kibanaServer.version.get();
await kibanaServer.savedObjects.update({
Expand Down

0 comments on commit 39d668c

Please sign in to comment.