Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Inventory] Inventory plugin #191798

Merged
merged 35 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
eb7569e
[Inventory] Inventory plugin
dgieselaar Jul 18, 2024
570f78d
Extract datasets
dgieselaar Aug 1, 2024
f5727e8
Disable inventory plugin by default
dgieselaar Aug 30, 2024
88cefe5
Fix types
dgieselaar Aug 30, 2024
e53b3b3
Disable by default
dgieselaar Aug 30, 2024
fe471af
Fix lint errors & CODEOWNERS
dgieselaar Aug 30, 2024
bc0b98c
Update codeowners via kibana.jsonc
dgieselaar Aug 30, 2024
f49bdac
Use right team
dgieselaar Aug 30, 2024
4336608
Add limits
dgieselaar Aug 30, 2024
e4bb64d
Separate repository client in fetch/stream
dgieselaar Aug 30, 2024
a709bec
Merge branch 'main' of github.com:elastic/kibana into inventory-plugin
dgieselaar Aug 30, 2024
cad3bb3
Update README
dgieselaar Aug 31, 2024
745b9da
Merge branch 'main' of github.com:elastic/kibana into inventory-plugin
dgieselaar Aug 31, 2024
ab9f8f9
Use KibanaRenderContextProvider
dgieselaar Aug 31, 2024
296ed2a
[CI] Auto-commit changed files from 'node scripts/yarn_deduplicate'
kibanamachine Aug 31, 2024
8dddf03
Fix types & tests
dgieselaar Aug 31, 2024
21003d7
Fix APM E2E test
dgieselaar Sep 1, 2024
b46a785
Fix bug in SSE formatting
dgieselaar Sep 2, 2024
b2fe459
Merge branch 'main' of github.com:elastic/kibana into inventory-plugin
dgieselaar Sep 2, 2024
171a8df
Merge branch 'main' of github.com:elastic/kibana into inventory-plugin
dgieselaar Sep 9, 2024
2f22a5d
Remove AI work
dgieselaar Sep 9, 2024
d73d1e5
Update CODEOWNERS
dgieselaar Sep 9, 2024
a4e7b65
Update CODEOWNERS
dgieselaar Sep 9, 2024
cd20fc0
[CI] Auto-commit changed files from 'node scripts/lint_packages --fix'
kibanamachine Sep 9, 2024
a61864e
Add back changes to menu
dgieselaar Sep 9, 2024
2c39d89
Merge branch 'inventory-plugin' of github.com:dgieselaar/kibana into …
dgieselaar Sep 9, 2024
70b0742
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Sep 9, 2024
ae4e035
Resolve merge conflict correctly
dgieselaar Sep 9, 2024
0b94e16
Fix tests
dgieselaar Sep 10, 2024
0238a8c
Fix type issues in routes
dgieselaar Sep 10, 2024
87b8924
Allow primitives as return types
dgieselaar Sep 10, 2024
4670089
Merge branch 'main' of github.com:elastic/kibana into inventory-plugin
dgieselaar Sep 10, 2024
6370430
Allow any as a value
dgieselaar Sep 11, 2024
a039dae
Update README.md
dgieselaar Sep 11, 2024
62e3ed0
[CI] Auto-commit changed files from 'node scripts/lint_packages --fix'
kibanamachine Sep 11, 2024
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
6 changes: 5 additions & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ packages/deeplinks/devtools @elastic/kibana-management
packages/deeplinks/fleet @elastic/fleet
packages/deeplinks/management @elastic/kibana-management
packages/deeplinks/ml @elastic/ml-ui
packages/deeplinks/observability @elastic/obs-ux-logs-team
packages/deeplinks/observability @elastic/obs-ux-management-team
packages/deeplinks/search @elastic/search-kibana
packages/deeplinks/security @elastic/security-solution
packages/deeplinks/shared @elastic/appex-sharedux
Expand Down Expand Up @@ -522,6 +522,7 @@ x-pack/plugins/integration_assistant @elastic/security-scalability
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/inventory @elastic/obs-ai-assistant
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
x-pack/plugins/observability_solution/inventory @elastic/obs-ai-assistant
x-pack/plugins/observability_solution/inventory @elastic/obs-ux-infra_services

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cheers, will update this in the kibana.jsonc file

x-pack/plugins/observability_solution/investigate_app @elastic/obs-ux-management-team
x-pack/plugins/observability_solution/investigate @elastic/obs-ux-management-team
packages/kbn-investigation-shared @elastic/obs-ux-management-team
Expand Down Expand Up @@ -876,6 +877,9 @@ packages/kbn-sort-predicates @elastic/kibana-visualizations
x-pack/plugins/spaces @elastic/kibana-security
x-pack/test/spaces_api_integration/common/plugins/spaces_test_plugin @elastic/kibana-security
packages/kbn-spec-to-console @elastic/kibana-management
packages/kbn-sse-utils @elastic/knowledge-team
packages/kbn-sse-utils-client @elastic/knowledge-team
packages/kbn-sse-utils-server @elastic/knowledge-team
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The team is not valid. Did you mean @elastic/obs-knowledge-team?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cheers, my bad!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure that the Knowledge team should be the owner though?
A recent Slack thread mentioned that we should use obs UI as the owner for things that can/should be shared across all of Obs solution.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that is practical tbh in this case. I've assigned the same CODEOWNER as @kbn/server-route-repository in this case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, which was also in the list of packages that maybe should be owned by Obs UI, but I'm not sure if action is being taken on that idea.

cc @jasonrhodes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to get route repository owned by the overall UI team to keep it unblocked, but I don't have an opinion on this code, especially while it's in an early exploratory phase.

x-pack/plugins/stack_alerts @elastic/response-ops
x-pack/plugins/stack_connectors @elastic/response-ops
x-pack/test/usage_collection/plugins/stack_management_usage_test @elastic/kibana-management
Expand Down
1 change: 1 addition & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
"searchTypes": "packages/kbn-search-types",
"securitySolutionPackages": "x-pack/packages/security-solution",
"serverlessPackages": "packages/serverless",
"sse": [ "packages/kbn-sse-utils" ],
"coloring": "packages/kbn-coloring/src",
"languageDocumentationPopover": "packages/kbn-language-documentation-popover/src",
"esql": "src/plugins/esql",
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 @@ -648,6 +648,10 @@ the infrastructure monitoring use-case within Kibana.
|Team owner: Security Integrations Scalability


|{kib-repo}blob/{branch}/x-pack/plugins/observability_solution/inventory/README.md[inventory]
|undefined


|{kib-repo}blob/{branch}/x-pack/plugins/observability_solution/investigate/README.md[investigate]
|undefined

Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,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/inventory-plugin": "link:x-pack/plugins/observability_solution/inventory",
"@kbn/investigate-app-plugin": "link:x-pack/plugins/observability_solution/investigate_app",
"@kbn/investigate-plugin": "link:x-pack/plugins/observability_solution/investigate",
"@kbn/investigation-shared": "link:packages/kbn-investigation-shared",
Expand Down Expand Up @@ -888,6 +889,9 @@
"@kbn/sort-predicates": "link:packages/kbn-sort-predicates",
"@kbn/spaces-plugin": "link:x-pack/plugins/spaces",
"@kbn/spaces-test-plugin": "link:x-pack/test/spaces_api_integration/common/plugins/spaces_test_plugin",
"@kbn/sse-utils": "link:packages/kbn-sse-utils",
"@kbn/sse-utils-client": "link:packages/kbn-sse-utils-client",
"@kbn/sse-utils-server": "link:packages/kbn-sse-utils-server",
"@kbn/stack-alerts-plugin": "link:x-pack/plugins/stack_alerts",
"@kbn/stack-connectors-plugin": "link:x-pack/plugins/stack_connectors",
"@kbn/stack-management-usage-test-plugin": "link:x-pack/test/usage_collection/plugins/stack_management_usage_test",
Expand Down
2 changes: 2 additions & 0 deletions packages/deeplinks/observability/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ export const INVESTIGATE_APP_ID = 'investigate';
export const OBLT_UX_APP_ID = 'ux';

export const OBLT_PROFILING_APP_ID = 'profiling';

export const INVENTORY_APP_ID = 'inventory';
10 changes: 8 additions & 2 deletions packages/deeplinks/observability/deep_links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
AI_ASSISTANT_APP_ID,
OBLT_UX_APP_ID,
OBLT_PROFILING_APP_ID,
INVENTORY_APP_ID,
} from './constants';

type LogsApp = typeof LOGS_APP_ID;
Expand All @@ -31,6 +32,7 @@ type SloApp = typeof SLO_APP_ID;
type AiAssistantApp = typeof AI_ASSISTANT_APP_ID;
type ObltUxApp = typeof OBLT_UX_APP_ID;
type ObltProfilingApp = typeof OBLT_PROFILING_APP_ID;
type InventoryApp = typeof INVENTORY_APP_ID;

export type AppId =
| LogsApp
Expand All @@ -43,10 +45,13 @@ export type AppId =
| SloApp
| AiAssistantApp
| ObltUxApp
| ObltProfilingApp;
| ObltProfilingApp
| InventoryApp;

export type LogsLinkId = 'log-categories' | 'settings' | 'anomalies' | 'stream';

export type InventoryLinkId = 'datastreams';

export type ObservabilityOverviewLinkId =
| 'alerts'
| 'cases'
Expand Down Expand Up @@ -89,4 +94,5 @@ export type DeepLinkId =
| `${MetricsApp}:${MetricsLinkId}`
| `${ApmApp}:${ApmLinkId}`
| `${SyntheticsApp}:${SyntheticsLinkId}`
| `${ObltProfilingApp}:${ProfilingLinkId}`;
| `${ObltProfilingApp}:${ProfilingLinkId}`
| `${InventoryApp}:${InventoryLinkId}`;
2 changes: 1 addition & 1 deletion packages/deeplinks/observability/kibana.jsonc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"type": "shared-common",
"id": "@kbn/deeplinks-observability",
"owner": "@elastic/obs-ux-logs-team"
"owner": "@elastic/obs-ux-management-team"
}
2 changes: 1 addition & 1 deletion packages/kbn-es-types/src/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export type SearchHit<
? {
fields: Partial<Record<ValueTypeOfField<TFields>, unknown[]>>;
}
: {}) &
: { fields?: Record<string, unknown[]> }) &
(TDocValueFields extends DocValueFields
? {
fields: Partial<Record<ValueTypeOfField<TDocValueFields>, unknown[]>>;
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 @@ -86,6 +86,7 @@ pageLoadAssetSize:
inspector: 148711
integrationAssistant: 19524
interactiveSetup: 80000
inventory: 27430
investigate: 17970
investigateApp: 91898
kibanaOverview: 56279
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { createParser } from 'eventsource-parser';
import { Observable, throwError } from 'rxjs';

export interface StreamedHttpResponse {
response?: { body: ReadableStream<Uint8Array> | null | undefined };
}

class NoReadableStreamError extends Error {
constructor() {
super(`No readable stream found in response`);
}
}

export function isNoReadableStreamError(error: any): error is NoReadableStreamError {
return error instanceof NoReadableStreamError;
}

export function createObservableFromHttpResponse(
response: StreamedHttpResponse
): Observable<string> {
const rawResponse = response.response;

const body = rawResponse?.body;
if (!body) {
return throwError(() => {
throw new NoReadableStreamError();
});
}

return new Observable<string>((subscriber) => {
const parser = createParser((event) => {
if (event.type === 'event') {
subscriber.next(event.data);
}
});

const readStream = async () => {
const reader = body.getReader();
const decoder = new TextDecoder();

// Function to process each chunk
const processChunk = ({
done,
value,
}: ReadableStreamReadResult<Uint8Array>): Promise<void> => {
if (done) {
return Promise.resolve();
}

parser.feed(decoder.decode(value, { stream: true }));

return reader.read().then(processChunk);
};

// Start reading the stream
return reader.read().then(processChunk);
};

readStream()
.then(() => {
subscriber.complete();
})
.catch((error) => {
subscriber.error(error);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,52 @@ import type { CoreSetup, CoreStart } from '@kbn/core-lifecycle-browser';
import {
RouteRepositoryClient,
ServerRouteRepository,
DefaultClientOptions,
formatRequest,
} from '@kbn/server-route-repository-utils';
import { httpResponseIntoObservable } from '@kbn/sse-utils-client';
import { from } from 'rxjs';
import { HttpFetchOptions, HttpFetchQuery, HttpResponse } from '@kbn/core-http-browser';
import { omit } from 'lodash';

export function createRepositoryClient<
TRepository extends ServerRouteRepository,
TClientOptions extends Record<string, any> = DefaultClientOptions
>(core: CoreStart | CoreSetup) {
TClientOptions extends HttpFetchOptions = {}
>(core: CoreStart | CoreSetup): RouteRepositoryClient<TRepository, TClientOptions> {
const fetch = (
endpoint: string,
params: { path?: Record<string, string>; body?: unknown; query?: HttpFetchQuery } | undefined,
options: TClientOptions
) => {
const { method, pathname, version } = formatRequest(endpoint, params?.path);

return core.http[method](pathname, {
...options,
body: params && params.body ? JSON.stringify(params.body) : undefined,
query: params?.query,
version,
});
};

return {
fetch: (endpoint, optionsWithParams) => {
const { params, ...options } = (optionsWithParams ?? { params: {} }) as unknown as {
params?: Partial<Record<string, any>>;
};
fetch: (endpoint, ...args) => {
const allOptions = args[0] ?? {};
const params = 'params' in allOptions ? (allOptions.params as Record<string, any>) : {};
const otherOptions = omit(allOptions, 'params') as TClientOptions;

const { method, pathname, version } = formatRequest(endpoint, params?.path);
return fetch(endpoint, params, otherOptions) as any;
},
stream: (endpoint, ...args) => {
miltonhultgren marked this conversation as resolved.
Show resolved Hide resolved
const allOptions = args[0] ?? {};
const params = 'params' in allOptions ? (allOptions.params as Record<string, any>) : {};
const otherOptions = omit(allOptions, 'params') as TClientOptions;

return core.http[method](pathname, {
...options,
body: params && params.body ? JSON.stringify(params.body) : undefined,
query: params?.query,
version,
});
return from(
fetch(endpoint, params, {
...otherOptions,
asResponse: true,
rawResponse: true,
}) as Promise<HttpResponse>
).pipe(httpResponseIntoObservable<any>()) as any;
},
} as { fetch: RouteRepositoryClient<TRepository, TClientOptions> };
};
}
1 change: 1 addition & 0 deletions packages/kbn-server-route-repository-client/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"@kbn/server-route-repository-utils",
"@kbn/core-lifecycle-browser",
"@kbn/core-http-browser",
"@kbn/sse-utils-client",
]
}
44 changes: 33 additions & 11 deletions packages/kbn-server-route-repository-utils/src/typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import type {
RouteConfigOptions,
RouteMethod,
} from '@kbn/core/server';
import type { ServerSentEvent } from '@kbn/sse-utils';
import { z } from '@kbn/zod';
import * as t from 'io-ts';
import { Observable } from 'rxjs';
import { RequiredKeys } from 'utility-types';

type PathMaybeOptional<T extends { path: Record<string, any> }> = RequiredKeys<
Expand Down Expand Up @@ -96,6 +98,12 @@ type ValidateEndpoint<TEndpoint extends string> = string extends TEndpoint
: false
: false;

type IsInvalidObservableReturnType<TReturnType> = TReturnType extends Observable<infer TValueType>
? TValueType extends ServerSentEvent
? false
: true
: false;

export type ServerRoute<
TEndpoint extends string,
TRouteParamsRT extends RouteParamsRT | undefined,
Expand All @@ -109,7 +117,9 @@ export type ServerRoute<
handler: ({}: TRouteHandlerResources &
(TRouteParamsRT extends RouteParamsRT
? DecodedRequestParamsOfType<TRouteParamsRT>
: {})) => Promise<TReturnType>;
: {})) => IsInvalidObservableReturnType<TReturnType> extends true
? never
: Promise<TReturnType>;
} & TRouteCreateOptions
: never;

Expand Down Expand Up @@ -192,24 +202,36 @@ type MaybeOptionalArgs<T extends Record<string, any>> = RequiredKeys<T> extends
? [T] | []
: [T];

export type RouteRepositoryClient<
export interface RouteRepositoryClient<
TServerRouteRepository extends ServerRouteRepository,
TAdditionalClientOptions extends Record<string, any> = DefaultClientOptions
> = <TEndpoint extends Extract<keyof TServerRouteRepository, string>>(
endpoint: TEndpoint,
...args: MaybeOptionalArgs<
ClientRequestParamsOf<TServerRouteRepository, TEndpoint> & TAdditionalClientOptions
>
) => Promise<ReturnOf<TServerRouteRepository, TEndpoint>>;

export type DefaultClientOptions = HttpFetchOptions;
TAdditionalClientOptions extends Record<string, any>
> {
fetch<TEndpoint extends Extract<keyof TServerRouteRepository, string>>(
endpoint: TEndpoint,
...args: MaybeOptionalArgs<
ClientRequestParamsOf<TServerRouteRepository, TEndpoint> & TAdditionalClientOptions
>
): Promise<ReturnOf<TServerRouteRepository, TEndpoint>>;
stream<TEndpoint extends Extract<keyof TServerRouteRepository, string>>(
endpoint: TEndpoint,
...args: MaybeOptionalArgs<
ClientRequestParamsOf<TServerRouteRepository, TEndpoint> & TAdditionalClientOptions
>
): ReturnOf<TServerRouteRepository, TEndpoint> extends Observable<infer TReturnType>
? TReturnType extends ServerSentEvent
? Observable<TReturnType>
: never
: never;
}

interface CoreRouteHandlerResources {
request: KibanaRequest;
response: KibanaResponseFactory;
context: RequestHandlerContext;
}

export type DefaultClientOptions = HttpFetchOptions;

export interface DefaultRouteHandlerResources extends CoreRouteHandlerResources {
logger: Logger;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/kbn-server-route-repository-utils/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
"target/**/*"
],
"kbn_references": [
"@kbn/core-http-browser",
"@kbn/core-http-server",
"@kbn/core",
"@kbn/zod",
"@kbn/core-http-browser",
"@kbn/sse-utils",
]
}
7 changes: 7 additions & 0 deletions packages/kbn-server-route-repository/src/register_routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ import {
ZodParamsObject,
parseEndpoint,
} from '@kbn/server-route-repository-utils';
import { observableIntoEventSourceStream } from '@kbn/sse-utils-server';
import { isZod } from '@kbn/zod';
import { merge } from 'lodash';
import { Observable, isObservable } from 'rxjs';
import { ServerSentEvent } from '@kbn/sse-utils';
import { passThroughValidationObject, noParamsValidationObject } from './validation_objects';
import { validateAndDecodeParams } from './validate_and_decode_params';
import { makeZodValidationObject } from './make_zod_validation_object';
Expand Down Expand Up @@ -88,6 +91,10 @@ export function registerRoutes<TDependencies extends Record<string, any>>({

if (isKibanaResponse(result)) {
return result;
} else if (isObservable(result)) {
return response.ok({
body: observableIntoEventSourceStream(result as Observable<ServerSentEvent>),
});
} else {
const body = result || {};
return response.ok({ body });
Expand Down
Loading