-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Onboarding] k8s quickstart flow (#186380)
Depends on: elastic/elastic-agent#4754 Depends on: #186106 Closes: #182407 ## Summary Adds a Kubernetes onboarding quick start flow using `kubectl kustomize` command. ![CleanShot 2024-06-18 at 15 10 27@2x](https://github.com/elastic/kibana/assets/793851/522d2481-6a0e-43d3-b9ef-d09ee9953b3c) ## How to test 1. Run Kibana and ES locally (make sure to expose ES on 0.0.0.0 so elastic agent can reach it from within a container, I use this command `yarn es snapshot --license trial -E xpack.security.authc.api_key.enabled=true -E http.host=0.0.0.0`) 2. Setup a test cluster with [minikube](https://minikube.sigs.k8s.io/docs/start/?arch=%2Fmacos%2Fx86-64%2Fstable%2Fbinary+download) 3. Open Kibana and navigate to the Onboarding screen 4. Make sure Kubernetes quick start card is visible under the infrastructure category and click on it 5. Copy the command snippet 6. Paste the command into a terminal, but don't run it yet 7. Replace `localhost` in the command with you local IP `ipconfig getifaddr en0` 8. In case elastic/elastic-agent#4754 was not merged yet, you'd need to also clone the elastic-agent repo and replace the template URL with a local path to the `elastic-agent-kustomize/default/elastic-agent-standalone` folder. 9. Run the command and make sure all resources were created 10. Go back to Kibana, after ~1 minute UI should identify that the data was ingested 11. Click on the cluster overview link and make sure it works --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
- Loading branch information
1 parent
fe312f7
commit 141e619
Showing
19 changed files
with
525 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
...bility_onboarding/public/application/quickstart_flows/kubernetes/build_kubectl_command.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
interface Params { | ||
encodedApiKey: string; | ||
onboardingId: string; | ||
elasticsearchUrl: string; | ||
elasticAgentVersion: string; | ||
} | ||
|
||
const KUSTOMIZE_TEMPLATE_URL = | ||
'https://github.com/elastic/elastic-agent/deploy/kubernetes/elastic-agent-kustomize/default/elastic-agent-standalone'; | ||
|
||
export function buildKubectlCommand({ | ||
encodedApiKey, | ||
onboardingId, | ||
elasticsearchUrl, | ||
elasticAgentVersion, | ||
}: Params) { | ||
const escapedElasticsearchUrl = elasticsearchUrl.replace(/\//g, '\\/'); | ||
|
||
return ` | ||
kubectl kustomize ${KUSTOMIZE_TEMPLATE_URL}\\?ref\\=v${elasticAgentVersion} | ||
| sed -e 's/JUFQSV9LRVkl/${encodedApiKey}/g' | ||
-e "s/%ES_HOST%/${escapedElasticsearchUrl}/g" | ||
-e "s/%ONBOARDING_ID%/${onboardingId}/g" | ||
-e "s/\\(docker.elastic.co\\/beats\\/elastic-agent\:\\).*$/\\1${elasticAgentVersion}/g" | ||
-e "/{CA_TRUSTED}/c\\ " | ||
| kubectl apply -f- | ||
` | ||
.trim() | ||
.replace(/\n/g, ' ') | ||
.replace(/\s\s+/g, ' '); | ||
} |
72 changes: 72 additions & 0 deletions
72
...servability_onboarding/public/application/quickstart_flows/kubernetes/command_snippet.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* 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 from 'react'; | ||
import { EuiCodeBlock, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; | ||
import { FormattedMessage } from '@kbn/i18n-react'; | ||
import { i18n } from '@kbn/i18n'; | ||
import { buildKubectlCommand } from './build_kubectl_command'; | ||
import { CopyToClipboardButton } from '../shared/copy_to_clipboard_button'; | ||
|
||
interface Props { | ||
encodedApiKey: string; | ||
onboardingId: string; | ||
elasticsearchUrl: string; | ||
elasticAgentVersion: string; | ||
} | ||
|
||
export function CommandSnippet({ | ||
encodedApiKey, | ||
onboardingId, | ||
elasticsearchUrl, | ||
elasticAgentVersion, | ||
}: Props) { | ||
const command = buildKubectlCommand({ | ||
encodedApiKey, | ||
onboardingId, | ||
elasticsearchUrl, | ||
elasticAgentVersion, | ||
}); | ||
|
||
return ( | ||
<> | ||
<EuiText> | ||
<p> | ||
<FormattedMessage | ||
id="xpack.observability_onboarding.kubernetesPanel.installElasticAgentDescription" | ||
defaultMessage="Copy and run the install command. Note that the following manifest contains resource limits that may not be appropriate for a production environment, review our guide on {scalingLink} before deploying this manifest." | ||
values={{ | ||
scalingLink: ( | ||
<EuiLink | ||
data-test-subj="observabilityOnboardingKubernetesPanelScalingElasticAgentOnKubernetesLink" | ||
href="https://www.elastic.co/guide/en/fleet/current/scaling-on-kubernetes.html" | ||
external | ||
target="_blank" | ||
> | ||
{i18n.translate( | ||
'xpack.observability_onboarding.kubernetesPanel.scalingElasticAgentOnLinkLabel', | ||
{ defaultMessage: 'Scaling Elastic Agent on Kubernetes' } | ||
)} | ||
</EuiLink> | ||
), | ||
}} | ||
/> | ||
</p> | ||
</EuiText> | ||
|
||
<EuiSpacer /> | ||
|
||
<EuiCodeBlock language="text" paddingSize="m" fontSize="m"> | ||
{command} | ||
</EuiCodeBlock> | ||
|
||
<EuiSpacer /> | ||
|
||
<CopyToClipboardButton textToCopy={command} fill /> | ||
</> | ||
); | ||
} |
182 changes: 182 additions & 0 deletions
182
...vability_onboarding/public/application/quickstart_flows/kubernetes/data_ingest_status.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
/* | ||
* 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, { useEffect, useState } from 'react'; | ||
import { EuiFlexGroup, EuiFlexItem, EuiImage, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; | ||
import { css } from '@emotion/react'; | ||
import { i18n } from '@kbn/i18n'; | ||
import { useKibana } from '@kbn/kibana-react-plugin/public'; | ||
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics'; | ||
import { FormattedMessage } from '@kbn/i18n-react'; | ||
import { | ||
StepsProgress, | ||
useFlowProgressTelemetry, | ||
} from '../../../hooks/use_flow_progress_telemetry'; | ||
import { ObservabilityOnboardingContextValue } from '../../../plugin'; | ||
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher'; | ||
import { ProgressIndicator } from '../shared/progress_indicator'; | ||
|
||
interface Props { | ||
onboardingId: string; | ||
} | ||
|
||
const FETCH_INTERVAL = 2000; | ||
const SHOW_TROUBLESHOOTING_DELAY = 120000; // 2 minutes | ||
const CLUSTER_OVERVIEW_DASHBOARD_ID = 'kubernetes-f4dc26db-1b53-4ea2-a78b-1bfab8ea267c'; | ||
|
||
export function DataIngestStatus({ onboardingId }: Props) { | ||
const { | ||
services: { share, http }, | ||
} = useKibana<ObservabilityOnboardingContextValue>(); | ||
const [progress, setProgress] = useState<StepsProgress | undefined>(undefined); | ||
const [checkDataStartTime] = useState(Date.now()); | ||
|
||
const dashboardLocator = share.url.locators.get(DASHBOARD_APP_LOCATOR); | ||
|
||
const { data, status, refetch } = useFetcher( | ||
(callApi) => { | ||
return callApi('GET /internal/observability_onboarding/kubernetes/{onboardingId}/has-data', { | ||
params: { path: { onboardingId } }, | ||
}); | ||
}, | ||
[onboardingId] | ||
); | ||
|
||
useEffect(() => { | ||
const pendingStatusList = [FETCH_STATUS.LOADING, FETCH_STATUS.NOT_INITIATED]; | ||
|
||
if (pendingStatusList.includes(status) || data?.hasData === true) { | ||
return; | ||
} | ||
|
||
const timeout = setTimeout(() => { | ||
refetch(); | ||
}, FETCH_INTERVAL); | ||
|
||
return () => clearTimeout(timeout); | ||
}, [data?.hasData, refetch, status]); | ||
|
||
useEffect(() => { | ||
if (data?.hasData === true) { | ||
setProgress({ 'logs-ingest': { status: 'complete' } }); | ||
} | ||
}, [data?.hasData]); | ||
|
||
useFlowProgressTelemetry(progress, onboardingId); | ||
|
||
const isTroubleshootingVisible = | ||
data?.hasData === false && Date.now() - checkDataStartTime > SHOW_TROUBLESHOOTING_DELAY; | ||
|
||
return ( | ||
<> | ||
<ProgressIndicator | ||
title={data?.hasData ? 'We are monitoring your cluster' : 'Waiting for data to be shipped'} | ||
iconType="checkInCircleFilled" | ||
isLoading={!data?.hasData} | ||
css={css` | ||
max-width: 40%; | ||
`} | ||
/> | ||
|
||
{isTroubleshootingVisible && ( | ||
<> | ||
<EuiSpacer /> | ||
<EuiText color="subdued" size="s"> | ||
<FormattedMessage | ||
id="xpack.observability_onboarding.dataIngestStatus.troubleshootingTextLabel" | ||
defaultMessage="Find more details and troubleshooting solutions in our documentation. {troubleshootingLink}" | ||
values={{ | ||
troubleshootingLink: ( | ||
<EuiLink | ||
data-test-subj="observabilityOnboardingDataIngestStatusTroubleshootingLink" | ||
href="https://www.elastic.co/guide/en/fleet/current/fleet-troubleshooting.html#agent-oom-k8s" | ||
external | ||
target="_blank" | ||
> | ||
{i18n.translate( | ||
'xpack.observability_onboarding.dataIngestStatus.troubleshootingLinkText', | ||
{ | ||
defaultMessage: 'Open documentation', | ||
} | ||
)} | ||
</EuiLink> | ||
), | ||
}} | ||
/> | ||
</EuiText> | ||
</> | ||
)} | ||
|
||
{data?.hasData === true && ( | ||
<> | ||
<EuiSpacer /> | ||
|
||
<EuiFlexGroup alignItems="center"> | ||
<EuiFlexItem grow={false}> | ||
<EuiImage | ||
src={http.staticAssets.getPluginAssetHref('waterfall_screen.svg')} | ||
width={162} | ||
height={117} | ||
alt="" | ||
hasShadow | ||
/> | ||
</EuiFlexItem> | ||
|
||
<EuiFlexItem> | ||
<EuiText> | ||
<p> | ||
{i18n.translate( | ||
'xpack.observability_onboarding.kubernetesPanel.monitoringCluster', | ||
{ | ||
defaultMessage: | ||
'Overview your Kubernetes cluster with this pre-made dashboard', | ||
} | ||
)} | ||
</p> | ||
</EuiText> | ||
<EuiSpacer size="xs" /> | ||
<EuiLink | ||
data-test-subj="observabilityOnboardingDataIngestStatusViewDashboardLink" | ||
href={dashboardLocator?.getRedirectUrl({ | ||
dashboardId: CLUSTER_OVERVIEW_DASHBOARD_ID, | ||
})} | ||
> | ||
{i18n.translate('xpack.observability_onboarding.kubernetesPanel.exploreDashboard', { | ||
defaultMessage: 'Explore Kubernetes cluster', | ||
})} | ||
</EuiLink> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
|
||
<EuiSpacer /> | ||
|
||
<EuiText color="subdued" size="s"> | ||
<FormattedMessage | ||
id="xpack.observability_onboarding.dataIngestStatus.findAllPremadeAssetsTextLabel" | ||
defaultMessage="Find all pre-made assets ready to use {viewAllAssetsLink}" | ||
values={{ | ||
viewAllAssetsLink: ( | ||
<EuiLink | ||
data-test-subj="observabilityOnboardingDataIngestStatusViewAllAssetsLink" | ||
href={`${http.basePath.get()}/app/integrations/detail/kubernetes/assets`} | ||
> | ||
{i18n.translate( | ||
'xpack.observability_onboarding.dataIngestStatus.viewAllAssetsLinkText', | ||
{ | ||
defaultMessage: 'View all assets', | ||
} | ||
)} | ||
</EuiLink> | ||
), | ||
}} | ||
/> | ||
</EuiText> | ||
</> | ||
)} | ||
</> | ||
); | ||
} |
Oops, something went wrong.