Add link to ingest pipeline dashboard from Stack Monitoring (#149721)

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/149386
This commit is contained in:
Josh Dover 2023-02-03 08:06:24 +01:00 committed by GitHub
parent f2b8c7f907
commit 136171a63d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 200 additions and 4 deletions

View file

@ -16,7 +16,9 @@
"triggersActionsUi",
"alerting",
"actions",
"encryptedSavedObjects"
"encryptedSavedObjects",
"dashboard",
"fleet"
],
"server": true,
"ui": true,

View file

@ -6,10 +6,15 @@
*/
import React from 'react';
import { i18n } from '@kbn/i18n';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { includes } from 'lodash';
import { DashboardStart } from '@kbn/dashboard-plugin/public';
import { FleetStart } from '@kbn/fleet-plugin/public';
import { EuiIcon, EuiToolTip } from '@elastic/eui';
import { PageTemplate } from '../page_template';
import { TabMenuItem, PageTemplateProps } from '../page_template';
import { ML_SUPPORTED_LICENSES } from '../../../../common/constants';
import { ingestPipelineTabOnClick } from './ingest_pipeline_modal';
interface ElasticsearchTemplateProps extends PageTemplateProps {
cluster?: any;
@ -19,6 +24,8 @@ export const ElasticsearchTemplate: React.FC<ElasticsearchTemplateProps> = ({
cluster,
...props
}) => {
const { services } = useKibana<{ dashboard?: DashboardStart; fleet?: FleetStart }>();
const tabs: TabMenuItem[] = [
{
id: 'overview',
@ -43,6 +50,25 @@ export const ElasticsearchTemplate: React.FC<ElasticsearchTemplateProps> = ({
},
];
if (services.dashboard) {
tabs.push({
id: 'ingest_pipeines',
label: i18n.translate('xpack.monitoring.esNavigation.ingestPipelinesLinkText', {
defaultMessage: 'Ingest Pipelines',
}),
prepend: (
<EuiToolTip
content={i18n.translate('xpack.monitoring.esNavigation.ingestPipelinesBetaTooltip', {
defaultMessage: 'Ingest Pipeline monitoring is a beta feature',
})}
>
<EuiIcon type="beaker" />
</EuiToolTip>
),
onClick: () => ingestPipelineTabOnClick(services),
});
}
if (cluster && mlIsSupported(cluster.license)) {
tabs.push({
id: 'ml',

View file

@ -0,0 +1,158 @@
/*
* 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 { toMountPoint } from '@kbn/kibana-react-plugin/public';
import type { CoreStart } from '@kbn/core/public';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { EuiCallOut, EuiConfirmModal, EuiSpacer } from '@elastic/eui';
import { DashboardStart } from '@kbn/dashboard-plugin/public';
import { FleetStart } from '@kbn/fleet-plugin/public';
const INGEST_PIPELINE_DASHBOARD_ID = 'elasticsearch-metrics-ingest-pipelines';
/**
* If the ingest pipeline dashboard is installed, navigate to it. Otherwise, prompt the user to install the package
* first, then navigate. If user does not have permission to install packages, show a message.
* @param services
* @returns
*/
export const ingestPipelineTabOnClick = async (
services: Partial<CoreStart & { dashboard: DashboardStart; fleet: FleetStart }>
) => {
const dashboard = await services.savedObjects!.client.get(
'dashboard',
INGEST_PIPELINE_DASHBOARD_ID
);
const dashboardFound = !dashboard.error && dashboard.attributes;
const navigateToDashboard = () =>
services.dashboard!.locator!.navigate({
dashboardId: INGEST_PIPELINE_DASHBOARD_ID,
});
if (!dashboardFound) {
const installPackage = () => services.http!.post('/api/fleet/epm/packages/elasticsearch');
const ref = services.overlays!.openModal(
toMountPoint(
<IngestPipelineModal
installPackage={installPackage}
navigateToDashboard={navigateToDashboard}
canInstallPackages={!!services.fleet?.authz.integrations.installPackages}
closeModal={() => ref.close()}
/>,
{
theme$: services.theme?.theme$,
}
)
);
return await ref.onClose;
} else {
return navigateToDashboard();
}
};
/**
* Modal to prompt the user to either install the Elasticsearch integration or contact an admin.
*/
export const IngestPipelineModal = ({
canInstallPackages,
closeModal,
installPackage,
navigateToDashboard,
}: {
closeModal: () => void;
canInstallPackages: boolean;
installPackage: () => Promise<unknown>;
navigateToDashboard: () => void;
}) => {
const [installing, setInstalling] = useState(false);
const [error, setError] = useState<string>();
if (!canInstallPackages) {
return (
<EuiConfirmModal
title={i18n.translate(
'xpack.monitoring.esNavigation.ingestPipelineModal.noPermissionToInstallPackage.packageRequiredTitle',
{ defaultMessage: 'Elasticsearch integration is required' }
)}
confirmButtonText={i18n.translate(
'xpack.monitoring.esNavigation.ingestPipelineModal.noPermissionToInstallPackage.confirmButtonText',
{ defaultMessage: 'OK' }
)}
onCancel={closeModal}
onConfirm={closeModal}
>
<p>
<FormattedMessage
id="xpack.monitoring.esNavigation.ingestPipelineModal.noPermissionToInstallPackage.descriptionText"
defaultMessage="Viewing Ingest pipeline metrics requires installing the Elasticsearch integration. You must ask your administrator to install it."
/>
</p>
</EuiConfirmModal>
);
}
return (
<EuiConfirmModal
title={i18n.translate(
'xpack.monitoring.esNavigation.ingestPipelineModal.installPromptTitle',
{
defaultMessage: 'Install Elasticsearch integration?',
}
)}
confirmButtonText={i18n.translate(
'xpack.monitoring.esNavigation.ingestPipelineModal.installButtonText',
{ defaultMessage: 'Install' }
)}
cancelButtonText={i18n.translate(
'xpack.monitoring.esNavigation.ingestPipelineModal.cancelButtonText',
{ defaultMessage: 'Cancel' }
)}
confirmButtonDisabled={installing}
onCancel={closeModal}
onConfirm={async () => {
setInstalling(true);
try {
await installPackage();
closeModal();
navigateToDashboard();
} catch (e) {
setError(e.body?.error || e.message);
setInstalling(false);
}
}}
>
{error && (
<>
<EuiCallOut
title={
<FormattedMessage
id="xpack.monitoring.esNavigation.ingestPipelineModal.errorCalloutText"
defaultMessage="Could not install the package due to an error: {error}"
values={{ error }}
/>
}
color="danger"
iconType="alert"
/>
<EuiSpacer />
</>
)}
<p>
<FormattedMessage
id="xpack.monitoring.esNavigation.ingestPipelineModal.installPromptDescriptionText"
defaultMessage="Viewing Ingest pipeline metrics requires installing the Elasticsearch integration. Do you
want to install it now?"
/>
</p>
</EuiConfirmModal>
);
};

View file

@ -38,7 +38,9 @@ export interface TabMenuItem {
id: string;
label: string;
testSubj?: string;
route: string;
route?: string;
onClick?: () => void;
prepend?: React.ReactNode;
}
export interface PageTemplateProps {
title: string;
@ -139,8 +141,10 @@ export const PageTemplate: React.FC<PageTemplateProps> = ({
disabled={isDisabledTab(product)}
title={item.label}
data-test-subj={item.testSubj}
href={createHref(item.route)}
isSelected={isTabSelected(item.route)}
href={item.route ? createHref(item.route) : undefined}
isSelected={item.route ? isTabSelected(item.route) : undefined}
onClick={item.onClick}
prepend={item.prepend}
>
{item.label}
</EuiTab>

View file

@ -13,6 +13,8 @@ import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
export type { MonitoringConfig } from '../server';
export type { MLJobs } from '../server/lib/elasticsearch/get_ml_jobs';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { DashboardStart } from '@kbn/dashboard-plugin/public';
import { FleetStart } from '@kbn/fleet-plugin/public';
export interface MonitoringStartPluginDependencies {
navigation: NavigationStart;
@ -20,6 +22,8 @@ export interface MonitoringStartPluginDependencies {
triggersActionsUi: TriggersAndActionsUIPublicPluginStart;
usageCollection: UsageCollectionSetup;
dataViews: DataViewsPublicPluginStart;
dashboard?: DashboardStart;
fleet?: FleetStart;
}
interface LegacyStartDependencies {

View file

@ -37,6 +37,8 @@
"@kbn/core-elasticsearch-client-server-mocks",
"@kbn/logging-mocks",
"@kbn/io-ts-utils",
"@kbn/dashboard-plugin",
"@kbn/fleet-plugin",
],
"exclude": [
"target/**/*",