mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Logs onboarding] Refactors the install elastic agent steps to own component (#162600)
This commit is contained in:
parent
698ff714de
commit
7277dba30f
4 changed files with 570 additions and 428 deletions
|
@ -8,28 +8,25 @@
|
|||
import {
|
||||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
EuiButtonGroup,
|
||||
EuiCallOut,
|
||||
EuiCodeBlock,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiIconTip,
|
||||
EuiLink,
|
||||
EuiSkeletonRectangle,
|
||||
EuiSpacer,
|
||||
EuiSteps,
|
||||
EuiStepsProps,
|
||||
EuiSwitch,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { Buffer } from 'buffer';
|
||||
import { flatten, zip } from 'lodash';
|
||||
import { default as React, useCallback, useEffect, useState } from 'react';
|
||||
import { useWizard } from '.';
|
||||
import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
|
||||
import { useKibanaNavigation } from '../../../../hooks/use_kibana_navigation';
|
||||
import {
|
||||
ElasticAgentPlatform,
|
||||
getElasticAgentSetupCommand,
|
||||
} from '../../../shared/get_elastic_agent_setup_command';
|
||||
import {
|
||||
InstallElasticAgentSteps,
|
||||
ProgressStepId,
|
||||
EuiStepStatus,
|
||||
} from '../../../shared/install_elastic_agent_steps';
|
||||
import {
|
||||
StepPanel,
|
||||
StepPanelContent,
|
||||
|
@ -37,9 +34,7 @@ import {
|
|||
} from '../../../shared/step_panel';
|
||||
import { ApiKeyBanner } from './api_key_banner';
|
||||
import { BackButton } from './back_button';
|
||||
import { StepStatus } from './step_status';
|
||||
|
||||
type ElasticAgentPlatform = 'linux-tar' | 'macos' | 'windows';
|
||||
export function InstallElasticAgent() {
|
||||
const { navigateToKibanaUrl } = useKibanaNavigation();
|
||||
const { goBack, goToStep, getState, setState } = useWizard();
|
||||
|
@ -196,56 +191,29 @@ export function InstallElasticAgent() {
|
|||
}
|
||||
}, [progressSucceded, refetchProgress]);
|
||||
|
||||
const getStep = useCallback(
|
||||
({ id, incompleteTitle, loadingTitle, completedTitle }) => {
|
||||
const progress = progressData?.progress;
|
||||
if (progress) {
|
||||
const stepStatus = progress?.[id]
|
||||
?.status as EuiStepsProps['steps'][number]['status'];
|
||||
const title =
|
||||
stepStatus === 'loading'
|
||||
? loadingTitle
|
||||
: stepStatus === 'complete'
|
||||
? completedTitle
|
||||
: incompleteTitle;
|
||||
return {
|
||||
title,
|
||||
children: null,
|
||||
status: stepStatus ?? ('incomplete' as const),
|
||||
message: progress?.[id]?.message,
|
||||
};
|
||||
}
|
||||
return {
|
||||
title: incompleteTitle,
|
||||
children: null,
|
||||
status: 'incomplete' as const,
|
||||
};
|
||||
},
|
||||
[progressData?.progress]
|
||||
);
|
||||
const getCheckLogsStep = useCallback(() => {
|
||||
const progress = progressData?.progress;
|
||||
if (progress) {
|
||||
const stepStatus = progress?.['logs-ingest']?.status as EuiStepStatus;
|
||||
const title =
|
||||
stepStatus === 'loading'
|
||||
? CHECK_LOGS_LABELS.loading
|
||||
: stepStatus === 'complete'
|
||||
? CHECK_LOGS_LABELS.completed
|
||||
: CHECK_LOGS_LABELS.incomplete;
|
||||
return { title, status: stepStatus };
|
||||
}
|
||||
return {
|
||||
title: CHECK_LOGS_LABELS.incomplete,
|
||||
status: 'incomplete' as const,
|
||||
};
|
||||
}, [progressData?.progress]);
|
||||
|
||||
const isInstallStarted = progressData?.progress['ea-download'] !== undefined;
|
||||
const isInstallCompleted =
|
||||
progressData?.progress?.['ea-status']?.status === 'complete';
|
||||
|
||||
const autoDownloadConfigStep = getStep({
|
||||
id: 'ea-config',
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaConfig.incompleteTitle',
|
||||
{ defaultMessage: 'Configure the agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaConfig.loadingTitle',
|
||||
{ defaultMessage: 'Downloading Elastic Agent config' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaConfig.completedTitle',
|
||||
{
|
||||
defaultMessage: 'Elastic Agent config written to {configPath}',
|
||||
values: { configPath: '/opt/Elastic/Agent/elastic-agent.yml' },
|
||||
}
|
||||
),
|
||||
});
|
||||
const autoDownloadConfigStatus = (progressData?.progress?.['ea-config']
|
||||
?.status ?? 'incomplete') as EuiStepStatus;
|
||||
|
||||
return (
|
||||
<StepPanel
|
||||
|
@ -311,389 +279,89 @@ export function InstallElasticAgent() {
|
|||
)
|
||||
)}
|
||||
<EuiSpacer size="m" />
|
||||
<EuiSteps
|
||||
steps={[
|
||||
<InstallElasticAgentSteps
|
||||
installAgentPlatformOptions={[
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.title',
|
||||
{ defaultMessage: 'Install the Elastic Agent' }
|
||||
),
|
||||
status:
|
||||
installShipperSetupStatus === FETCH_STATUS.LOADING
|
||||
? 'loading'
|
||||
: isInstallCompleted
|
||||
? 'complete'
|
||||
: 'current',
|
||||
children: (
|
||||
<>
|
||||
<EuiText color="subdued">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.observability_onboarding.installElasticAgent.installStep.description"
|
||||
defaultMessage="Select your platform, and run the install command in your terminal to enroll and start the Elastic Agent. Do this for each host. Review {hostRequirementsLink} before installing."
|
||||
values={{
|
||||
hostRequirementsLink: (
|
||||
<EuiLink
|
||||
external
|
||||
href="https://www.elastic.co/guide/en/fleet/8.7/elastic-agent-installation.html"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.hostRequirements',
|
||||
{
|
||||
defaultMessage:
|
||||
'host requirements and other installation options',
|
||||
}
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer size="l" />
|
||||
<EuiSwitch
|
||||
label={
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="xs"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
{i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.autoDownloadConfig',
|
||||
{
|
||||
defaultMessage:
|
||||
"Automatically download the agent's config",
|
||||
}
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIconTip
|
||||
content={i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.autoDownloadConfig.tooltip',
|
||||
{
|
||||
defaultMessage:
|
||||
"Turn on to add a string to the following code block that downloads the agent's standard configuration to your host during installation. Turn off to manually configure the agent in the next step.",
|
||||
}
|
||||
)}
|
||||
position="right"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
checked={wizardState.autoDownloadConfig}
|
||||
onChange={onAutoDownloadConfig}
|
||||
disabled={
|
||||
isInstallStarted ||
|
||||
(monitoringRole && !monitoringRole?.hasPrivileges)
|
||||
}
|
||||
/>
|
||||
<EuiSpacer size="l" />
|
||||
{wizardState.autoDownloadConfig && (
|
||||
<>
|
||||
<EuiCallOut
|
||||
title={i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.autoDownloadConfig.overwriteWarning',
|
||||
{
|
||||
defaultMessage:
|
||||
'Automatically downloading the agent config will overwrite any existing agent config on your host.',
|
||||
}
|
||||
)}
|
||||
color="warning"
|
||||
iconType="warning"
|
||||
/>
|
||||
<EuiSpacer size="l" />
|
||||
</>
|
||||
)}
|
||||
<EuiButtonGroup
|
||||
isFullWidth
|
||||
legend={i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.choosePlatform',
|
||||
{ defaultMessage: 'Choose platform' }
|
||||
)}
|
||||
options={[
|
||||
{
|
||||
id: 'linux-tar',
|
||||
label: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.choosePlatform.linux',
|
||||
{ defaultMessage: 'Linux' }
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'macos',
|
||||
label: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.choosePlatform.macOS',
|
||||
{ defaultMessage: 'MacOS' }
|
||||
),
|
||||
isDisabled: true,
|
||||
},
|
||||
{
|
||||
id: 'windows',
|
||||
label: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.choosePlatform.windows',
|
||||
{ defaultMessage: 'Windows' }
|
||||
),
|
||||
isDisabled: true,
|
||||
},
|
||||
]}
|
||||
type="single"
|
||||
idSelected={elasticAgentPlatform}
|
||||
onChange={(id: string) =>
|
||||
setElasticAgentPlatform(id as typeof elasticAgentPlatform)
|
||||
}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiCodeBlock language="bash" isCopyable>
|
||||
{getInstallShipperCommand({
|
||||
elasticAgentPlatform,
|
||||
apiKeyEncoded,
|
||||
apiEndpoint: setup?.apiEndpoint,
|
||||
scriptDownloadUrl: setup?.scriptDownloadUrl,
|
||||
elasticAgentVersion: setup?.elasticAgentVersion,
|
||||
autoDownloadConfig: wizardState.autoDownloadConfig,
|
||||
onboardingId,
|
||||
})}
|
||||
</EuiCodeBlock>
|
||||
<EuiSpacer size="m" />
|
||||
{isInstallStarted && (
|
||||
<>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup direction="column" gutterSize="m">
|
||||
{[
|
||||
{
|
||||
id: 'ea-download',
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaDownload.incompleteTitle',
|
||||
{ defaultMessage: 'Download Elastic Agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaDownload.loadingTitle',
|
||||
{ defaultMessage: 'Downloading Elastic Agent' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaDownload.completedTitle',
|
||||
{ defaultMessage: 'Elastic Agent downloaded' }
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'ea-extract',
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaExtract.incompleteTitle',
|
||||
{ defaultMessage: 'Extract Elastic Agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaExtract.loadingTitle',
|
||||
{ defaultMessage: 'Extracting Elastic Agent' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaExtract.completedTitle',
|
||||
{ defaultMessage: 'Elastic Agent extracted' }
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'ea-install',
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaInstall.incompleteTitle',
|
||||
{ defaultMessage: 'Install Elastic Agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaInstall.loadingTitle',
|
||||
{ defaultMessage: 'Installing Elastic Agent' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaInstall.completedTitle',
|
||||
{ defaultMessage: 'Elastic Agent installed' }
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'ea-status',
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaStatus.incompleteTitle',
|
||||
{ defaultMessage: 'Connect to the Elastic Agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaStatus.loadingTitle',
|
||||
{
|
||||
defaultMessage:
|
||||
'Connecting to the Elastic Agent',
|
||||
}
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaStatus.completedTitle',
|
||||
{
|
||||
defaultMessage:
|
||||
'Connected to the Elastic Agent',
|
||||
}
|
||||
),
|
||||
},
|
||||
].map((step, index) => {
|
||||
const { title, status, message } = getStep(step);
|
||||
return (
|
||||
<StepStatus
|
||||
status={status}
|
||||
title={title}
|
||||
message={message}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
label: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.choosePlatform.linux',
|
||||
{ defaultMessage: 'Linux' }
|
||||
),
|
||||
id: 'linux-tar',
|
||||
},
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configureStep.title',
|
||||
{ defaultMessage: 'Configure the Elastic agent' }
|
||||
),
|
||||
status:
|
||||
yamlConfigStatus === FETCH_STATUS.LOADING
|
||||
? 'loading'
|
||||
: autoDownloadConfigStep.status,
|
||||
children: (
|
||||
<>
|
||||
<EuiText color="subdued">
|
||||
<p>
|
||||
{wizardState.autoDownloadConfig
|
||||
? i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configStep.auto.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'The agent config below will be downloaded by the install script and written to ({configPath}). This will overwrite any existing agent configuration.',
|
||||
values: {
|
||||
configPath:
|
||||
'/opt/Elastic/Agent/elastic-agent.yml',
|
||||
},
|
||||
}
|
||||
)
|
||||
: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configStep.manual.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Add the following configuration to {configPath} on the host where you installed the Elastic agent.',
|
||||
values: {
|
||||
configPath:
|
||||
'/opt/Elastic/Agent/elastic-agent.yml',
|
||||
},
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiSkeletonRectangle
|
||||
isLoading={yamlConfigStatus === FETCH_STATUS.NOT_INITIATED}
|
||||
contentAriaLabel={i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configStep.yamlCodeBlockdescription',
|
||||
{ defaultMessage: 'Elastic agent yaml configuration' }
|
||||
)}
|
||||
width="100%"
|
||||
height={300}
|
||||
borderRadius="s"
|
||||
>
|
||||
<EuiCodeBlock
|
||||
language="yaml"
|
||||
isCopyable
|
||||
style={{
|
||||
opacity: wizardState.autoDownloadConfig ? '.5' : '1',
|
||||
}}
|
||||
>
|
||||
{yamlConfig}
|
||||
</EuiCodeBlock>
|
||||
</EuiSkeletonRectangle>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiButton
|
||||
iconType="download"
|
||||
color="primary"
|
||||
href={`data:application/yaml;base64,${Buffer.from(
|
||||
yamlConfig,
|
||||
'utf8'
|
||||
).toString('base64')}`}
|
||||
download="elastic-agent.yml"
|
||||
target="_blank"
|
||||
isDisabled={wizardState.autoDownloadConfig}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configStep.downloadConfigButton',
|
||||
{ defaultMessage: 'Download config file' }
|
||||
)}
|
||||
</EuiButton>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup direction="column">
|
||||
<StepStatus
|
||||
status={autoDownloadConfigStep.status}
|
||||
title={autoDownloadConfigStep.title}
|
||||
message={autoDownloadConfigStep.message}
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
label: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.choosePlatform.macOS',
|
||||
{ defaultMessage: 'MacOS' }
|
||||
),
|
||||
id: 'macos',
|
||||
},
|
||||
getStep({
|
||||
id: 'logs-ingest',
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.logsIngest.incompleteTitle',
|
||||
{ defaultMessage: 'Ship logs to Elastic Observability' }
|
||||
{
|
||||
label: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.choosePlatform.windows',
|
||||
{ defaultMessage: 'Windows' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.logsIngest.loadingTitle',
|
||||
{ defaultMessage: 'Waiting for Logs to be shipped...' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.logsIngest.completedTitle',
|
||||
{ defaultMessage: 'Logs are being shipped!' }
|
||||
),
|
||||
}),
|
||||
id: 'windows',
|
||||
isDisabled: true,
|
||||
},
|
||||
]}
|
||||
onSelectPlatform={(id) => setElasticAgentPlatform(id)}
|
||||
selectedPlatform={elasticAgentPlatform}
|
||||
installAgentCommand={getElasticAgentSetupCommand({
|
||||
elasticAgentPlatform,
|
||||
apiKeyEncoded,
|
||||
apiEndpoint: setup?.apiEndpoint,
|
||||
scriptDownloadUrl: setup?.scriptDownloadUrl,
|
||||
elasticAgentVersion: setup?.elasticAgentVersion,
|
||||
autoDownloadConfig: wizardState.autoDownloadConfig,
|
||||
onboardingId,
|
||||
})}
|
||||
autoDownloadConfig={wizardState.autoDownloadConfig}
|
||||
onToggleAutoDownloadConfig={onAutoDownloadConfig}
|
||||
installAgentStatus={
|
||||
installShipperSetupStatus === FETCH_STATUS.LOADING
|
||||
? 'loading'
|
||||
: isInstallCompleted
|
||||
? 'complete'
|
||||
: 'current'
|
||||
}
|
||||
showInstallProgressSteps={isInstallStarted}
|
||||
installProgressSteps={
|
||||
(progressData?.progress ?? {}) as Partial<
|
||||
Record<
|
||||
ProgressStepId,
|
||||
{ status: EuiStepStatus; message?: string }
|
||||
>
|
||||
>
|
||||
}
|
||||
configureAgentStatus={
|
||||
yamlConfigStatus === FETCH_STATUS.LOADING
|
||||
? 'loading'
|
||||
: autoDownloadConfigStatus
|
||||
}
|
||||
configureAgentYaml={yamlConfig}
|
||||
appendedSteps={[getCheckLogsStep()]}
|
||||
/>
|
||||
</StepPanelContent>
|
||||
</StepPanel>
|
||||
);
|
||||
}
|
||||
|
||||
function getInstallShipperCommand({
|
||||
elasticAgentPlatform,
|
||||
apiKeyEncoded = '$API_KEY',
|
||||
apiEndpoint = '$API_ENDPOINT',
|
||||
scriptDownloadUrl = '$SCRIPT_DOWNLOAD_URL',
|
||||
elasticAgentVersion = '$ELASTIC_AGENT_VERSION',
|
||||
autoDownloadConfig = false,
|
||||
onboardingId = '$ONBOARDING_ID',
|
||||
}: {
|
||||
elasticAgentPlatform: ElasticAgentPlatform;
|
||||
apiKeyEncoded: string | undefined;
|
||||
apiEndpoint: string | undefined;
|
||||
scriptDownloadUrl: string | undefined;
|
||||
elasticAgentVersion: string | undefined;
|
||||
autoDownloadConfig: boolean;
|
||||
onboardingId: string | undefined;
|
||||
}) {
|
||||
const setupScriptFilename = 'standalone_agent_setup.sh';
|
||||
const PLATFORM_COMMAND: Record<ElasticAgentPlatform, string> = {
|
||||
'linux-tar': oneLine`
|
||||
curl ${scriptDownloadUrl} -o ${setupScriptFilename} &&
|
||||
sudo bash ${setupScriptFilename} ${apiKeyEncoded} ${apiEndpoint} ${elasticAgentVersion} ${onboardingId} ${
|
||||
autoDownloadConfig ? 'autoDownloadConfig=1' : ''
|
||||
}
|
||||
`,
|
||||
macos: oneLine`
|
||||
curl -O https://elastic.co/agent-setup.sh &&
|
||||
sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==
|
||||
`,
|
||||
windows: oneLine`
|
||||
curl -O https://elastic.co/agent-setup.sh &&
|
||||
sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==
|
||||
`,
|
||||
};
|
||||
return PLATFORM_COMMAND[elasticAgentPlatform];
|
||||
}
|
||||
|
||||
function oneLine(parts: TemplateStringsArray, ...args: string[]) {
|
||||
const str = flatten(zip(parts, args)).join('');
|
||||
return str.replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
|
||||
type WizardState = ReturnType<ReturnType<typeof useWizard>['getState']>;
|
||||
function hasAlreadySavedFlow({ apiKeyEncoded, onboardingId }: WizardState) {
|
||||
return Boolean(apiKeyEncoded && onboardingId);
|
||||
}
|
||||
|
||||
const CHECK_LOGS_LABELS = {
|
||||
incomplete: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.logsIngest.incompleteTitle',
|
||||
{ defaultMessage: 'Ship logs to Elastic Observability' }
|
||||
),
|
||||
loading: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.logsIngest.loadingTitle',
|
||||
{ defaultMessage: 'Waiting for Logs to be shipped...' }
|
||||
),
|
||||
completed: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.logsIngest.completedTitle',
|
||||
{ defaultMessage: 'Logs are being shipped!' }
|
||||
),
|
||||
};
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 { flatten, zip } from 'lodash';
|
||||
|
||||
export type ElasticAgentPlatform = 'linux-tar' | 'macos' | 'windows';
|
||||
|
||||
export function getElasticAgentSetupCommand({
|
||||
elasticAgentPlatform,
|
||||
apiKeyEncoded = '$API_KEY',
|
||||
apiEndpoint = '$API_ENDPOINT',
|
||||
scriptDownloadUrl = '$SCRIPT_DOWNLOAD_URL',
|
||||
elasticAgentVersion = '$ELASTIC_AGENT_VERSION',
|
||||
autoDownloadConfig = false,
|
||||
onboardingId = '$ONBOARDING_ID',
|
||||
}: {
|
||||
elasticAgentPlatform: ElasticAgentPlatform;
|
||||
apiKeyEncoded: string | undefined;
|
||||
apiEndpoint: string | undefined;
|
||||
scriptDownloadUrl: string | undefined;
|
||||
elasticAgentVersion: string | undefined;
|
||||
autoDownloadConfig: boolean;
|
||||
onboardingId: string | undefined;
|
||||
}) {
|
||||
const setupScriptFilename = 'standalone_agent_setup.sh';
|
||||
const LINUX_MACOS_COMMAND = oneLine`
|
||||
curl ${scriptDownloadUrl} -o ${setupScriptFilename} &&
|
||||
sudo bash ${setupScriptFilename} ${apiKeyEncoded} ${apiEndpoint} ${elasticAgentVersion} ${onboardingId} ${
|
||||
autoDownloadConfig ? `autoDownloadConfig=1` : ''
|
||||
}
|
||||
`;
|
||||
const PLATFORM_COMMAND: Record<ElasticAgentPlatform, string> = {
|
||||
'linux-tar': LINUX_MACOS_COMMAND,
|
||||
macos: LINUX_MACOS_COMMAND,
|
||||
windows: oneLine`
|
||||
curl -O https://elastic.co/agent-setup.sh &&
|
||||
sudo bash agent-setup.sh -- service.name=my-service --url=https://elasticsearch:8220 --enrollment-token=SRSc2ozWUItWXNuWE5oZzdERFU6anJtY0FIzhSRGlzeTJYcUF5UklfUQ==
|
||||
`,
|
||||
};
|
||||
return PLATFORM_COMMAND[elasticAgentPlatform];
|
||||
}
|
||||
|
||||
function oneLine(parts: TemplateStringsArray, ...args: string[]) {
|
||||
const str = flatten(zip(parts, args)).join('');
|
||||
return str.replace(/\s+/g, ' ').trim();
|
||||
}
|
|
@ -0,0 +1,425 @@
|
|||
/*
|
||||
* 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 {
|
||||
EuiButton,
|
||||
EuiButtonGroup,
|
||||
EuiCallOut,
|
||||
EuiCodeBlock,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiIconTip,
|
||||
EuiLink,
|
||||
EuiSkeletonRectangle,
|
||||
EuiSpacer,
|
||||
EuiSteps,
|
||||
EuiStepsProps,
|
||||
EuiSwitch,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Buffer } from 'buffer';
|
||||
import React from 'react';
|
||||
import { intersection } from 'lodash';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { StepStatus } from './step_status';
|
||||
|
||||
export type EuiStepStatus = EuiStepsProps['steps'][number]['status'];
|
||||
|
||||
export type ProgressStepId =
|
||||
| 'ea-download'
|
||||
| 'ea-extract'
|
||||
| 'ea-install'
|
||||
| 'ea-status'
|
||||
| 'ea-config';
|
||||
|
||||
interface Props<PlatformId extends string> {
|
||||
installAgentPlatformOptions: Array<{
|
||||
label: string;
|
||||
id: PlatformId;
|
||||
isDisabled?: boolean;
|
||||
}>;
|
||||
onSelectPlatform: (id: PlatformId) => void;
|
||||
selectedPlatform: PlatformId;
|
||||
installAgentCommand: string;
|
||||
autoDownloadConfig: boolean;
|
||||
onToggleAutoDownloadConfig: () => void;
|
||||
installAgentStatus: EuiStepStatus;
|
||||
showInstallProgressSteps: boolean;
|
||||
installProgressSteps: Partial<
|
||||
Record<ProgressStepId, { status: EuiStepStatus; message?: string }>
|
||||
>;
|
||||
configureAgentStatus: EuiStepStatus;
|
||||
configureAgentYaml: string;
|
||||
appendedSteps?: Array<Omit<EuiStepsProps['steps'][number], 'children'>>;
|
||||
}
|
||||
|
||||
export function InstallElasticAgentSteps<PlatformId extends string>({
|
||||
installAgentPlatformOptions,
|
||||
onSelectPlatform,
|
||||
selectedPlatform,
|
||||
installAgentCommand,
|
||||
autoDownloadConfig,
|
||||
onToggleAutoDownloadConfig,
|
||||
installAgentStatus,
|
||||
showInstallProgressSteps,
|
||||
installProgressSteps,
|
||||
configureAgentStatus,
|
||||
configureAgentYaml,
|
||||
appendedSteps = [],
|
||||
}: Props<PlatformId>) {
|
||||
const isInstallStarted =
|
||||
intersection(
|
||||
Object.keys(installProgressSteps),
|
||||
Object.keys(PROGRESS_STEP_TITLES)
|
||||
).length > 0;
|
||||
const autoDownloadConfigStep = getStep('ea-config', installProgressSteps);
|
||||
return (
|
||||
<EuiSteps
|
||||
steps={[
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.title',
|
||||
{ defaultMessage: 'Install the Elastic Agent' }
|
||||
),
|
||||
status: installAgentStatus,
|
||||
children: (
|
||||
<>
|
||||
<EuiText color="subdued">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.observability_onboarding.installElasticAgent.installStep.description"
|
||||
defaultMessage="Select your platform, and run the install command in your terminal to enroll and start the Elastic Agent. Do this for each host. Review {hostRequirementsLink} before installing."
|
||||
values={{
|
||||
hostRequirementsLink: (
|
||||
<EuiLink
|
||||
external
|
||||
href="https://www.elastic.co/guide/en/fleet/8.7/elastic-agent-installation.html"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.hostRequirements',
|
||||
{
|
||||
defaultMessage:
|
||||
'host requirements and other installation options',
|
||||
}
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer size="l" />
|
||||
<EuiSwitch
|
||||
label={
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="xs"
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
{i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.autoDownloadConfig',
|
||||
{
|
||||
defaultMessage:
|
||||
"Automatically download the agent's config",
|
||||
}
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIconTip
|
||||
content={i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.autoDownloadConfig.tooltip',
|
||||
{
|
||||
defaultMessage:
|
||||
"Turn on to add a string to the following code block that downloads the agent's standard configuration to your host during installation. Turn off to manually configure the agent in the next step.",
|
||||
}
|
||||
)}
|
||||
position="right"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
checked={autoDownloadConfig}
|
||||
onChange={onToggleAutoDownloadConfig}
|
||||
disabled={isInstallStarted}
|
||||
/>
|
||||
<EuiSpacer size="l" />
|
||||
{autoDownloadConfig && (
|
||||
<>
|
||||
<EuiCallOut
|
||||
title={i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.autoDownloadConfig.overwriteWarning',
|
||||
{
|
||||
defaultMessage:
|
||||
'Automatically downloading the agent config will overwrite any existing agent config on your host.',
|
||||
}
|
||||
)}
|
||||
color="warning"
|
||||
iconType="warning"
|
||||
/>
|
||||
<EuiSpacer size="l" />
|
||||
</>
|
||||
)}
|
||||
<EuiButtonGroup
|
||||
isFullWidth
|
||||
legend={i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.installStep.choosePlatform',
|
||||
{ defaultMessage: 'Choose platform' }
|
||||
)}
|
||||
options={installAgentPlatformOptions.map(
|
||||
({ id, label, isDisabled }) => ({
|
||||
id,
|
||||
label,
|
||||
isDisabled,
|
||||
})
|
||||
)}
|
||||
type="single"
|
||||
idSelected={selectedPlatform}
|
||||
onChange={(id: string) => {
|
||||
onSelectPlatform(id as PlatformId);
|
||||
}}
|
||||
isDisabled={isInstallStarted}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiCodeBlock language="bash" isCopyable>
|
||||
{installAgentCommand}
|
||||
</EuiCodeBlock>
|
||||
<EuiSpacer size="m" />
|
||||
{showInstallProgressSteps && (
|
||||
<>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup direction="column" gutterSize="m">
|
||||
{(
|
||||
[
|
||||
'ea-download',
|
||||
'ea-extract',
|
||||
'ea-install',
|
||||
'ea-status',
|
||||
] as const
|
||||
).map((stepId) => {
|
||||
const { title, status, message } = getStep(
|
||||
stepId,
|
||||
installProgressSteps
|
||||
);
|
||||
return (
|
||||
<StepStatus
|
||||
key={stepId}
|
||||
status={status}
|
||||
title={title}
|
||||
message={message}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configureStep.title',
|
||||
{ defaultMessage: 'Configure the Elastic agent' }
|
||||
),
|
||||
status: configureAgentStatus,
|
||||
children: (
|
||||
<>
|
||||
<EuiText color="subdued">
|
||||
<p>
|
||||
{autoDownloadConfig
|
||||
? i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configStep.auto.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'The agent config below will be downloaded by the install script and written to ({configPath}). This will overwrite any existing agent configuration.',
|
||||
values: {
|
||||
configPath: '/opt/Elastic/Agent/elastic-agent.yml',
|
||||
},
|
||||
}
|
||||
)
|
||||
: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configStep.manual.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Add the following configuration to {configPath} on the host where you installed the Elastic agent.',
|
||||
values: {
|
||||
configPath: '/opt/Elastic/Agent/elastic-agent.yml',
|
||||
},
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiSkeletonRectangle
|
||||
isLoading={false}
|
||||
contentAriaLabel={i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configStep.yamlCodeBlockdescription',
|
||||
{ defaultMessage: 'Elastic agent yaml configuration' }
|
||||
)}
|
||||
width="100%"
|
||||
height={300}
|
||||
borderRadius="s"
|
||||
>
|
||||
<EuiCodeBlock
|
||||
language="yaml"
|
||||
isCopyable
|
||||
style={{
|
||||
opacity: autoDownloadConfig ? '.5' : '1',
|
||||
}}
|
||||
>
|
||||
{configureAgentYaml}
|
||||
</EuiCodeBlock>
|
||||
</EuiSkeletonRectangle>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiButton
|
||||
iconType="download"
|
||||
color="primary"
|
||||
href={`data:application/yaml;base64,${Buffer.from(
|
||||
configureAgentYaml,
|
||||
'utf8'
|
||||
).toString('base64')}`}
|
||||
download="elastic-agent.yml"
|
||||
target="_blank"
|
||||
isDisabled={autoDownloadConfig}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.configStep.downloadConfigButton',
|
||||
{ defaultMessage: 'Download config file' }
|
||||
)}
|
||||
</EuiButton>
|
||||
{showInstallProgressSteps && autoDownloadConfig ? (
|
||||
<>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup direction="column">
|
||||
<StepStatus
|
||||
status={autoDownloadConfigStep.status}
|
||||
title={autoDownloadConfigStep.title}
|
||||
message={autoDownloadConfigStep.message}
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
) : null}
|
||||
</>
|
||||
),
|
||||
},
|
||||
...appendedSteps.map((euiStep) => ({ children: null, ...euiStep })),
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function getStep(
|
||||
id: ProgressStepId,
|
||||
installProgressSteps: Props<string>['installProgressSteps']
|
||||
): { title: string; status: EuiStepStatus; message?: string } {
|
||||
const { loadingTitle, completedTitle, incompleteTitle } =
|
||||
PROGRESS_STEP_TITLES[id];
|
||||
const stepProgress = installProgressSteps[id];
|
||||
if (stepProgress) {
|
||||
const { status, message } = stepProgress;
|
||||
const title =
|
||||
status === 'loading'
|
||||
? loadingTitle
|
||||
: status === 'complete'
|
||||
? completedTitle
|
||||
: incompleteTitle;
|
||||
return {
|
||||
title,
|
||||
status: status ?? ('incomplete' as const),
|
||||
message,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
title: incompleteTitle,
|
||||
status: 'incomplete' as const,
|
||||
};
|
||||
}
|
||||
|
||||
const PROGRESS_STEP_TITLES: Record<
|
||||
ProgressStepId,
|
||||
Record<'incompleteTitle' | 'loadingTitle' | 'completedTitle', string>
|
||||
> = {
|
||||
'ea-download': {
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaDownload.incompleteTitle',
|
||||
{ defaultMessage: 'Download Elastic Agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaDownload.loadingTitle',
|
||||
{ defaultMessage: 'Downloading Elastic Agent' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaDownload.completedTitle',
|
||||
{ defaultMessage: 'Elastic Agent downloaded' }
|
||||
),
|
||||
},
|
||||
'ea-extract': {
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaExtract.incompleteTitle',
|
||||
{ defaultMessage: 'Extract Elastic Agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaExtract.loadingTitle',
|
||||
{ defaultMessage: 'Extracting Elastic Agent' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaExtract.completedTitle',
|
||||
{ defaultMessage: 'Elastic Agent extracted' }
|
||||
),
|
||||
},
|
||||
'ea-install': {
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaInstall.incompleteTitle',
|
||||
{ defaultMessage: 'Install Elastic Agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaInstall.loadingTitle',
|
||||
{ defaultMessage: 'Installing Elastic Agent' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaInstall.completedTitle',
|
||||
{ defaultMessage: 'Elastic Agent installed' }
|
||||
),
|
||||
},
|
||||
'ea-status': {
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaStatus.incompleteTitle',
|
||||
{ defaultMessage: 'Connect to the Elastic Agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaStatus.loadingTitle',
|
||||
{
|
||||
defaultMessage: 'Connecting to the Elastic Agent',
|
||||
}
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaStatus.completedTitle',
|
||||
{
|
||||
defaultMessage: 'Connected to the Elastic Agent',
|
||||
}
|
||||
),
|
||||
},
|
||||
'ea-config': {
|
||||
incompleteTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaConfig.incompleteTitle',
|
||||
{ defaultMessage: 'Configure the agent' }
|
||||
),
|
||||
loadingTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaConfig.loadingTitle',
|
||||
{ defaultMessage: 'Downloading Elastic Agent config' }
|
||||
),
|
||||
completedTitle: i18n.translate(
|
||||
'xpack.observability_onboarding.installElasticAgent.progress.eaConfig.completedTitle',
|
||||
{
|
||||
defaultMessage: 'Elastic Agent config written to {configPath}',
|
||||
values: { configPath: '/opt/Elastic/Agent/elastic-agent.yml' },
|
||||
}
|
||||
),
|
||||
},
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue