Skip to content

Commit

Permalink
[Investigate] Create plugin (#184908)
Browse files Browse the repository at this point in the history
Create the Investigate plugin (naming TBD). Part of
#183293, splitting up the work in
several PRs.

The investigate plugin is mostly a registry to allow plugins to register
their widgets without creating dependency issues.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
dgieselaar and kibanamachine authored Jun 7, 2024
1 parent 2c8201d commit 15b6ba9
Show file tree
Hide file tree
Showing 27 changed files with 607 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ src/plugins/inspector @elastic/kibana-presentation
src/plugins/interactive_setup @elastic/kibana-security
test/interactive_setup_api_integration/plugins/test_endpoints @elastic/kibana-security
packages/kbn-interpreter @elastic/kibana-visualizations
x-pack/plugins/observability_solution/investigate @elastic/obs-ai-assistant
packages/kbn-io-ts-utils @elastic/obs-knowledge-team
packages/kbn-ipynb @elastic/search-kibana
packages/kbn-jest-serializers @elastic/kibana-operations
Expand Down
4 changes: 4 additions & 0 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,10 @@ the infrastructure monitoring use-case within Kibana.
|The ingest_pipelines plugin provides Kibana support for Elasticsearch's ingest pipelines.
|{kib-repo}blob/{branch}/x-pack/plugins/observability_solution/investigate/README.md[investigate]
|undefined
|{kib-repo}blob/{branch}/x-pack/plugins/kubernetes_security/README.md[kubernetesSecurity]
|This plugin provides interactive visualizations of your Kubernetes workload and session data.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@
"@kbn/interactive-setup-plugin": "link:src/plugins/interactive_setup",
"@kbn/interactive-setup-test-endpoints-plugin": "link:test/interactive_setup_api_integration/plugins/test_endpoints",
"@kbn/interpreter": "link:packages/kbn-interpreter",
"@kbn/investigate-plugin": "link:x-pack/plugins/observability_solution/investigate",
"@kbn/io-ts-utils": "link:packages/kbn-io-ts-utils",
"@kbn/ipynb": "link:packages/kbn-ipynb",
"@kbn/kbn-health-gateway-status-plugin": "link:test/health_gateway/plugins/status",
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 @@ -83,6 +83,7 @@ pageLoadAssetSize:
inputControlVis: 172675
inspector: 148711
interactiveSetup: 80000
investigate: 17970
kibanaOverview: 56279
kibanaReact: 74422
kibanaUsageCollection: 16463
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,8 @@
"@kbn/interactive-setup-test-endpoints-plugin/*": ["test/interactive_setup_api_integration/plugins/test_endpoints/*"],
"@kbn/interpreter": ["packages/kbn-interpreter"],
"@kbn/interpreter/*": ["packages/kbn-interpreter/*"],
"@kbn/investigate-plugin": ["x-pack/plugins/observability_solution/investigate"],
"@kbn/investigate-plugin/*": ["x-pack/plugins/observability_solution/investigate/*"],
"@kbn/io-ts-utils": ["packages/kbn-io-ts-utils"],
"@kbn/io-ts-utils/*": ["packages/kbn-io-ts-utils/*"],
"@kbn/ipynb": ["packages/kbn-ipynb"],
Expand Down
1 change: 1 addition & 0 deletions x-pack/.i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"xpack.logsShared": "plugins/observability_solution/logs_shared",
"xpack.fleet": "plugins/fleet",
"xpack.ingestPipelines": "plugins/ingest_pipelines",
"xpack.investigate": "plugins/observability_solution/investigate",
"xpack.kubernetesSecurity": "plugins/kubernetes_security",
"xpack.lens": "plugins/lens",
"xpack.licenseApiGuard": "plugins/license_api_guard",
Expand Down
Empty file.
14 changes: 14 additions & 0 deletions x-pack/plugins/observability_solution/investigate/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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 type {
InvestigateTimeline,
InvestigateWidget,
InvestigateWidgetCreate,
WorkflowBlock,
} from './types';

export { InvestigateWidgetColumnSpan } from './types';
76 changes: 76 additions & 0 deletions x-pack/plugins/observability_solution/investigate/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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 type { EuiThemeComputed } from '@elastic/eui';
import type { Filter } from '@kbn/es-query';
import type { DeepPartial, PickByValue } from 'utility-types';

export interface InvestigateUser {
name: string;
}

export interface GlobalWidgetParameters {
timeRange: {
from: string;
to: string;
};
query: {
query: string;
language: 'kuery';
};
filters: Filter[];
}

export enum InvestigateWidgetColumnSpan {
One = 1,
Two = 2,
Three = 3,
Four = 4,
}

export interface InvestigateTimeline {
id: string;
title: string;
'@timestamp': number;
user: InvestigateUser;
items: InvestigateWidget[];
}

export interface InvestigateWidget<
TParameters extends Record<string, any> = {},
TData extends Record<string, any> = {}
> {
id: string;
created: number;
last_updated: number;
type: string;
user: InvestigateUser;
parameters: GlobalWidgetParameters & TParameters;
data: TData;
title: string;
description?: string;
columns: InvestigateWidgetColumnSpan;
rows: number;
locked: boolean;
}

export type InvestigateWidgetCreate<TParameters extends Record<string, any> = {}> = Pick<
InvestigateWidget,
'title' | 'description' | 'columns' | 'rows' | 'type' | 'locked'
> & {
parameters: DeepPartial<GlobalWidgetParameters> & TParameters;
};

export interface WorkflowBlock {
id: string;
content?: string;
description?: string;
loading: boolean;
onClick?: () => void;
color?: keyof PickByValue<EuiThemeComputed<{}>['colors'], string>;
children?: React.ReactNode;
}
23 changes: 23 additions & 0 deletions x-pack/plugins/observability_solution/investigate/jest.config.js
Original file line number Diff line number Diff line change
@@ -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.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../../../..',
roots: [
'<rootDir>/x-pack/plugins/observability_solution/investigate/public',
'<rootDir>/x-pack/plugins/observability_solution/investigate/common',
'<rootDir>/x-pack/plugins/observability_solution/investigate/server',
],
setupFiles: [],
collectCoverage: true,
collectCoverageFrom: [
'<rootDir>/x-pack/plugins/observability_solution/investigate/{common,public,server}/**/*.{js,ts,tsx}',
],

coverageReporters: ['html'],
};
18 changes: 18 additions & 0 deletions x-pack/plugins/observability_solution/investigate/kibana.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "plugin",
"id": "@kbn/investigate-plugin",
"owner": "@elastic/obs-ai-assistant",
"plugin": {
"id": "investigate",
"server": true,
"browser": true,
"configPath": ["xpack", "investigate"],
"requiredPlugins": [
"observabilityAIAssistant"
],
"requiredBundles": [
],
"optionalPlugins": [],
"extraPublicDirs": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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 { DeepPartial } from 'utility-types';
import { InvestigateWidgetColumnSpan, InvestigateWidgetCreate } from '../common';
import { GlobalWidgetParameters } from '../common/types';

type MakePartial<T extends Record<string, any>, K extends keyof T> = Omit<T, K> &
DeepPartial<Pick<T, K>>;

type PredefinedKeys = 'rows' | 'columns' | 'locked' | 'type';

type AllowedDefaultKeys = 'rows' | 'columns';

export type WidgetFactory<TParameters extends Record<string, any>> = <
T extends MakePartial<InvestigateWidgetCreate<TParameters>, PredefinedKeys>
>(
widgetCreate: T
) => Pick<InvestigateWidgetCreate<TParameters>, PredefinedKeys> &
Omit<T, 'parameters'> & { parameters: T['parameters'] & DeepPartial<GlobalWidgetParameters> };

export function createWidgetFactory<TParameters extends Record<string, any>>(
type: string,
defaults?: Pick<Partial<InvestigateWidgetCreate>, AllowedDefaultKeys>
): WidgetFactory<TParameters> {
const createWidget: WidgetFactory<TParameters> = (widgetCreate) => {
return {
rows: 12,
columns: InvestigateWidgetColumnSpan.Four,
locked: false,
type,
...defaults,
...widgetCreate,
};
};

return createWidget;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* 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 ESQL_WIDGET_NAME = 'esql';
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* 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 { createWidgetFactory } from '../create_widget';
import { ESQL_WIDGET_NAME } from './constants';
import type { EsqlWidgetParameters } from './types';

export const createEsqlWidget = createWidgetFactory<EsqlWidgetParameters>(ESQL_WIDGET_NAME);
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 type { IconType } from '@elastic/eui';
import type { Ast } from '@kbn/interpreter';
import type { InvestigateWidgetCreate } from '../../common';
import type { GlobalWidgetParameters } from '../../common/types';

// copied over from the Lens plugin to prevent dependency hell
type TableChangeType = 'initial' | 'unchanged' | 'reduced' | 'extended' | 'reorder' | 'layers';

interface Suggestion<T = unknown, V = unknown> {
visualizationId: string;
datasourceState?: V;
datasourceId?: string;
columns: number;
score: number;
title: string;
visualizationState: T;
previewExpression?: Ast | string;
previewIcon: IconType;
hide?: boolean;
// flag to indicate if the visualization is incomplete
incomplete?: boolean;
changeType: TableChangeType;
keptLayerIds: string[];
}

export interface EsqlWidgetParameters {
esql: string;
suggestion?: Suggestion;
predefined?: Partial<GlobalWidgetParameters>;
}

export type EsqlWidgetCreate = InvestigateWidgetCreate<EsqlWidgetParameters>;
47 changes: 47 additions & 0 deletions x-pack/plugins/observability_solution/investigate/public/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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 type { PluginInitializer, PluginInitializerContext } from '@kbn/core/public';

import { InvestigatePlugin } from './plugin';
import type {
InvestigatePublicSetup,
InvestigatePublicStart,
InvestigateSetupDependencies,
InvestigateStartDependencies,
ConfigSchema,
OnWidgetAdd,
WidgetRenderAPI,
} from './types';

export type { InvestigatePublicSetup, InvestigatePublicStart, OnWidgetAdd, WidgetRenderAPI };

export {
type InvestigateTimeline,
type InvestigateWidget,
type InvestigateWidgetCreate,
InvestigateWidgetColumnSpan,
type GlobalWidgetParameters,
type InvestigateUser,
type WorkflowBlock,
} from '../common/types';

export { ChromeOption } from './types';

export { createWidgetFactory } from './create_widget';
export { getEsFilterFromGlobalParameters } from './util/get_es_filters_from_global_parameters';

export { ESQL_WIDGET_NAME } from './esql_widget/constants';
export { createEsqlWidget } from './esql_widget/create_esql_widget';
export type { EsqlWidgetParameters } from './esql_widget/types';

export const plugin: PluginInitializer<
InvestigatePublicSetup,
InvestigatePublicStart,
InvestigateSetupDependencies,
InvestigateStartDependencies
> = (pluginInitializerContext: PluginInitializerContext<ConfigSchema>) =>
new InvestigatePlugin(pluginInitializerContext);
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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 type { CoreSetup, CoreStart, PluginInitializerContext, Plugin } from '@kbn/core/public';
import type { Logger } from '@kbn/logging';
import type {
ConfigSchema,
InvestigatePublicSetup,
InvestigatePublicStart,
InvestigateSetupDependencies,
InvestigateStartDependencies,
} from './types';
import { WidgetRegistry } from './widget_registry';

export class InvestigatePlugin
implements
Plugin<
InvestigatePublicSetup,
InvestigatePublicStart,
InvestigateSetupDependencies,
InvestigateStartDependencies
>
{
logger: Logger;

widgetRegistry: WidgetRegistry = new WidgetRegistry();

constructor(context: PluginInitializerContext<ConfigSchema>) {
this.logger = context.logger.get();
}
setup(coreSetup: CoreSetup, pluginsSetup: InvestigateSetupDependencies): InvestigatePublicSetup {
return {
registerWidget: this.widgetRegistry.registerWidget,
};
}

start(coreStart: CoreStart, pluginsStart: InvestigateStartDependencies): InvestigatePublicStart {
return {
getWidgetDefinitions: this.widgetRegistry.getWidgetDefinitions,
};
}
}
Loading

0 comments on commit 15b6ba9

Please sign in to comment.