Skip to content

Commit

Permalink
[serverless] Create Search Serverless plugin (#156037)
Browse files Browse the repository at this point in the history
  • Loading branch information
clintandrewhall authored Apr 28, 2023
1 parent 604a02f commit 965b327
Show file tree
Hide file tree
Showing 30 changed files with 446 additions and 134 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ packages/kbn-server-http-tools @elastic/kibana-core
packages/kbn-server-route-repository @elastic/apm-ui
x-pack/plugins/serverless @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
packages/serverless/types @elastic/appex-sharedux
test/plugin_functional/plugins/session_notifications @elastic/kibana-core
Expand Down
13 changes: 13 additions & 0 deletions config/serverless.es.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
# Search Project Config

## Disable APM and Uptime, enable Enterprise Search
xpack.apm.enabled: false
xpack.uptime.enabled: false
enterpriseSearch.enabled: true

## Enable the Serverless Search plugin
xpack.serverless.search.enabled: true

## Set the home route
uiSettings.overrides.defaultRoute: /app/enterprise_search/content/search_indices

## Set the dev project switcher current type
xpack.serverless.plugin.developer.projectSwitcher.currentType: 'search'
4 changes: 4 additions & 0 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,10 @@ 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.
|{kib-repo}blob/{branch}/x-pack/plugins/session_view/README.md[sessionView]
|Session View is meant to provide a visualization into what is going on in a particular Linux environment where the agent is running. It looks likes a terminal emulator; however, it is a tool for introspecting process activity and understanding user and service behaviour in your Linux servers and infrastructure. It is a time-ordered series of process executions displayed in a tree over time.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@
"@kbn/server-route-repository": "link:packages/kbn-server-route-repository",
"@kbn/serverless": "link:x-pack/plugins/serverless",
"@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",
"@kbn/session-notifications-plugin": "link:test/plugin_functional/plugins/session_notifications",
"@kbn/session-view-plugin": "link:x-pack/plugins/session_view",
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pageLoadAssetSize:
security: 65433
securitySolution: 66738
serverless: 16573
serverlessSearch: 17548
sessionView: 77750
share: 71239
snapshotRestore: 79032
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,8 @@
"@kbn/serverless/*": ["x-pack/plugins/serverless/*"],
"@kbn/serverless-project-switcher": ["packages/serverless/project_switcher"],
"@kbn/serverless-project-switcher/*": ["packages/serverless/project_switcher/*"],
"@kbn/serverless-search": ["x-pack/plugins/serverless_search"],
"@kbn/serverless-search/*": ["x-pack/plugins/serverless_search/*"],
"@kbn/serverless-storybook-config": ["packages/serverless/storybook/config"],
"@kbn/serverless-storybook-config/*": ["packages/serverless/storybook/config/*"],
"@kbn/serverless-types": ["packages/serverless/types"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export const mockAllActions = {
*/
jest.mock('kea', () => ({
...(jest.requireActual('kea') as object),
useValues: jest.fn(() => ({ ...mockAllValues })),
useActions: jest.fn(() => ({ ...mockAllActions })),
useValues: jest.fn(() => ({ ...mockAllValues })),
}));

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const mockKibanaValues = {
guidedOnboarding: {},
history: mockHistory,
isCloud: false,
isSidebarEnabled: true,
lens: {
EmbeddableComponent: jest.fn(),
stateHelperApi: jest.fn().mockResolvedValue({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import { renderApp, renderHeaderActions } from '.';

describe('renderApp', () => {
const kibanaDeps = {
params: coreMock.createAppMountParameters(),
core: coreMock.createStart(),
params: coreMock.createAppMountParameters(),
plugins: {
charts: chartPluginMock.createStartContract(),
data: dataPluginMock.createStartContract(),
Expand Down
60 changes: 39 additions & 21 deletions x-pack/plugins/enterprise_search/public/applications/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,55 +37,73 @@ import { mountLicensingLogic } from './shared/licensing';

export const renderApp = (
App: React.FC<InitialAppData>,
{ params, core, plugins }: { params: AppMountParameters; core: CoreStart; plugins: PluginsStart },
{
params,
core,
plugins,
isSidebarEnabled = true,
}: {
core: CoreStart;
isSidebarEnabled: boolean;
params: AppMountParameters;
plugins: PluginsStart;
},
{ config, data }: { config: ClientConfigType; data: ClientData }
) => {
const { publicUrl, errorConnectingMessage, ...initialData } = data;
const { access, features, publicUrl, errorConnectingMessage, readOnlyMode, ...initialData } =
data;
const { history } = params;
const { application, chrome, http, uiSettings } = core;
const { capabilities, navigateToUrl } = application;
const { charts, cloud, guidedOnboarding, lens, security } = plugins;

const entCloudHost = getCloudEnterpriseSearchHost(plugins.cloud);
externalUrl.enterpriseSearchUrl = publicUrl || entCloudHost || config.host || '';

const noProductAccess: ProductAccess = {
hasAppSearchAccess: false,
hasWorkplaceSearchAccess: false,
};
const productAccess = data.access || noProductAccess;
const productFeatures = data.features ?? { ...DEFAULT_PRODUCT_FEATURES };

const productAccess = access || noProductAccess;
const productFeatures = features ?? { ...DEFAULT_PRODUCT_FEATURES };

const EmptyContext: FC = ({ children }) => <>{children}</>;
const CloudContext = plugins.cloud?.CloudContextProvider || EmptyContext;
const CloudContext = cloud?.CloudContextProvider || EmptyContext;

resetContext({ createStore: true });
const store = getContext().store;

const unmountKibanaLogic = mountKibanaLogic({
application: core.application,
capabilities: core.application.capabilities,
application,
capabilities,
charts,
cloud,
config,
data: plugins.data,
lens: plugins.lens,
guidedOnboarding,
history,
isSidebarEnabled,
lens,
navigateToUrl,
productAccess,
productFeatures,
charts: plugins.charts,
cloud: plugins.cloud,
uiSettings: core.uiSettings,
guidedOnboarding: plugins.guidedOnboarding,
history: params.history,
navigateToUrl: core.application.navigateToUrl,
security: plugins.security,
setBreadcrumbs: core.chrome.setBreadcrumbs,
setChromeIsVisible: core.chrome.setIsVisible,
setDocTitle: core.chrome.docTitle.change,
renderHeaderActions: (HeaderActions) =>
params.setHeaderActionMenu((el) => renderHeaderActions(HeaderActions, store, el)),
security,
setBreadcrumbs: chrome.setBreadcrumbs,
setChromeIsVisible: chrome.setIsVisible,
setDocTitle: chrome.docTitle.change,
uiSettings,
});
const unmountLicensingLogic = mountLicensingLogic({
license$: plugins.licensing.license$,
canManageLicense: core.application.capabilities.management?.stack?.license_management,
license$: plugins.licensing.license$,
});
const unmountHttpLogic = mountHttpLogic({
http: core.http,
errorConnectingMessage,
readOnlyMode: initialData.readOnlyMode,
http,
readOnlyMode,
});
const unmountFlashMessagesLogic = mountFlashMessagesLogic();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,26 @@ type RequiredFieldsOnly<T> = {
};
interface KibanaLogicProps {
application: ApplicationStart;
config: ClientConfigType;
productAccess: ProductAccess;
productFeatures: ProductFeatures;
// Kibana core
capabilities: Capabilities;
charts: ChartsPluginStart;
cloud?: CloudSetup;
config: ClientConfigType;
data: DataPublicPluginStart;
guidedOnboarding: GuidedOnboardingPluginStart;
history: ScopedHistory;
isSidebarEnabled: boolean;
lens: LensPublicStart;
navigateToUrl: RequiredFieldsOnly<ApplicationStart['navigateToUrl']>;
productAccess: ProductAccess;
productFeatures: ProductFeatures;
renderHeaderActions(HeaderActions: FC): void;
security: SecurityPluginStart;
setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void;
setChromeIsVisible(isVisible: boolean): void;
setDocTitle(title: string): void;
renderHeaderActions(HeaderActions: FC): void;
// Required plugins
charts: ChartsPluginStart;
guidedOnboarding: GuidedOnboardingPluginStart;
security: SecurityPluginStart;
uiSettings: IUiSettingsClient;
// Optional plugins
cloud?: CloudSetup;
}

export interface KibanaValues extends Omit<KibanaLogicProps, 'cloud'> {
cloud: Partial<CloudSetup>;
data: DataPublicPluginStart;
Expand All @@ -73,6 +72,7 @@ export const KibanaLogic = kea<MakeLogicType<KibanaValues>>({
data: [props.data, {}],
guidedOnboarding: [props.guidedOnboarding, {}],
history: [props.history, {}],
isSidebarEnabled: [props.isSidebarEnabled, {}],
lens: [props.lens, {}],
navigateToUrl: [
(url: string, options?: CreateHrefOptions) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ describe('useEnterpriseSearchContentNav', () => {

it('returns an array of top-level Enterprise Search nav items', () => {
const fullProductAccess: ProductAccess = DEFAULT_PRODUCT_ACCESS;
setMockValues({ productAccess: fullProductAccess, productFeatures: DEFAULT_PRODUCT_FEATURES });
setMockValues({
isSidebarEnabled: true,
productAccess: fullProductAccess,
productFeatures: DEFAULT_PRODUCT_FEATURES,
});

expect(useEnterpriseSearchNav()).toEqual([
{
Expand All @@ -48,9 +52,9 @@ describe('useEnterpriseSearchContentNav', () => {
name: 'Elasticsearch',
},
{
href: '/app/enterprise_search/search_experiences',
id: 'searchExperiences',
name: 'Search Experiences',
href: '/app/enterprise_search/search_experiences',
},
],
name: 'Overview',
Expand All @@ -74,19 +78,19 @@ describe('useEnterpriseSearchContentNav', () => {
},
{
id: 'applications',
name: 'Applications',
items: [
{
href: '/app/enterprise_search/content/engines',
id: 'searchApplications',
name: 'Search Applications',
href: '/app/enterprise_search/content/engines',
},
{
href: '/app/enterprise_search/analytics',
id: 'analyticsCollections',
name: 'Behavioral Analytics',
},
],
name: 'Applications',
},
{
id: 'standaloneExperiences',
Expand Down Expand Up @@ -114,7 +118,11 @@ describe('useEnterpriseSearchContentNav', () => {
hasWorkplaceSearchAccess: false,
};

setMockValues({ productAccess: noProductAccess, productFeatures: DEFAULT_PRODUCT_FEATURES });
setMockValues({
isSidebarEnabled: true,
productAccess: noProductAccess,
productFeatures: DEFAULT_PRODUCT_FEATURES,
});
mockKibanaValues.uiSettings.get.mockReturnValue(false);

const esNav = useEnterpriseSearchNav();
Expand All @@ -130,6 +138,7 @@ describe('useEnterpriseSearchContentNav', () => {
};

setMockValues({
isSidebarEnabled: true,
productAccess: workplaceSearchProductAccess,
productFeatures: DEFAULT_PRODUCT_FEATURES,
});
Expand Down Expand Up @@ -157,6 +166,7 @@ describe('useEnterpriseSearchContentNav', () => {
};

setMockValues({
isSidebarEnabled: true,
productAccess: appSearchProductAccess,
productFeatures: DEFAULT_PRODUCT_FEATURES,
});
Expand All @@ -183,6 +193,7 @@ describe('useEnterpriseSearchEngineNav', () => {
jest.clearAllMocks();
mockKibanaValues.uiSettings.get.mockReturnValue(true);
setMockValues({
isSidebarEnabled: true,
productAccess: DEFAULT_PRODUCT_ACCESS,
productFeatures: DEFAULT_PRODUCT_FEATURES,
});
Expand All @@ -200,9 +211,9 @@ describe('useEnterpriseSearchEngineNav', () => {
name: 'Elasticsearch',
},
{
href: '/app/enterprise_search/search_experiences',
id: 'searchExperiences',
name: 'Search Experiences',
href: '/app/enterprise_search/search_experiences',
},
],
name: 'Overview',
Expand All @@ -225,19 +236,19 @@ describe('useEnterpriseSearchEngineNav', () => {
},
{
id: 'applications',
name: 'Applications',
items: [
{
href: '/app/enterprise_search/content/engines',
id: 'searchApplications',
name: 'Search Applications',
href: '/app/enterprise_search/content/engines',
},
{
href: '/app/enterprise_search/analytics',
id: 'analyticsCollections',
name: 'Behavioral Analytics',
},
],
name: 'Applications',
},
{
id: 'standaloneExperiences',
Expand Down Expand Up @@ -346,9 +357,9 @@ describe('useEnterpriseSearchAnalyticsNav', () => {
name: 'Elasticsearch',
},
{
href: '/app/enterprise_search/search_experiences',
id: 'searchExperiences',
name: 'Search Experiences',
href: '/app/enterprise_search/search_experiences',
},
],
name: 'Overview',
Expand All @@ -366,7 +377,6 @@ describe('useEnterpriseSearchAnalyticsNav', () => {
},
{
id: 'applications',
name: 'Applications',
items: [
{
href: '/app/enterprise_search/content/engines',
Expand All @@ -379,6 +389,7 @@ describe('useEnterpriseSearchAnalyticsNav', () => {
name: 'Behavioral Analytics',
},
],
name: 'Applications',
},
{
id: 'standaloneExperiences',
Expand All @@ -400,7 +411,9 @@ describe('useEnterpriseSearchAnalyticsNav', () => {

beforeEach(() => {
jest.clearAllMocks();
setMockValues({});
setMockValues({
isSidebarEnabled: true,
});
});

it('returns basic nav all params are empty', () => {
Expand Down
Loading

0 comments on commit 965b327

Please sign in to comment.