[Fleet] Allow agent force upgrading to a newer patch release (#142450)

This commit is contained in:
Josh Dover 2022-10-04 12:56:28 +02:00 committed by GitHub
parent 74f30dcf8e
commit b8c17b0227
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 7 deletions

View file

@ -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();
});
});
});

View file

@ -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';
@ -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,
@ -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,
@ -158,7 +160,7 @@ 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`);
@ -166,14 +168,31 @@ export const checkKibanaVersion = (version: string, kibanaVersion: string) => {
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[];
@ -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}`
);
}
};