diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/fleet_server_requirement_page.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/fleet_server_requirement_page.tsx index 463fdb4c62cad..2e37d9efc7857 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/fleet_server_requirement_page.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/fleet_server_requirement_page.tsx @@ -21,6 +21,7 @@ import { EuiCallOut, EuiSelect, } from '@elastic/eui'; +import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -51,7 +52,144 @@ const PLATFORM_OPTIONS: Array<{ text: string; value: PLATFORM_TYPE }> = [ { text: 'RPM / DEB', value: 'rpm-deb' }, ]; -const OnPremInstructions: React.FC = () => { +export const ServiceTokenStep = ({ + serviceToken, + getServiceToken, + isLoadingServiceToken, +}: { + serviceToken?: string; + getServiceToken: () => void; + isLoadingServiceToken: boolean; +}): EuiStepProps => { + return { + title: i18n.translate('xpack.fleet.fleetServerSetup.stepGenerateServiceTokenTitle', { + defaultMessage: 'Generate a service token', + }), + children: ( + <> + + + + + {!serviceToken ? ( + + + { + getServiceToken(); + }} + > + + + + + ) : ( + <> + + + + + + + + + + + + + {serviceToken} + + + + + )} + + ), + }; +}; + +export const FleetServerCommandStep = ({ + serviceToken, + installCommand, + platform, + setPlatform, +}: { + serviceToken?: string; + installCommand: string; + platform: string; + setPlatform: (platform: PLATFORM_TYPE) => void; +}): EuiStepProps => { + return { + title: i18n.translate('xpack.fleet.fleetServerSetup.stepInstallAgentTitle', { + defaultMessage: 'Start Fleet Server', + }), + status: !serviceToken ? 'disabled' : undefined, + children: serviceToken ? ( + <> + + + + + ), + }} + /> + + + + + + } + options={PLATFORM_OPTIONS} + value={platform} + onChange={(e) => setPlatform(e.target.value as PLATFORM_TYPE)} + aria-label={i18n.translate('xpack.fleet.fleetServerSetup.platformSelectAriaLabel', { + defaultMessage: 'Platform', + })} + /> + + + {installCommand} + + + ) : null, + }; +}; + +export const useFleetServerInstructions = () => { const outputsRequest = useGetOutputs(); const { notifications } = useStartServices(); const [serviceToken, setServiceToken] = useState(); @@ -95,6 +233,26 @@ const OnPremInstructions: React.FC = () => { setIsLoadingServiceToken(false); }, [notifications]); + return { + serviceToken, + getServiceToken, + isLoadingServiceToken, + installCommand, + platform, + setPlatform, + }; +}; + +const OnPremInstructions: React.FC = () => { + const { + serviceToken, + getServiceToken, + isLoadingServiceToken, + installCommand, + platform, + setPlatform, + } = useFleetServerInstructions(); + return ( @@ -126,112 +284,8 @@ const OnPremInstructions: React.FC = () => { className="eui-textLeft" steps={[ DownloadStep(), - { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepGenerateServiceTokenTitle', { - defaultMessage: 'Generate a service token', - }), - children: ( - <> - - - - - {!serviceToken ? ( - - - { - getServiceToken(); - }} - > - - - - - ) : ( - <> - - - - - - - - - - - - - {serviceToken} - - - - - )} - - ), - }, - { - title: i18n.translate('xpack.fleet.fleetServerSetup.stepInstallAgentTitle', { - defaultMessage: 'Install the Elastic Agent as a Fleet Server', - }), - status: !serviceToken ? 'disabled' : undefined, - children: serviceToken ? ( - <> - - - - - - - - } - options={PLATFORM_OPTIONS} - value={platform} - onChange={(e) => setPlatform(e.target.value as PLATFORM_TYPE)} - aria-label={i18n.translate( - 'xpack.fleet.fleetServerSetup.platformSelectAriaLabel', - { - defaultMessage: 'Platform', - } - )} - /> - - - {installCommand} - - - ) : null, - }, + ServiceTokenStep({ serviceToken, getServiceToken, isLoadingServiceToken }), + FleetServerCommandStep({ serviceToken, installCommand, platform, setPlatform }), ]} /> diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/index.tsx index 9993014f55cdb..9e6505ede4918 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_requirements_page/index.tsx @@ -6,4 +6,9 @@ */ export { MissingESRequirementsPage } from './es_requirements_page'; -export { FleetServerRequirementPage } from './fleet_server_requirement_page'; +export { + FleetServerRequirementPage, + ServiceTokenStep, + FleetServerCommandStep, + useFleetServerInstructions, +} from './fleet_server_requirement_page'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/managed_instructions.tsx index 34b3536ac2810..8f6a2a26a2f6f 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/managed_instructions.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState } from 'react'; +import React, { useState, useMemo } from 'react'; import { EuiSteps, EuiLink, EuiText, EuiSpacer } from '@elastic/eui'; import type { EuiContainedStepProps } from '@elastic/eui/src/components/steps/steps'; import { i18n } from '@kbn/i18n'; @@ -19,7 +19,12 @@ import { useFleetStatus, } from '../../../../hooks'; import { ManualInstructions } from '../../../../components/enrollment_instructions'; -import { FleetServerRequirementPage } from '../../agent_requirements_page'; +import { + FleetServerRequirementPage, + ServiceTokenStep, + FleetServerCommandStep, + useFleetServerInstructions, +} from '../../agent_requirements_page'; import { DownloadStep, AgentPolicySelectionStep } from './steps'; @@ -58,23 +63,55 @@ export const ManagedInstructions = React.memo(({ agentPolicies }) => { const fleetStatus = useFleetStatus(); const [selectedAPIKeyId, setSelectedAPIKeyId] = useState(); + const [isFleetServerPolicySelected, setIsFleetServerPolicySelected] = useState(false); const apiKey = useGetOneEnrollmentAPIKey(selectedAPIKeyId); const settings = useGetSettings(); - const fleetServerHosts = settings.data?.item?.fleet_server_hosts || []; + const fleetServerInstructions = useFleetServerInstructions(); - const steps: EuiContainedStepProps[] = [ - DownloadStep(), - AgentPolicySelectionStep({ agentPolicies, setSelectedAPIKeyId }), - { - title: i18n.translate('xpack.fleet.agentEnrollment.stepEnrollAndRunAgentTitle', { - defaultMessage: 'Enroll and start the Elastic Agent', + const steps = useMemo(() => { + const { + serviceToken, + getServiceToken, + isLoadingServiceToken, + installCommand, + platform, + setPlatform, + } = fleetServerInstructions; + const fleetServerHosts = settings.data?.item?.fleet_server_hosts || []; + const baseSteps: EuiContainedStepProps[] = [ + DownloadStep(), + AgentPolicySelectionStep({ + agentPolicies, + setSelectedAPIKeyId, + setIsFleetServerPolicySelected, }), - children: apiKey.data && ( - - ), - }, - ]; + ]; + if (isFleetServerPolicySelected) { + baseSteps.push( + ...[ + ServiceTokenStep({ serviceToken, getServiceToken, isLoadingServiceToken }), + FleetServerCommandStep({ serviceToken, installCommand, platform, setPlatform }), + ] + ); + } else { + baseSteps.push({ + title: i18n.translate('xpack.fleet.agentEnrollment.stepEnrollAndRunAgentTitle', { + defaultMessage: 'Enroll and start the Elastic Agent', + }), + children: apiKey.data && ( + + ), + }); + } + return baseSteps; + }, [ + agentPolicies, + apiKey.data, + isFleetServerPolicySelected, + settings.data?.item?.fleet_server_hosts, + fleetServerInstructions, + ]); return ( <> diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/steps.tsx index faa0461ed4773..08b1cbdb341d5 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_enrollment_flyout/steps.tsx @@ -5,12 +5,14 @@ * 2.0. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { EuiText, EuiButton, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import type { AgentPolicy } from '../../../../types'; +import type { AgentPolicy, PackagePolicy } from '../../../../types'; +import { sendGetOneAgentPolicy } from '../../../../hooks'; +import { FLEET_SERVER_PACKAGE } from '../../../../constants'; import { EnrollmentStepAgentPolicy } from './agent_policy_selection'; @@ -48,14 +50,39 @@ export const AgentPolicySelectionStep = ({ agentPolicies, setSelectedAPIKeyId, setSelectedPolicyId, + setIsFleetServerPolicySelected, }: { agentPolicies?: AgentPolicy[]; setSelectedAPIKeyId?: (key: string) => void; setSelectedPolicyId?: (policyId: string) => void; + setIsFleetServerPolicySelected?: (selected: boolean) => void; }) => { const regularAgentPolicies = Array.isArray(agentPolicies) ? agentPolicies.filter((policy) => policy && !policy.is_managed) : []; + + const onAgentPolicyChange = useCallback( + async (policyId: string) => { + if (setSelectedPolicyId) { + setSelectedPolicyId(policyId); + } + if (setIsFleetServerPolicySelected) { + const agentPolicyRequest = await sendGetOneAgentPolicy(policyId); + if ( + agentPolicyRequest.data?.item && + (agentPolicyRequest.data.item.package_policies as PackagePolicy[]).some( + (packagePolicy) => packagePolicy.package?.name === FLEET_SERVER_PACKAGE + ) + ) { + setIsFleetServerPolicySelected(true); + } else { + setIsFleetServerPolicySelected(false); + } + } + }, + [setIsFleetServerPolicySelected, setSelectedPolicyId] + ); + return { title: i18n.translate('xpack.fleet.agentEnrollment.stepChooseAgentPolicyTitle', { defaultMessage: 'Choose an agent policy', @@ -65,7 +92,7 @@ export const AgentPolicySelectionStep = ({ agentPolicies={regularAgentPolicies} withKeySelection={setSelectedAPIKeyId ? true : false} onKeyChange={setSelectedAPIKeyId} - onAgentPolicyChange={setSelectedPolicyId} + onAgentPolicyChange={onAgentPolicyChange} /> ), };