Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e7b9b84
disabled apm plugin, changed default route to /app/observability/over…
bryce-b Jun 5, 2025
8415e44
disables all features under Applications
bryce-b Jun 6, 2025
7133966
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 6, 2025
48b7b9b
fixed observability-complete
bryce-b Jun 6, 2025
49679d4
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 9, 2025
b2007e4
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 9, 2025
ea9ba68
Disables observability overview for logs essentials
bryce-b Jun 9, 2025
a5011b6
corrected construction of observability routes
bryce-b Jun 9, 2025
307294c
disabled AI assistant in essentials
bryce-b Jun 10, 2025
79ae10b
added tests for pricing feature observability:overview_complete
bryce-b Jun 11, 2025
925bee3
removed unused import
bryce-b Jun 11, 2025
0a49d62
[CI] Auto-commit changed files from 'node scripts/styled_components_m…
kibanamachine Jun 11, 2025
081fbed
duplicate root fleet registery exludes for essentials
bryce-b Jun 11, 2025
b395810
Merge remote-tracking branch 'upstream/main' into 4494_applications-e…
bryce-b Jun 12, 2025
35bfa62
reduced redundant code in test
bryce-b Jun 12, 2025
59b8e37
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 12, 2025
08982b6
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 12, 2025
094aa59
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 13, 2025
d272767
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 16, 2025
c07b134
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 16, 2025
5a719a4
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 16, 2025
f45dc69
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 17, 2025
a76bccd
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 17, 2025
ed6ced0
cleaned up settings
bryce-b Jun 17, 2025
894247d
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 17, 2025
8f85d65
changed navigation test to use discover, vs landing page
bryce-b Jun 18, 2025
34c92fe
changed test navigation from removed landing page to discover
bryce-b Jun 18, 2025
50aa97b
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 18, 2025
a94ed6b
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 20, 2025
d555b4c
replaced flaky spinner wait in test
bryce-b Jun 20, 2025
317d5ac
updated discover nav method with testSubject validation
bryce-b Jun 20, 2025
6a3f870
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 20, 2025
61392a0
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 23, 2025
4fcc6dc
removed default landing page from logs_essentials yml per feedback
bryce-b Jun 23, 2025
0338e43
removed duplicated listing
bryce-b Jun 23, 2025
662e84f
removed uptime from fleet package excludes
bryce-b Jun 23, 2025
5b930b4
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 23, 2025
1a3bc1a
Merge branch 'main' into 4494_applications-essentials
bryce-b Jun 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion config/serverless.oblt.complete.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,22 @@
## Enabled plugins
xpack.infra.enabled: true
xpack.slo.enabled: true
xpack.uptime.enabled: true

xpack.features.overrides:
### By default, this feature named as `Metrics`, but should be renamed to `Infrastructure`.
infrastructure.name: 'Infrastructure'
### By default, this feature named as `APM and User Experience`, but should be renamed to `Applications`.
apm.name: 'Applications'
### Dashboards feature should be moved from Analytics category to the Observability one.
dashboard_v2.category: 'observability'
### Discover feature should be moved from Analytics category to the Observability one and its privileges are
### fine-tuned to grant access to Observability app.
discover_v2.category: 'observability'
### Machine Learning feature should be moved from Analytics category to the Observability one and renamed to `AI Ops`.
ml:
category: 'observability'
order: 1200
### Stack alerts is hidden in Role management since it's not needed.
stackAlerts.hidden: true
### By default, this feature named as `Synthetics and Uptime`, but should be renamed to `Synthetics` since `Uptime` is not available.
uptime.name: 'Synthetics'
38 changes: 38 additions & 0 deletions config/serverless.oblt.logs_essentials.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,41 @@ xpack.infra.enabled: false
xpack.slo.enabled: false
xpack.observabilityAIAssistant.enabled: false
xpack.aiops.ui.enabled: false
xpack.apm.enabled: false

xpack.legacy_uptime.enabled: false
xpack.ux.enabled: false
xpack.uptime.enabled: false

xpack.fleet.internal.registry.excludePackages: [
# Oblt integrations
'synthetics',
# Security integrations
'endpoint',
'beaconing',
'cloud_security_posture',
'cloud_defend',
'security_detection_engine',

# Deprecated security integrations
'bluecoat',
'cisco',
'cyberark',
'cylance',
'f5',
'fortinet_forticlient',
'juniper_junos',
'juniper_netscreen',
'microsoft',
'netscout',
'radware',
'symantec',
'tomcat',

# ML integrations
'dga',

# Profiling integrations
'profiler_agent',
'synthetics_dashboards',
]
17 changes: 0 additions & 17 deletions config/serverless.oblt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,6 @@ plugins.allowlistPluginGroups: ['platform', 'observability']
xpack.ux.enabled: false
xpack.legacy_uptime.enabled: false

xpack.features.overrides:
### By default, this feature named as `APM and User Experience`, but should be renamed to `Applications`.
apm.name: 'Applications'
### Dashboards feature should be moved from Analytics category to the Observability one.
dashboard_v2.category: 'observability'
### Discover feature should be moved from Analytics category to the Observability one and its privileges are
### fine-tuned to grant access to Observability app.
discover_v2.category: 'observability'
### Machine Learning feature should be moved from Analytics category to the Observability one and renamed to `AI Ops`.
ml:
category: 'observability'
order: 1200
### Stack alerts is hidden in Role management since it's not needed.
stackAlerts.hidden: true
### By default, this feature named as `Synthetics and Uptime`, but should be renamed to `Synthetics` since `Uptime` is not available.
uptime.name: 'Synthetics'

## Cloud settings
xpack.cloud.serverless.project_type: observability

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
* 2.0.
*/

import { createMemoryHistory } from 'history';
import { render } from '@testing-library/react';
import { pricingServiceMock } from '@kbn/core-pricing-browser-mocks';
import { noop } from 'lodash';
import React from 'react';
import React, { ReactNode } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { Observable } from 'rxjs';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';

import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { themeServiceMock } from '@kbn/core/public/mocks';
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
import { ConfigSchema, ObservabilityPublicPluginsStart } from '../plugin';
import { createObservabilityRuleTypeRegistryMock } from '../rules/observability_rule_type_registry_mock';
import { renderApp } from '.';
import { renderApp, App } from '.';
import { mockService } from '@kbn/observability-ai-assistant-plugin/public/mock';
import { createMemoryHistory } from 'history';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';

describe('renderApp', () => {
const originalConsole = global.console;
Expand All @@ -29,6 +35,8 @@ describe('renderApp', () => {
global.console = originalConsole;
});

let pricingStart: ReturnType<typeof pricingServiceMock.createStartContract>;

const mockSearchSessionClear = jest.fn();

const plugins = {
Expand Down Expand Up @@ -82,6 +90,14 @@ describe('renderApp', () => {
},
};

beforeEach(() => {
pricingStart = pricingServiceMock.createStartContract();
});

afterEach(() => {
jest.restoreAllMocks();
});

it('renders', async () => {
expect(() => {
const unmount = renderApp({
Expand Down Expand Up @@ -123,4 +139,42 @@ describe('renderApp', () => {

expect(mockSearchSessionClear).toBeCalled();
});

function AppWrapper({ children }: { children?: ReactNode }) {
return (
<KibanaRenderContextProvider {...core}>
<KibanaContextProvider services={{ pricing: pricingStart }}>
<MemoryRouter initialEntries={['/overview']}>
<App />
</MemoryRouter>
</KibanaContextProvider>
</KibanaRenderContextProvider>
);
}

it('should adjust routes for complete', () => {
// Mock feature availability
pricingStart.isFeatureAvailable.mockImplementation((featureId) => {
if (featureId === 'observability:complete_overview') {
return true;
}
return true;
});

render(<App />, { wrapper: AppWrapper });
expect(document.body.textContent).toContain('Unable to load page');
});

it('should adjust routes for essentials', () => {
// Mock feature availability
pricingStart.isFeatureAvailable.mockImplementation((featureId) => {
if (featureId === 'observability:complete_overview') {
return false;
}
return true;
});

render(<App />, { wrapper: AppWrapper });
expect(document.body.textContent).not.toContain('Unable to load page');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,23 @@ import { Storage } from '@kbn/kibana-utils-plugin/public';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import { PluginContext } from '../context/plugin_context/plugin_context';
import { ConfigSchema, ObservabilityPublicPluginsStart } from '../plugin';
import { routes } from '../routes/routes';
import { routes, completeRoutes } from '../routes/routes';
import { useKibana } from '../utils/kibana_react';
import { ObservabilityRuleTypeRegistry } from '../rules/create_observability_rule_type_registry';
import { HideableReactQueryDevTools } from './hideable_react_query_dev_tools';

function App() {
export function App() {
const { pricing } = useKibana().services;
const isCompleteOverviewEnabled = pricing.isFeatureAvailable('observability:complete_overview');
const allRoutes = {
...(isCompleteOverviewEnabled ? { ...completeRoutes, ...routes } : { ...routes }),
};
return (
<>
<Routes enableExecutionContextTracking={true}>
{Object.keys(routes).map((key) => {
const path = key as keyof typeof routes;
const { handler, exact } = routes[path];
{Object.keys(allRoutes).map((key) => {
const path = key as keyof typeof allRoutes;
const { handler, exact } = allRoutes[path];
const Wrapper = () => {
return handler();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,32 +62,35 @@ function SimpleRedirect({ to, redirectToApp }: { to: string; redirectToApp?: str
return null;
}

export const routes = {
export const completeRoutes = {
[ROOT_PATH]: {
handler: () => {
return <SimpleRedirect to={OVERVIEW_PATH} />;
},
params: {},
exact: true,
},
[LANDING_PATH]: {
[OVERVIEW_PATH]: {
handler: () => {
return (
<HasDataContextProvider>
<LandingPage />
<DatePickerContextProvider>
<OverviewPage />
</DatePickerContextProvider>
</HasDataContextProvider>
);
},
params: {},
exact: true,
},
[OVERVIEW_PATH]: {
};

export const routes = {
[LANDING_PATH]: {
handler: () => {
return (
<HasDataContextProvider>
<DatePickerContextProvider>
<OverviewPage />
</DatePickerContextProvider>
<LandingPage />
</HasDataContextProvider>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@
"@kbn/object-utils",
"@kbn/task-manager-plugin",
"@kbn/core-saved-objects-server",
"@kbn/esql"
"@kbn/core-pricing-browser-mocks",
"@kbn/esql",
],
"exclude": ["target/**/*"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../../../../..',
roots: ['<rootDir>/x-pack/solutions/observability/plugins/serverless_observability'],
coverageDirectory:
'<rootDir>/target/kibana-coverage/jest/x-pack/solutions/observability/plugins/serverless_observability',
coverageReporters: ['text', 'html'],
collectCoverageFrom: [
'<rootDir>/x-pack/solutions/observability/plugins/serverless_observability/{common,public,server}/**/*.{js,ts,tsx}',
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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 { createNavigationTree } from './navigation_tree';
import type { GroupDefinition, AppDeepLinkId } from '@kbn/core-chrome-browser';

describe('Navigation Tree', () => {
it('should generate tree with overview', () => {
const navigation = createNavigationTree({});
expect((navigation.body[0] as GroupDefinition<AppDeepLinkId, string, string>).children).toEqual(
expect.arrayContaining([
{
title: 'Overview',
link: 'observability-overview',
},
])
);
});
it('should not generate tree with overview', () => {
const navigation = createNavigationTree({ overviewAvailable: false });
expect(
(navigation.body[0] as GroupDefinition<AppDeepLinkId, string, string>).children
).not.toEqual(
expect.arrayContaining([
{
title: 'Overview',
link: 'observability-overview',
},
])
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import type { NavigationTreeDefinition } from '@kbn/core-chrome-browser';

export const createNavigationTree = ({
streamsAvailable,
overviewAvailable = true,
}: {
streamsAvailable?: boolean;
overviewAvailable?: boolean;
}): NavigationTreeDefinition => {
return {
body: [
Expand All @@ -24,12 +26,16 @@ export const createNavigationTree = ({
isCollapsible: false,
breadcrumbStatus: 'hidden',
children: [
{
title: i18n.translate('xpack.serverlessObservability.nav.overview', {
defaultMessage: 'Overview',
}),
link: 'observability-overview',
},
...(overviewAvailable
? [
{
title: i18n.translate('xpack.serverlessObservability.nav.overview', {
defaultMessage: 'Overview',
}),
link: 'observability-overview' as const,
},
]
: []),
{
title: i18n.translate('xpack.serverlessObservability.nav.discover', {
defaultMessage: 'Discover',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ export class ServerlessObservabilityPlugin
const { serverless, management, security } = setupDeps;
const navigationTree$ = (setupDeps.streams?.status$ || of({ status: 'disabled' })).pipe(
map(({ status }) => {
return createNavigationTree({ streamsAvailable: status === 'enabled' });
return createNavigationTree({
streamsAvailable: status === 'enabled',
overviewAvailable: core.pricing.isFeatureAvailable('observability:complete_overview'),
});
})
);
serverless.setProjectHome('/app/observability/landing');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,22 @@ export class ServerlessObservabilityPlugin
{
constructor(_initializerContext: PluginInitializerContext) {}

public setup(_coreSetup: CoreSetup, pluginsSetup: SetupDependencies) {
public setup(
_coreSetup: CoreSetup<StartDependencies, ServerlessObservabilityPluginStart>,
pluginsSetup: SetupDependencies
) {
pluginsSetup.serverless.setupProjectSettings([
...OBSERVABILITY_PROJECT_SETTINGS,
...(pluginsSetup.observabilityAIAssistant ? OBSERVABILITY_AI_ASSISTANT_PROJECT_SETTINGS : []),
]);

_coreSetup.pricing.registerProductFeatures([
{
id: 'observability:complete_overview',
products: [{ name: 'observability', tier: 'complete' }],
description:
'Observability Overview Complete - Enables overview of the Observability solution.',
},
]);
return {};
}

Expand Down
Loading