[serverless] Create Observability Serverless plugin (#156118)

> Derived from https://github.com/elastic/kibana/pull/153274
> Builds upon https://github.com/elastic/kibana/pull/155582

## Summary

This PR creates the Serverless Observability plugin, based on the work
from https://github.com/elastic/kibana/pull/153274:

- creates the plugin,
- adds API to hide the solution navigation from Enterprise Search,
- calls that API if the chrome style is `project`.

<img width="1610" alt="Screenshot 2023-04-27 at 5 03 44 PM"
src="https://user-images.githubusercontent.com/297604/234990765-d6770650-41b3-4e94-ad7f-c6a22778d39a.png">

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Clint Andrew Hall 2023-05-01 03:27:32 -04:00 committed by GitHub
parent 29dfcd56cd
commit 4e88645b59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 299 additions and 12 deletions

1
.github/CODEOWNERS vendored
View file

@ -574,6 +574,7 @@ packages/kbn-securitysolution-utils @elastic/security-solution-platform
packages/kbn-server-http-tools @elastic/kibana-core
packages/kbn-server-route-repository @elastic/apm-ui
x-pack/plugins/serverless @elastic/appex-sharedux
x-pack/plugins/serverless_observability @elastic/appex-sharedux
packages/serverless/project_switcher @elastic/appex-sharedux
x-pack/plugins/serverless_search @elastic/appex-sharedux
packages/serverless/storybook/config @elastic/appex-sharedux

View file

@ -1,3 +1,18 @@
uiSettings.overrides.defaultRoute: /app/observability/overview
# Observability Project config
## Disable plugins
enterpriseSearch.enabled: false
xpack.cloudSecurityPosture.enabled: false
xpack.securitySolution.enabled: false
## Enable the Serverless Obsersability plugin
xpack.serverless.observability.enabled: true
## Configure plugins
xpack.infra.logs.app_target: discover
## Set the home route
uiSettings.overrides.defaultRoute: /app/observability/overview
## Set the dev project switch current type
xpack.serverless.plugin.developer.projectSwitcher.currentType: 'observability'

View file

@ -714,6 +714,10 @@ Kibana.
|
|{kib-repo}blob/{branch}/x-pack/plugins/serverless_observability/README.mdx[serverlessObservability]
|This plugin contains configuration and code used to create a Serverless Observability project. It leverages universal configuration and other APIs in the serverless plugin to configure Kibana.
|{kib-repo}blob/{branch}/x-pack/plugins/serverless_search/README.mdx[serverlessSearch]
|This plugin contains configuration and code used to create a Serverless Search project. It leverages universal configuration and other APIs in the serverless plugin to configure Kibana.

View file

@ -575,6 +575,7 @@
"@kbn/server-http-tools": "link:packages/kbn-server-http-tools",
"@kbn/server-route-repository": "link:packages/kbn-server-route-repository",
"@kbn/serverless": "link:x-pack/plugins/serverless",
"@kbn/serverless-observability": "link:x-pack/plugins/serverless_observability",
"@kbn/serverless-project-switcher": "link:packages/serverless/project_switcher",
"@kbn/serverless-search": "link:x-pack/plugins/serverless_search",
"@kbn/serverless-types": "link:packages/serverless/types",

View file

@ -116,6 +116,7 @@ pageLoadAssetSize:
security: 65433
securitySolution: 66738
serverless: 16573
serverlessObservability: 16582
serverlessSearch: 17548
sessionView: 77750
share: 71239

View file

@ -1142,6 +1142,8 @@
"@kbn/server-route-repository/*": ["packages/kbn-server-route-repository/*"],
"@kbn/serverless": ["x-pack/plugins/serverless"],
"@kbn/serverless/*": ["x-pack/plugins/serverless/*"],
"@kbn/serverless-observability": ["x-pack/plugins/serverless_observability"],
"@kbn/serverless-observability/*": ["x-pack/plugins/serverless_observability/*"],
"@kbn/serverless-project-switcher": ["packages/serverless/project_switcher"],
"@kbn/serverless-project-switcher/*": ["packages/serverless/project_switcher/*"],
"@kbn/serverless-search": ["x-pack/plugins/serverless_search"],

View file

@ -6,6 +6,8 @@
*/
import React from 'react';
import useObservable from 'react-use/lib/useObservable';
import type {
ObservabilityPageTemplateDependencies,
WrappedPageTemplateProps,
@ -15,12 +17,19 @@ export const LazyObservabilityPageTemplate = React.lazy(() => import('./page_tem
export type LazyObservabilityPageTemplateProps = WrappedPageTemplateProps;
export function createLazyObservabilityPageTemplate(
injectedDeps: ObservabilityPageTemplateDependencies
) {
return (pageTemplateProps: LazyObservabilityPageTemplateProps) => (
<React.Suspense fallback={null}>
<LazyObservabilityPageTemplate {...pageTemplateProps} {...injectedDeps} />
</React.Suspense>
);
export function createLazyObservabilityPageTemplate({
isSidebarEnabled$,
...injectedDeps
}: ObservabilityPageTemplateDependencies) {
return (pageTemplateProps: LazyObservabilityPageTemplateProps) => {
const isSidebarEnabled = useObservable(isSidebarEnabled$);
const { showSolutionNav: showSolutionNavProp, ...props } = pageTemplateProps;
const showSolutionNav = !!showSolutionNavProp || isSidebarEnabled;
return (
<React.Suspense fallback={null}>
<LazyObservabilityPageTemplate {...{ ...props, showSolutionNav }} {...injectedDeps} />
</React.Suspense>
);
};
}

View file

@ -9,7 +9,7 @@ import { I18nProvider } from '@kbn/i18n-react';
import { render } from '@testing-library/react';
import { shallow } from 'enzyme';
import React from 'react';
import { of } from 'rxjs';
import { BehaviorSubject, of } from 'rxjs';
import { getKibanaPageTemplateKibanaDependenciesMock as getPageTemplateServices } from '@kbn/shared-ux-page-kibana-template-mocks';
import { guidedOnboardingMock } from '@kbn/guided-onboarding-plugin/public/mocks';
@ -56,6 +56,7 @@ describe('Page template', () => {
navigationSections$: navigationRegistry.sections$,
getPageTemplateServices,
guidedOnboardingApi: guidedOnboardingMock.createStart().guidedOnboardingApi,
isSidebarEnabled$: new BehaviorSubject<boolean>(true),
});
const component = shallow(

View file

@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n';
import React, { useMemo } from 'react';
import { matchPath, useLocation } from 'react-router-dom';
import useObservable from 'react-use/lib/useObservable';
import type { Observable } from 'rxjs';
import type { BehaviorSubject, Observable } from 'rxjs';
import type { ApplicationStart } from '@kbn/core/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import {
@ -85,9 +85,13 @@ export interface ObservabilityPageTemplateDependencies {
navigationSections$: Observable<NavigationSection[]>;
getPageTemplateServices: () => KibanaPageTemplateKibanaDependencies;
guidedOnboardingApi: GuidedOnboardingPluginStart['guidedOnboardingApi'];
isSidebarEnabled$: BehaviorSubject<boolean>;
}
export type ObservabilityPageTemplateProps = ObservabilityPageTemplateDependencies &
export type ObservabilityPageTemplateProps = Omit<
ObservabilityPageTemplateDependencies,
'isSidebarEnabled$'
> &
WrappedPageTemplateProps;
export function ObservabilityPageTemplate({

View file

@ -5,6 +5,8 @@
* 2.0.
*/
import { BehaviorSubject } from 'rxjs';
import type { CoreStart, Plugin } from '@kbn/core/public';
import type { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public';
import { createNavigationRegistry } from './components/page_template/helpers/navigation_registry';
@ -13,6 +15,7 @@ import { updateGlobalNavigation } from './services/update_global_navigation';
export interface ObservabilitySharedStart {
guidedOnboarding: GuidedOnboardingPluginStart;
setIsSidebarEnabled: (isEnabled: boolean) => void;
}
export type ObservabilitySharedPluginSetup = ReturnType<ObservabilitySharedPlugin['setup']>;
@ -20,6 +23,11 @@ export type ObservabilitySharedPluginStart = ReturnType<ObservabilitySharedPlugi
export class ObservabilitySharedPlugin implements Plugin {
private readonly navigationRegistry = createNavigationRegistry();
private isSidebarEnabled$: BehaviorSubject<boolean>;
constructor() {
this.isSidebarEnabled$ = new BehaviorSubject<boolean>(true);
}
public setup() {
return {
@ -39,6 +47,7 @@ export class ObservabilitySharedPlugin implements Plugin {
navigationSections$: this.navigationRegistry.sections$,
guidedOnboardingApi: plugins.guidedOnboarding.guidedOnboardingApi,
getPageTemplateServices: () => ({ coreStart: core }),
isSidebarEnabled$: this.isSidebarEnabled$,
});
return {
@ -46,6 +55,7 @@ export class ObservabilitySharedPlugin implements Plugin {
PageTemplate,
},
updateGlobalNavigation,
setIsSidebarEnabled: (isEnabled: boolean) => this.isSidebarEnabled$.next(isEnabled),
};
}

View file

@ -0,0 +1,2 @@
/build
/target

View file

@ -0,0 +1,3 @@
# Serverless Observability project plugin
This plugin contains configuration and code used to create a Serverless Observability project. It leverages universal configuration and other APIs in the [`serverless`](../serverless/README.mdx) plugin to configure Kibana.

View file

@ -0,0 +1,9 @@
/*
* 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.
*/
export const PLUGIN_ID = 'serverlessObservability';
export const PLUGIN_NAME = 'serverlessObservability';

View file

@ -0,0 +1,22 @@
{
"type": "plugin",
"id": "@kbn/serverless-observability",
"owner": "@elastic/appex-sharedux",
"description": "Serverless customizations for observability.",
"plugin": {
"id": "serverlessObservability",
"server": true,
"browser": true,
"configPath": [
"xpack",
"serverless",
"observability"
],
"requiredPlugins": [
"serverless",
"observabilityShared"
],
"optionalPlugins": [],
"requiredBundles": []
}
}

View file

@ -0,0 +1,11 @@
{
"name": "@kbn/serverless-observability",
"version": "1.0.0",
"license": "Elastic License 2.0",
"private": true,
"scripts": {
"build": "yarn plugin-helpers build",
"plugin-helpers": "node ../../../scripts/plugin_helpers",
"kbn": "node ../../../scripts/kbn"
}
}

View file

@ -0,0 +1,19 @@
/*
* 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 { ServerlessObservabilityPlugin } from './plugin';
// This exports static code and TypeScript types,
// as well as, Kibana Platform `plugin()` initializer.
export function plugin() {
return new ServerlessObservabilityPlugin();
}
export type {
ServerlessObservabilityPluginSetup,
ServerlessObservabilityPluginStart,
} from './types';

View file

@ -0,0 +1,35 @@
/*
* 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 { CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
import {
ServerlessObservabilityPluginSetup,
ServerlessObservabilityPluginStart,
ServerlessObservabilityPluginSetupDependencies,
ServerlessObservabilityPluginStartDependencies,
} from './types';
export class ServerlessObservabilityPlugin
implements Plugin<ServerlessObservabilityPluginSetup, ServerlessObservabilityPluginStart>
{
public setup(
_core: CoreSetup,
_setupDeps: ServerlessObservabilityPluginSetupDependencies
): ServerlessObservabilityPluginSetup {
return {};
}
public start(
_core: CoreStart,
{ observabilityShared }: ServerlessObservabilityPluginStartDependencies
): ServerlessObservabilityPluginStart {
observabilityShared.setIsSidebarEnabled(false);
return {};
}
public stop() {}
}

View file

@ -0,0 +1,28 @@
/*
* 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 { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public';
import {
ObservabilitySharedPluginSetup,
ObservabilitySharedPluginStart,
} from '@kbn/observability-shared-plugin/public';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ServerlessObservabilityPluginSetup {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ServerlessObservabilityPluginStart {}
export interface ServerlessObservabilityPluginSetupDependencies {
observabilityShared: ObservabilitySharedPluginSetup;
serverless: ServerlessPluginSetup;
}
export interface ServerlessObservabilityPluginStartDependencies {
observabilityShared: ObservabilitySharedPluginStart;
serverless: ServerlessPluginStart;
}

View file

@ -0,0 +1,23 @@
/*
* 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 { schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
export * from './types';
const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: false }),
});
type ConfigType = TypeOf<typeof configSchema>;
export const config: PluginConfigDescriptor<ConfigType> = {
schema: configSchema,
};
export type ServerlessObservabilityConfig = TypeOf<typeof configSchema>;

View file

@ -0,0 +1,23 @@
/*
* 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 { PluginInitializerContext } from '@kbn/core/server';
import { ServerlessObservabilityPlugin } from './plugin';
export { config } from './config';
// This exports static code and TypeScript types,
// as well as, Kibana Platform `plugin()` initializer.
export function plugin(initializerContext: PluginInitializerContext) {
return new ServerlessObservabilityPlugin(initializerContext);
}
export type {
ServerlessObservabilityPluginSetup,
ServerlessObservabilityPluginStart,
} from './types';

View file

@ -0,0 +1,26 @@
/*
* 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 { PluginInitializerContext, Plugin } from '@kbn/core/server';
import { ServerlessObservabilityPluginSetup, ServerlessObservabilityPluginStart } from './types';
export class ServerlessObservabilityPlugin
implements Plugin<ServerlessObservabilityPluginSetup, ServerlessObservabilityPluginStart>
{
constructor(_initializerContext: PluginInitializerContext) {}
public setup() {
return {};
}
public start() {
return {};
}
public stop() {}
}

View file

@ -0,0 +1,11 @@
/*
* 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.
*/
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ServerlessObservabilityPluginSetup {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ServerlessObservabilityPluginStart {}

View file

@ -0,0 +1,23 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "target/types"
},
"include": [
"index.ts",
"common/**/*.ts",
"public/**/*.ts",
"public/**/*.tsx",
"server/**/*.ts",
"../../../typings/**/*"
],
"exclude": [
"target/**/*"
],
"kbn_references": [
"@kbn/core",
"@kbn/config-schema",
"@kbn/serverless",
"@kbn/observability-shared-plugin",
]
}

View file

@ -5016,6 +5016,10 @@
"@kbn/server-route-repository@link:packages/kbn-server-route-repository":
version "0.0.0"
uid ""
"@kbn/serverless-observability@link:x-pack/plugins/serverless_observability":
version "0.0.0"
uid ""
"@kbn/serverless-project-switcher@link:packages/serverless/project_switcher":
version "0.0.0"