diff --git a/x-pack/plugins/fleet/common/services/is_agent_upgradeable.ts b/x-pack/plugins/fleet/common/services/is_agent_upgradeable.ts index 2a523d1a2eab..d4dea44834a4 100644 --- a/x-pack/plugins/fleet/common/services/is_agent_upgradeable.ts +++ b/x-pack/plugins/fleet/common/services/is_agent_upgradeable.ts @@ -11,7 +11,11 @@ import semverGt from 'semver/functions/gt'; import type { Agent } from '../types'; -export function isAgentUpgradeable(agent: Agent, kibanaVersion: string, versionToUpgrade?: string) { +export function isAgentUpgradeable( + agent: Agent, + latestAgentVersion: string, + versionToUpgrade?: string +) { let agentVersion: string; if (typeof agent?.local_metadata?.elastic?.agent?.version === 'string') { agentVersion = agent.local_metadata.elastic.agent.version; @@ -31,23 +35,23 @@ export function isAgentUpgradeable(agent: Agent, kibanaVersion: string, versionT if (versionToUpgrade !== undefined) { return ( isNotDowngrade(agentVersion, versionToUpgrade) && - isAgentVersionLessThanKibana(agentVersion, kibanaVersion) + isAgentVersionLessThanLatest(agentVersion, latestAgentVersion) ); } - return isAgentVersionLessThanKibana(agentVersion, kibanaVersion); + return isAgentVersionLessThanLatest(agentVersion, latestAgentVersion); } -export const isAgentVersionLessThanKibana = (agentVersion: string, kibanaVersion: string) => { +const isAgentVersionLessThanLatest = (agentVersion: string, latestAgentVersion: string) => { // make sure versions are only the number before comparison const agentVersionNumber = semverCoerce(agentVersion); if (!agentVersionNumber) throw new Error('agent version is not valid'); - const kibanaVersionNumber = semverCoerce(kibanaVersion); - if (!kibanaVersionNumber) throw new Error('kibana version is not valid'); + const latestAgentVersionNumber = semverCoerce(latestAgentVersion); + if (!latestAgentVersionNumber) throw new Error('latest version is not valid'); - return semverLt(agentVersionNumber, kibanaVersionNumber); + return semverLt(agentVersionNumber, latestAgentVersionNumber); }; -export const isNotDowngrade = (agentVersion: string, versionToUpgrade: string) => { +const isNotDowngrade = (agentVersion: string, versionToUpgrade: string) => { const agentVersionNumber = semverCoerce(agentVersion); if (!agentVersionNumber) throw new Error('agent version is not valid'); const versionToUpgradeNumber = semverCoerce(versionToUpgrade); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/action_menu.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/action_menu.test.tsx index 51c2250e0fe1..2f05354b09a0 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/action_menu.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/action_menu.test.tsx @@ -12,14 +12,17 @@ import { createFleetTestRendererMock } from '../../../../../../mock'; import type { Agent, AgentPolicy } from '../../../../types'; import { ExperimentalFeaturesService } from '../../../../services'; import { useAuthz } from '../../../../../../hooks/use_authz'; +import { useAgentVersion } from '../../../../../../hooks/use_agent_version'; import { AgentDetailsActionMenu } from './actions_menu'; jest.mock('../../../../../../services/experimental_features'); jest.mock('../../../../../../hooks/use_authz'); +jest.mock('../../../../../../hooks/use_agent_version'); const mockedExperimentalFeaturesService = jest.mocked(ExperimentalFeaturesService); const mockedUseAuthz = jest.mocked(useAuthz); +const mockedUseAgentVersion = jest.mocked(useAgentVersion); function renderActions({ agent, agentPolicy }: { agent: Agent; agentPolicy?: AgentPolicy }) { const renderer = createFleetTestRendererMock(); @@ -48,6 +51,7 @@ describe('AgentDetailsActionMenu', () => { all: true, }, } as any); + mockedUseAgentVersion.mockReturnValue('8.10.2'); }); describe('Request Diagnotics action', () => { @@ -162,45 +166,90 @@ describe('AgentDetailsActionMenu', () => { expect(res).toBeEnabled(); }); }); -}); -describe('Restart upgrade action', () => { - function renderAndGetRestartUpgradeButton({ - agent, - agentPolicy, - }: { - agent: Agent; - agentPolicy?: AgentPolicy; - }) { - const { utils } = renderActions({ + describe('Restart upgrade action', () => { + function renderAndGetRestartUpgradeButton({ agent, agentPolicy, + }: { + agent: Agent; + agentPolicy?: AgentPolicy; + }) { + const { utils } = renderActions({ + agent, + agentPolicy, + }); + + return utils.queryByTestId('restartUpgradeBtn'); + } + + it('should render an active button', async () => { + const res = renderAndGetRestartUpgradeButton({ + agent: { + status: 'updating', + upgrade_started_at: '2022-11-21T12:27:24Z', + } as any, + agentPolicy: {} as AgentPolicy, + }); + + expect(res).not.toBe(null); + expect(res).toBeEnabled(); }); - return utils.queryByTestId('restartUpgradeBtn'); - } - - it('should render an active button', async () => { - const res = renderAndGetRestartUpgradeButton({ - agent: { - status: 'updating', - upgrade_started_at: '2022-11-21T12:27:24Z', - } as any, - agentPolicy: {} as AgentPolicy, + it('should not render action if agent is not stuck in updating', async () => { + const res = renderAndGetRestartUpgradeButton({ + agent: { + status: 'updating', + upgrade_started_at: new Date().toISOString(), + } as any, + agentPolicy: {} as AgentPolicy, + }); + expect(res).toBe(null); }); - - expect(res).not.toBe(null); - expect(res).toBeEnabled(); }); - it('should not render action if agent is not stuck in updating', async () => { - const res = renderAndGetRestartUpgradeButton({ - agent: { - status: 'updating', - upgrade_started_at: new Date().toISOString(), - } as any, - agentPolicy: {} as AgentPolicy, + describe('Upgrade action', () => { + function renderAndGetUpgradeButton({ + agent, + agentPolicy, + }: { + agent: Agent; + agentPolicy?: AgentPolicy; + }) { + const { utils } = renderActions({ + agent, + agentPolicy, + }); + + return utils.queryByTestId('upgradeBtn'); + } + + it('should render an active action button if agent version is not the latest', async () => { + const res = renderAndGetUpgradeButton({ + agent: { + active: true, + status: 'online', + local_metadata: { elastic: { agent: { version: '8.8.0', upgradeable: true } } }, + } as any, + agentPolicy: {} as AgentPolicy, + }); + + expect(res).not.toBe(null); + expect(res).toBeEnabled(); + }); + + it('should render a disabled action button if agent version is latest', async () => { + const res = renderAndGetUpgradeButton({ + agent: { + active: true, + status: 'online', + local_metadata: { elastic: { agent: { version: '8.10.2', upgradeable: true } } }, + } as any, + agentPolicy: {} as AgentPolicy, + }); + + expect(res).not.toBe(null); + expect(res).not.toBeEnabled(); }); - expect(res).toBe(null); }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx index 251a5407de04..d2426dbac8ca 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/actions_menu.tsx @@ -13,7 +13,7 @@ import { isAgentRequestDiagnosticsSupported } from '../../../../../../../common/ import { isStuckInUpdating } from '../../../../../../../common/services/agent_status'; import type { Agent, AgentPolicy } from '../../../../types'; -import { useAuthz, useKibanaVersion } from '../../../../hooks'; +import { useAgentVersion, useAuthz } from '../../../../hooks'; import { ContextMenuActions } from '../../../../components'; import { AgentUnenrollAgentModal, @@ -34,7 +34,7 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{ onCancelReassign?: () => void; }> = memo(({ agent, assignFlyoutOpenByDefault = false, onCancelReassign, agentPolicy }) => { const hasFleetAllPrivileges = useAuthz().fleet.all; - const kibanaVersion = useKibanaVersion(); + const latestAgentVersion = useAgentVersion(); const refreshAgent = useAgentRefresh(); const [isReassignFlyoutOpen, setIsReassignFlyoutOpen] = useState(assignFlyoutOpenByDefault); const [isUnenrollModalOpen, setIsUnenrollModalOpen] = useState(false); @@ -102,11 +102,12 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{ , { setIsUpgradeModalOpen(true); }} key="upgradeAgent" + data-test-subj="upgradeBtn" > = memo(({ agent, agentPolicy }) => { - const kibanaVersion = useKibanaVersion(); + const latestAgentVersion = useAgentVersion(); const { displayAgentMetrics } = ExperimentalFeaturesService.get(); return ( @@ -173,7 +173,7 @@ export const AgentDetailsOverviewSection: React.FunctionComponent<{ {agent.local_metadata.elastic.agent.version} - {isAgentUpgradeable(agent, kibanaVersion) ? ( + {latestAgentVersion && isAgentUpgradeable(agent, latestAgentVersion) ? ( = (props: Props) => { const { displayAgentMetrics } = ExperimentalFeaturesService.get(); const { getHref } = useLink(); - const kibanaVersion = useKibanaVersion(); + const latestAgentVersion = useAgentVersion(); const isAgentSelectable = (agent: Agent) => { if (!agent.active) return false; @@ -284,7 +285,9 @@ export const AgentListTable: React.FC = (props: Props) => { {safeMetadata(version)} - {isAgentSelectable(agent) && isAgentUpgradeable(agent, kibanaVersion) ? ( + {isAgentSelectable(agent) && + latestAgentVersion && + isAgentUpgradeable(agent, latestAgentVersion) ? ( @@ -324,7 +327,10 @@ export const AgentListTable: React.FC = (props: Props) => { totalAgents ? showUpgradeable ? agents.filter( - (agent) => isAgentSelectable(agent) && isAgentUpgradeable(agent, kibanaVersion) + (agent) => + isAgentSelectable(agent) && + latestAgentVersion && + isAgentUpgradeable(agent, latestAgentVersion) ) : agents : [] diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.test.tsx index 17ebb6a6631f..a2fed8d3ed61 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.test.tsx @@ -12,14 +12,17 @@ import { createFleetTestRendererMock } from '../../../../../../mock'; import type { Agent, AgentPolicy } from '../../../../types'; import { ExperimentalFeaturesService } from '../../../../services'; import { useAuthz } from '../../../../../../hooks/use_authz'; +import { useAgentVersion } from '../../../../../../hooks/use_agent_version'; import { TableRowActions } from './table_row_actions'; jest.mock('../../../../../../services/experimental_features'); jest.mock('../../../../../../hooks/use_authz'); +jest.mock('../../../../../../hooks/use_agent_version'); const mockedExperimentalFeaturesService = jest.mocked(ExperimentalFeaturesService); const mockedUseAuthz = jest.mocked(useAuthz); +const mockedUseAgentVersion = jest.mocked(useAgentVersion); function renderTableRowActions({ agent, @@ -57,6 +60,7 @@ describe('TableRowActions', () => { all: true, }, } as any); + mockedUseAgentVersion.mockReturnValue('8.10.2'); }); describe('Request Diagnotics action', () => { @@ -179,4 +183,53 @@ describe('TableRowActions', () => { expect(res).toBe(null); }); }); + + describe('Upgrade action', () => { + function renderAndGetUpgradeButton({ + agent, + agentPolicy, + }: { + agent: Agent; + agentPolicy?: AgentPolicy; + }) { + const { utils } = renderTableRowActions({ + agent, + agentPolicy, + }); + + return utils.queryByTestId('upgradeBtn'); + } + + it('should render an active action button if agent version is not the latest', async () => { + const res = renderAndGetUpgradeButton({ + agent: { + active: true, + status: 'online', + local_metadata: { elastic: { agent: { version: '8.8.0', upgradeable: true } } }, + } as any, + agentPolicy: { + is_managed: false, + } as AgentPolicy, + }); + + expect(res).not.toBe(null); + expect(res).toBeEnabled(); + }); + + it('should render a disabled action button if agent version is latest', async () => { + const res = renderAndGetUpgradeButton({ + agent: { + active: true, + status: 'online', + local_metadata: { elastic: { agent: { version: '8.10.2', upgradeable: true } } }, + } as any, + agentPolicy: { + is_managed: false, + } as AgentPolicy, + }); + + expect(res).not.toBe(null); + expect(res).not.toBeEnabled(); + }); + }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.tsx index 6b36f0a29d58..ba2efb1d86f8 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/table_row_actions.tsx @@ -14,7 +14,7 @@ import { isAgentRequestDiagnosticsSupported } from '../../../../../../../common/ import { isStuckInUpdating } from '../../../../../../../common/services/agent_status'; import type { Agent, AgentPolicy } from '../../../../types'; -import { useAuthz, useLink, useKibanaVersion } from '../../../../hooks'; +import { useAuthz, useLink, useAgentVersion } from '../../../../hooks'; import { ContextMenuActions } from '../../../../components'; import { isAgentUpgradeable } from '../../../../services'; import { ExperimentalFeaturesService } from '../../../../services'; @@ -42,7 +42,7 @@ export const TableRowActions: React.FunctionComponent<{ const hasFleetAllPrivileges = useAuthz().fleet.all; const isUnenrolling = agent.status === 'unenrolling'; - const kibanaVersion = useKibanaVersion(); + const latestAgentVersion = useAgentVersion(); const [isMenuOpen, setIsMenuOpen] = useState(false); const { diagnosticFileUploadEnabled, agentTamperProtectionEnabled } = ExperimentalFeaturesService.get(); @@ -107,10 +107,11 @@ export const TableRowActions: React.FunctionComponent<{ { onUpgradeClick(); }} + data-test-subj="upgradeBtn" > { ...jest.requireActual('../../../../hooks'), sendGetAgentsAvailableVersions: jest.fn().mockResolvedValue({ data: { - items: ['8.7.0'], + items: ['8.10.2', '8.7.0'], }, }), sendGetAgentStatus: jest.fn().mockResolvedValue({ data: { results: { updating: 2 } }, }), sendPostBulkAgentUpgrade: jest.fn(), + useAgentVersion: jest.fn().mockReturnValue('8.10.2'), }; }); @@ -86,6 +87,18 @@ describe('AgentUpgradeAgentModal', () => { }); }); + it('should default the version combo to latest agent version', async () => { + const { utils } = renderAgentUpgradeAgentModal({ + agents: [{ id: 'agent1', local_metadata: { host: 'abc' } }] as any, + agentCount: 1, + }); + + const el = utils.getByTestId('agentUpgradeModal.VersionCombobox'); + await waitFor(() => { + expect(el.textContent).toEqual('8.10.2'); + }); + }); + it('should restart uprade on updating agents if some agents in updating', async () => { const { utils } = renderAgentUpgradeAgentModal({ agents: [ diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx index 94e1710cbacb..7b3592765795 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_upgrade_modal/index.tsx @@ -41,6 +41,7 @@ import { useKibanaVersion, useConfig, sendGetAgentStatus, + useAgentVersion, } from '../../../../hooks'; import { sendGetAgentsAvailableVersions } from '../../../../hooks'; @@ -196,6 +197,20 @@ export const AgentUpgradeAgentModal: React.FunctionComponent { + if (latestAgentVersion) { + setSelectedVersion([ + { + label: latestAgentVersion, + value: latestAgentVersion, + }, + ]); + } + }, [latestAgentVersion]); + const [selectedMaintenanceWindow, setSelectedMaintenanceWindow] = useState([ isSmallBatch ? maintenanceOptions[0] : maintenanceOptions[1], ]); diff --git a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts index f13044d97539..fedef7b4957c 100644 --- a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts @@ -24,6 +24,7 @@ import { getAgentById } from '../../services/agents'; import type { Agent } from '../../types'; import { getAllFleetServerAgents } from '../../collectors/get_all_fleet_server_agents'; +import { getLatestAvailableVersion } from '../../services/agents/versions'; export const postAgentUpgradeHandler: RequestHandler< TypeOf, @@ -35,6 +36,7 @@ export const postAgentUpgradeHandler: RequestHandler< const esClient = coreContext.elasticsearch.client.asInternalUser; const { version, source_uri: sourceUri, force } = request.body; const kibanaVersion = appContextService.getKibanaVersion(); + const latestAgentVersion = await getLatestAvailableVersion(); try { checkKibanaVersion(version, kibanaVersion, force); } catch (err) { @@ -73,7 +75,7 @@ export const postAgentUpgradeHandler: RequestHandler< }, }); } - if (!force && !isAgentUpgradeable(agent, kibanaVersion, version)) { + if (!force && !isAgentUpgradeable(agent, latestAgentVersion, version)) { return response.customError({ statusCode: 400, body: { diff --git a/x-pack/plugins/fleet/server/services/agents/crud.ts b/x-pack/plugins/fleet/server/services/agents/crud.ts index b6a124d3c32a..1521a19f51af 100644 --- a/x-pack/plugins/fleet/server/services/agents/crud.ts +++ b/x-pack/plugins/fleet/server/services/agents/crud.ts @@ -24,6 +24,7 @@ import { auditLoggingService } from '../audit_logging'; import { searchHitToAgent, agentSOAttributesToFleetServerAgentDoc } from './helpers'; import { buildAgentStatusRuntimeField } from './build_status_runtime_field'; +import { getLatestAvailableVersion } from './versions'; const INACTIVE_AGENT_CONDITION = `status:inactive OR status:unenrolled`; const ACTIVE_AGENT_CONDITION = `NOT (${INACTIVE_AGENT_CONDITION})`; @@ -302,6 +303,7 @@ export async function getAgentsByKuery( // filtering for a range on the version string will not work, // nor does filtering on a flattened field (local_metadata), so filter here if (showUpgradeable) { + const latestAgentVersion = await getLatestAvailableVersion(); // fixing a bug where upgradeable filter was not returning right results https://github.com/elastic/kibana/issues/117329 // query all agents, then filter upgradeable, and return the requested page and correct total // if there are more than SO_SEARCH_LIMIT agents, the logic falls back to same as before @@ -309,14 +311,12 @@ export async function getAgentsByKuery( const response = await queryAgents(0, SO_SEARCH_LIMIT); agents = response.hits.hits .map(searchHitToAgent) - .filter((agent) => isAgentUpgradeable(agent, appContextService.getKibanaVersion())); + .filter((agent) => isAgentUpgradeable(agent, latestAgentVersion)); total = agents.length; const start = (page - 1) * perPage; agents = agents.slice(start, start + perPage); } else { - agents = agents.filter((agent) => - isAgentUpgradeable(agent, appContextService.getKibanaVersion()) - ); + agents = agents.filter((agent) => isAgentUpgradeable(agent, latestAgentVersion)); } } diff --git a/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts b/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts index 8b7409375fb2..014a9bec8973 100644 --- a/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts @@ -26,6 +26,7 @@ import { createErrorActionResults, createAgentAction } from './actions'; import { getHostedPolicies, isHostedAgent } from './hosted_agent'; import { BulkActionTaskType } from './bulk_action_types'; import { getCancelledActions } from './action_status'; +import { getLatestAvailableVersion } from './versions'; export class UpgradeActionRunner extends ActionRunner { protected async processAgents(agents: Agent[]): Promise<{ actionId: string }> { @@ -72,12 +73,12 @@ export async function upgradeBatch( ? givenAgents.filter((agent: Agent) => !isHostedAgent(hostedPolicies, agent)) : givenAgents; - const kibanaVersion = appContextService.getKibanaVersion(); + const latestAgentVersion = await getLatestAvailableVersion(); const upgradeableResults = await Promise.allSettled( agentsToCheckUpgradeable.map(async (agent) => { // Filter out agents currently unenrolling, unenrolled, or not upgradeable b/c of version check const isNotAllowed = - !options.force && !isAgentUpgradeable(agent, kibanaVersion, options.version); + !options.force && !isAgentUpgradeable(agent, latestAgentVersion, options.version); if (isNotAllowed) { throw new FleetError(`Agent ${agent.id} is not upgradeable`); } diff --git a/x-pack/plugins/fleet/server/services/agents/versions.test.ts b/x-pack/plugins/fleet/server/services/agents/versions.test.ts index 6274fe421527..92e30141c006 100644 --- a/x-pack/plugins/fleet/server/services/agents/versions.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/versions.test.ts @@ -30,7 +30,7 @@ describe('getAvailableVersions', () => { mockKibanaVersion = '300.0.0'; mockedReadFile.mockResolvedValue(`["8.1.0", "8.0.0", "7.17.0", "7.16.0"]`); - const res = await getAvailableVersions({ cached: false }); + const res = await getAvailableVersions({ cached: false, includeCurrentVersion: true }); expect(res).toEqual(['300.0.0', '8.1.0', '8.0.0', '7.17.0']); }); @@ -39,11 +39,11 @@ describe('getAvailableVersions', () => { mockKibanaVersion = '300.0.0-SNAPSHOT'; mockedReadFile.mockResolvedValue(`["8.1.0", "8.0.0", "7.17.0", "7.16.0"]`); - const res = await getAvailableVersions({ cached: false }); + const res = await getAvailableVersions({ cached: false, includeCurrentVersion: true }); expect(res).toEqual(['300.0.0-SNAPSHOT', '8.1.0', '8.0.0', '7.17.0']); }); - it('should not include the current version if onlyAllowAgentUpgradeToKnownVersions = true', async () => { + it('should not include the current version if includeCurrentVersion is not set', async () => { mockKibanaVersion = '300.0.0-SNAPSHOT'; mockConfig = { internal: { @@ -65,4 +65,18 @@ describe('getAvailableVersions', () => { expect(res).toEqual(['8.1.0', '8.0.0', '7.17.0']); }); + + it('should return kibana version only if cannot read versions', async () => { + mockKibanaVersion = '300.0.0'; + mockConfig = { + internal: { + onlyAllowAgentUpgradeToKnownVersions: false, + }, + }; + mockedReadFile.mockRejectedValue({ code: 'ENOENT' }); + + const res = await getAvailableVersions({ cached: false }); + + expect(res).toEqual(['300.0.0']); + }); }); diff --git a/x-pack/plugins/fleet/server/services/agents/versions.ts b/x-pack/plugins/fleet/server/services/agents/versions.ts index 90436de70d7d..fda703056daa 100644 --- a/x-pack/plugins/fleet/server/services/agents/versions.ts +++ b/x-pack/plugins/fleet/server/services/agents/versions.ts @@ -60,8 +60,7 @@ export const getAvailableVersions = async ({ .sort((a: any, b: any) => (semverGt(a, b) ? -1 : 1)); versionsToDisplay = uniq(versions) as string[]; - const appendCurrentVersion = - includeCurrentVersion ?? !config?.internal?.onlyAllowAgentUpgradeToKnownVersions; + const appendCurrentVersion = includeCurrentVersion; if (appendCurrentVersion) { // Add current version if not already present