diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/components/index.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/components/index.ts new file mode 100644 index 0000000000000..4e5cacadf216b --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/components/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 { UpgradeStatusCallout } from './upgrade'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/components/upgrade.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/components/upgrade.tsx new file mode 100644 index 0000000000000..8b981c89fe743 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/components/upgrade.tsx @@ -0,0 +1,121 @@ +/* + * 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. + */ + +/* + * 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 React, { useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiCallOut, + EuiLink, + EuiFlyout, + EuiCodeBlock, + EuiPortal, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiTitle, +} from '@elastic/eui'; +import styled from 'styled-components'; + +import type { UpgradePackagePolicyDryRunResponse } from '../../../../../../../common/types/rest_spec'; + +const FlyoutBody = styled(EuiFlyoutBody)` + .euiFlyoutBody__overflowContent { + padding: 0; + } +`; + +export const UpgradeStatusCallout: React.FunctionComponent<{ + dryRunData: UpgradePackagePolicyDryRunResponse; +}> = ({ dryRunData }) => { + const [isPreviousVersionFlyoutOpen, setIsPreviousVersionFlyoutOpen] = useState(false); + + if (!dryRunData) { + return null; + } + + const isReadyForUpgrade = !dryRunData[0].hasErrors; + + const [currentPackagePolicy, proposedUpgradePackagePolicy] = dryRunData[0].diff || []; + + return ( + <> + {isPreviousVersionFlyoutOpen && currentPackagePolicy && ( + + setIsPreviousVersionFlyoutOpen(false)} size="l" maxWidth={640}> + + +

+ +

+
+
+ + + {JSON.stringify(dryRunData[0].agent_diff?.[0] || [], null, 2)} + + +
+
+ )} + + {isReadyForUpgrade && currentPackagePolicy ? ( + + + + ) : ( + + setIsPreviousVersionFlyoutOpen(true)}> + + + ), + }} + /> + + )} + + ); +}; 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 ede221eaf0355..9381dfcbe3bd6 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 @@ -15,20 +15,11 @@ import deepEqual from 'fast-deep-equal'; import { EuiButtonEmpty, EuiBottomBar, - EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiSpacer, - EuiLink, - EuiFlyout, - EuiCodeBlock, - EuiPortal, - EuiFlyoutBody, - EuiFlyoutHeader, - EuiTitle, EuiErrorBoundary, } from '@elastic/eui'; -import styled from 'styled-components'; import type { AgentPolicy, PackageInfo, UpdatePackagePolicy, PackagePolicy } from '../../../types'; import { @@ -71,6 +62,7 @@ import { pkgKeyFromPackageInfo } from '../../../services'; import { fixApmDurationVars, hasUpgradeAvailable } from './utils'; import { useHistoryBlock } from './hooks'; +import { UpgradeStatusCallout } from './components'; export const EditPackagePolicyPage = memo(() => { const { @@ -760,94 +752,3 @@ const UpgradeBreadcrumb: React.FunctionComponent<{ useBreadcrumbs('upgrade_package_policy', { policyName, policyId }); return null; }; - -const FlyoutBody = styled(EuiFlyoutBody)` - .euiFlyoutBody__overflowContent { - padding: 0; - } -`; - -const UpgradeStatusCallout: React.FunctionComponent<{ - dryRunData: UpgradePackagePolicyDryRunResponse; -}> = ({ dryRunData }) => { - const [isPreviousVersionFlyoutOpen, setIsPreviousVersionFlyoutOpen] = useState(false); - - if (!dryRunData) { - return null; - } - - const isReadyForUpgrade = !dryRunData[0].hasErrors; - - const [currentPackagePolicy, proposedUpgradePackagePolicy] = dryRunData[0].diff || []; - - return ( - <> - {isPreviousVersionFlyoutOpen && currentPackagePolicy && ( - - setIsPreviousVersionFlyoutOpen(false)} size="l" maxWidth={640}> - - -

- -

-
-
- - - {JSON.stringify(dryRunData[0].agent_diff?.[0] || [], null, 2)} - - -
-
- )} - - {isReadyForUpgrade && currentPackagePolicy ? ( - - - - ) : ( - - setIsPreviousVersionFlyoutOpen(true)}> - - - ), - }} - /> - - )} - - ); -}; diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index b5d072374989f..b2caca6cae904 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -114,6 +114,36 @@ async function mockedGetPackageInfo(params: any) { if (params.pkgName === 'apache') pkg = { version: '1.3.2' }; if (params.pkgName === 'aws') pkg = { version: '0.3.3' }; if (params.pkgName === 'endpoint') pkg = {}; + if (params.pkgName === 'test') { + pkg = { + version: '1.0.2', + }; + } + if (params.pkgName === 'test-conflict') { + pkg = { + version: '1.0.2', + policy_templates: [ + { + name: 'test-conflict', + inputs: [ + { + title: 'test', + type: 'logs', + description: 'test', + vars: [ + { + name: 'test-var-required', + required: true, + type: 'integer', + }, + ], + }, + ], + }, + ], + }; + } + return Promise.resolve(pkg); } @@ -1111,6 +1141,10 @@ describe('Package policy service', () => { }); }); + describe('delete', () => { + it('should allow to delete a package policy', async () => {}); + }); + describe('runDeleteExternalCallbacks', () => { let callbackOne: jest.MockedFunction; let callbackTwo: jest.MockedFunction; @@ -3384,6 +3418,72 @@ describe('Package policy service', () => { }); }); +describe('getUpgradeDryRunDiff', () => { + let savedObjectsClient: jest.Mocked; + beforeEach(() => { + savedObjectsClient = savedObjectsClientMock.create(); + appContextService.start(createAppContextStartContractMock()); + }); + afterEach(() => { + appContextService.stop(); + }); + it('should return no errors if there is no conflict to upgrade', async () => { + const res = await packagePolicyService.getUpgradeDryRunDiff( + savedObjectsClient, + 'package-policy-id', + { + id: '123', + name: 'test-123', + package: { + title: 'test', + name: 'test', + version: '1.0.1', + }, + namespace: 'default', + inputs: [ + { + id: 'toto', + enabled: true, + streams: [], + type: 'logs', + }, + ], + } as any, + '1.0.2' + ); + + expect(res.hasErrors).toBeFalsy(); + }); + + it('should no errors if there is a conflict to upgrade', async () => { + const res = await packagePolicyService.getUpgradeDryRunDiff( + savedObjectsClient, + 'package-policy-id', + { + id: '123', + name: 'test-123', + package: { + title: 'test', + name: 'test-conflict', + version: '1.0.1', + }, + namespace: 'default', + inputs: [ + { + id: 'toto', + enabled: true, + streams: [], + type: 'logs', + }, + ], + } as any, + '1.0.2' + ); + + expect(res.hasErrors).toBeTruthy(); + }); +}); + describe('_applyIndexPrivileges()', () => { function createPackageStream(indexPrivileges?: string[]): RegistryDataStream { const stream: RegistryDataStream = {