diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx index 99d470f9f2396..0255d913a753b 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx @@ -65,6 +65,8 @@ import type { import type { PackagePolicyEditExtensionComponentProps } from '../../../types'; import { pkgKeyFromPackageInfo, storedPackagePoliciesToAgentInputs } from '../../../services'; +import { hasUpgradeAvailable } from './utils'; + export const EditPackagePolicyPage = memo(() => { const { params: { packagePolicyId }, @@ -84,16 +86,16 @@ export const EditPackagePolicyPage = memo(() => { // the edit form in an "upgrade" state regardless of whether the user intended to // "edit" their policy or "upgrade" it. This ensures the new policy generated will be // set to use the latest version of the package, not its current version. - isUpgrade={extensionView?.useLatestPackageVersion} + forceUpgrade={extensionView?.useLatestPackageVersion} /> ); }); export const EditPackagePolicyForm = memo<{ packagePolicyId: string; - isUpgrade?: boolean; + forceUpgrade?: boolean; from?: EditPackagePolicyFrom; -}>(({ packagePolicyId, isUpgrade = false, from = 'edit' }) => { +}>(({ packagePolicyId, forceUpgrade = false, from = 'edit' }) => { const { application, notifications } = useStartServices(); const { agents: { enabled: isFleetEnabled }, @@ -119,6 +121,14 @@ export const EditPackagePolicyForm = memo<{ useState(); const [dryRunData, setDryRunData] = useState(); + const [isUpgrade, setIsUpgrade] = useState(false); + + useEffect(() => { + if (forceUpgrade) { + setIsUpgrade(true); + } + }, [forceUpgrade]); + const policyId = agentPolicy?.id ?? ''; // Retrieve agent policy, package, and package policy info @@ -146,11 +156,24 @@ export const EditPackagePolicyForm = memo<{ setAgentPolicy(agentPolicyData.item); } - const { data: upgradePackagePolicyDryRunData } = await sendUpgradePackagePolicyDryRun([ - packagePolicyId, - ]); + const { data: upgradePackagePolicyDryRunData, error: upgradePackagePolicyDryRunError } = + await sendUpgradePackagePolicyDryRun([packagePolicyId]); + + if (upgradePackagePolicyDryRunError) { + throw upgradePackagePolicyDryRunError; + } + + const hasUpgrade = upgradePackagePolicyDryRunData + ? hasUpgradeAvailable(upgradePackagePolicyDryRunData) + : false; + + // If the dry run data doesn't indicate a difference in version numbers, flip the form back + // to its non-upgrade state, even if we were initially set to the upgrade view + if (!hasUpgrade) { + setIsUpgrade(false); + } - if (upgradePackagePolicyDryRunData) { + if (upgradePackagePolicyDryRunData && hasUpgrade) { setDryRunData(upgradePackagePolicyDryRunData); } @@ -441,7 +464,7 @@ export const EditPackagePolicyForm = memo<{ const [selectedTab, setSelectedTab] = useState(0); const layoutProps = { - from: extensionView?.useLatestPackageVersion ? 'upgrade-from-extension' : from, + from: extensionView?.useLatestPackageVersion && isUpgrade ? 'upgrade-from-extension' : from, cancelUrl, agentPolicy, packageInfo, diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/utils/has_upgrade_available.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/utils/has_upgrade_available.ts new file mode 100644 index 0000000000000..d042eddb09334 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/utils/has_upgrade_available.ts @@ -0,0 +1,25 @@ +/* + * 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 type { UpgradePackagePolicyDryRunResponse } from '../../../../types'; + +/** + * Given a dry run response, determines if a greater version exists in the "proposed" + * version of the first package policy in the response. + */ +export function hasUpgradeAvailable(dryRunData: UpgradePackagePolicyDryRunResponse) { + return ( + dryRunData && + dryRunData[0].diff && + semverGt( + dryRunData[0].diff[1].package?.version ?? '', + dryRunData[0].diff[0].package?.version ?? '' + ) + ); +} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/utils/index.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/utils/index.ts new file mode 100644 index 0000000000000..e8206e9dbbf97 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/utils/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export * from './has_upgrade_available'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/upgrade_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/upgrade_package_policy_page/index.tsx index 18cf7847cd29b..853caeb0cc826 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/upgrade_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/upgrade_package_policy_page/index.tsx @@ -30,5 +30,5 @@ export const UpgradePackagePolicyPage = memo(() => { from = 'upgrade-from-integrations-policy-list'; } - return ; + return ; }); diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/policy/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/policy/index.tsx index ed8ad166cde9b..e78a2954a86d6 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/policy/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/policy/index.tsx @@ -28,7 +28,7 @@ export const Policy = memo(() => { ); });