-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fleet] Display warning when trying to upgrade agent to version > max…
… fleet server version (#178079) Closes [173727](#173727) ## Summary Adding a warning to the agent upgrade modal: when the selected version is > than the greatest installed fleet server agent, a warning is presented to the user. This happens both for a single agent upgrade and for a bulk upgrade. The submit button is only disabled in the case of a single agent upgrade to avoid blocking the user from doing a bulk upgrade. In that case the endpoint will respond with the same error. Also adding a link to agent upgrade docs and opened a request to improve the docs: elastic/ingest-docs#966 ![Screenshot 2024-03-11 at 10 39 49](https://github.com/elastic/kibana/assets/16084106/5f3765b6-af25-4fa1-99fd-993d561d0f3b) ![Screenshot 2024-03-08 at 17 17 26](https://github.com/elastic/kibana/assets/16084106/1d0cfe26-8d6e-4937-86da-a53072069450) Warning for "not upgradeable agent": ![Screenshot 2024-03-11 at 10 50 10](https://github.com/elastic/kibana/assets/16084106/249c69c1-0e38-4c73-b2bf-8122a562da49) ### Checklist - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Julia Bardi <90178898+juliaElastic@users.noreply.github.com>
- Loading branch information
1 parent
a918e8f
commit f3f2315
Showing
9 changed files
with
426 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
x-pack/plugins/fleet/common/services/check_fleet_server_versions.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { checkFleetServerVersion } from './check_fleet_server_versions'; | ||
|
||
describe('checkFleetServerVersion', () => { | ||
it('should not throw if no force is specified and patch is newer', () => { | ||
const fleetServers = [ | ||
{ local_metadata: { elastic: { agent: { version: '8.3.0' } } } }, | ||
{ local_metadata: { elastic: { agent: { version: '8.4.0' } } } }, | ||
] as any; | ||
expect(() => checkFleetServerVersion('8.4.1', fleetServers, false)).not.toThrowError(); | ||
expect(() => checkFleetServerVersion('8.4.1-SNAPSHOT', fleetServers, false)).not.toThrowError(); | ||
}); | ||
|
||
it('should throw if no force is specified and minor is newer', () => { | ||
const fleetServers = [ | ||
{ local_metadata: { elastic: { agent: { version: '8.3.0' } } } }, | ||
{ local_metadata: { elastic: { agent: { version: '8.4.0' } } } }, | ||
] as any; | ||
expect(() => checkFleetServerVersion('8.5.1', fleetServers, false)).toThrowError( | ||
'Cannot upgrade to version 8.5.1 because it is higher than the latest fleet server version 8.4.0.' | ||
); | ||
}); | ||
|
||
it('should throw if force is specified and patch should not be considered', () => { | ||
const fleetServers = [ | ||
{ local_metadata: { elastic: { agent: { version: '8.3.0' } } } }, | ||
{ local_metadata: { elastic: { agent: { version: '8.4.0' } } } }, | ||
] as any; | ||
expect(() => checkFleetServerVersion('8.5.1', fleetServers, true)).toThrowError( | ||
'Cannot force upgrade to version 8.5.1 because it does not satisfy the major and minor of the latest fleet server version 8.4.0.' | ||
); | ||
}); | ||
}); |
98 changes: 98 additions & 0 deletions
98
x-pack/plugins/fleet/common/services/check_fleet_server_versions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import semverGt from 'semver/functions/gt'; | ||
import semverMajor from 'semver/functions/major'; | ||
import semverMinor from 'semver/functions/minor'; | ||
|
||
import type { Agent } from '../types'; | ||
|
||
import { AgentRequestInvalidError } from '../errors'; | ||
|
||
import { differsOnlyInPatch } from '.'; | ||
import { getMaxVersion } from './get_min_max_version'; | ||
|
||
// Check the installed fleet server version | ||
export const checkFleetServerVersion = ( | ||
versionToUpgradeNumber: string, | ||
fleetServerAgents: Agent[], | ||
force = false | ||
) => { | ||
const message = getFleetServerVersionMessage(versionToUpgradeNumber, fleetServerAgents, force); | ||
if (force && message) throw new AgentRequestInvalidError(message); | ||
if (message) throw new Error(message); | ||
}; | ||
|
||
export const getFleetServerVersionMessage = ( | ||
versionToUpgradeNumber: string | undefined, | ||
fleetServerAgents: Agent[], | ||
force = false | ||
) => { | ||
const fleetServerVersions = fleetServerAgents.map( | ||
(agent) => agent.local_metadata.elastic.agent.version | ||
) as string[]; | ||
|
||
const maxFleetServerVersion = getMaxVersion(fleetServerVersions); | ||
|
||
if (!maxFleetServerVersion || !versionToUpgradeNumber) { | ||
return; | ||
} | ||
|
||
if ( | ||
!force && | ||
semverGt(versionToUpgradeNumber, maxFleetServerVersion) && | ||
!differsOnlyInPatch(versionToUpgradeNumber, maxFleetServerVersion) | ||
) { | ||
return `Cannot upgrade to version ${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)) { | ||
return `Cannot force upgrade to version ${versionToUpgradeNumber} because it does not satisfy the major and minor of the latest fleet server version ${maxFleetServerVersion}.`; | ||
} | ||
}; | ||
|
||
export const isAgentVersionLessThanFleetServer = ( | ||
versionToUpgradeNumber: string | undefined, | ||
fleetServerAgents: Agent[], | ||
force = false | ||
) => { | ||
const fleetServerVersions = fleetServerAgents.map( | ||
(agent) => agent.local_metadata.elastic.agent.version | ||
) as string[]; | ||
|
||
const maxFleetServerVersion = getMaxVersion(fleetServerVersions); | ||
|
||
if (!maxFleetServerVersion || !versionToUpgradeNumber) { | ||
return false; | ||
} | ||
if ( | ||
!force && | ||
semverGt(versionToUpgradeNumber, maxFleetServerVersion) && | ||
!differsOnlyInPatch(versionToUpgradeNumber, maxFleetServerVersion) | ||
) | ||
return false; | ||
|
||
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)) { | ||
return false; | ||
} | ||
|
||
return true; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.