Skip to content

Commit

Permalink
[Fleet] Allow agent force upgrading to a newer patch release (#142450) (
Browse files Browse the repository at this point in the history
#142581)

(cherry picked from commit b8c17b0)

Co-authored-by: Josh Dover <[email protected]>
  • Loading branch information
kibanamachine and joshdover authored Oct 4, 2022
1 parent 0a456a1 commit 71cab61
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 7 deletions.
14 changes: 14 additions & 0 deletions x-pack/plugins/fleet/server/routes/agent/upgrade_handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,19 @@ describe('upgrade handler', () => {
it('should not throw if upgrade version is equal to kibana version with snapshot', () => {
expect(() => checkKibanaVersion('8.4.0', '8.4.0-SNAPSHOT')).not.toThrowError();
});

it('should not throw if force is specified and patch is newer', () => {
expect(() => checkKibanaVersion('8.4.1', '8.4.0', true)).not.toThrowError();
expect(() => checkKibanaVersion('8.4.1-SNAPSHOT', '8.4.0', true)).not.toThrowError();
});

it('should throw if force is specified and minor is newer', () => {
expect(() => checkKibanaVersion('8.5.0', '8.4.0', true)).toThrowError();
});

it('should not throw if force is specified and major and minor is newer', () => {
expect(() => checkKibanaVersion('7.5.0', '8.4.0', true)).not.toThrowError();
expect(() => checkKibanaVersion('8.4.0', '8.4.0', true)).not.toThrowError();
});
});
});
46 changes: 39 additions & 7 deletions x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import type { TypeOf } from '@kbn/config-schema';

import semverCoerce from 'semver/functions/coerce';
import semverGt from 'semver/functions/gt';
import semverMajor from 'semver/functions/major';
import semverMinor from 'semver/functions/minor';

import type { PostAgentUpgradeResponse, GetCurrentUpgradesResponse } from '../../../common/types';
import type { PostAgentUpgradeRequestSchema, PostBulkAgentUpgradeRequestSchema } from '../../types';
Expand All @@ -34,7 +36,7 @@ export const postAgentUpgradeHandler: RequestHandler<
const { version, source_uri: sourceUri, force } = request.body;
const kibanaVersion = appContextService.getKibanaVersion();
try {
checkKibanaVersion(version, kibanaVersion);
checkKibanaVersion(version, kibanaVersion, force);
} catch (err) {
return response.customError({
statusCode: 400,
Expand Down Expand Up @@ -114,9 +116,9 @@ export const postBulkAgentsUpgradeHandler: RequestHandler<
} = request.body;
const kibanaVersion = appContextService.getKibanaVersion();
try {
checkKibanaVersion(version, kibanaVersion);
checkKibanaVersion(version, kibanaVersion, force);
const fleetServerAgents = await getAllFleetServerAgents(soClient, esClient);
checkFleetServerVersion(version, fleetServerAgents);
checkFleetServerVersion(version, fleetServerAgents, force);
} catch (err) {
return response.customError({
statusCode: 400,
Expand Down Expand Up @@ -158,22 +160,39 @@ export const getCurrentUpgradesHandler: RequestHandler = async (context, request
}
};

export const checkKibanaVersion = (version: string, kibanaVersion: string) => {
export const checkKibanaVersion = (version: string, kibanaVersion: string, force = false) => {
// get version number only in case "-SNAPSHOT" is in it
const kibanaVersionNumber = semverCoerce(kibanaVersion)?.version;
if (!kibanaVersionNumber) throw new Error(`kibanaVersion ${kibanaVersionNumber} is not valid`);
const versionToUpgradeNumber = semverCoerce(version)?.version;
if (!versionToUpgradeNumber)
throw new Error(`version to upgrade ${versionToUpgradeNumber} is not valid`);

if (semverGt(versionToUpgradeNumber, kibanaVersionNumber))
if (!force && semverGt(versionToUpgradeNumber, kibanaVersionNumber)) {
throw new Error(
`cannot upgrade agent to ${versionToUpgradeNumber} because it is higher than the installed kibana version ${kibanaVersionNumber}`
);
}

const kibanaMajorGt = semverMajor(kibanaVersionNumber) > semverMajor(versionToUpgradeNumber);
const kibanaMajorEqMinorGte =
semverMajor(kibanaVersionNumber) === semverMajor(versionToUpgradeNumber) &&
semverMinor(kibanaVersionNumber) >= semverMinor(versionToUpgradeNumber);

// When force is enabled, only the major and minor versions are checked
if (force && !(kibanaMajorGt || kibanaMajorEqMinorGte)) {
throw new Error(
`cannot force upgrade agent to ${versionToUpgradeNumber} because it does not satisfy the major and minor of the installed kibana version ${kibanaVersionNumber}`
);
}
};

// Check the installed fleet server version
const checkFleetServerVersion = (versionToUpgradeNumber: string, fleetServerAgents: Agent[]) => {
const checkFleetServerVersion = (
versionToUpgradeNumber: string,
fleetServerAgents: Agent[],
force = false
) => {
const fleetServerVersions = fleetServerAgents.map(
(agent) => agent.local_metadata.elastic.agent.version
) as string[];
Expand All @@ -184,9 +203,22 @@ const checkFleetServerVersion = (versionToUpgradeNumber: string, fleetServerAgen
return;
}

if (semverGt(versionToUpgradeNumber, maxFleetServerVersion)) {
if (!force && semverGt(versionToUpgradeNumber, maxFleetServerVersion)) {
throw new Error(
`cannot upgrade agent to ${versionToUpgradeNumber} because it is higher than the latest fleet server version ${maxFleetServerVersion}`
);
}

const fleetServerMajorGt =
semverMajor(maxFleetServerVersion) > semverMajor(versionToUpgradeNumber);
const fleetServerMajorEqMinorGte =
semverMajor(maxFleetServerVersion) === semverMajor(versionToUpgradeNumber) &&
semverMinor(maxFleetServerVersion) >= semverMinor(versionToUpgradeNumber);

// When force is enabled, only the major and minor versions are checked
if (force && !(fleetServerMajorGt || fleetServerMajorEqMinorGte)) {
throw new Error(
`cannot force upgrade agent to ${versionToUpgradeNumber} because it does not satisfy the major and minor of the latest fleet server version ${maxFleetServerVersion}`
);
}
};

0 comments on commit 71cab61

Please sign in to comment.