kibana/x-pack/plugins/infra/public/apps/metrics_app.tsx
Mykola Harmash d0a0a1f9e6
[Infra IU] Disable Metrics Explorer for serverless (#167022)
Closes #163282 

## Summary

This PR:
* Adds a `featureFlags.metricsExplorerEnabled` property to the Infra
plugin config to enable and disable Metrics Explorer depending on the
offering type
* Prevents `MetricsExplorerViewsService` initialization for serveless
based on the feature flag
* Prevents creating Metrics Explorer frontend routes when in serverless
* Prevents registration of the MetricsExplorerViews saved object when in
serverless
* Prevents initialization of the `metrics_explorer_views` API routes
when in serverless

**Trying to access Metrics Explorer in serverless**
<img width="1829" alt="CleanShot 2023-09-22 at 12 59 35@2x"
src="2b039925-0f0b-4c07-be29-bbe910de7a34">

**Trying to access views API**
<img width="1829" alt="CleanShot 2023-09-22 at 13 00 00@2x"
src="15269ec2-becd-4ee3-9b5e-d916df28a7b8">

**`infra/metrics_explorer` API still works as per ticket requirements**
<img width="1829" alt="CleanShot 2023-09-22 at 13 00 06@2x"
src="fb23f912-c6fd-46c8-9084-c17c51e5b064">


## How to test
* Checkout locally
* Enable Infra in `serverless.oblt.yml`: `xpack.infra.enabled: true`
* Run Kibana in serverless mode
* Try accessing `/app/metrics/explorer` route and make sure it's not
available
* Make sure other Infra routes (`/app/metrics/inventory` and
`/app/metrics/hosts`) still load as expected
* In Kibana dev console make sure you get 404 for `GET
kbn:/api/infra/metrics_explorer_views`
* Also check that you don't see `metrics-explorer-view` saved object in
the response for `GET
kbn:/api/kibana/management/saved_objects/_allowed_types`
* Run Kibana in non-serverless mode and make sure Metrics Explorer is
accessible and works as usual

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2023-09-29 11:27:19 +02:00

114 lines
3.9 KiB
TypeScript

/*
* 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 { History } from 'history';
import { CoreStart } from '@kbn/core/public';
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
import { AppMountParameters } from '@kbn/core/public';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import '../index.scss';
import { InfraPublicConfig } from '../../common/plugin_config_types';
import { LinkToMetricsPage } from '../pages/link_to/link_to_metrics';
import { InfrastructurePage } from '../pages/metrics';
import { InfraClientStartDeps, InfraClientStartExports } from '../types';
import { RedirectWithQueryParams } from '../utils/redirect_with_query_params';
import { CommonInfraProviders, CoreProviders } from './common_providers';
import { prepareMountElement } from './common_styles';
import { SourceProvider } from '../containers/metrics_source';
import { PluginConfigProvider } from '../containers/plugin_config_context';
export const METRICS_APP_DATA_TEST_SUBJ = 'infraMetricsPage';
export const renderApp = (
core: CoreStart,
plugins: InfraClientStartDeps,
pluginStart: InfraClientStartExports,
pluginConfig: InfraPublicConfig,
{ element, history, setHeaderActionMenu, theme$ }: AppMountParameters
) => {
const storage = new Storage(window.localStorage);
prepareMountElement(element, METRICS_APP_DATA_TEST_SUBJ);
ReactDOM.render(
<MetricsApp
core={core}
history={history}
plugins={plugins}
pluginStart={pluginStart}
pluginConfig={pluginConfig}
setHeaderActionMenu={setHeaderActionMenu}
storage={storage}
theme$={theme$}
/>,
element
);
return () => {
core.chrome.docTitle.reset();
ReactDOM.unmountComponentAtNode(element);
};
};
const MetricsApp: React.FC<{
core: CoreStart;
history: History<unknown>;
pluginStart: InfraClientStartExports;
pluginConfig: InfraPublicConfig;
plugins: InfraClientStartDeps;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
storage: Storage;
theme$: AppMountParameters['theme$'];
}> = ({
core,
history,
pluginStart,
pluginConfig,
plugins,
setHeaderActionMenu,
storage,
theme$,
}) => {
const uiCapabilities = core.application.capabilities;
return (
<CoreProviders core={core} pluginStart={pluginStart} plugins={plugins} theme$={theme$}>
<CommonInfraProviders
appName="Metrics UI"
setHeaderActionMenu={setHeaderActionMenu}
storage={storage}
theme$={theme$}
triggersActionsUI={plugins.triggersActionsUi}
observabilityAIAssistant={plugins.observabilityAIAssistant}
>
<SourceProvider sourceId="default">
<PluginConfigProvider value={pluginConfig}>
<Router history={history}>
<Routes>
<Route path="/link-to" component={LinkToMetricsPage} />
{uiCapabilities?.infrastructure?.show && (
<RedirectWithQueryParams from="/" exact={true} to="/inventory" />
)}
{uiCapabilities?.infrastructure?.show && (
<RedirectWithQueryParams from="/snapshot" exact={true} to="/inventory" />
)}
{uiCapabilities?.infrastructure?.show && (
<RedirectWithQueryParams from="/metrics-explorer" exact={true} to="/explorer" />
)}
{uiCapabilities?.infrastructure?.show && (
<Route path="/" component={InfrastructurePage} />
)}
</Routes>
</Router>
</PluginConfigProvider>
</SourceProvider>
</CommonInfraProviders>
</CoreProviders>
);
};