diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.deprecations.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.deprecations.md new file mode 100644 index 000000000000000..51d93371e518e9b --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.deprecations.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) > [deprecations](./kibana-plugin-core-server.corerequesthandlercontext.deprecations.md) + +## CoreRequestHandlerContext.deprecations property + +Signature: + +```typescript +deprecations: { + client: DeprecationsClient; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md new file mode 100644 index 000000000000000..22ff84ce1cb5747 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) > [elasticsearch](./kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md) + +## CoreRequestHandlerContext.elasticsearch property + +Signature: + +```typescript +elasticsearch: { + client: IScopedClusterClient; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.md new file mode 100644 index 000000000000000..47297bcddc906de --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) + +## CoreRequestHandlerContext interface + +The `core` context provided to route handler. + +Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.client](./kibana-plugin-core-server.iscopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request + +Signature: + +```typescript +export interface CoreRequestHandlerContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [deprecations](./kibana-plugin-core-server.corerequesthandlercontext.deprecations.md) | { client: DeprecationsClient; } | | +| [elasticsearch](./kibana-plugin-core-server.corerequesthandlercontext.elasticsearch.md) | { client: IScopedClusterClient; } | | +| [savedObjects](./kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md) | { client: SavedObjectsClientContract; typeRegistry: ISavedObjectTypeRegistry; getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; } | | +| [uiSettings](./kibana-plugin-core-server.corerequesthandlercontext.uisettings.md) | { client: IUiSettingsClient; } | | + diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md new file mode 100644 index 000000000000000..6d1aa0a8bb5f161 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) > [savedObjects](./kibana-plugin-core-server.corerequesthandlercontext.savedobjects.md) + +## CoreRequestHandlerContext.savedObjects property + +Signature: + +```typescript +savedObjects: { + client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; + getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; + getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; + getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.uisettings.md b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.uisettings.md new file mode 100644 index 000000000000000..f76dcc8965a03f3 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.corerequesthandlercontext.uisettings.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) > [uiSettings](./kibana-plugin-core-server.corerequesthandlercontext.uisettings.md) + +## CoreRequestHandlerContext.uiSettings property + +Signature: + +```typescript +uiSettings: { + client: IUiSettingsClient; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.customrequesthandlercontext.md b/docs/development/core/server/kibana-plugin-core-server.customrequesthandlercontext.md new file mode 100644 index 000000000000000..afaf8c278565a91 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.customrequesthandlercontext.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CustomRequestHandlerContext](./kibana-plugin-core-server.customrequesthandlercontext.md) + +## CustomRequestHandlerContext type + + +Signature: + +```typescript +export declare type CustomRequestHandlerContext = RequestHandlerContext & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md index f3be1a9130b9c71..bb03887e547e22a 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.md @@ -87,5 +87,5 @@ async (context, request, response) => { | [registerOnPreAuth](./kibana-plugin-core-server.httpservicesetup.registeronpreauth.md) | (handler: OnPreAuthHandler) => void | To define custom logic to perform for incoming requests before the Auth interceptor performs a check that user has access to requested resources. | | [registerOnPreResponse](./kibana-plugin-core-server.httpservicesetup.registeronpreresponse.md) | (handler: OnPreResponseHandler) => void | To define custom logic to perform for the server response. | | [registerOnPreRouting](./kibana-plugin-core-server.httpservicesetup.registeronprerouting.md) | (handler: OnPreRoutingHandler) => void | To define custom logic to perform for incoming requests before server performs a route lookup. | -| [registerRouteHandlerContext](./kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md) | <Context extends RequestHandlerContext, ContextName extends keyof Context>(contextName: ContextName, provider: RequestHandlerContextProvider<Context, ContextName>) => RequestHandlerContextContainer | Register a context provider for a route handler. | +| [registerRouteHandlerContext](./kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md) | <Context extends RequestHandlerContext, ContextName extends keyof Omit<Context, 'resolve'>>(contextName: ContextName, provider: RequestHandlerContextProvider<Context, ContextName>) => RequestHandlerContextContainer | Register a context provider for a route handler. | diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md index c793080305d0cd8..23e009864dcd654 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registerroutehandlercontext.md @@ -9,7 +9,7 @@ Register a context provider for a route handler. Signature: ```typescript -registerRouteHandlerContext: (contextName: ContextName, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; +registerRouteHandlerContext: >(contextName: ContextName, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; ``` ## Example diff --git a/docs/development/core/server/kibana-plugin-core-server.icontextprovider.md b/docs/development/core/server/kibana-plugin-core-server.icontextprovider.md index ddd8a0e92f46532..eb2ec3cbf90b88b 100644 --- a/docs/development/core/server/kibana-plugin-core-server.icontextprovider.md +++ b/docs/development/core/server/kibana-plugin-core-server.icontextprovider.md @@ -9,7 +9,7 @@ A function that returns a context value for a specific key of given context type Signature: ```typescript -export declare type IContextProvider = (context: Omit, ...rest: HandlerParameters) => Promise | Context[ContextName]; +export declare type IContextProvider = (context: Omit, ...rest: HandlerParameters) => MaybePromise>; ``` ## Remarks diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index d142579e1ced37f..e33beb19e01a4f7 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -60,6 +60,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ConfigDeprecationDetails](./kibana-plugin-core-server.configdeprecationdetails.md) | | | [ContextSetup](./kibana-plugin-core-server.contextsetup.md) | An object that handles registration of context providers and configuring handlers with context. | | [CorePreboot](./kibana-plugin-core-server.corepreboot.md) | Context passed to the setup method of preboot plugins. | +| [CoreRequestHandlerContext](./kibana-plugin-core-server.corerequesthandlercontext.md) | The core context provided to route handler.Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.client](./kibana-plugin-core-server.iscopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request | | [CoreSetup](./kibana-plugin-core-server.coresetup.md) | Context passed to the setup method of standard plugins. | | [CoreStart](./kibana-plugin-core-server.corestart.md) | Context passed to the plugins start method. | | [CoreStatus](./kibana-plugin-core-server.corestatus.md) | Status of core services. | @@ -133,7 +134,8 @@ The plugin integrates with the core system via lifecycle events: `setup` | [PrebootPlugin](./kibana-plugin-core-server.prebootplugin.md) | The interface that should be returned by a PluginInitializer for a preboot plugin. | | [PrebootServicePreboot](./kibana-plugin-core-server.prebootservicepreboot.md) | Kibana Preboot Service allows to control the boot flow of Kibana. Preboot plugins can use it to hold the boot until certain condition is met. | | [RegisterDeprecationsConfig](./kibana-plugin-core-server.registerdeprecationsconfig.md) | | -| [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md) | Plugin specific context passed to a route handler.Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.client](./kibana-plugin-core-server.iscopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request | +| [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md) | Base context passed to a route handler. | +| [RequestHandlerContextBase](./kibana-plugin-core-server.requesthandlercontextbase.md) | \* | | [ResolveCapabilitiesOptions](./kibana-plugin-core-server.resolvecapabilitiesoptions.md) | Defines a set of additional options for the resolveCapabilities method of [CapabilitiesStart](./kibana-plugin-core-server.capabilitiesstart.md). | | [RouteConfig](./kibana-plugin-core-server.routeconfig.md) | Route specific configuration. | | [RouteConfigOptions](./kibana-plugin-core-server.routeconfigoptions.md) | Additional route options. | @@ -262,6 +264,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [AuthResult](./kibana-plugin-core-server.authresult.md) | | | [CapabilitiesProvider](./kibana-plugin-core-server.capabilitiesprovider.md) | See [CapabilitiesSetup](./kibana-plugin-core-server.capabilitiessetup.md) | | [CapabilitiesSwitcher](./kibana-plugin-core-server.capabilitiesswitcher.md) | See [CapabilitiesSetup](./kibana-plugin-core-server.capabilitiessetup.md) | +| [CustomRequestHandlerContext](./kibana-plugin-core-server.customrequesthandlercontext.md) | | | [DeprecationsDetails](./kibana-plugin-core-server.deprecationsdetails.md) | | | [DestructiveRouteMethod](./kibana-plugin-core-server.destructiveroutemethod.md) | Set of HTTP methods changing the state of the server. | | [DocLinksServiceStart](./kibana-plugin-core-server.doclinksservicestart.md) | | diff --git a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.core.md b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.core.md index dcf6975c5fa702d..8d0b715fdef7bc1 100644 --- a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.core.md +++ b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.core.md @@ -7,22 +7,5 @@ Signature: ```typescript -core: { - savedObjects: { - client: SavedObjectsClientContract; - typeRegistry: ISavedObjectTypeRegistry; - getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; - getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; - getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; - }; - elasticsearch: { - client: IScopedClusterClient; - }; - uiSettings: { - client: IUiSettingsClient; - }; - deprecations: { - client: DeprecationsClient; - }; - }; +core: Promise; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.md b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.md index 0d705c9daa33384..214f8a6f6ba5c28 100644 --- a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontext.md @@ -4,19 +4,18 @@ ## RequestHandlerContext interface -Plugin specific context passed to a route handler. - -Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.client](./kibana-plugin-core-server.iscopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request +Base context passed to a route handler. Signature: ```typescript -export interface RequestHandlerContext +export interface RequestHandlerContext extends RequestHandlerContextBase ``` +Extends: RequestHandlerContextBase ## Properties | Property | Type | Description | | --- | --- | --- | -| [core](./kibana-plugin-core-server.requesthandlercontext.core.md) | { savedObjects: { client: SavedObjectsClientContract; typeRegistry: ISavedObjectTypeRegistry; getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; }; elasticsearch: { client: IScopedClusterClient; }; uiSettings: { client: IUiSettingsClient; }; deprecations: { client: DeprecationsClient; }; } | | +| [core](./kibana-plugin-core-server.requesthandlercontext.core.md) | Promise<CoreRequestHandlerContext> | | diff --git a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.md b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.md new file mode 100644 index 000000000000000..33a123eefae633a --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [RequestHandlerContextBase](./kibana-plugin-core-server.requesthandlercontextbase.md) + +## RequestHandlerContextBase interface + +\* + +Signature: + +```typescript +export interface RequestHandlerContextBase +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [resolve](./kibana-plugin-core-server.requesthandlercontextbase.resolve.md) | <T extends keyof Omit<this, 'resolve'>>(parts: T\[\]) => Promise<AwaitedProperties<Pick<this, T>>> | Await all the specified context parts and return them. | + diff --git a/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.resolve.md b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.resolve.md new file mode 100644 index 000000000000000..74192c0e1aee8d3 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.requesthandlercontextbase.resolve.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [RequestHandlerContextBase](./kibana-plugin-core-server.requesthandlercontextbase.md) > [resolve](./kibana-plugin-core-server.requesthandlercontextbase.resolve.md) + +## RequestHandlerContextBase.resolve property + +Await all the specified context parts and return them. + +Signature: + +```typescript +resolve: >(parts: T[]) => Promise>>; +``` + +## Example + + +```ts +const resolved = await context.resolve(['core', 'pluginA']); +const esClient = resolved.core.elasticsearch.client; +const pluginAService = resolved.pluginA.someService; +``` + diff --git a/examples/screenshot_mode_example/server/routes.ts b/examples/screenshot_mode_example/server/routes.ts index adf4c2e2b6fc5b3..44515abc48c703d 100644 --- a/examples/screenshot_mode_example/server/routes.ts +++ b/examples/screenshot_mode_example/server/routes.ts @@ -14,7 +14,7 @@ export const registerRoutes = ({ router, log, screenshotMode }: RouteDependencie { path: `${BASE_API_ROUTE}/check_is_screenshot`, validate: false }, async (ctx, req, res) => { log.info(`Reading screenshot mode from a request: ${screenshotMode.isScreenshotMode(req)}`); - log.info(`Reading is screenshot mode from ctx: ${ctx.screenshotMode.isScreenshot}`); + log.info(`Reading is screenshot mode from ctx: ${(await ctx.screenshotMode).isScreenshot}`); return res.ok(); } ); diff --git a/examples/search_examples/server/routes/server_search_route.ts b/examples/search_examples/server/routes/server_search_route.ts index d7464561a0abb64..632952b6c46176f 100644 --- a/examples/search_examples/server/routes/server_search_route.ts +++ b/examples/search_examples/server/routes/server_search_route.ts @@ -33,8 +33,9 @@ export function registerServerSearchRoute(router: IRouter = T | Promise; */ export type ShallowPromise = T extends Promise ? Promise : Promise; +/** + * Unwrap all promise attributes of the given type + */ +export type AwaitedProperties = { + [K in keyof T]: Awaited; +}; + /** * Minimal interface for an object resembling an `Observable`. */ diff --git a/src/core/server/context/container/context.test.ts b/src/core/server/context/container/context.test.ts index 25fab2e3f0bfbb0..17a04531dedd156 100644 --- a/src/core/server/context/container/context.test.ts +++ b/src/core/server/context/container/context.test.ts @@ -7,7 +7,7 @@ */ import { ContextContainer } from './context'; -import { PluginOpaqueId } from '../..'; +import type { PluginOpaqueId, RequestHandlerContextBase } from '../..'; import { httpServerMock } from '../../http/http_server.mocks'; const pluginA = Symbol('pluginA'); @@ -22,7 +22,7 @@ const plugins: ReadonlyMap = new Map([ ]); const coreId = Symbol(); -interface MyContext { +interface MyContext extends RequestHandlerContextBase { core: any; core1: string; core2: number; @@ -32,31 +32,47 @@ interface MyContext { ctxFromD: object; } +type TestContext = T & RequestHandlerContextBase; + describe('ContextContainer', () => { - it('does not allow the same context to be registered twice', () => { - const contextContainer = new ContextContainer(plugins, coreId); - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( - coreId, - 'ctxFromA', - () => 'aString' - ); - - expect(() => - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( + describe('registerContext', () => { + it('throws an error if the same context is registered twice', () => { + const contextContainer = new ContextContainer(plugins, coreId); + contextContainer.registerContext, 'ctxFromA'>( coreId, 'ctxFromA', () => 'aString' - ) - ).toThrowErrorMatchingInlineSnapshot( - `"Context provider for ctxFromA has already been registered."` - ); - }); + ); + + expect(() => + contextContainer.registerContext, 'ctxFromA'>( + coreId, + 'ctxFromA', + () => 'aString' + ) + ).toThrowErrorMatchingInlineSnapshot( + `"Context provider for ctxFromA has already been registered."` + ); + }); + + it('throws an error if a `resolve` context is registered', () => { + const contextContainer = new ContextContainer(plugins, coreId); + expect(() => + contextContainer.registerContext, 'ctxFromA'>( + coreId, + // @ts-expect-error protected with typing too + 'resolve', + () => 'aString' + ) + ).toThrowErrorMatchingInlineSnapshot( + `"Cannot register a provider for resolve, it is a reserved keyword."` + ); + }); - describe('registerContext', () => { it('throws error if called with an unknown symbol', async () => { const contextContainer = new ContextContainer(plugins, coreId); await expect(() => - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( + contextContainer.registerContext, 'ctxFromA'>( Symbol('unknown'), 'ctxFromA', jest.fn() @@ -69,7 +85,7 @@ describe('ContextContainer', () => { it('reports a TS error if returned contract does not satisfy the Context interface', async () => { const contextContainer = new ContextContainer(plugins, coreId); await expect(() => - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( + contextContainer.registerContext, 'ctxFromA'>( pluginA, 'ctxFromA', // @ts-expect-error expected string, returned number @@ -82,7 +98,7 @@ describe('ContextContainer', () => { const contextContainer = new ContextContainer(plugins, coreId); await expect(() => // @ts-expect-error expects ctxFromB, but given ctxFromC - contextContainer.registerContext<{ ctxFromB: string; core: any }, 'ctxFromC'>( + contextContainer.registerContext, 'ctxFromC'>( pluginB, 'ctxFromC', async () => 1 @@ -92,39 +108,216 @@ describe('ContextContainer', () => { }); describe('context building', () => { + const resolveAllContexts = async (ctx: Record): Promise => { + const resolved = {} as Record; + for (const key of Object.getOwnPropertyNames(ctx)) { + if (key === 'resolve') { + continue; + } + resolved[key] = await ctx[key]; + } + return resolved; + }; + + it('lazily loads the providers when accessed', async () => { + const contextContainer = new ContextContainer(plugins, coreId); + + const core1provider = jest.fn().mockReturnValue('core1'); + const ctxFromAProvider = jest.fn().mockReturnValue('ctxFromA'); + + contextContainer.registerContext, 'core1'>( + coreId, + 'core1', + core1provider + ); + + contextContainer.registerContext, 'ctxFromA'>( + pluginA, + 'ctxFromA', + ctxFromAProvider + ); + + let context: any; + const rawHandler1 = jest.fn((ctx) => { + context = ctx; + return 'rawHandler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + await handler1(request, response); + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + await context!.core1; + + expect(core1provider).toHaveBeenCalledTimes(1); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + await context!.ctxFromA; + + expect(core1provider).toHaveBeenCalledTimes(1); + expect(ctxFromAProvider).toHaveBeenCalledTimes(1); + }); + + it(`does not eagerly loads a provider's dependencies`, async () => { + const contextContainer = new ContextContainer(plugins, coreId); + + const core1provider = jest.fn().mockReturnValue('core1'); + const ctxFromAProvider = jest.fn().mockReturnValue('ctxFromA'); + + contextContainer.registerContext, 'core1'>( + coreId, + 'core1', + core1provider + ); + + contextContainer.registerContext, 'ctxFromA'>( + pluginA, + 'ctxFromA', + ctxFromAProvider + ); + + let context: any; + const rawHandler1 = jest.fn((ctx) => { + context = ctx; + return 'rawHandler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + await handler1(request, response); + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + await context!.ctxFromA; + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).toHaveBeenCalledTimes(1); + }); + + it(`allows to load a dependency from a provider`, async () => { + const contextContainer = new ContextContainer(plugins, coreId); + + const core1provider = jest.fn().mockReturnValue('core1'); + const ctxFromAProvider = jest.fn().mockImplementation(async (ctx: any) => { + const core1 = await ctx.core1; + return `${core1}-ctxFromA`; + }); + + contextContainer.registerContext, 'core1'>( + coreId, + 'core1', + core1provider + ); + + contextContainer.registerContext, 'ctxFromA'>( + pluginA, + 'ctxFromA', + ctxFromAProvider + ); + + let context: any; + const rawHandler1 = jest.fn((ctx) => { + context = ctx; + return 'rawHandler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + await handler1(request, response); + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + const contextValue = await context!.ctxFromA; + + expect(contextValue).toEqual('core1-ctxFromA'); + expect(core1provider).toHaveBeenCalledTimes(1); + expect(ctxFromAProvider).toHaveBeenCalledTimes(1); + }); + + it(`only calls a provider once and caches the returned value`, async () => { + const contextContainer = new ContextContainer(plugins, coreId); + + const core1provider = jest.fn().mockReturnValue('core1'); + const ctxFromAProvider = jest.fn().mockImplementation(async (ctx: any) => { + const core1 = await ctx.core1; + return `${core1}-ctxFromA`; + }); + + contextContainer.registerContext, 'core1'>( + coreId, + 'core1', + core1provider + ); + + contextContainer.registerContext, 'ctxFromA'>( + pluginA, + 'ctxFromA', + ctxFromAProvider + ); + + let context: any; + const rawHandler1 = jest.fn((ctx) => { + context = ctx; + return 'rawHandler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + await handler1(request, response); + + expect(core1provider).not.toHaveBeenCalled(); + expect(ctxFromAProvider).not.toHaveBeenCalled(); + + await context!.core1; + await context!.ctxFromA; + await context!.core1; + + expect(core1provider).toHaveBeenCalledTimes(1); + expect(ctxFromAProvider).toHaveBeenCalledTimes(1); + }); + it('resolves dependencies', async () => { const contextContainer = new ContextContainer(plugins, coreId); - expect.assertions(8); - contextContainer.registerContext<{ core1: string; core: any }, 'core1'>( + expect.assertions(10); + contextContainer.registerContext, 'core1'>( coreId, 'core1', - (context) => { - expect(context).toEqual({}); + async (context) => { + expect(await resolveAllContexts(context)).toEqual({}); return 'core'; } ); - contextContainer.registerContext<{ ctxFromA: string; core: any }, 'ctxFromA'>( + contextContainer.registerContext, 'ctxFromA'>( pluginA, 'ctxFromA', - (context) => { - expect(context).toEqual({ core1: 'core' }); + async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core' }); return 'aString'; } ); - contextContainer.registerContext<{ ctxFromB: number; core: any }, 'ctxFromB'>( + contextContainer.registerContext, 'ctxFromB'>( pluginB, 'ctxFromB', - (context) => { - expect(context).toEqual({ core1: 'core', ctxFromA: 'aString' }); + async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core', ctxFromA: 'aString' }); return 299; } ); - contextContainer.registerContext<{ ctxFromC: boolean; core: any }, 'ctxFromC'>( + contextContainer.registerContext, 'ctxFromC'>( pluginC, 'ctxFromC', - (context) => { - expect(context).toEqual({ + async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core', ctxFromA: 'aString', ctxFromB: 299, @@ -132,19 +325,34 @@ describe('ContextContainer', () => { return false; } ); - contextContainer.registerContext<{ ctxFromD: {}; core: any }, 'ctxFromD'>( + contextContainer.registerContext, 'ctxFromD'>( pluginD, 'ctxFromD', - (context) => { - expect(context).toEqual({ core1: 'core' }); + async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core' }); return {}; } ); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + ctxFromA: 'aString', + ctxFromB: 299, + ctxFromC: false, + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(pluginC, rawHandler1); - const rawHandler2 = jest.fn(() => 'handler2' as any); + const rawHandler2 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + ctxFromD: {}, + }); + return 'handler2' as any; + }); + const handler2 = contextContainer.createHandler(pluginD, rawHandler2); const request = httpServerMock.createKibanaRequest(); @@ -154,41 +362,25 @@ describe('ContextContainer', () => { await handler2(request, response); // Should have context from pluginC, its deps, and core - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - ctxFromA: 'aString', - ctxFromB: 299, - ctxFromC: false, - }, - request, - response - ); + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); // Should have context from pluginD, and core - expect(rawHandler2).toHaveBeenCalledWith( - { - core1: 'core', - ctxFromD: {}, - }, - request, - response - ); + expect(rawHandler2).toHaveBeenCalledWith(expect.any(Object), request, response); }); it('exposes all core context to all providers regardless of registration order', async () => { - expect.assertions(4); + expect.assertions(5); const contextContainer = new ContextContainer(plugins, coreId); contextContainer - .registerContext(pluginA, 'ctxFromA', (context) => { - expect(context).toEqual({ core1: 'core', core2: 101 }); - return `aString ${context.core1} ${context.core2}`; + .registerContext(pluginA, 'ctxFromA', async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core', core2: 101 }); + return `aString ${await context.core1} ${await context.core2}`; }) .registerContext(coreId, 'core1', () => 'core') .registerContext(coreId, 'core2', () => 101) - .registerContext(pluginB, 'ctxFromB', (context) => { - expect(context).toEqual({ + .registerContext(pluginB, 'ctxFromB', async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core', core2: 101, ctxFromA: 'aString core 101', @@ -196,40 +388,45 @@ describe('ContextContainer', () => { return 277; }); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + core2: 101, + ctxFromA: 'aString core 101', + ctxFromB: 277, + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(pluginB, rawHandler1); const request = httpServerMock.createKibanaRequest(); const response = httpServerMock.createResponseFactory(); expect(await handler1(request, response)).toEqual('handler1'); - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - core2: 101, - ctxFromA: 'aString core 101', - ctxFromB: 277, - }, - request, - response - ); + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); }); it('exposes all core context to core providers', async () => { - expect.assertions(4); + expect.assertions(5); const contextContainer = new ContextContainer(plugins, coreId); contextContainer - .registerContext(coreId, 'core1', (context) => { - expect(context).toEqual({}); + .registerContext(coreId, 'core1', async (context) => { + expect(await resolveAllContexts(context)).toEqual({}); return 'core'; }) - .registerContext(coreId, 'core2', (context) => { - expect(context).toEqual({ core1: 'core' }); + .registerContext(coreId, 'core2', async (context) => { + expect(await resolveAllContexts(context)).toEqual({ core1: 'core' }); return 101; }); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + core2: 101, + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(pluginA, rawHandler1); const request = httpServerMock.createKibanaRequest(); @@ -237,14 +434,7 @@ describe('ContextContainer', () => { expect(await handler1(request, response)).toEqual('handler1'); // If no context is registered for pluginA, only core contexts should be exposed - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - core2: 101, - }, - request, - response - ); + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); }); it('does not expose plugin contexts to core handler', async () => { @@ -254,24 +444,24 @@ describe('ContextContainer', () => { .registerContext(coreId, 'core1', (context) => 'core') .registerContext(pluginA, 'ctxFromA', (context) => 'aString'); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + // pluginA context should not be present in a core handler + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(coreId, rawHandler1); const request = httpServerMock.createKibanaRequest(); const response = httpServerMock.createResponseFactory(); expect(await handler1(request, response)).toEqual('handler1'); - // pluginA context should not be present in a core handler - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - }, - request, - response - ); + + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); }); it('passes additional arguments to providers', async () => { - expect.assertions(6); + expect.assertions(7); const contextContainer = new ContextContainer(plugins, coreId); const request = httpServerMock.createKibanaRequest(); @@ -292,19 +482,102 @@ describe('ContextContainer', () => { } ); - const rawHandler1 = jest.fn(() => 'handler1' as any); + const rawHandler1 = jest.fn(async (context) => { + expect(await resolveAllContexts(context)).toEqual({ + core1: 'core', + ctxFromB: 77, + }); + return 'handler1' as any; + }); const handler1 = contextContainer.createHandler(pluginD, rawHandler1); expect(await handler1(request, response)).toEqual('handler1'); - expect(rawHandler1).toHaveBeenCalledWith( - { - core1: 'core', - ctxFromB: 77, - }, - request, - response - ); + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); + }); + + describe('#resolve', () => { + it('resolves dependencies', async () => { + const contextContainer = new ContextContainer(plugins, coreId); + expect.assertions(10); + contextContainer.registerContext(coreId, 'core1', async (context) => { + expect(await context.resolve([])).toEqual({}); + return 'core'; + }); + + contextContainer.registerContext( + pluginA, + 'ctxFromA', + async (context) => { + expect(await context.resolve(['core1'])).toEqual({ core1: 'core' }); + return 'aString'; + } + ); + contextContainer.registerContext( + pluginB, + 'ctxFromB', + async (context) => { + expect(await context.resolve(['core1', 'ctxFromA'])).toEqual({ + core1: 'core', + ctxFromA: 'aString', + }); + return 299; + } + ); + contextContainer.registerContext( + pluginC, + 'ctxFromC', + async (context) => { + expect(await context.resolve(['core1', 'ctxFromA', 'ctxFromB'])).toEqual({ + core1: 'core', + ctxFromA: 'aString', + ctxFromB: 299, + }); + return false; + } + ); + contextContainer.registerContext( + pluginD, + 'ctxFromD', + async (context) => { + expect(await context.resolve(['core1'])).toEqual({ core1: 'core' }); + return {}; + } + ); + + const rawHandler1 = jest.fn(async (context) => { + expect(await context.resolve(['core1', 'ctxFromA', 'ctxFromB', 'ctxFromC'])).toEqual({ + core1: 'core', + ctxFromA: 'aString', + ctxFromB: 299, + ctxFromC: false, + }); + return 'handler1' as any; + }); + const handler1 = contextContainer.createHandler(pluginC, rawHandler1); + + const rawHandler2 = jest.fn(async (context) => { + expect(await context.resolve(['core1', 'ctxFromD'])).toEqual({ + core1: 'core', + ctxFromD: {}, + }); + return 'handler2' as any; + }); + + const handler2 = contextContainer.createHandler(pluginD, rawHandler2); + + const request = httpServerMock.createKibanaRequest(); + const response = httpServerMock.createResponseFactory(); + + await handler1(request, response); + await handler2(request, response); + + // Should have context from pluginC, its deps, and core + expect(rawHandler1).toHaveBeenCalledWith(expect.any(Object), request, response); + + // Should have context from pluginD, and core + expect(rawHandler2).toHaveBeenCalledWith(expect.any(Object), request, response); + }); }); }); @@ -337,7 +610,11 @@ describe('ContextContainer', () => { const request = httpServerMock.createKibanaRequest(); const response = httpServerMock.createResponseFactory(); await handler1(request, response); - expect(rawHandler1).toHaveBeenCalledWith({}, request, response); + expect(rawHandler1).toHaveBeenCalledWith( + { resolve: expect.any(Function) }, + request, + response + ); }); }); }); diff --git a/src/core/server/context/container/context.ts b/src/core/server/context/container/context.ts index 2650c218536044b..4bc9a70a7afbbea 100644 --- a/src/core/server/context/container/context.ts +++ b/src/core/server/context/container/context.ts @@ -7,8 +7,7 @@ */ import { flatten } from 'lodash'; -import { ShallowPromise } from '@kbn/utility-types'; -import { pick } from 'lodash'; +import { ShallowPromise, MaybePromise } from '@kbn/utility-types'; import type { CoreId, PluginOpaqueId, RequestHandler, RequestHandlerContext } from '../..'; /** @@ -31,7 +30,7 @@ export type IContextProvider< // context.core will always be available, but plugin contexts are typed as optional context: Omit, ...rest: HandlerParameters -) => Promise | Context[ContextName]; +) => MaybePromise>; /** * A function that accepts a context object and an optional number of additional arguments. Used for the generic types @@ -202,6 +201,9 @@ export class ContextContainer implements IContextContainer { provider: IContextProvider ): this => { const contextName = name as string; + if (contextName === 'resolve') { + throw new Error(`Cannot register a provider for ${contextName}, it is a reserved keyword.`); + } if (this.contextProviders.has(contextName)) { throw new Error(`Context provider for ${contextName} has already been registered.`); } @@ -224,36 +226,51 @@ export class ContextContainer implements IContextContainer { } return (async (...args: HandlerParameters) => { - const context = await this.buildContext(source, ...args); + const context = this.buildContext(source, ...args); return handler(context, ...args); }) as ( ...args: HandlerParameters ) => ShallowPromise>; }; - private async buildContext( + private buildContext( source: symbol, ...contextArgs: HandlerParameters - ): Promise> { + ): HandlerContextType { const contextsToBuild = new Set(this.getContextNamesForSource(source)); + const builtContextPromises: Record> = {}; + + const builtContext = {} as HandlerContextType; + (builtContext as unknown as RequestHandlerContext).resolve = async (keys) => { + const resolved = await Promise.all( + keys.map(async (key) => { + return [key, await builtContext[key]]; + }) + ); + return Object.fromEntries(resolved); + }; return [...this.contextProviders] .sort(sortByCoreFirst(this.coreId)) .filter(([contextName]) => contextsToBuild.has(contextName)) - .reduce(async (contextPromise, [contextName, { provider, source: providerSource }]) => { - const resolvedContext = await contextPromise; - - // For the next provider, only expose the context available based on the dependencies of the plugin that - // registered that provider. - const exposedContext = pick(resolvedContext, [ - ...this.getContextNamesForSource(providerSource), - ]); + .reduce((contextAccessors, [contextName, { provider, source: providerSource }]) => { + const exposedContext = createExposedContext({ + currentContextName: contextName, + exposedContextNames: [...this.getContextNamesForSource(providerSource)], + contextAccessors, + }); + Object.defineProperty(contextAccessors, contextName, { + get: async () => { + const contextKey = contextName as keyof HandlerContextType; + if (!builtContextPromises[contextKey]) { + builtContextPromises[contextKey] = provider(exposedContext, ...contextArgs); + } + return await builtContextPromises[contextKey]; + }, + }); - return { - ...resolvedContext, - [contextName]: await provider(exposedContext, ...contextArgs), - }; - }, Promise.resolve({}) as Promise>); + return contextAccessors; + }, builtContext); } private getContextNamesForSource(source: symbol): ReadonlySet { @@ -299,3 +316,28 @@ const sortByCoreFirst = return rightProvider.source === coreId ? 1 : 0; } }; + +const createExposedContext = ({ + currentContextName, + exposedContextNames, + contextAccessors, +}: { + currentContextName: string; + exposedContextNames: string[]; + contextAccessors: Partial>; +}) => { + const exposedContext: Partial> = {}; + exposedContext.resolve = contextAccessors.resolve; + + for (const contextName of exposedContextNames) { + if (contextName === currentContextName) { + continue; + } + const descriptor = Object.getOwnPropertyDescriptor(contextAccessors, contextName); + if (descriptor) { + Object.defineProperty(exposedContext, contextName, descriptor); + } + } + + return exposedContext; +}; diff --git a/src/core/server/core_app/core_app.ts b/src/core/server/core_app/core_app.ts index bd7de6b20226c47..28c52775b2d20a6 100644 --- a/src/core/server/core_app/core_app.ts +++ b/src/core/server/core_app/core_app.ts @@ -89,7 +89,8 @@ export class CoreApp { const resources = coreSetup.httpResources.createRegistrar(router); router.get({ path: '/', validate: false }, async (context, req, res) => { - const defaultRoute = await context.core.uiSettings.client.get('defaultRoute'); + const { uiSettings } = await context.core; + const defaultRoute = await uiSettings.client.get('defaultRoute'); const basePath = httpSetup.basePath.get(req); const url = `${basePath}${defaultRoute}`; diff --git a/src/core/server/deprecations/routes/get.ts b/src/core/server/deprecations/routes/get.ts index cce9369db6171f4..88965505488f98c 100644 --- a/src/core/server/deprecations/routes/get.ts +++ b/src/core/server/deprecations/routes/get.ts @@ -15,7 +15,7 @@ export const registerGetRoute = (router: IRouter) => { validate: false, }, async (context, req, res) => { - const deprecationsClient = context.core.deprecations.client; + const deprecationsClient = (await context.core).deprecations.client; const body: DeprecationsGetResponse = { deprecations: await deprecationsClient.getAllDeprecations(), diff --git a/src/core/server/execution_context/integration_tests/tracing.test.ts b/src/core/server/execution_context/integration_tests/tracing.test.ts index 15813529c358bdc..2634c81833735fc 100644 --- a/src/core/server/execution_context/integration_tests/tracing.test.ts +++ b/src/core/server/execution_context/integration_tests/tracing.test.ts @@ -65,10 +65,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asInternalUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asInternalUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -90,10 +88,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -115,10 +111,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asInternalUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asInternalUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -136,10 +130,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -157,7 +149,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asInternalUser.ping( + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asInternalUser.ping( {}, { opaqueId: 'new-opaque-id', @@ -203,10 +196,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -229,10 +220,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(parentContext); - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: { context: executionContext.get()?.toJSON(), @@ -345,10 +334,8 @@ describe('trace', () => { router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(parentContext); await delay(id-- * 100); - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -397,10 +384,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -487,10 +472,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -511,10 +494,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asInternalUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asInternalUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -535,10 +516,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -561,10 +540,8 @@ describe('trace', () => { const router = createRouter(''); router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(parentContext); - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -593,10 +570,8 @@ describe('trace', () => { }; router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { executionContext.set(ctx); - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return res.ok({ body: headers || {} }); }); @@ -663,9 +638,10 @@ describe('trace', () => { description: 'new-description', }; router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { - const { headers } = await executionContext.withContext(newContext, () => - context.core.elasticsearch.client.asCurrentUser.ping({}, { meta: true }) - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await executionContext.withContext(newContext, () => { + return esClient.asCurrentUser.ping({}, { meta: true }); + }); return res.ok({ body: headers || {} }); }); diff --git a/src/core/server/http/types.ts b/src/core/server/http/types.ts index e6d95141077982f..27f240af48e0123 100644 --- a/src/core/server/http/types.ts +++ b/src/core/server/http/types.ts @@ -366,7 +366,7 @@ export interface HttpServiceSetup { */ registerRouteHandlerContext: < Context extends RequestHandlerContext, - ContextName extends keyof Context + ContextName extends keyof Omit >( contextName: ContextName, provider: RequestHandlerContextProvider @@ -393,7 +393,7 @@ export interface InternalHttpServiceSetup authRequestHeaders: IAuthHeadersStorage; registerRouteHandlerContext: < Context extends RequestHandlerContext, - ContextName extends keyof Context + ContextName extends keyof Omit >( pluginOpaqueId: PluginOpaqueId, contextName: ContextName, diff --git a/src/core/server/http_resources/http_resources_service.test.ts b/src/core/server/http_resources/http_resources_service.test.ts index 0a661f25d314121..c74fde4d2e2a73f 100644 --- a/src/core/server/http_resources/http_resources_service.test.ts +++ b/src/core/server/http_resources/http_resources_service.test.ts @@ -27,7 +27,7 @@ describe('HttpResources service', () => { let setupDeps: SetupDeps; let router: jest.Mocked; const kibanaRequest = httpServerMock.createKibanaRequest(); - const context = { core: coreMock.createRequestHandlerContext() }; + const context = coreMock.createCustomRequestHandlerContext({}); const apmConfig = { mockApmConfig: true }; beforeEach(() => { @@ -71,7 +71,7 @@ describe('HttpResources service', () => { await routeHandler(context, kibanaRequest, responseFactory); expect(getDeps().rendering.render).toHaveBeenCalledWith( kibanaRequest, - context.core.uiSettings.client, + (await context.core).uiSettings.client, { isAnonymousPage: false, vars: { @@ -117,7 +117,7 @@ describe('HttpResources service', () => { await routeHandler(context, kibanaRequest, responseFactory); expect(getDeps().rendering.render).toHaveBeenCalledWith( kibanaRequest, - context.core.uiSettings.client, + (await context.core).uiSettings.client, { isAnonymousPage: true, vars: { diff --git a/src/core/server/http_resources/http_resources_service.ts b/src/core/server/http_resources/http_resources_service.ts index 692b248752df944..2d49cb17cf4c07b 100644 --- a/src/core/server/http_resources/http_resources_service.ts +++ b/src/core/server/http_resources/http_resources_service.ts @@ -93,7 +93,8 @@ export class HttpResourcesService implements CoreService>( + parts: T[] + ) => Promise>>; +} + /** - * Plugin specific context passed to a route handler. + * Base context passed to a route handler. + * + * @public + */ +export interface RequestHandlerContext extends RequestHandlerContextBase { + core: Promise; +} + +/** @public */ +export type CustomRequestHandlerContext = RequestHandlerContext & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; + +/** + * The `core` context provided to route handler. * * Provides the following clients and services: * - {@link SavedObjectsClient | savedObjects.client} - Saved Objects client @@ -477,27 +509,24 @@ export { TelemetryCounterType } from './analytics'; * data client which uses the credentials of the incoming request * - {@link IUiSettingsClient | uiSettings.client} - uiSettings client * which uses the credentials of the incoming request - * * @public */ -export interface RequestHandlerContext { - core: { - savedObjects: { - client: SavedObjectsClientContract; - typeRegistry: ISavedObjectTypeRegistry; - getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; - getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; - getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; - }; - elasticsearch: { - client: IScopedClusterClient; - }; - uiSettings: { - client: IUiSettingsClient; - }; - deprecations: { - client: DeprecationsClient; - }; +export interface CoreRequestHandlerContext { + savedObjects: { + client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; + getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; + getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; + getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; + }; + elasticsearch: { + client: IScopedClusterClient; + }; + uiSettings: { + client: IUiSettingsClient; + }; + deprecations: { + client: DeprecationsClient; }; } diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 0e5821bcc1c23d4..cb7010808fe32fd 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -9,6 +9,7 @@ import { of } from 'rxjs'; import { duration } from 'moment'; import { ByteSizeValue } from '@kbn/config-schema'; +import { isPromise } from '@kbn/std'; import type { MockedKeys } from '@kbn/utility-types/jest'; import type { PluginInitializerContext, @@ -66,7 +67,11 @@ export { executionContextServiceMock } from './execution_context/execution_conte export { docLinksServiceMock } from './doc_links/doc_links_service.mock'; export { analyticsServiceMock } from './analytics/analytics_service.mock'; -export type { ElasticsearchClientMock } from './elasticsearch/client/mocks'; +export type { + ElasticsearchClientMock, + ClusterClientMock, + ScopedClusterClientMock, +} from './elasticsearch/client/mocks'; type MockedPluginInitializerConfig = jest.Mocked['config']>; @@ -280,6 +285,40 @@ function createCoreRequestHandlerContextMock() { }; } +export type CustomRequestHandlerMock = { + core: Promise>; + resolve: jest.MockedFunction; +} & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; + +const createCustomRequestHandlerContextMock = (contextParts: T): CustomRequestHandlerMock => { + const mock = Object.entries(contextParts).reduce( + (context, [key, value]) => { + // @ts-expect-error type matching from inferred types is hard + context[key] = isPromise(value) ? value : Promise.resolve(value); + return context; + }, + { + core: Promise.resolve(createCoreRequestHandlerContextMock()), + } as CustomRequestHandlerMock + ); + + mock.resolve = jest.fn().mockImplementation(async () => { + const resolved = {}; + for (const propName of Object.keys(mock)) { + if (propName === 'resolve') { + continue; + } + // @ts-expect-error type matching from inferred types is hard + resolved[propName] = await mock[propName]; + } + return resolved; + }); + + return mock; +}; + export const coreMock = { createPreboot: createCorePrebootMock, createSetup: createCoreSetupMock, @@ -289,4 +328,5 @@ export const coreMock = { createInternalStart: createInternalCoreStartMock, createPluginInitializerContext: pluginInitializerContextMock, createRequestHandlerContext: createCoreRequestHandlerContextMock, + createCustomRequestHandlerContext: createCustomRequestHandlerContextMock, }; diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index 1566fd5bbe07b7a..81e3b3a107c725a 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -185,7 +185,7 @@ export function createPluginSetupContext( createCookieSessionStorageFactory: deps.http.createCookieSessionStorageFactory, registerRouteHandlerContext: < Context extends RequestHandlerContext, - ContextName extends keyof Context + ContextName extends keyof Omit >( contextName: ContextName, provider: RequestHandlerContextProvider diff --git a/src/core/server/rendering/bootstrap/register_bootstrap_route.ts b/src/core/server/rendering/bootstrap/register_bootstrap_route.ts index 6be537dce1981eb..06f4100a01576c2 100644 --- a/src/core/server/rendering/bootstrap/register_bootstrap_route.ts +++ b/src/core/server/rendering/bootstrap/register_bootstrap_route.ts @@ -25,7 +25,7 @@ export const registerBootstrapRoute = ({ validate: false, }, async (ctx, req, res) => { - const uiSettingsClient = ctx.core.uiSettings.client; + const uiSettingsClient = (await ctx.core).uiSettings.client; const { body, etag } = await renderer({ uiSettingsClient, request: req }); return res.ok({ @@ -48,7 +48,7 @@ export const registerBootstrapRoute = ({ validate: false, }, async (ctx, req, res) => { - const uiSettingsClient = ctx.core.uiSettings.client; + const uiSettingsClient = (await ctx.core).uiSettings.client; const { body, etag } = await renderer({ uiSettingsClient, request: req, diff --git a/src/core/server/saved_objects/routes/bulk_create.ts b/src/core/server/saved_objects/routes/bulk_create.ts index f8438a70d041871..b72cd6715fa10c7 100644 --- a/src/core/server/saved_objects/routes/bulk_create.ts +++ b/src/core/server/saved_objects/routes/bulk_create.ts @@ -51,7 +51,8 @@ export const registerBulkCreateRoute = (router: IRouter, { coreUsageData }: Rout const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsBulkCreate({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.bulkCreate(req.body, { overwrite }); + const { savedObjects } = await context.core; + const result = await savedObjects.client.bulkCreate(req.body, { overwrite }); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/bulk_get.ts b/src/core/server/saved_objects/routes/bulk_get.ts index cffa69b06f4e448..87b6a604ac6c49e 100644 --- a/src/core/server/saved_objects/routes/bulk_get.ts +++ b/src/core/server/saved_objects/routes/bulk_get.ts @@ -34,7 +34,8 @@ export const registerBulkGetRoute = (router: IRouter, { coreUsageData }: RouteDe const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsBulkGet({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.bulkGet(req.body); + const { savedObjects } = await context.core; + const result = await savedObjects.client.bulkGet(req.body); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/bulk_resolve.ts b/src/core/server/saved_objects/routes/bulk_resolve.ts index 493f76a2c497c88..5754ec180541c5e 100644 --- a/src/core/server/saved_objects/routes/bulk_resolve.ts +++ b/src/core/server/saved_objects/routes/bulk_resolve.ts @@ -32,7 +32,8 @@ export const registerBulkResolveRoute = (router: IRouter, { coreUsageData }: Rou const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsBulkResolve({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.bulkResolve(req.body); + const { savedObjects } = await context.core; + const result = await savedObjects.client.bulkResolve(req.body); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/bulk_update.ts b/src/core/server/saved_objects/routes/bulk_update.ts index 277673971dabe06..961b8349d17456d 100644 --- a/src/core/server/saved_objects/routes/bulk_update.ts +++ b/src/core/server/saved_objects/routes/bulk_update.ts @@ -44,7 +44,8 @@ export const registerBulkUpdateRoute = (router: IRouter, { coreUsageData }: Rout const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsBulkUpdate({ request: req }).catch(() => {}); - const savedObject = await context.core.savedObjects.client.bulkUpdate(req.body); + const { savedObjects } = await context.core; + const savedObject = await savedObjects.client.bulkUpdate(req.body); return res.ok({ body: savedObject }); }) ); diff --git a/src/core/server/saved_objects/routes/create.ts b/src/core/server/saved_objects/routes/create.ts index 3e287e91fec8097..eb3938db0a9c719 100644 --- a/src/core/server/saved_objects/routes/create.ts +++ b/src/core/server/saved_objects/routes/create.ts @@ -61,7 +61,8 @@ export const registerCreateRoute = (router: IRouter, { coreUsageData }: RouteDep references, initialNamespaces, }; - const result = await context.core.savedObjects.client.create(type, attributes, options); + const { savedObjects } = await context.core; + const result = await savedObjects.client.create(type, attributes, options); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/delete.ts b/src/core/server/saved_objects/routes/delete.ts index e8404ba7fc8cf3c..5c239a55a692372 100644 --- a/src/core/server/saved_objects/routes/delete.ts +++ b/src/core/server/saved_objects/routes/delete.ts @@ -32,7 +32,7 @@ export const registerDeleteRoute = (router: IRouter, { coreUsageData }: RouteDep catchAndReturnBoomErrors(async (context, req, res) => { const { type, id } = req.params; const { force } = req.query; - const { getClient } = context.core.savedObjects; + const { getClient } = (await context.core).savedObjects; const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsDelete({ request: req }).catch(() => {}); diff --git a/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts b/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts index 97100980a37b3fa..a30da9723b916ff 100644 --- a/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts +++ b/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts @@ -25,9 +25,10 @@ export const registerDeleteUnknownTypesRoute = ( validate: false, }, catchAndReturnBoomErrors(async (context, req, res) => { + const { elasticsearch, savedObjects } = await context.core; await deleteUnknownTypeObjects({ - esClient: context.core.elasticsearch.client, - typeRegistry: context.core.savedObjects.typeRegistry, + esClient: elasticsearch.client, + typeRegistry: savedObjects.typeRegistry, kibanaIndex, kibanaVersion, }); diff --git a/src/core/server/saved_objects/routes/export.ts b/src/core/server/saved_objects/routes/export.ts index e224f30a1bb022c..16547970369c270 100644 --- a/src/core/server/saved_objects/routes/export.ts +++ b/src/core/server/saved_objects/routes/export.ts @@ -165,7 +165,7 @@ export const registerExportRoute = ( }, catchAndReturnBoomErrors(async (context, req, res) => { const cleaned = cleanOptions(req.body); - const { typeRegistry, getExporter, getClient } = context.core.savedObjects; + const { typeRegistry, getExporter, getClient } = (await context.core).savedObjects; const supportedTypes = typeRegistry.getImportableAndExportableTypes().map((t) => t.name); let options: EitherExportOptions; diff --git a/src/core/server/saved_objects/routes/find.ts b/src/core/server/saved_objects/routes/find.ts index 6e009f80bda7d72..01ac9ae9025f4ab 100644 --- a/src/core/server/saved_objects/routes/find.ts +++ b/src/core/server/saved_objects/routes/find.ts @@ -73,8 +73,8 @@ export const registerFindRoute = (router: IRouter, { coreUsageData }: RouteDepen }); } } - - const result = await context.core.savedObjects.client.find({ + const { savedObjects } = await context.core; + const result = await savedObjects.client.find({ perPage: query.per_page, page: query.page, type: Array.isArray(query.type) ? query.type : [query.type], diff --git a/src/core/server/saved_objects/routes/get.ts b/src/core/server/saved_objects/routes/get.ts index ae0656599a1e24d..2ea9a13bbce642d 100644 --- a/src/core/server/saved_objects/routes/get.ts +++ b/src/core/server/saved_objects/routes/get.ts @@ -32,8 +32,9 @@ export const registerGetRoute = (router: IRouter, { coreUsageData }: RouteDepend const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsGet({ request: req }).catch(() => {}); - const savedObject = await context.core.savedObjects.client.get(type, id); - return res.ok({ body: savedObject }); + const { savedObjects } = await context.core; + const object = await savedObjects.client.get(type, id); + return res.ok({ body: object }); }) ); }; diff --git a/src/core/server/saved_objects/routes/import.ts b/src/core/server/saved_objects/routes/import.ts index d373dd5e63bc686..545d01b454741a5 100644 --- a/src/core/server/saved_objects/routes/import.ts +++ b/src/core/server/saved_objects/routes/import.ts @@ -63,7 +63,7 @@ export const registerImportRoute = ( }, catchAndReturnBoomErrors(async (context, req, res) => { const { overwrite, createNewCopies } = req.query; - const { getClient, getImporter, typeRegistry } = context.core.savedObjects; + const { getClient, getImporter, typeRegistry } = (await context.core).savedObjects; const usageStatsClient = coreUsageData.getClient(); usageStatsClient diff --git a/src/core/server/saved_objects/routes/legacy_import_export/export.ts b/src/core/server/saved_objects/routes/legacy_import_export/export.ts index fd10e60c4c804d2..7141d74b719044d 100644 --- a/src/core/server/saved_objects/routes/legacy_import_export/export.ts +++ b/src/core/server/saved_objects/routes/legacy_import_export/export.ts @@ -38,7 +38,7 @@ export const registerLegacyExportRoute = ( ); const ids = Array.isArray(req.query.dashboard) ? req.query.dashboard : [req.query.dashboard]; - const { client } = ctx.core.savedObjects; + const { client } = (await ctx.core).savedObjects; const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementLegacyDashboardsExport({ request: req }).catch(() => {}); diff --git a/src/core/server/saved_objects/routes/legacy_import_export/import.ts b/src/core/server/saved_objects/routes/legacy_import_export/import.ts index 09027af810149fa..d98c14f9b620d39 100644 --- a/src/core/server/saved_objects/routes/legacy_import_export/import.ts +++ b/src/core/server/saved_objects/routes/legacy_import_export/import.ts @@ -46,7 +46,7 @@ export const registerLegacyImportRoute = ( "The import dashboard API '/api/kibana/dashboards/import' is deprecated. Use the saved objects import objects API '/api/saved_objects/_import' instead." ); - const { client } = ctx.core.savedObjects; + const { client } = (await ctx.core).savedObjects; const objects = req.body.objects as SavedObject[]; const { force, exclude } = req.query; diff --git a/src/core/server/saved_objects/routes/resolve.ts b/src/core/server/saved_objects/routes/resolve.ts index 78e85d17fe1fad4..ae09f6526baa301 100644 --- a/src/core/server/saved_objects/routes/resolve.ts +++ b/src/core/server/saved_objects/routes/resolve.ts @@ -27,11 +27,12 @@ export const registerResolveRoute = (router: IRouter, { coreUsageData }: RouteDe }, router.handleLegacyErrors(async (context, req, res) => { const { type, id } = req.params; + const { savedObjects } = await context.core; const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsResolve({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.resolve(type, id); + const result = await savedObjects.client.resolve(type, id); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/resolve_import_errors.ts b/src/core/server/saved_objects/routes/resolve_import_errors.ts index f1fe2e9cfe43156..bf536e906d7da7b 100644 --- a/src/core/server/saved_objects/routes/resolve_import_errors.ts +++ b/src/core/server/saved_objects/routes/resolve_import_errors.ts @@ -92,7 +92,7 @@ export const registerResolveImportErrorsRoute = ( }); } - const { getClient, getImporter, typeRegistry } = context.core.savedObjects; + const { getClient, getImporter, typeRegistry } = (await context.core).savedObjects; const includedHiddenTypes = chain(req.body.retries) .map('type') diff --git a/src/core/server/saved_objects/routes/update.ts b/src/core/server/saved_objects/routes/update.ts index f21fc183cdadeea..5383ab76a1e4d72 100644 --- a/src/core/server/saved_objects/routes/update.ts +++ b/src/core/server/saved_objects/routes/update.ts @@ -49,7 +49,8 @@ export const registerUpdateRoute = (router: IRouter, { coreUsageData }: RouteDep const usageStatsClient = coreUsageData.getClient(); usageStatsClient.incrementSavedObjectsUpdate({ request: req }).catch(() => {}); - const result = await context.core.savedObjects.client.update(type, id, attributes, options); + const { savedObjects } = await context.core; + const result = await savedObjects.client.update(type, id, attributes, options); return res.ok({ body: result }); }) ); diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 67aca94de642648..2228c8fee879482 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -9,6 +9,7 @@ import { AddConfigDeprecation } from '@kbn/config'; import { AnalyticsClient } from '@kbn/analytics-client'; import apm from 'elastic-apm-node'; +import { AwaitedProperties } from '@kbn/utility-types'; import Boom from '@hapi/boom'; import { ByteSizeValue } from '@kbn/config-schema'; import { CliArgs } from '@kbn/config'; @@ -446,6 +447,30 @@ export interface CorePreboot { preboot: PrebootServicePreboot; } +// @public +export interface CoreRequestHandlerContext { + // (undocumented) + deprecations: { + client: DeprecationsClient; + }; + // (undocumented) + elasticsearch: { + client: IScopedClusterClient; + }; + // (undocumented) + savedObjects: { + client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; + getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; + getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; + getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; + }; + // (undocumented) + uiSettings: { + client: IUiSettingsClient; + }; +} + // @internal export interface CoreServicesUsageData { // (undocumented) @@ -840,6 +865,11 @@ export interface CustomHttpResponseOptions = RequestHandlerContext & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; + // @internal (undocumented) export const DEFAULT_APP_CATEGORIES: Record; @@ -1189,7 +1219,7 @@ export interface HttpServiceSetup { registerOnPreAuth: (handler: OnPreAuthHandler) => void; registerOnPreResponse: (handler: OnPreResponseHandler) => void; registerOnPreRouting: (handler: OnPreRoutingHandler) => void; - registerRouteHandlerContext: (contextName: ContextName, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; + registerRouteHandlerContext: >(contextName: ContextName, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; } // @public (undocumented) @@ -1221,7 +1251,7 @@ export interface IContextContainer { } // @public -export type IContextProvider = (context: Omit, ...rest: HandlerParameters) => Promise | Context[ContextName]; +export type IContextProvider = (context: Omit, ...rest: HandlerParameters) => MaybePromise>; // @public export interface ICspConfig { @@ -1840,26 +1870,14 @@ export interface RegisterDeprecationsConfig { export type RequestHandler

= (context: Context, request: KibanaRequest, response: ResponseFactory) => IKibanaResponse | Promise>; // @public -export interface RequestHandlerContext { +export interface RequestHandlerContext extends RequestHandlerContextBase { // (undocumented) - core: { - savedObjects: { - client: SavedObjectsClientContract; - typeRegistry: ISavedObjectTypeRegistry; - getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; - getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter; - getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter; - }; - elasticsearch: { - client: IScopedClusterClient; - }; - uiSettings: { - client: IUiSettingsClient; - }; - deprecations: { - client: DeprecationsClient; - }; - }; + core: Promise; +} + +// @public (undocumented) +export interface RequestHandlerContextBase { + resolve: >(parts: T[]) => Promise>>; } // @public diff --git a/src/core/server/server.ts b/src/core/server/server.ts index fc215d905581821..c73e98f4bb6c4f3 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -42,7 +42,6 @@ import { config as uiSettingsConfig } from './ui_settings'; import { config as statusConfig } from './status'; import { config as i18nConfig } from './i18n'; import { ContextService } from './context'; -import { RequestHandlerContext } from '.'; import { InternalCorePreboot, InternalCoreSetup, @@ -372,13 +371,9 @@ export class Server { } private registerCoreContext(coreSetup: InternalCoreSetup) { - coreSetup.http.registerRouteHandlerContext( - coreId, - 'core', - (context, req, res): RequestHandlerContext['core'] => { - return new CoreRouteHandlerContext(this.coreStart!, req); - } - ); + coreSetup.http.registerRouteHandlerContext(coreId, 'core', async (context, req, res) => { + return new CoreRouteHandlerContext(this.coreStart!, req); + }); } public setupCoreConfig() { diff --git a/src/core/server/ui_settings/routes/delete.ts b/src/core/server/ui_settings/routes/delete.ts index f8ab4d5d0c2c4c6..87c6edf38642861 100644 --- a/src/core/server/ui_settings/routes/delete.ts +++ b/src/core/server/ui_settings/routes/delete.ts @@ -23,7 +23,7 @@ export function registerDeleteRoute(router: IRouter) { { path: '/api/kibana/settings/{key}', validate }, async (context, request, response) => { try { - const uiSettingsClient = context.core.uiSettings.client; + const uiSettingsClient = (await context.core).uiSettings.client; await uiSettingsClient.remove(request.params.key); diff --git a/src/core/server/ui_settings/routes/get.ts b/src/core/server/ui_settings/routes/get.ts index 051d562c398046b..0929330cf0238cd 100644 --- a/src/core/server/ui_settings/routes/get.ts +++ b/src/core/server/ui_settings/routes/get.ts @@ -14,7 +14,7 @@ export function registerGetRoute(router: IRouter) { { path: '/api/kibana/settings', validate: false }, async (context, request, response) => { try { - const uiSettingsClient = context.core.uiSettings.client; + const uiSettingsClient = (await context.core).uiSettings.client; return response.ok({ body: { settings: await uiSettingsClient.getUserProvided(), diff --git a/src/core/server/ui_settings/routes/set.ts b/src/core/server/ui_settings/routes/set.ts index 7de287f4ebe6a9a..91518fb6f347627 100644 --- a/src/core/server/ui_settings/routes/set.ts +++ b/src/core/server/ui_settings/routes/set.ts @@ -26,7 +26,7 @@ export function registerSetRoute(router: IRouter) { { path: '/api/kibana/settings/{key}', validate }, async (context, request, response) => { try { - const uiSettingsClient = context.core.uiSettings.client; + const uiSettingsClient = (await context.core).uiSettings.client; const { key } = request.params; const { value } = request.body; diff --git a/src/core/server/ui_settings/routes/set_many.ts b/src/core/server/ui_settings/routes/set_many.ts index c4053dd3e7eed64..f4f3f509bf920fc 100644 --- a/src/core/server/ui_settings/routes/set_many.ts +++ b/src/core/server/ui_settings/routes/set_many.ts @@ -21,7 +21,7 @@ const validate = { export function registerSetManyRoute(router: IRouter) { router.post({ path: '/api/kibana/settings', validate }, async (context, request, response) => { try { - const uiSettingsClient = context.core.uiSettings.client; + const uiSettingsClient = (await context.core).uiSettings.client; const { changes } = request.body; diff --git a/src/plugins/controls/server/control_types/options_list/options_list_suggestions_route.ts b/src/plugins/controls/server/control_types/options_list/options_list_suggestions_route.ts index 7ed1ace5dbde94c..9af4800ca00fbae 100644 --- a/src/plugins/controls/server/control_types/options_list/options_list_suggestions_route.ts +++ b/src/plugins/controls/server/control_types/options_list/options_list_suggestions_route.ts @@ -53,7 +53,7 @@ export const setupOptionsListSuggestionsRoute = ( try { const suggestionRequest: OptionsListRequestBody = request.body; const { index } = request.params; - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; const suggestionsResponse = await getOptionsListSuggestions({ abortedEvent$: request.events.aborted$, request: suggestionRequest, diff --git a/src/plugins/data/server/mocks.ts b/src/plugins/data/server/mocks.ts index 62e1798c714a185..8df65f7e5b90e4c 100644 --- a/src/plugins/data/server/mocks.ts +++ b/src/plugins/data/server/mocks.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { coreMock } from '@kbn/core/server/mocks'; import { createFieldFormatsSetupMock, createFieldFormatsStartMock, @@ -17,7 +18,6 @@ import { } from './search/mocks'; import { createIndexPatternsStartMock } from './data_views/mocks'; import { createDatatableUtilitiesMock } from './datatable_utilities/mock'; -import { DataRequestHandlerContext } from './search'; function createSetupContract() { return { @@ -43,8 +43,9 @@ function createStartContract() { function createRequestHandlerContext() { return { + core: coreMock.createRequestHandlerContext(), search: createSearchRequestHandlerContext(), - } as unknown as jest.Mocked; + }; } export const dataPluginMock = { diff --git a/src/plugins/data/server/query/route_handler_context.test.ts b/src/plugins/data/server/query/route_handler_context.test.ts index 69908f9733f56d5..c0db432ce3fd90a 100644 --- a/src/plugins/data/server/query/route_handler_context.test.ts +++ b/src/plugins/data/server/query/route_handler_context.test.ts @@ -20,7 +20,6 @@ const { savedObjects: { client: mockSavedObjectsClient }, }, } = mockContext; -const context = registerSavedQueryRouteHandlerContext(mockContext); const savedQueryAttributes: SavedQueryAttributes = { title: 'foo', @@ -73,7 +72,15 @@ const savedQueryReferences = [ ]; describe('saved query route handler context', () => { - beforeEach(() => { + let context: Awaited>; + + beforeEach(async () => { + context = await registerSavedQueryRouteHandlerContext( + coreMock.createCustomRequestHandlerContext({ + core: mockContext.core, + }) + ); + mockSavedObjectsClient.create.mockClear(); mockSavedObjectsClient.resolve.mockClear(); mockSavedObjectsClient.find.mockClear(); diff --git a/src/plugins/data/server/query/route_handler_context.ts b/src/plugins/data/server/query/route_handler_context.ts index e72257fe185d388..0af658d7692c5a1 100644 --- a/src/plugins/data/server/query/route_handler_context.ts +++ b/src/plugins/data/server/query/route_handler_context.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { RequestHandlerContext, SavedObject } from '@kbn/core/server'; +import { CustomRequestHandlerContext, RequestHandlerContext, SavedObject } from '@kbn/core/server'; import { isFilters } from '@kbn/es-query'; import { isQuery, SavedQueryAttributes } from '../../common'; import { extract, inject } from '../../common/query/persistable_state'; @@ -66,18 +66,16 @@ function verifySavedQuery({ title, query, filters = [] }: SavedQueryAttributes) } } -export function registerSavedQueryRouteHandlerContext(context: RequestHandlerContext) { +export async function registerSavedQueryRouteHandlerContext(context: RequestHandlerContext) { + const soClient = (await context.core).savedObjects.client; + const createSavedQuery = async (attrs: SavedQueryAttributes) => { verifySavedQuery(attrs); const { attributes, references } = extractReferences(attrs); - const savedObject = await context.core.savedObjects.client.create( - 'query', - attributes, - { - references, - } - ); + const savedObject = await soClient.create('query', attributes, { + references, + }); // TODO: Handle properly if (savedObject.error) throw new Error(savedObject.error.message); @@ -89,14 +87,9 @@ export function registerSavedQueryRouteHandlerContext(context: RequestHandlerCon verifySavedQuery(attrs); const { attributes, references } = extractReferences(attrs); - const savedObject = await context.core.savedObjects.client.update( - 'query', - id, - attributes, - { - references, - } - ); + const savedObject = await soClient.update('query', id, attributes, { + references, + }); // TODO: Handle properly if (savedObject.error) throw new Error(savedObject.error.message); @@ -105,8 +98,10 @@ export function registerSavedQueryRouteHandlerContext(context: RequestHandlerCon }; const getSavedQuery = async (id: string) => { - const { saved_object: savedObject, outcome } = - await context.core.savedObjects.client.resolve('query', id); + const { saved_object: savedObject, outcome } = await soClient.resolve( + 'query', + id + ); if (outcome === 'conflict') { throw new Error(`Multiple saved queries found with ID: ${id} (legacy URL alias conflict)`); } else if (savedObject.error) { @@ -116,20 +111,19 @@ export function registerSavedQueryRouteHandlerContext(context: RequestHandlerCon }; const getSavedQueriesCount = async () => { - const { total } = await context.core.savedObjects.client.find({ + const { total } = await soClient.find({ type: 'query', }); return total; }; const findSavedQueries = async ({ page = 1, perPage = 50, search = '' } = {}) => { - const { total, saved_objects: savedObjects } = - await context.core.savedObjects.client.find({ - type: 'query', - page, - perPage, - search, - }); + const { total, saved_objects: savedObjects } = await soClient.find({ + type: 'query', + page, + perPage, + search, + }); const savedQueries = savedObjects.map(injectReferences); @@ -137,7 +131,7 @@ export function registerSavedQueryRouteHandlerContext(context: RequestHandlerCon }; const getAllSavedQueries = async () => { - const finder = context.core.savedObjects.client.createPointInTimeFinder({ + const finder = soClient.createPointInTimeFinder({ type: 'query', perPage: 100, }); @@ -152,8 +146,8 @@ export function registerSavedQueryRouteHandlerContext(context: RequestHandlerCon return { total: savedQueries.length, savedQueries }; }; - const deleteSavedQuery = (id: string) => { - return context.core.savedObjects.client.delete('query', id); + const deleteSavedQuery = async (id: string) => { + return await soClient.delete('query', id); }; return { @@ -167,6 +161,6 @@ export function registerSavedQueryRouteHandlerContext(context: RequestHandlerCon }; } -export interface SavedQueryRouteHandlerContext extends RequestHandlerContext { - savedQuery: ReturnType; -} +export type SavedQueryRouteHandlerContext = CustomRequestHandlerContext<{ + savedQuery: Promise>; +}>; diff --git a/src/plugins/data/server/query/routes.ts b/src/plugins/data/server/query/routes.ts index d5997e93fa99382..16f5d8f9955a7f2 100644 --- a/src/plugins/data/server/query/routes.ts +++ b/src/plugins/data/server/query/routes.ts @@ -37,7 +37,8 @@ export function registerSavedQueryRoutes({ http }: CoreSetup): void { }, async (context, request, response) => { try { - const body = await context.savedQuery.create(request.body); + const savedQuery = await context.savedQuery; + const body = await savedQuery.create(request.body); return response.ok({ body }); } catch (e) { // TODO: Handle properly @@ -57,7 +58,8 @@ export function registerSavedQueryRoutes({ http }: CoreSetup): void { async (context, request, response) => { const { id } = request.params; try { - const body = await context.savedQuery.update(id, request.body); + const savedQuery = await context.savedQuery; + const body = await savedQuery.update(id, request.body); return response.ok({ body }); } catch (e) { // TODO: Handle properly @@ -76,7 +78,8 @@ export function registerSavedQueryRoutes({ http }: CoreSetup): void { async (context, request, response) => { const { id } = request.params; try { - const body = await context.savedQuery.get(id); + const savedQuery = await context.savedQuery; + const body = await savedQuery.get(id); return response.ok({ body }); } catch (e) { // TODO: Handle properly @@ -92,7 +95,8 @@ export function registerSavedQueryRoutes({ http }: CoreSetup): void { }, async (context, request, response) => { try { - const count = await context.savedQuery.count(); + const savedQuery = await context.savedQuery; + const count = await savedQuery.count(); return response.ok({ body: `${count}` }); } catch (e) { // TODO: Handle properly @@ -114,7 +118,8 @@ export function registerSavedQueryRoutes({ http }: CoreSetup): void { }, async (context, request, response) => { try { - const body = await context.savedQuery.find(request.body); + const savedQuery = await context.savedQuery; + const body = await savedQuery.find(request.body); return response.ok({ body }); } catch (e) { // TODO: Handle properly @@ -130,7 +135,8 @@ export function registerSavedQueryRoutes({ http }: CoreSetup): void { }, async (context, request, response) => { try { - const body = await context.savedQuery.getAll(); + const savedQuery = await context.savedQuery; + const body = await savedQuery.getAll(); return response.ok({ body }); } catch (e) { // TODO: Handle properly @@ -149,7 +155,8 @@ export function registerSavedQueryRoutes({ http }: CoreSetup): void { async (context, request, response) => { const { id } = request.params; try { - const body = await context.savedQuery.delete(id); + const savedQuery = await context.savedQuery; + const body = await savedQuery.delete(id); return response.ok({ body }); } catch (e) { // TODO: Handle properly diff --git a/src/plugins/data/server/search/routes/search.ts b/src/plugins/data/server/search/routes/search.ts index 6f48ba747a7157f..aa0f69b55816c1e 100644 --- a/src/plugins/data/server/search/routes/search.ts +++ b/src/plugins/data/server/search/routes/search.ts @@ -47,8 +47,9 @@ export function registerSearchRoute(router: DataPluginRouter): void { const abortSignal = getRequestAbortedSignal(request.events.aborted$); try { - const response = await context - .search!.search( + const search = await context.search; + const response = await search + .search( { ...searchRequest, id }, { abortSignal, @@ -85,7 +86,8 @@ export function registerSearchRoute(router: DataPluginRouter): void { const { strategy, id } = request.params; try { - await context.search!.cancel(id, { strategy }); + const search = await context.search; + await search.cancel(id, { strategy }); return res.ok(); } catch (err) { return reportServerError(res, err); diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index 8c264889ebf2aed..c59893cdead9663 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -143,7 +143,7 @@ export class SearchService implements Plugin { core.http.registerRouteHandlerContext( 'search', - async (context, request) => { + (context, request) => { return this.asScoped(request); } ); diff --git a/src/plugins/data/server/search/types.ts b/src/plugins/data/server/search/types.ts index ef6a2f5f88fe51b..70e04e97ea16926 100644 --- a/src/plugins/data/server/search/types.ts +++ b/src/plugins/data/server/search/types.ts @@ -13,7 +13,7 @@ import type { IUiSettingsClient, SavedObjectsClientContract, KibanaRequest, - RequestHandlerContext, + CustomRequestHandlerContext, } from '@kbn/core/server'; import { ISearchOptions, @@ -126,8 +126,8 @@ export interface ISearchStart< export type SearchRequestHandlerContext = IScopedSearchClient; -export interface DataRequestHandlerContext extends RequestHandlerContext { +export type DataRequestHandlerContext = CustomRequestHandlerContext<{ search: SearchRequestHandlerContext; -} +}>; export type DataPluginRouter = IRouter; diff --git a/src/plugins/data_view_field_editor/server/routes/field_preview.ts b/src/plugins/data_view_field_editor/server/routes/field_preview.ts index 022cd92a4bb1e14..5595eeeaeddfbf7 100644 --- a/src/plugins/data_view_field_editor/server/routes/field_preview.ts +++ b/src/plugins/data_view_field_editor/server/routes/field_preview.ts @@ -38,7 +38,7 @@ export const registerFieldPreviewRoute = ({ router }: RouteDependencies): void = }, }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; const type = req.body.context.split('_field')[0] as estypes.MappingRuntimeFieldType; const body = { diff --git a/src/plugins/data_view_management/server/routes/preview_scripted_field.ts b/src/plugins/data_view_management/server/routes/preview_scripted_field.ts index aee953af1c2988c..3a19872150a8bc9 100644 --- a/src/plugins/data_view_management/server/routes/preview_scripted_field.ts +++ b/src/plugins/data_view_management/server/routes/preview_scripted_field.ts @@ -24,7 +24,7 @@ export function registerPreviewScriptedFieldRoute(router: IRouter): void { }, }, async (context, request, res) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const { index, name, script, query, additionalFields } = request.body; try { diff --git a/src/plugins/data_view_management/server/routes/resolve_index.ts b/src/plugins/data_view_management/server/routes/resolve_index.ts index 85ad6ae8993a31b..820e6de1c9d7da6 100644 --- a/src/plugins/data_view_management/server/routes/resolve_index.ts +++ b/src/plugins/data_view_management/server/routes/resolve_index.ts @@ -31,7 +31,8 @@ export function registerResolveIndexRoute(router: IRouter): void { }, }, async (context, req, res) => { - const body = await context.core.elasticsearch.client.asCurrentUser.indices.resolveIndex({ + const esClient = (await context.core).elasticsearch.client; + const body = await esClient.asCurrentUser.indices.resolveIndex({ name: req.params.query, expand_wildcards: req.query.expand_wildcards || 'open', }); diff --git a/src/plugins/data_views/server/rest_api_routes/create_data_view.ts b/src/plugins/data_views/server/rest_api_routes/create_data_view.ts index 755ba5dcd86efb3..c35344f54c4fab9 100644 --- a/src/plugins/data_views/server/rest_api_routes/create_data_view.ts +++ b/src/plugins/data_views/server/rest_api_routes/create_data_view.ts @@ -94,8 +94,9 @@ const registerCreateDataViewRouteFactory = }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( diff --git a/src/plugins/data_views/server/rest_api_routes/default_data_view.ts b/src/plugins/data_views/server/rest_api_routes/default_data_view.ts index da89bbe95b69d27..7ce241176228eea 100644 --- a/src/plugins/data_views/server/rest_api_routes/default_data_view.ts +++ b/src/plugins/data_views/server/rest_api_routes/default_data_view.ts @@ -64,8 +64,9 @@ const manageDefaultIndexPatternRoutesFactory = validate: {}, }, handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, @@ -103,8 +104,9 @@ const manageDefaultIndexPatternRoutesFactory = }, }, handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/delete_data_view.ts b/src/plugins/data_views/server/rest_api_routes/delete_data_view.ts index 88370b5aea77626..b3fd0b8a041c8b5 100644 --- a/src/plugins/data_views/server/rest_api_routes/delete_data_view.ts +++ b/src/plugins/data_views/server/rest_api_routes/delete_data_view.ts @@ -58,8 +58,9 @@ const deleteIndexPatternRouteFactory = }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/fields/update_fields.ts b/src/plugins/data_views/server/rest_api_routes/fields/update_fields.ts index 49e3d3fc0f1ef33..d99aa67c7f1537c 100644 --- a/src/plugins/data_views/server/rest_api_routes/fields/update_fields.ts +++ b/src/plugins/data_views/server/rest_api_routes/fields/update_fields.ts @@ -134,8 +134,9 @@ const updateFieldsActionRouteFactory = (path: string, serviceKey: string) => { }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/get_data_view.ts b/src/plugins/data_views/server/rest_api_routes/get_data_view.ts index 63ef2701a306268..86185fb0b2777d9 100644 --- a/src/plugins/data_views/server/rest_api_routes/get_data_view.ts +++ b/src/plugins/data_views/server/rest_api_routes/get_data_view.ts @@ -63,8 +63,9 @@ const getDataViewRouteFactory = }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/has_user_data_view.ts b/src/plugins/data_views/server/rest_api_routes/has_user_data_view.ts index 5bbe7966ae2670c..1031a04456b4710 100644 --- a/src/plugins/data_views/server/rest_api_routes/has_user_data_view.ts +++ b/src/plugins/data_views/server/rest_api_routes/has_user_data_view.ts @@ -45,8 +45,9 @@ const hasUserDataViewRouteFactory = }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( diff --git a/src/plugins/data_views/server/rest_api_routes/runtime_fields/create_runtime_field.ts b/src/plugins/data_views/server/rest_api_routes/runtime_fields/create_runtime_field.ts index 4ae100e1a79f5b8..5c9faaf2c8593a2 100644 --- a/src/plugins/data_views/server/rest_api_routes/runtime_fields/create_runtime_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/runtime_fields/create_runtime_field.ts @@ -92,8 +92,9 @@ const runtimeCreateFieldRouteFactory = }, }, handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/runtime_fields/delete_runtime_field.ts b/src/plugins/data_views/server/rest_api_routes/runtime_fields/delete_runtime_field.ts index 94dde735c06745a..e7db34f43cf37d8 100644 --- a/src/plugins/data_views/server/rest_api_routes/runtime_fields/delete_runtime_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/runtime_fields/delete_runtime_field.ts @@ -73,8 +73,9 @@ const deleteRuntimeFieldRouteFactory = }, }, handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/runtime_fields/get_runtime_field.ts b/src/plugins/data_views/server/rest_api_routes/runtime_fields/get_runtime_field.ts index 4d9a5678392a294..867766eec3124c4 100644 --- a/src/plugins/data_views/server/rest_api_routes/runtime_fields/get_runtime_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/runtime_fields/get_runtime_field.ts @@ -80,8 +80,9 @@ const getRuntimeFieldRouteFactory = }, handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/runtime_fields/put_runtime_field.ts b/src/plugins/data_views/server/rest_api_routes/runtime_fields/put_runtime_field.ts index ed4f01d703f0c1c..0f5399606dfdc13 100644 --- a/src/plugins/data_views/server/rest_api_routes/runtime_fields/put_runtime_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/runtime_fields/put_runtime_field.ts @@ -92,8 +92,9 @@ const putRuntimeFieldRouteFactory = }, }, handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/runtime_fields/update_runtime_field.ts b/src/plugins/data_views/server/rest_api_routes/runtime_fields/update_runtime_field.ts index fe632f5533dc770..1aaf1b112feedcc 100644 --- a/src/plugins/data_views/server/rest_api_routes/runtime_fields/update_runtime_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/runtime_fields/update_runtime_field.ts @@ -93,8 +93,9 @@ const updateRuntimeFieldRouteFactory = }, }, handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/scripted_fields/create_scripted_field.ts b/src/plugins/data_views/server/rest_api_routes/scripted_fields/create_scripted_field.ts index 4335fc6aea905fe..759627f92676226 100644 --- a/src/plugins/data_views/server/rest_api_routes/scripted_fields/create_scripted_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/scripted_fields/create_scripted_field.ts @@ -42,8 +42,9 @@ export const registerCreateScriptedFieldRoute = ( }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { indexPatternsServiceFactory }] = await getStartServices(); const indexPatternsService = await indexPatternsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/scripted_fields/delete_scripted_field.ts b/src/plugins/data_views/server/rest_api_routes/scripted_fields/delete_scripted_field.ts index 811c3e096ca1869..7e3333820e4e9a2 100644 --- a/src/plugins/data_views/server/rest_api_routes/scripted_fields/delete_scripted_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/scripted_fields/delete_scripted_field.ts @@ -43,8 +43,9 @@ export const registerDeleteScriptedFieldRoute = ( }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { indexPatternsServiceFactory }] = await getStartServices(); const indexPatternsService = await indexPatternsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/scripted_fields/get_scripted_field.ts b/src/plugins/data_views/server/rest_api_routes/scripted_fields/get_scripted_field.ts index 3b76d56070f1ec4..befe30f8437f2fc 100644 --- a/src/plugins/data_views/server/rest_api_routes/scripted_fields/get_scripted_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/scripted_fields/get_scripted_field.ts @@ -43,8 +43,9 @@ export const registerGetScriptedFieldRoute = ( }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { indexPatternsServiceFactory }] = await getStartServices(); const indexPatternsService = await indexPatternsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/scripted_fields/put_scripted_field.ts b/src/plugins/data_views/server/rest_api_routes/scripted_fields/put_scripted_field.ts index 8989c1412769e6c..93312dd6d3cf6b2 100644 --- a/src/plugins/data_views/server/rest_api_routes/scripted_fields/put_scripted_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/scripted_fields/put_scripted_field.ts @@ -42,8 +42,9 @@ export const registerPutScriptedFieldRoute = ( }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { indexPatternsServiceFactory }] = await getStartServices(); const indexPatternsService = await indexPatternsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/scripted_fields/update_scripted_field.ts b/src/plugins/data_views/server/rest_api_routes/scripted_fields/update_scripted_field.ts index 28f28064b2a1b22..ddc9d7ae552e86b 100644 --- a/src/plugins/data_views/server/rest_api_routes/scripted_fields/update_scripted_field.ts +++ b/src/plugins/data_views/server/rest_api_routes/scripted_fields/update_scripted_field.ts @@ -63,8 +63,9 @@ export const registerUpdateScriptedFieldRoute = ( }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { indexPatternsServiceFactory }] = await getStartServices(); const indexPatternsService = await indexPatternsServiceFactory( savedObjectsClient, diff --git a/src/plugins/data_views/server/rest_api_routes/update_data_view.ts b/src/plugins/data_views/server/rest_api_routes/update_data_view.ts index c0f890fda9d85e8..424680f85b4985e 100644 --- a/src/plugins/data_views/server/rest_api_routes/update_data_view.ts +++ b/src/plugins/data_views/server/rest_api_routes/update_data_view.ts @@ -161,8 +161,9 @@ const updateDataViewRouteFactory = }, router.handleLegacyErrors( handleErrors(async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const [, , { dataViewsServiceFactory }] = await getStartServices(); const dataViewsService = await dataViewsServiceFactory( diff --git a/src/plugins/data_views/server/routes.ts b/src/plugins/data_views/server/routes.ts index 1a35b75b2a104b4..8f6299a58870a46 100644 --- a/src/plugins/data_views/server/routes.ts +++ b/src/plugins/data_views/server/routes.ts @@ -56,7 +56,7 @@ export function registerRoutes( }, }, async (context, request, response) => { - const { asCurrentUser } = context.core.elasticsearch.client; + const { asCurrentUser } = (await context.core).elasticsearch.client; const indexPatterns = new IndexPatternsFetcher(asCurrentUser); const { pattern, interval, look_back: lookBack, meta_fields: metaFields } = request.query; diff --git a/src/plugins/data_views/server/routes/fields_for.ts b/src/plugins/data_views/server/routes/fields_for.ts index cc71eb9258d4c40..3ad854ab0d6ac3f 100644 --- a/src/plugins/data_views/server/routes/fields_for.ts +++ b/src/plugins/data_views/server/routes/fields_for.ts @@ -51,7 +51,7 @@ const validate: RouteValidatorFullConfig<{}, IQuery, IBody> = { body: schema.maybe(schema.object({ index_filter: schema.any() })), }; const handler: RequestHandler<{}, IQuery, IBody> = async (context, request, response) => { - const { asCurrentUser } = context.core.elasticsearch.client; + const { asCurrentUser } = (await context.core).elasticsearch.client; const indexPatterns = new IndexPatternsFetcher(asCurrentUser); const { pattern, diff --git a/src/plugins/data_views/server/routes/has_data_views.ts b/src/plugins/data_views/server/routes/has_data_views.ts index d74711e8c0d2b90..c4982311ce156a7 100644 --- a/src/plugins/data_views/server/routes/has_data_views.ts +++ b/src/plugins/data_views/server/routes/has_data_views.ts @@ -16,8 +16,9 @@ export const registerHasDataViewsRoute = (router: IRouter): void => { validate: {}, }, async (ctx, req, res) => { - const savedObjectsClient = ctx.core.savedObjects.client; - const elasticsearchClient = ctx.core.elasticsearch.client.asCurrentUser; + const core = await ctx.core; + const savedObjectsClient = core.savedObjects.client; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; const dataViews = await getIndexPattern({ esClient: elasticsearchClient, soClient: savedObjectsClient, diff --git a/src/plugins/home/server/routes/fetch_es_hits_status.ts b/src/plugins/home/server/routes/fetch_es_hits_status.ts index 557f93f0425e9a5..0ce090c6bfeed3a 100644 --- a/src/plugins/home/server/routes/fetch_es_hits_status.ts +++ b/src/plugins/home/server/routes/fetch_es_hits_status.ts @@ -22,7 +22,7 @@ export const registerHitsStatusRoute = (router: IRouter) => { }, router.handleLegacyErrors(async (context, req, res) => { const { index, query } = req.body; - const client = context.core.elasticsearch.client; + const client = (await context.core).elasticsearch.client; try { const body = await client.asCurrentUser.search({ diff --git a/src/plugins/home/server/services/sample_data/routes/install.ts b/src/plugins/home/server/services/sample_data/routes/install.ts index 58604ec30ce074f..f057e6861518e05 100644 --- a/src/plugins/home/server/services/sample_data/routes/install.ts +++ b/src/plugins/home/server/services/sample_data/routes/install.ts @@ -38,7 +38,7 @@ export function createInstallRoute( // @ts-ignore Custom query validation used const now = query.now ? new Date(query.now) : new Date(); - const sampleDataInstaller = getSampleDataInstaller({ + const sampleDataInstaller = await getSampleDataInstaller({ datasetId: sampleDataset.id, sampleDatasets, logger, diff --git a/src/plugins/home/server/services/sample_data/routes/list.ts b/src/plugins/home/server/services/sample_data/routes/list.ts index 8f500b1c955017f..39690b3944d0c2c 100644 --- a/src/plugins/home/server/services/sample_data/routes/list.ts +++ b/src/plugins/home/server/services/sample_data/routes/list.ts @@ -78,7 +78,7 @@ async function findExistingSampleObjects( .map(({ savedObjects }) => savedObjects.map(({ type, id }) => ({ type, id }))) .flat(); const objectTypes = getUniqueObjectTypes(objects); - const client = getSavedObjectsClient(context, objectTypes); + const client = await getSavedObjectsClient(context, objectTypes); const findSampleObjectsResult = await findSampleObjects({ client, logger, objects }); let objectCounter = 0; @@ -101,18 +101,20 @@ async function getSampleDatasetStatus( return { status: NOT_INSTALLED }; } + const { elasticsearch } = await context.core; + for (let i = 0; i < sampleDataset.dataIndices.length; i++) { const dataIndexConfig = sampleDataset.dataIndices[i]; const index = createIndexName(sampleDataset.id, dataIndexConfig.id); try { - const indexExists = await context.core.elasticsearch.client.asCurrentUser.indices.exists({ + const indexExists = await elasticsearch.client.asCurrentUser.indices.exists({ index, }); if (!indexExists) { return { status: NOT_INSTALLED }; } - const count = await context.core.elasticsearch.client.asCurrentUser.count({ + const count = await elasticsearch.client.asCurrentUser.count({ index, }); if (count.count === 0) { diff --git a/src/plugins/home/server/services/sample_data/routes/uninstall.ts b/src/plugins/home/server/services/sample_data/routes/uninstall.ts index e6f4b9a07514c7b..d2700b4985a796b 100644 --- a/src/plugins/home/server/services/sample_data/routes/uninstall.ts +++ b/src/plugins/home/server/services/sample_data/routes/uninstall.ts @@ -32,7 +32,7 @@ export function createUninstallRoute( return response.notFound(); } - const sampleDataInstaller = getSampleDataInstaller({ + const sampleDataInstaller = await getSampleDataInstaller({ datasetId: sampleDataset.id, sampleDatasets, logger, diff --git a/src/plugins/home/server/services/sample_data/routes/utils.ts b/src/plugins/home/server/services/sample_data/routes/utils.ts index b784c50ff118241..f4e99e4c04c934b 100644 --- a/src/plugins/home/server/services/sample_data/routes/utils.ts +++ b/src/plugins/home/server/services/sample_data/routes/utils.ts @@ -11,7 +11,7 @@ import type { SampleDatasetSchema } from '../lib/sample_dataset_registry_types'; import { SampleDataInstaller } from '../sample_data_installer'; import { getUniqueObjectTypes } from '../lib/utils'; -export const getSampleDataInstaller = ({ +export const getSampleDataInstaller = async ({ datasetId, context, sampleDatasets, @@ -22,14 +22,15 @@ export const getSampleDataInstaller = ({ sampleDatasets: SampleDatasetSchema[]; logger: Logger; }) => { + const core = await context.core; const sampleDataset = sampleDatasets.find(({ id }) => id === datasetId)!; - const { getImporter, client: soClient } = context.core.savedObjects; + const { getImporter, client: soClient } = core.savedObjects; const objectTypes = getUniqueObjectTypes(sampleDataset.savedObjects); - const savedObjectsClient = getSavedObjectsClient(context, objectTypes); + const savedObjectsClient = await getSavedObjectsClient(context, objectTypes); const soImporter = getImporter(savedObjectsClient); return new SampleDataInstaller({ - esClient: context.core.elasticsearch.client, + esClient: core.elasticsearch.client, soImporter, soClient, logger, @@ -37,8 +38,11 @@ export const getSampleDataInstaller = ({ }); }; -export const getSavedObjectsClient = (context: RequestHandlerContext, objectTypes: string[]) => { - const { getClient, typeRegistry } = context.core.savedObjects; +export const getSavedObjectsClient = async ( + context: RequestHandlerContext, + objectTypes: string[] +) => { + const { getClient, typeRegistry } = (await context.core).savedObjects; const includedHiddenTypes = objectTypes.filter((supportedType) => typeRegistry.isHidden(supportedType) ); diff --git a/src/plugins/saved_objects_management/server/routes/bulk_get.ts b/src/plugins/saved_objects_management/server/routes/bulk_get.ts index fab25b51d922455..9e31b1c24b0b878 100644 --- a/src/plugins/saved_objects_management/server/routes/bulk_get.ts +++ b/src/plugins/saved_objects_management/server/routes/bulk_get.ts @@ -29,7 +29,7 @@ export const registerBulkGetRoute = ( }, router.handleLegacyErrors(async (context, req, res) => { const managementService = await managementServicePromise; - const { getClient, typeRegistry } = context.core.savedObjects; + const { getClient, typeRegistry } = (await context.core).savedObjects; const objects = req.body; const uniqueTypes = objects.reduce((acc, { type }) => acc.add(type), new Set()); diff --git a/src/plugins/saved_objects_management/server/routes/find.ts b/src/plugins/saved_objects_management/server/routes/find.ts index 662ab680311581d..05e69da5d3204f7 100644 --- a/src/plugins/saved_objects_management/server/routes/find.ts +++ b/src/plugins/saved_objects_management/server/routes/find.ts @@ -47,7 +47,7 @@ export const registerFindRoute = ( router.handleLegacyErrors(async (context, req, res) => { const { query } = req; const managementService = await managementServicePromise; - const { getClient, typeRegistry } = context.core.savedObjects; + const { getClient, typeRegistry } = (await context.core).savedObjects; const searchTypes = Array.isArray(query.type) ? query.type : [query.type]; const includedFields = Array.isArray(query.fields) ? query.fields : [query.fields]; diff --git a/src/plugins/saved_objects_management/server/routes/get_allowed_types.ts b/src/plugins/saved_objects_management/server/routes/get_allowed_types.ts index 3ad8130654a77d1..cdd6dc215d69b9c 100644 --- a/src/plugins/saved_objects_management/server/routes/get_allowed_types.ts +++ b/src/plugins/saved_objects_management/server/routes/get_allowed_types.ts @@ -25,7 +25,7 @@ export const registerGetAllowedTypesRoute = (router: IRouter) => { validate: false, }, async (context, req, res) => { - const allowedTypes = context.core.savedObjects.typeRegistry + const allowedTypes = (await context.core).savedObjects.typeRegistry .getImportableAndExportableTypes() .filter((type) => type.management!.visibleInManagement ?? true) .map(convertType); diff --git a/src/plugins/saved_objects_management/server/routes/relationships.ts b/src/plugins/saved_objects_management/server/routes/relationships.ts index 875cf82488abee5..8900987a645fe74 100644 --- a/src/plugins/saved_objects_management/server/routes/relationships.ts +++ b/src/plugins/saved_objects_management/server/routes/relationships.ts @@ -32,7 +32,7 @@ export const registerRelationshipsRoute = ( }, router.handleLegacyErrors(async (context, req, res) => { const managementService = await managementServicePromise; - const { getClient, typeRegistry } = context.core.savedObjects; + const { getClient, typeRegistry } = (await context.core).savedObjects; const { type, id } = req.params; const { size, savedObjectTypes: maybeArraySavedObjectTypes } = req.query; const savedObjectTypes = Array.isArray(maybeArraySavedObjectTypes) diff --git a/src/plugins/saved_objects_management/server/routes/scroll_count.ts b/src/plugins/saved_objects_management/server/routes/scroll_count.ts index 217153bbb86e0b1..26dd1d57b4cf91f 100644 --- a/src/plugins/saved_objects_management/server/routes/scroll_count.ts +++ b/src/plugins/saved_objects_management/server/routes/scroll_count.ts @@ -31,7 +31,7 @@ export const registerScrollForCountRoute = (router: IRouter) => { }, }, router.handleLegacyErrors(async (context, req, res) => { - const { getClient, typeRegistry } = context.core.savedObjects; + const { getClient, typeRegistry } = (await context.core).savedObjects; const { typesToInclude, searchString, references } = req.body; const includedHiddenTypes = chain(typesToInclude) diff --git a/src/plugins/screenshot_mode/server/types.ts b/src/plugins/screenshot_mode/server/types.ts index 514bcb759428d7e..08655d2f0118d8e 100644 --- a/src/plugins/screenshot_mode/server/types.ts +++ b/src/plugins/screenshot_mode/server/types.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { RequestHandlerContext, KibanaRequest } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, KibanaRequest } from '@kbn/core/server'; export interface ScreenshotModePluginStart { /** @@ -32,8 +32,8 @@ export interface ScreenshotModePluginSetup extends ScreenshotModePluginStart { setScreenshotModeEnabled(): void; } -export interface ScreenshotModeRequestHandlerContext extends RequestHandlerContext { +export type ScreenshotModeRequestHandlerContext = CustomRequestHandlerContext<{ screenshotMode: { isScreenshot: boolean; }; -} +}>; diff --git a/src/plugins/share/server/url_service/http/short_urls/register_create_route.ts b/src/plugins/share/server/url_service/http/short_urls/register_create_route.ts index 972641d160e282e..1208f6fda4d1ed0 100644 --- a/src/plugins/share/server/url_service/http/short_urls/register_create_route.ts +++ b/src/plugins/share/server/url_service/http/short_urls/register_create_route.ts @@ -34,7 +34,7 @@ export const registerCreateRoute = (router: IRouter, url: ServerUrlService) => { }, }, router.handleLegacyErrors(async (ctx, req, res) => { - const savedObjects = ctx.core.savedObjects.client; + const savedObjects = (await ctx.core).savedObjects.client; const shortUrls = url.shortUrls.get({ savedObjects }); const { locatorId, params, slug, humanReadableSlug } = req.body; const locator = url.locators.get(locatorId); diff --git a/src/plugins/share/server/url_service/http/short_urls/register_delete_route.ts b/src/plugins/share/server/url_service/http/short_urls/register_delete_route.ts index 6e2b133ac3cffd8..ddc29117a3accfa 100644 --- a/src/plugins/share/server/url_service/http/short_urls/register_delete_route.ts +++ b/src/plugins/share/server/url_service/http/short_urls/register_delete_route.ts @@ -25,7 +25,7 @@ export const registerDeleteRoute = (router: IRouter, url: ServerUrlService) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const id = req.params.id; - const savedObjects = ctx.core.savedObjects.client; + const savedObjects = (await ctx.core).savedObjects.client; const shortUrls = url.shortUrls.get({ savedObjects }); await shortUrls.delete(id); diff --git a/src/plugins/share/server/url_service/http/short_urls/register_get_route.ts b/src/plugins/share/server/url_service/http/short_urls/register_get_route.ts index 7ece9b1ef6c6369..8e783b3fcfd3de6 100644 --- a/src/plugins/share/server/url_service/http/short_urls/register_get_route.ts +++ b/src/plugins/share/server/url_service/http/short_urls/register_get_route.ts @@ -25,7 +25,7 @@ export const registerGetRoute = (router: IRouter, url: ServerUrlService) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const id = req.params.id; - const savedObjects = ctx.core.savedObjects.client; + const savedObjects = (await ctx.core).savedObjects.client; const shortUrls = url.shortUrls.get({ savedObjects }); const shortUrl = await shortUrls.get(id); diff --git a/src/plugins/share/server/url_service/http/short_urls/register_resolve_route.ts b/src/plugins/share/server/url_service/http/short_urls/register_resolve_route.ts index b4c73780bdf7c82..47290d5754545a8 100644 --- a/src/plugins/share/server/url_service/http/short_urls/register_resolve_route.ts +++ b/src/plugins/share/server/url_service/http/short_urls/register_resolve_route.ts @@ -26,7 +26,7 @@ export const registerResolveRoute = (router: IRouter, url: ServerUrlService) => }, router.handleLegacyErrors(async (ctx, req, res) => { const slug = req.params.slug; - const savedObjects = ctx.core.savedObjects.client; + const savedObjects = (await ctx.core).savedObjects.client; try { const shortUrls = url.shortUrls.get({ savedObjects }); diff --git a/src/plugins/telemetry/server/routes/telemetry_opt_in.ts b/src/plugins/telemetry/server/routes/telemetry_opt_in.ts index fff5df2dff100df..06e443670518d31 100644 --- a/src/plugins/telemetry/server/routes/telemetry_opt_in.ts +++ b/src/plugins/telemetry/server/routes/telemetry_opt_in.ts @@ -48,12 +48,13 @@ export function registerTelemetryOptInRoutes({ }, async (context, req, res) => { const newOptInStatus = req.body.enabled; + const soClient = (await context.core).savedObjects.client; const attributes: TelemetrySavedObjectAttributes = { enabled: newOptInStatus, lastVersionChecked: currentKibanaVersion, }; const config = await firstValueFrom(config$); - const telemetrySavedObject = await getTelemetrySavedObject(context.core.savedObjects.client); + const telemetrySavedObject = await getTelemetrySavedObject(soClient); if (telemetrySavedObject === false) { // If we get false, we couldn't get the saved object due to lack of permissions @@ -96,7 +97,7 @@ export function registerTelemetryOptInRoutes({ } try { - await updateTelemetrySavedObject(context.core.savedObjects.client, attributes); + await updateTelemetrySavedObject(soClient, attributes); } catch (e) { if (SavedObjectsErrorHelpers.isForbiddenError(e)) { return res.forbidden(); diff --git a/src/plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts b/src/plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts index 686274dc4f5d342..cb990b68fd9b562 100644 --- a/src/plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts +++ b/src/plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts @@ -21,7 +21,7 @@ export function registerTelemetryUserHasSeenNotice(router: IRouter) { validate: false, }, async (context, req, res) => { - const internalRepository = context.core.savedObjects.client; + const internalRepository = (await context.core).savedObjects.client; const telemetrySavedObject: TelemetrySavedObject = await getTelemetrySavedObject( internalRepository ); diff --git a/src/plugins/unified_search/server/autocomplete/value_suggestions_route.ts b/src/plugins/unified_search/server/autocomplete/value_suggestions_route.ts index b073c584023151f..67d4deae4c5907c 100644 --- a/src/plugins/unified_search/server/autocomplete/value_suggestions_route.ts +++ b/src/plugins/unified_search/server/autocomplete/value_suggestions_route.ts @@ -45,13 +45,14 @@ export function registerValueSuggestionsRoute(router: IRouter, config$: Observab const { field: fieldName, query, filters, fieldMeta, method } = request.body; const { index } = request.params; const abortSignal = getRequestAbortedSignal(request.events.aborted$); + const { savedObjects, elasticsearch } = await context.core; try { const fn = method === 'terms_agg' ? termsAggSuggestions : termsEnumSuggestions; const body = await fn( config, - context.core.savedObjects.client, - context.core.elasticsearch.client.asCurrentUser, + savedObjects.client, + elasticsearch.client.asCurrentUser, index, fieldName, query, diff --git a/src/plugins/usage_collection/server/routes/stats/stats.ts b/src/plugins/usage_collection/server/routes/stats/stats.ts index 2c6c8e77d8cdfc0..d9c27afb5fb2af9 100644 --- a/src/plugins/usage_collection/server/routes/stats/stats.ts +++ b/src/plugins/usage_collection/server/routes/stats/stats.ts @@ -89,8 +89,9 @@ export function registerStatsRoute({ let extended; if (isExtended) { - const { asCurrentUser } = context.core.elasticsearch.client; - const savedObjectsClient = context.core.savedObjects.client; + const core = await context.core; + const { asCurrentUser } = core.elasticsearch.client; + const savedObjectsClient = core.savedObjects.client; const [usage, clusterUuid] = await Promise.all([ shouldGetUsage diff --git a/src/plugins/vis_types/timelion/server/routes/run.ts b/src/plugins/vis_types/timelion/server/routes/run.ts index 5fb6ef6c0a3d3de..e136f1ab5a24195 100644 --- a/src/plugins/vis_types/timelion/server/routes/run.ts +++ b/src/plugins/vis_types/timelion/server/routes/run.ts @@ -77,10 +77,11 @@ export function runRoute( }, router.handleLegacyErrors(async (context, request, response) => { const [, { dataViews }] = await core.getStartServices(); - const uiSettings = await context.core.uiSettings.client.getAll(); + const coreCtx = await context.core; + const uiSettings = await coreCtx.uiSettings.client.getAll(); const indexPatternsService = await dataViews.dataViewsServiceFactory( - context.core.savedObjects.client, - context.core.elasticsearch.client.asCurrentUser + coreCtx.savedObjects.client, + coreCtx.elasticsearch.client.asCurrentUser ); const tlConfig = getTlConfig({ diff --git a/src/plugins/vis_types/timelion/server/series_functions/es/index.js b/src/plugins/vis_types/timelion/server/series_functions/es/index.js index a86ee64f0056898..2001a39bf790194 100644 --- a/src/plugins/vis_types/timelion/server/series_functions/es/index.js +++ b/src/plugins/vis_types/timelion/server/series_functions/es/index.js @@ -117,7 +117,8 @@ export default new Datasource('es', { // we need to handle this scenario by aborting underlying server requests const abortSignal = getRequestAbortedSignal(tlConfig.request.events.aborted$); - const resp = await tlConfig.context.search + const searchContext = await tlConfig.context.search; + const resp = await searchContext .search( body, { diff --git a/src/plugins/vis_types/timeseries/server/lib/get_vis_data.ts b/src/plugins/vis_types/timeseries/server/lib/get_vis_data.ts index a76132e0fbd2153..360256ccb628bb3 100644 --- a/src/plugins/vis_types/timeseries/server/lib/get_vis_data.ts +++ b/src/plugins/vis_types/timeseries/server/lib/get_vis_data.ts @@ -28,7 +28,7 @@ export async function getVisData( request: VisTypeTimeseriesVisDataRequest, framework: Framework ): Promise { - const uiSettings = requestContext.core.uiSettings.client; + const uiSettings = (await requestContext.core).uiSettings.client; const esShardTimeout = await framework.getEsShardTimeout(); const fieldFormatService = await framework.getFieldFormatsService(uiSettings); const indexPatternsService = await framework.getIndexPatternsService(requestContext); diff --git a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.ts b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.ts index ae5dade8c55929c..9fb7fc2a3231747 100644 --- a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.ts +++ b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.test.ts @@ -84,7 +84,7 @@ describe('AbstractSearchStrategy', () => { ); expect(responses).toEqual([{}]); - expect(requestContext.search.search).toHaveBeenCalledWith( + expect((await requestContext.search).search).toHaveBeenCalledWith( { params: { body: {}, diff --git a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts index e89e999e583f07e..167bc9cec8e0313 100644 --- a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts +++ b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/abstract_search_strategy.ts @@ -46,11 +46,12 @@ export abstract class AbstractSearchStrategy { // User may abort the request without waiting for the results // we need to handle this scenario by aborting underlying server requests const abortSignal = getRequestAbortedSignal(req.events.aborted$); + const searchContext = await requestContext.search; esRequests.forEach(({ body, index, trackingEsSearchMeta }) => { const startTime = Date.now(); requests.push( - requestContext.search + searchContext .search( { indexType, diff --git a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/default_search_strategy.ts b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/default_search_strategy.ts index f2c52b59bf0d9e9..ca20f87641f88ba 100644 --- a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/default_search_strategy.ts +++ b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/default_search_strategy.ts @@ -22,7 +22,7 @@ export class DefaultSearchStrategy extends AbstractSearchStrategy { requestContext: VisTypeTimeseriesRequestHandlerContext, req: VisTypeTimeseriesRequest ) { - const uiSettings = requestContext.core.uiSettings.client; + const uiSettings = (await requestContext.core).uiSettings.client; return { isViable: true, diff --git a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/rollup_search_strategy.ts b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/rollup_search_strategy.ts index dbc98e624b27ac8..35223f5159a8645 100644 --- a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/rollup_search_strategy.ts +++ b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/rollup_search_strategy.ts @@ -38,10 +38,10 @@ export class RollupSearchStrategy extends AbstractSearchStrategy { indexPattern: string ) { try { - const body = - await requestContext.core.elasticsearch.client.asCurrentUser.rollup.getRollupIndexCaps({ - index: indexPattern, - }); + const esClient = (await requestContext.core).elasticsearch.client; + const body = await esClient.asCurrentUser.rollup.getRollupIndexCaps({ + index: indexPattern, + }); return body; } catch (e) { @@ -64,7 +64,7 @@ export class RollupSearchStrategy extends AbstractSearchStrategy { ) { const rollupData = await this.getRollupData(requestContext, indexPatternString); const rollupIndices = getRollupIndices(rollupData); - const uiSettings = requestContext.core.uiSettings.client; + const uiSettings = (await requestContext.core).uiSettings.client; isViable = rollupIndices.length === 1; diff --git a/src/plugins/vis_types/timeseries/server/plugin.ts b/src/plugins/vis_types/timeseries/server/plugin.ts index e30758745627b53..31ca2667ed3a7d8 100644 --- a/src/plugins/vis_types/timeseries/server/plugin.ts +++ b/src/plugins/vis_types/timeseries/server/plugin.ts @@ -109,10 +109,10 @@ export class VisTypeTimeseriesPlugin implements Plugin { ), getIndexPatternsService: async (requestContext) => { const [, { dataViews }] = await core.getStartServices(); - + const { elasticsearch, savedObjects } = await requestContext.core; return await dataViews.dataViewsServiceFactory( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser + savedObjects.client, + elasticsearch.client.asCurrentUser ); }, getFieldFormatsService: async (uiSettings) => { diff --git a/test/functional/apps/dashboard/dashboard_unsaved_listing.ts b/test/functional/apps/dashboard/dashboard_unsaved_listing.ts index d9451eda5ff6242..a1db57784b5f8d8 100644 --- a/test/functional/apps/dashboard/dashboard_unsaved_listing.ts +++ b/test/functional/apps/dashboard/dashboard_unsaved_listing.ts @@ -106,7 +106,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('can discard unsaved changes using the discard link', async () => { - await PageObjects.dashboard.clickUnsavedChangesDiscard(dashboardTitle); + await PageObjects.dashboard.clickUnsavedChangesDiscard( + `discard-unsaved-${dashboardTitle.split(' ').join('-')}` + ); await PageObjects.dashboard.expectUnsavedChangesDoesNotExist(dashboardTitle); await PageObjects.dashboard.loadSavedDashboard(dashboardTitle); await PageObjects.dashboard.switchToEditMode(); diff --git a/test/functional/apps/discover/_filter_editor.ts b/test/functional/apps/discover/_filter_editor.ts index 0fb883759890485..b2fbfbb71c7ee29 100644 --- a/test/functional/apps/discover/_filter_editor.ts +++ b/test/functional/apps/discover/_filter_editor.ts @@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const filterBar = getService('filterBar'); + const security = getService('security'); const PageObjects = getPageObjects(['common', 'discover', 'timePicker']); const defaultSettings = { defaultIndex: 'logstash-*', @@ -23,6 +24,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('discover filter editor', function describeIndexTests() { before(async function () { + await security.testUser.setRoles(['kibana_admin', 'version_test', 'test_logstash_reader']); log.debug('load kibana index with default index pattern'); await kibanaServer.savedObjects.clean({ types: ['search', 'index-pattern'] }); await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json'); @@ -111,5 +113,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); }); + + after(async () => { + await security.testUser.restoreDefaults(); + }); }); } diff --git a/test/functional/apps/visualize/_tsvb_time_series.ts b/test/functional/apps/visualize/_tsvb_time_series.ts index c27d2281d6119cd..3f6661aaecf0049 100644 --- a/test/functional/apps/visualize/_tsvb_time_series.ts +++ b/test/functional/apps/visualize/_tsvb_time_series.ts @@ -27,8 +27,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const browser = getService('browser'); const kibanaServer = getService('kibanaServer'); - // Failing: See https://github.com/elastic/kibana/issues/129785 - describe.skip('visual builder', function describeIndexTests() { + describe('visual builder', function describeIndexTests() { before(async () => { await security.testUser.setRoles([ 'kibana_admin', @@ -172,62 +171,62 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); describe('Clicking on the chart', () => { - it(`should create a filter`, async () => { - await visualBuilder.setMetricsGroupByTerms('machine.os.raw', { - include: 'win 7', - exclude: 'ios', - }); - await visualBuilder.clickSeriesOption(); + const act = async (visName: string, clickCoordinates: { x: number; y: number }) => { await testSubjects.click('visualizeSaveButton'); - await timeToVisualize.saveFromModal('My TSVB viz 1', { + await timeToVisualize.saveFromModal(visName, { addToDashboard: 'new', saveToLibrary: false, }); await dashboard.waitForRenderComplete(); - const el = await elasticChart.getCanvas(); await retry.try(async () => { - // click on specific coordinates - await browser - .getActions() - .move({ x: 105, y: 115, origin: el._webElement }) - .click() - .perform(); - await common.sleep(2000); - await testSubjects.click('applyFiltersPopoverButton'); - await testSubjects.missingOrFail('applyFiltersPopoverButton'); + const el = await elasticChart.getCanvas(); + + await el.clickMouseButton({ + xOffset: clickCoordinates.x, + yOffset: clickCoordinates.y, + }); + await common.sleep(1000); + await testSubjects.existOrFail('applyFiltersPopoverButton'); }); + await testSubjects.click('applyFiltersPopoverButton'); + }; + + const cleanup = async () => { + const discardDashboardPromptButton = 'discardDashboardPromptButton'; + await common.navigateToApp('dashboard'); + if (await testSubjects.exists(discardDashboardPromptButton)) { + await dashboard.clickUnsavedChangesDiscard(discardDashboardPromptButton, true); + } + }; + + afterEach(async () => { + await cleanup(); + }); + + it(`should create a filter`, async () => { + await visualBuilder.setMetricsGroupByTerms('machine.os.raw', { + include: 'win 7', + exclude: 'ios', + }); + await act('viz_1', { x: 105, y: 115 }); const hasMachineRawFilter = await filterBar.hasFilter('machine.os.raw', 'win 7'); expect(hasMachineRawFilter).to.be(true); }); it('should create a filter for series with multiple split by terms fields one of which has formatting', async () => { - const expectedFilterPills = ['0, win xp, logstash-2015.09.20']; + const expectedFilterPills = ['0, win 7']; await visualBuilder.setMetricsGroupByTerms('bytes'); await visualBuilder.setAnotherGroupByTermsField('machine.os.raw'); - await visualBuilder.setAnotherGroupByTermsField('_index'); - await visualBuilder.clickSeriesOption(); await visualBuilder.setChartType('Bar'); - await visualBuilder.setStackedType('Stacked'); await visualBuilder.clickPanelOptions('timeSeries'); await visualBuilder.setIntervalValue('1w'); - const el = await elasticChart.getCanvas(); - await el.scrollIntoViewIfNecessary(); - await browser - .getActions() - .move({ x: 100, y: 65, origin: el._webElement }) - .click() - .perform(); - - await retry.try(async () => { - await testSubjects.click('applyFiltersPopoverButton'); - await testSubjects.missingOrFail('applyFiltersPopoverButton'); - }); + await act('vis_2', { x: -100, y: 10 }); const filterPills = await filterBar.getFiltersLabel(); expect(filterPills).to.eql(expectedFilterPills); diff --git a/test/functional/page_objects/dashboard_page.ts b/test/functional/page_objects/dashboard_page.ts index 4a77b5673e9feb9..cd936baa1a41a7d 100644 --- a/test/functional/page_objects/dashboard_page.ts +++ b/test/functional/page_objects/dashboard_page.ts @@ -143,10 +143,10 @@ export class DashboardPageObject extends FtrService { await this.testSubjects.click(`edit-unsaved-${title.split(' ').join('-')}`); } - public async clickUnsavedChangesDiscard(title: string, confirmDiscard = true) { - this.log.debug(`Click Unsaved Changes Discard for `, title); - await this.testSubjects.existOrFail(`discard-unsaved-${title.split(' ').join('-')}`); - await this.testSubjects.click(`discard-unsaved-${title.split(' ').join('-')}`); + public async clickUnsavedChangesDiscard(testSubject: string, confirmDiscard = true) { + this.log.debug(`Click Unsaved Changes Discard for `, testSubject); + await this.testSubjects.existOrFail(testSubject); + await this.testSubjects.click(testSubject); if (confirmDiscard) { await this.common.clickConfirmOnModal(); } else { diff --git a/test/plugin_functional/plugins/core_plugin_a/server/plugin.ts b/test/plugin_functional/plugins/core_plugin_a/server/plugin.ts index aa86662871c29fc..a0f1ce279d652bc 100644 --- a/test/plugin_functional/plugins/core_plugin_a/server/plugin.ts +++ b/test/plugin_functional/plugins/core_plugin_a/server/plugin.ts @@ -6,15 +6,15 @@ * Side Public License, v 1. */ -import type { Plugin, CoreSetup, RequestHandlerContext } from '@kbn/core/server'; +import type { Plugin, CoreSetup, CustomRequestHandlerContext } from '@kbn/core/server'; export interface PluginAApiRequestContext { ping: () => Promise; } -interface PluginARequstHandlerContext extends RequestHandlerContext { +type PluginARequstHandlerContext = CustomRequestHandlerContext<{ pluginA: PluginAApiRequestContext; -} +}>; export class CorePluginAPlugin implements Plugin { public setup(core: CoreSetup, deps: {}) { @@ -23,7 +23,8 @@ export class CorePluginAPlugin implements Plugin { (context) => { return { ping: async () => { - const body = await context.core.elasticsearch.client.asInternalUser.ping(); + const esClient = (await context.core).elasticsearch.client; + const body = await esClient.asInternalUser.ping(); return String(body); }, }; diff --git a/test/plugin_functional/plugins/core_plugin_b/server/plugin.ts b/test/plugin_functional/plugins/core_plugin_b/server/plugin.ts index c9617eb81e8fbd7..9a34e82b38131fb 100644 --- a/test/plugin_functional/plugins/core_plugin_b/server/plugin.ts +++ b/test/plugin_functional/plugins/core_plugin_b/server/plugin.ts @@ -6,20 +6,21 @@ * Side Public License, v 1. */ -import { Plugin, CoreSetup, RequestHandlerContext } from '@kbn/core/server'; +import { Plugin, CoreSetup, CustomRequestHandlerContext } from '@kbn/core/server'; import { schema } from '@kbn/config-schema'; import { PluginAApiRequestContext } from '@kbn/core-plugin-a-plugin/server'; -interface PluginBContext extends RequestHandlerContext { +type PluginBContext = CustomRequestHandlerContext<{ pluginA: PluginAApiRequestContext; -} +}>; export class CorePluginBPlugin implements Plugin { public setup(core: CoreSetup, deps: {}) { const router = core.http.createRouter(); router.get({ path: '/core_plugin_b', validate: false }, async (context, req, res) => { - if (!context.pluginA) throw new Error('pluginA is disabled'); - const response = await context.pluginA.ping(); + const pluginAContext = await context.pluginA; + if (!pluginAContext) throw new Error('pluginA is disabled'); + const response = await pluginAContext.ping(); return res.ok({ body: `Pong via plugin A: ${response}` }); }); diff --git a/test/plugin_functional/plugins/core_plugin_deprecations/server/routes.ts b/test/plugin_functional/plugins/core_plugin_deprecations/server/routes.ts index ca7c17d1c94d268..aba6cd5b38e4c97 100644 --- a/test/plugin_functional/plugins/core_plugin_deprecations/server/routes.ts +++ b/test/plugin_functional/plugins/core_plugin_deprecations/server/routes.ts @@ -33,7 +33,7 @@ export function registerRoutes(http: HttpServiceSetup) { } if (keyId) { - const client = context.core.savedObjects.getClient(); + const client = (await context.core).savedObjects.getClient(); await client.delete('test-deprecations-plugin', keyId, { refresh: true, }); diff --git a/test/plugin_functional/plugins/core_plugin_execution_context/server/plugin.ts b/test/plugin_functional/plugins/core_plugin_execution_context/server/plugin.ts index 69001eb58b6f19d..d7dad3f7b3d297c 100644 --- a/test/plugin_functional/plugins/core_plugin_execution_context/server/plugin.ts +++ b/test/plugin_functional/plugins/core_plugin_execution_context/server/plugin.ts @@ -20,10 +20,8 @@ export class CorePluginExecutionContext implements Plugin { }, }, async (context, request, response) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( - {}, - { meta: true } - ); + const esClient = (await context.core).elasticsearch.client; + const { headers } = await esClient.asCurrentUser.ping({}, { meta: true }); return response.ok({ body: headers || {} }); } ); diff --git a/test/plugin_functional/plugins/elasticsearch_client_plugin/server/plugin.ts b/test/plugin_functional/plugins/elasticsearch_client_plugin/server/plugin.ts index d66069aa3ab64a7..ba161e05aaac83b 100644 --- a/test/plugin_functional/plugins/elasticsearch_client_plugin/server/plugin.ts +++ b/test/plugin_functional/plugins/elasticsearch_client_plugin/server/plugin.ts @@ -10,12 +10,14 @@ import { Plugin, CoreSetup, CoreStart, ICustomClusterClient } from '@kbn/core/se export class ElasticsearchClientPlugin implements Plugin { private client?: ICustomClusterClient; + public setup(core: CoreSetup) { const router = core.http.createRouter(); router.get( { path: '/api/elasticsearch_client_plugin/context/ping', validate: false }, async (context, req, res) => { - const body = await context.core.elasticsearch.client.asInternalUser.ping(); + const esClient = (await context.core).elasticsearch.client; + const body = await esClient.asInternalUser.ping(); return res.ok({ body: JSON.stringify(body) }); } ); @@ -39,5 +41,6 @@ export class ElasticsearchClientPlugin implements Plugin { public start(core: CoreStart) { this.client = core.elasticsearch.createClient('my-custom-client-test'); } + public stop() {} } diff --git a/test/plugin_functional/plugins/ui_settings_plugin/server/plugin.ts b/test/plugin_functional/plugins/ui_settings_plugin/server/plugin.ts index fee0773a76141cb..daa02f90426fa62 100644 --- a/test/plugin_functional/plugins/ui_settings_plugin/server/plugin.ts +++ b/test/plugin_functional/plugins/ui_settings_plugin/server/plugin.ts @@ -23,13 +23,13 @@ export class UiSettingsPlugin implements Plugin { const router = core.http.createRouter(); router.get({ path: '/api/ui-settings-plugin', validate: false }, async (context, req, res) => { - const uiSettingsValue = await context.core.uiSettings.client.get( - 'ui_settings_plugin' - ); + const { uiSettings } = await context.core; + const uiSettingsValue = await uiSettings.client.get('ui_settings_plugin'); return res.ok({ body: { uiSettingsValue } }); }); } public start() {} + public stop() {} } diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index 9d4a720eeae6bb9..ba8757b70b52278 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -554,6 +554,8 @@ export class ActionsPlugin implements Plugin { if (isESOCanEncrypt !== true) { @@ -569,7 +571,7 @@ export class ActionsPlugin implements Plugin = await actionsClient.execute({ diff --git a/x-pack/plugins/actions/server/routes/get.ts b/x-pack/plugins/actions/server/routes/get.ts index 64463c49c57beb9..352670bd5b170b2 100644 --- a/x-pack/plugins/actions/server/routes/get.ts +++ b/x-pack/plugins/actions/server/routes/get.ts @@ -41,7 +41,7 @@ export const getActionRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const { id } = req.params; return res.ok({ body: rewriteBodyRes(await actionsClient.get({ id })), diff --git a/x-pack/plugins/actions/server/routes/get_all.ts b/x-pack/plugins/actions/server/routes/get_all.ts index ebb357280f85e27..3710b60ce5101d7 100644 --- a/x-pack/plugins/actions/server/routes/get_all.ts +++ b/x-pack/plugins/actions/server/routes/get_all.ts @@ -34,7 +34,7 @@ export const getAllActionRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const result = await actionsClient.getAll(); return res.ok({ body: rewriteBodyRes(result), diff --git a/x-pack/plugins/actions/server/routes/legacy/create.ts b/x-pack/plugins/actions/server/routes/legacy/create.ts index 89b9f19d8263321..120a7e533623547 100644 --- a/x-pack/plugins/actions/server/routes/legacy/create.ts +++ b/x-pack/plugins/actions/server/routes/legacy/create.ts @@ -35,7 +35,7 @@ export const createActionRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const action = req.body; trackLegacyRouteUsage('create', usageCounter); return res.ok({ diff --git a/x-pack/plugins/actions/server/routes/legacy/delete.ts b/x-pack/plugins/actions/server/routes/legacy/delete.ts index 59392c6592631f4..dd5f99aebd974c2 100644 --- a/x-pack/plugins/actions/server/routes/legacy/delete.ts +++ b/x-pack/plugins/actions/server/routes/legacy/delete.ts @@ -34,7 +34,7 @@ export const deleteActionRoute = ( if (!context.actions) { return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' }); } - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const { id } = req.params; trackLegacyRouteUsage('delete', usageCounter); try { diff --git a/x-pack/plugins/actions/server/routes/legacy/execute.ts b/x-pack/plugins/actions/server/routes/legacy/execute.ts index 0616235cd52cbd4..e54e5f6c503974d 100644 --- a/x-pack/plugins/actions/server/routes/legacy/execute.ts +++ b/x-pack/plugins/actions/server/routes/legacy/execute.ts @@ -43,7 +43,7 @@ export const executeActionRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' }); } - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const { params } = req.body; const { id } = req.params; trackLegacyRouteUsage('execute', usageCounter); diff --git a/x-pack/plugins/actions/server/routes/legacy/get.ts b/x-pack/plugins/actions/server/routes/legacy/get.ts index 7612858c9fc8b1c..f1037202335071e 100644 --- a/x-pack/plugins/actions/server/routes/legacy/get.ts +++ b/x-pack/plugins/actions/server/routes/legacy/get.ts @@ -34,7 +34,7 @@ export const getActionRoute = ( if (!context.actions) { return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' }); } - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const { id } = req.params; trackLegacyRouteUsage('get', usageCounter); return res.ok({ diff --git a/x-pack/plugins/actions/server/routes/legacy/get_all.ts b/x-pack/plugins/actions/server/routes/legacy/get_all.ts index f968f4de859462a..6fc478b04d51feb 100644 --- a/x-pack/plugins/actions/server/routes/legacy/get_all.ts +++ b/x-pack/plugins/actions/server/routes/legacy/get_all.ts @@ -27,7 +27,7 @@ export const getAllActionRoute = ( if (!context.actions) { return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' }); } - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const result = await actionsClient.getAll(); trackLegacyRouteUsage('getAll', usageCounter); return res.ok({ diff --git a/x-pack/plugins/actions/server/routes/legacy/list_action_types.ts b/x-pack/plugins/actions/server/routes/legacy/list_action_types.ts index 1c600b68b4e0e6e..92213c0b9be611f 100644 --- a/x-pack/plugins/actions/server/routes/legacy/list_action_types.ts +++ b/x-pack/plugins/actions/server/routes/legacy/list_action_types.ts @@ -27,7 +27,7 @@ export const listActionTypesRoute = ( if (!context.actions) { return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' }); } - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); trackLegacyRouteUsage('listActionTypes', usageCounter); return res.ok({ body: await actionsClient.listTypes(), diff --git a/x-pack/plugins/actions/server/routes/legacy/update.ts b/x-pack/plugins/actions/server/routes/legacy/update.ts index 28edcfd3368986a..a4e441d5d9846f9 100644 --- a/x-pack/plugins/actions/server/routes/legacy/update.ts +++ b/x-pack/plugins/actions/server/routes/legacy/update.ts @@ -41,7 +41,7 @@ export const updateActionRoute = ( if (!context.actions) { return res.badRequest({ body: 'RouteHandlerContext is not registered for actions' }); } - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const { id } = req.params; const { name, config, secrets } = req.body; trackLegacyRouteUsage('update', usageCounter); diff --git a/x-pack/plugins/actions/server/routes/update.ts b/x-pack/plugins/actions/server/routes/update.ts index 3f1ceb0a0096fec..a8892c814fc66d1 100644 --- a/x-pack/plugins/actions/server/routes/update.ts +++ b/x-pack/plugins/actions/server/routes/update.ts @@ -48,7 +48,7 @@ export const updateActionRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const actionsClient = context.actions.getActionsClient(); + const actionsClient = (await context.actions).getActionsClient(); const { id } = req.params; const { name, config, secrets } = req.body; diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index b13df8dfe2460fb..9cb4f1aec63e8ae 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -12,7 +12,7 @@ import { SavedObjectsClientContract, SavedObjectAttributes, ElasticsearchClient, - RequestHandlerContext, + CustomRequestHandlerContext, SavedObjectReference, } from '@kbn/core/server'; import { ActionTypeRegistry } from './action_type_registry'; @@ -21,6 +21,7 @@ import { ActionsClient } from './actions_client'; import { ActionTypeExecutorResult } from '../common'; import { TaskInfo } from './lib/action_executor'; import { ConnectorTokenClient } from './builtin_action_types/lib/connector_token_client'; + export type { ActionTypeExecutorResult } from '../common'; export type { GetFieldsByIssueTypeResponse as JiraGetFieldsResponse } from './builtin_action_types/jira/types'; export type { GetCommonFieldsResponse as ServiceNowGetFieldsResponse } from './builtin_action_types/servicenow/types'; @@ -46,9 +47,9 @@ export interface ActionsApiRequestHandlerContext { listTypes: ActionTypeRegistry['list']; } -export interface ActionsRequestHandlerContext extends RequestHandlerContext { +export type ActionsRequestHandlerContext = CustomRequestHandlerContext<{ actions: ActionsApiRequestHandlerContext; -} +}>; export interface ActionsPlugin { setup: PluginSetupContract; @@ -97,6 +98,7 @@ interface ValidatorType { export interface ActionValidationService { isHostnameAllowed(hostname: string): boolean; + isUriAllowed(uri: string): boolean; } @@ -116,11 +118,13 @@ export interface ActionType< secrets?: ValidatorType; connector?: (config: Config, secrets: Secrets) => string | null; }; + renderParameterTemplates?( params: Params, variables: Record, actionId?: string ): Params; + executor: ExecutorType; } @@ -146,6 +150,7 @@ interface PersistedActionTaskExecutorParams { spaceId: string; actionTaskParamsId: string; } + interface EphemeralActionTaskExecutorParams { spaceId: string; taskParams: ActionTaskParams; diff --git a/x-pack/plugins/alerting/server/routes/aggregate_rules.ts b/x-pack/plugins/alerting/server/routes/aggregate_rules.ts index 5bba2b714d4d073..312def72dd65e43 100644 --- a/x-pack/plugins/alerting/server/routes/aggregate_rules.ts +++ b/x-pack/plugins/alerting/server/routes/aggregate_rules.ts @@ -73,7 +73,7 @@ export const aggregateRulesRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const options = rewriteQueryReq({ ...req.query, has_reference: req.query.has_reference || undefined, diff --git a/x-pack/plugins/alerting/server/routes/create_rule.ts b/x-pack/plugins/alerting/server/routes/create_rule.ts index 5278f748f0ce408..cf044c94f2529da 100644 --- a/x-pack/plugins/alerting/server/routes/create_rule.ts +++ b/x-pack/plugins/alerting/server/routes/create_rule.ts @@ -110,7 +110,7 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const rule = req.body; const params = req.params; diff --git a/x-pack/plugins/alerting/server/routes/delete_rule.ts b/x-pack/plugins/alerting/server/routes/delete_rule.ts index 278bd031a8d6f06..e4ccd491046d1a5 100644 --- a/x-pack/plugins/alerting/server/routes/delete_rule.ts +++ b/x-pack/plugins/alerting/server/routes/delete_rule.ts @@ -28,7 +28,7 @@ export const deleteRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; await rulesClient.delete({ id }); return res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/disable_rule.ts b/x-pack/plugins/alerting/server/routes/disable_rule.ts index 6e6700c3ece4d09..99795e7ee2bf279 100644 --- a/x-pack/plugins/alerting/server/routes/disable_rule.ts +++ b/x-pack/plugins/alerting/server/routes/disable_rule.ts @@ -28,7 +28,7 @@ export const disableRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.disable({ id }); diff --git a/x-pack/plugins/alerting/server/routes/enable_rule.ts b/x-pack/plugins/alerting/server/routes/enable_rule.ts index f3b3c5bfbefdc60..84a4086cd245c6a 100644 --- a/x-pack/plugins/alerting/server/routes/enable_rule.ts +++ b/x-pack/plugins/alerting/server/routes/enable_rule.ts @@ -28,7 +28,7 @@ export const enableRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.enable({ id }); diff --git a/x-pack/plugins/alerting/server/routes/find_rules.ts b/x-pack/plugins/alerting/server/routes/find_rules.ts index 2c5819f7b71153c..ef8b8b29057c0fc 100644 --- a/x-pack/plugins/alerting/server/routes/find_rules.ts +++ b/x-pack/plugins/alerting/server/routes/find_rules.ts @@ -140,7 +140,7 @@ const buildFindRulesRoute = ({ }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); trackLegacyTerminology( [req.query.search, req.query.search_fields, req.query.sort_field].filter( diff --git a/x-pack/plugins/alerting/server/routes/get_rule.ts b/x-pack/plugins/alerting/server/routes/get_rule.ts index 189401f03815cc9..f4414b0364dcbec 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule.ts @@ -85,7 +85,7 @@ const buildGetRuleRoute = ({ }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; const rule = await rulesClient.get({ id, excludeFromPublicApi }); return res.ok({ diff --git a/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.ts b/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.ts index 033c0f178cef77d..c0d31d1ccbfac56 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_alert_summary.ts @@ -72,7 +72,7 @@ export const getRuleAlertSummaryRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; const summary = await rulesClient.getAlertSummary(rewriteReq({ id, ...req.query })); return res.ok({ body: rewriteBodyRes(summary) }); diff --git a/x-pack/plugins/alerting/server/routes/get_rule_execution_log.ts b/x-pack/plugins/alerting/server/routes/get_rule_execution_log.ts index 6f07c8daa14e7fc..650bdd83a0a8360 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_execution_log.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_execution_log.ts @@ -67,7 +67,7 @@ export const getRuleExecutionLogRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; return res.ok({ body: await rulesClient.getExecutionLogForRule(rewriteReq({ id, ...req.query })), diff --git a/x-pack/plugins/alerting/server/routes/get_rule_state.ts b/x-pack/plugins/alerting/server/routes/get_rule_state.ts index 5f9bee59c4e7083..50ad1f776110ef6 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule_state.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule_state.ts @@ -44,7 +44,7 @@ export const getRuleStateRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; const state = await rulesClient.getAlertState({ id }); return state ? res.ok({ body: rewriteBodyRes(state) }) : res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/health.ts b/x-pack/plugins/alerting/server/routes/health.ts index 4d9fcde896281bc..4d3934911221ee0 100644 --- a/x-pack/plugins/alerting/server/routes/health.ts +++ b/x-pack/plugins/alerting/server/routes/health.ts @@ -52,15 +52,16 @@ export const healthRoute = ( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { try { + const alertingContext = await context.alerting; // Verify that user has access to at least one rule type - const ruleTypes = Array.from(await context.alerting.getRulesClient().listAlertTypes()); + const ruleTypes = Array.from(await alertingContext.getRulesClient().listAlertTypes()); if (ruleTypes.length > 0) { - const alertingFrameworkHealth = await context.alerting.getFrameworkHealth(); + const alertingFrameworkHealth = await alertingContext.getFrameworkHealth(); const securityHealth = await getSecurityHealth( async () => (licenseState ? licenseState.getIsSecurityEnabled() : null), async () => encryptedSavedObjects.canEncrypt, - context.alerting.areApiKeysEnabled + alertingContext.areApiKeysEnabled ); const frameworkHealth: AlertingFrameworkHealth = { diff --git a/x-pack/plugins/alerting/server/routes/legacy/aggregate.ts b/x-pack/plugins/alerting/server/routes/legacy/aggregate.ts index 67bb1a416d1c002..ba520cc40126228 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/aggregate.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/aggregate.ts @@ -53,7 +53,7 @@ export const aggregateAlertRoute = ( if (!context.alerting) { return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); trackLegacyRouteUsage('aggregate', usageCounter); trackLegacyTerminology( diff --git a/x-pack/plugins/alerting/server/routes/legacy/create.ts b/x-pack/plugins/alerting/server/routes/legacy/create.ts index fb56279eaabc769..e7583033ae4bacb 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/create.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/create.ts @@ -64,7 +64,7 @@ export const createAlertRoute = ({ router, licenseState, usageCounter }: RouteOp if (!context.alerting) { return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const alert = req.body; const params = req.params; const notifyWhen = alert?.notifyWhen ? (alert.notifyWhen as RuleNotifyWhenType) : null; diff --git a/x-pack/plugins/alerting/server/routes/legacy/delete.ts b/x-pack/plugins/alerting/server/routes/legacy/delete.ts index 4e29ded6951815e..4fcf85678db53f7 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/delete.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/delete.ts @@ -35,7 +35,7 @@ export const deleteAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('delete', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; await rulesClient.delete({ id }); return res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/legacy/disable.ts b/x-pack/plugins/alerting/server/routes/legacy/disable.ts index b9ad5765e977ef3..5572220eb217111 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/disable.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/disable.ts @@ -36,7 +36,7 @@ export const disableAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('disable', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.disable({ id }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/enable.ts b/x-pack/plugins/alerting/server/routes/legacy/enable.ts index 6835be0631cb2a4..eb86b5db65da1cf 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/enable.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/enable.ts @@ -38,7 +38,7 @@ export const enableAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('enable', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.enable({ id }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/find.ts b/x-pack/plugins/alerting/server/routes/legacy/find.ts index e6d57572a223873..9a33f5b2dc5fd2b 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/find.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/find.ts @@ -66,7 +66,7 @@ export const findAlertRoute = ( ) as string[], usageCounter ); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const query = req.query; const renameMap = { diff --git a/x-pack/plugins/alerting/server/routes/legacy/get.ts b/x-pack/plugins/alerting/server/routes/legacy/get.ts index 82b56030de4cdbc..62fdde550714894 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get.ts @@ -35,7 +35,7 @@ export const getAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('get', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; return res.ok({ body: await rulesClient.get({ id, excludeFromPublicApi: true }), diff --git a/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts b/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts index 7d467aed1b3fd9b..c33aea8060d777f 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts @@ -46,7 +46,7 @@ export const getAlertInstanceSummaryRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('instanceSummary', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; const { dateStart } = req.query; const summary = await rulesClient.getAlertSummary({ id, dateStart }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts b/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts index 49a0daf5ea1803b..86a56403b39ae5f 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts @@ -35,7 +35,7 @@ export const getAlertStateRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('state', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; const state = await rulesClient.getAlertState({ id }); return state ? res.ok({ body: state }) : res.noContent(); diff --git a/x-pack/plugins/alerting/server/routes/legacy/health.ts b/x-pack/plugins/alerting/server/routes/legacy/health.ts index e9f770b437caaa1..02b8c8279b81597 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/health.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/health.ts @@ -32,15 +32,16 @@ export function healthRoute( } trackLegacyRouteUsage('health', usageCounter); try { + const alertingContext = await context.alerting; // Verify that user has access to at least one rule type - const ruleTypes = Array.from(await context.alerting.getRulesClient().listAlertTypes()); + const ruleTypes = Array.from(await alertingContext.getRulesClient().listAlertTypes()); if (ruleTypes.length > 0) { - const alertingFrameworkHealth = await context.alerting.getFrameworkHealth(); + const alertingFrameworkHealth = await alertingContext.getFrameworkHealth(); const securityHealth = await getSecurityHealth( async () => (licenseState ? licenseState.getIsSecurityEnabled() : null), async () => encryptedSavedObjects.canEncrypt, - context.alerting.areApiKeysEnabled + alertingContext.areApiKeysEnabled ); const frameworkHealth: AlertingFrameworkHealth = { diff --git a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts index 5c0ef90ccc5e244..8cfef8af462478c 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts @@ -27,8 +27,9 @@ export const listAlertTypesRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('listAlertTypes', usageCounter); + const alertingContext = await context.alerting; return res.ok({ - body: Array.from(await context.alerting.getRulesClient().listAlertTypes()), + body: Array.from(await alertingContext.getRulesClient().listAlertTypes()), }); }) ); diff --git a/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts b/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts index 2b16b332c9cbb8e..dcbc0c19dbe359c 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts @@ -36,7 +36,7 @@ export const muteAllAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('muteAll', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.muteAll({ id }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts b/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts index 50c4a3de95893cb..f6c6a28ecc8655c 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts @@ -41,7 +41,7 @@ export const muteAlertInstanceRoute = ( trackLegacyRouteUsage('muteInstance', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const renameMap = { alert_id: 'alertId', diff --git a/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts b/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts index 34297624b45d6c8..31f82849ea1da44 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts @@ -36,7 +36,7 @@ export const unmuteAllAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('unmuteAll', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.unmuteAll({ id }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts b/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts index 8f3b1f2413953d4..4d5b9b02da5f157 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts @@ -37,7 +37,7 @@ export const unmuteAlertInstanceRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('unmuteInstance', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { alertId, alertInstanceId } = req.params; try { await rulesClient.unmuteInstance({ alertId, alertInstanceId }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/update.ts b/x-pack/plugins/alerting/server/routes/legacy/update.ts index 415d2f0af4a6099..07bde524076c170 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update.ts @@ -64,7 +64,7 @@ export const updateAlertRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('update', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; const { name, actions, params, schedule, tags, throttle, notifyWhen } = req.body; try { diff --git a/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts b/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts index 3c288219812cac8..f0f7716b00771ea 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts @@ -38,7 +38,7 @@ export const updateApiKeyRoute = ( return res.badRequest({ body: 'RouteHandlerContext is not registered for alerting' }); } trackLegacyRouteUsage('updateApiKey', usageCounter); - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.updateApiKey({ id }); diff --git a/x-pack/plugins/alerting/server/routes/mute_alert.ts b/x-pack/plugins/alerting/server/routes/mute_alert.ts index a90dc77e5fb6b86..22d9a1670dde51f 100644 --- a/x-pack/plugins/alerting/server/routes/mute_alert.ts +++ b/x-pack/plugins/alerting/server/routes/mute_alert.ts @@ -38,7 +38,7 @@ export const muteAlertRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const params = rewriteParamsReq(req.params); try { await rulesClient.muteInstance(params); diff --git a/x-pack/plugins/alerting/server/routes/mute_all_rule.ts b/x-pack/plugins/alerting/server/routes/mute_all_rule.ts index e9d64ce3e30f00e..41b561db0b2fd6e 100644 --- a/x-pack/plugins/alerting/server/routes/mute_all_rule.ts +++ b/x-pack/plugins/alerting/server/routes/mute_all_rule.ts @@ -31,7 +31,7 @@ export const muteAllRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; trackDeprecatedRouteUsage('muteAll', usageCounter); try { diff --git a/x-pack/plugins/alerting/server/routes/resolve_rule.ts b/x-pack/plugins/alerting/server/routes/resolve_rule.ts index 02c70c555fc0d5a..cde747f9272fe60 100644 --- a/x-pack/plugins/alerting/server/routes/resolve_rule.ts +++ b/x-pack/plugins/alerting/server/routes/resolve_rule.ts @@ -73,7 +73,7 @@ export const resolveRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; const rule = await rulesClient.resolve({ id }); return res.ok({ diff --git a/x-pack/plugins/alerting/server/routes/rule_types.ts b/x-pack/plugins/alerting/server/routes/rule_types.ts index f78a0ef3ee89e56..5d6c9e9a3f0f476 100644 --- a/x-pack/plugins/alerting/server/routes/rule_types.ts +++ b/x-pack/plugins/alerting/server/routes/rule_types.ts @@ -54,7 +54,8 @@ export const ruleTypesRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const ruleTypes = Array.from(await context.alerting.getRulesClient().listAlertTypes()); + const rulesClient = (await context.alerting).getRulesClient(); + const ruleTypes = Array.from(await rulesClient.listAlertTypes()); return res.ok({ body: rewriteBodyRes(ruleTypes), }); diff --git a/x-pack/plugins/alerting/server/routes/snooze_rule.ts b/x-pack/plugins/alerting/server/routes/snooze_rule.ts index ed717de973c9a85..a408a4d3175dffb 100644 --- a/x-pack/plugins/alerting/server/routes/snooze_rule.ts +++ b/x-pack/plugins/alerting/server/routes/snooze_rule.ts @@ -44,7 +44,7 @@ export const snoozeRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const params = req.params; const body = rewriteBodyReq(req.body); try { diff --git a/x-pack/plugins/alerting/server/routes/unmute_alert.ts b/x-pack/plugins/alerting/server/routes/unmute_alert.ts index 6b02674de0267d0..1e4191745f621fb 100644 --- a/x-pack/plugins/alerting/server/routes/unmute_alert.ts +++ b/x-pack/plugins/alerting/server/routes/unmute_alert.ts @@ -38,7 +38,7 @@ export const unmuteAlertRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const params = rewriteParamsReq(req.params); try { await rulesClient.unmuteInstance(params); diff --git a/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts b/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts index bead959a6d7d8df..4e102f96cf38106 100644 --- a/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts +++ b/x-pack/plugins/alerting/server/routes/unmute_all_rule.ts @@ -28,7 +28,7 @@ export const unmuteAllRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.unmuteAll({ id }); diff --git a/x-pack/plugins/alerting/server/routes/unsnooze_rule.ts b/x-pack/plugins/alerting/server/routes/unsnooze_rule.ts index f0c1a9a12ac505c..b91fb24bea56a7b 100644 --- a/x-pack/plugins/alerting/server/routes/unsnooze_rule.ts +++ b/x-pack/plugins/alerting/server/routes/unsnooze_rule.ts @@ -28,7 +28,7 @@ export const unsnoozeRuleRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const params = req.params; try { await rulesClient.unsnooze({ ...params }); diff --git a/x-pack/plugins/alerting/server/routes/update_rule.ts b/x-pack/plugins/alerting/server/routes/update_rule.ts index f58e61b5d1ac2e6..d2130e1f3354102 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule.ts @@ -119,7 +119,7 @@ export const updateRuleRoute = ( handleDisabledApiKeysError( router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; const rule = req.body; try { diff --git a/x-pack/plugins/alerting/server/routes/update_rule_api_key.ts b/x-pack/plugins/alerting/server/routes/update_rule_api_key.ts index af10d97bc2a9799..4e99b54e76af400 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule_api_key.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule_api_key.ts @@ -28,7 +28,7 @@ export const updateRuleApiKeyRoute = ( }, router.handleLegacyErrors( verifyAccessAndContext(licenseState, async function (context, req, res) { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const { id } = req.params; try { await rulesClient.updateApiKey({ id }); diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index 7469bdfd9827771..32c6e41c63268e9 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -7,18 +7,16 @@ import type { IRouter, - RequestHandlerContext, + CustomRequestHandlerContext, SavedObjectReference, IUiSettingsClient, -} from '@kbn/core/server'; -import type { PublicMethodsOf } from '@kbn/utility-types'; -import { ISearchStartSearchSource } from '@kbn/data-plugin/common'; -import { LicenseType } from '@kbn/licensing-plugin/server'; -import { IScopedClusterClient, SavedObjectAttributes, SavedObjectsClientContract, } from '@kbn/core/server'; +import type { PublicMethodsOf } from '@kbn/utility-types'; +import { ISearchStartSearchSource } from '@kbn/data-plugin/common'; +import { LicenseType } from '@kbn/licensing-plugin/server'; import { AlertFactoryDoneUtils, PublicAlert } from './alert'; import { RuleTypeRegistry as OrigruleTypeRegistry } from './rule_type_registry'; import { PluginSetupContract, PluginStartContract } from './plugin'; @@ -60,9 +58,9 @@ export interface AlertingApiRequestHandlerContext { /** * @internal */ -export interface AlertingRequestHandlerContext extends RequestHandlerContext { +export type AlertingRequestHandlerContext = CustomRequestHandlerContext<{ alerting: AlertingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts index f494a39956f2b86..522fd5c078af397 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts @@ -21,14 +21,16 @@ import { cancelEsRequestOnAbort } from '../cancel_es_request_on_abort'; export type APMIndexDocumentParams = estypes.IndexRequest; -export type APMInternalClient = ReturnType; +export type APMInternalClient = Awaited< + ReturnType +>; -export function createInternalESClient({ +export async function createInternalESClient({ context, debug, request, }: Pick & { debug: boolean }) { - const { asInternalUser } = context.core.elasticsearch.client; + const { asInternalUser } = (await context.core).elasticsearch.client; function callEs( operationName: string, diff --git a/x-pack/plugins/apm/server/lib/helpers/setup_request.ts b/x-pack/plugins/apm/server/lib/helpers/setup_request.ts index a3eb942111a480b..2701d754350f5f4 100644 --- a/x-pack/plugins/apm/server/lib/helpers/setup_request.ts +++ b/x-pack/plugins/apm/server/lib/helpers/setup_request.ts @@ -42,36 +42,38 @@ export async function setupRequest({ }: APMRouteHandlerResources) { return withApmSpan('setup_request', async () => { const { query } = params; + const coreContext = await context.core; + const licensingContext = await context.licensing; const [indices, includeFrozen] = await Promise.all([ getApmIndices({ - savedObjectsClient: context.core.savedObjects.client, + savedObjectsClient: coreContext.savedObjects.client, config, }), withApmSpan('get_ui_settings', () => - context.core.uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN) + coreContext.uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN) ), ]); return { indices, apmEventClient: new APMEventClient({ - esClient: context.core.elasticsearch.client.asCurrentUser, + esClient: coreContext.elasticsearch.client.asCurrentUser, debug: query._inspect, request, indices, options: { includeFrozen }, }), - internalClient: createInternalESClient({ + internalClient: await createInternalESClient({ context, request, debug: query._inspect, }), ml: - plugins.ml && isActivePlatinumLicense(context.licensing.license) + plugins.ml && isActivePlatinumLicense(licensingContext.license) ? getMlSetup( plugins.ml.setup, - context.core.savedObjects.client, + coreContext.savedObjects.client, request ) : undefined, @@ -82,7 +84,9 @@ export async function setupRequest({ function getMlSetup( ml: Required['ml']['setup'], - savedObjectsClient: APMRouteHandlerResources['context']['core']['savedObjects']['client'], + savedObjectsClient: Awaited< + APMRouteHandlerResources['context']['core'] + >['savedObjects']['client'], request: KibanaRequest ) { return { diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index bc4c0d30a9a81c5..ad058a535206ed7 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -218,12 +218,13 @@ export class APMPlugin request: KibanaRequest; context: ApmPluginRequestHandlerContext; }) => { + const coreContext = await context.core; const [indices, includeFrozen] = await Promise.all([ boundGetApmIndices(), - context.core.uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN), + coreContext.uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN), ]); - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = coreContext.elasticsearch.client.asCurrentUser; return new APMEventClient({ debug: debug ?? false, diff --git a/x-pack/plugins/apm/server/routes/agent_keys/create_agent_key.ts b/x-pack/plugins/apm/server/routes/agent_keys/create_agent_key.ts index 3b47b81a86416eb..0bcd85a88ce8cd6 100644 --- a/x-pack/plugins/apm/server/routes/agent_keys/create_agent_key.ts +++ b/x-pack/plugins/apm/server/routes/agent_keys/create_agent_key.ts @@ -26,6 +26,7 @@ export async function createAgentKey({ privileges, resources: [resource], }; + const coreContext = await context.core; // Elasticsearch will allow a user without the right apm privileges to create API keys, but the keys won't validate // check first whether the user has the right privileges, and bail out early if not @@ -33,7 +34,7 @@ export async function createAgentKey({ application: userApplicationPrivileges, username, has_all_requested: hasRequiredPrivileges, - } = await context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges( + } = await coreContext.elasticsearch.client.asCurrentUser.security.hasPrivileges( { body: { application: [application], @@ -80,11 +81,9 @@ export async function createAgentKey({ }; const agentKey = - await context.core.elasticsearch.client.asCurrentUser.security.createApiKey( - { - body, - } - ); + await coreContext.elasticsearch.client.asCurrentUser.security.createApiKey({ + body, + }); return { agentKey, diff --git a/x-pack/plugins/apm/server/routes/agent_keys/get_agent_keys.ts b/x-pack/plugins/apm/server/routes/agent_keys/get_agent_keys.ts index ee01876d743d4bd..239cc6ca896c4b5 100644 --- a/x-pack/plugins/apm/server/routes/agent_keys/get_agent_keys.ts +++ b/x-pack/plugins/apm/server/routes/agent_keys/get_agent_keys.ts @@ -27,7 +27,7 @@ export async function getAgentKeys({ }, }; - const esClient = context.core.elasticsearch.client; + const esClient = (await context.core).elasticsearch.client; const apiResponse = await esClient.asCurrentUser.transport.request<{ api_keys: ApiKey[]; }>({ diff --git a/x-pack/plugins/apm/server/routes/agent_keys/get_agent_keys_privileges.ts b/x-pack/plugins/apm/server/routes/agent_keys/get_agent_keys_privileges.ts index 29514739f222513..c9fba5d6ec71e38 100644 --- a/x-pack/plugins/apm/server/routes/agent_keys/get_agent_keys_privileges.ts +++ b/x-pack/plugins/apm/server/routes/agent_keys/get_agent_keys_privileges.ts @@ -15,8 +15,9 @@ export async function getAgentKeysPrivileges({ context: ApmPluginRequestHandlerContext; securityPluginStart: NonNullable; }) { + const esClient = (await context.core).elasticsearch.client; const [securityHasPrivilegesResponse, areApiKeysEnabled] = await Promise.all([ - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + esClient.asCurrentUser.security.hasPrivileges({ body: { cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'], }, diff --git a/x-pack/plugins/apm/server/routes/agent_keys/invalidate_agent_key.ts b/x-pack/plugins/apm/server/routes/agent_keys/invalidate_agent_key.ts index ec244f8e9bee38b..95ee67f0dff37e3 100644 --- a/x-pack/plugins/apm/server/routes/agent_keys/invalidate_agent_key.ts +++ b/x-pack/plugins/apm/server/routes/agent_keys/invalidate_agent_key.ts @@ -15,12 +15,11 @@ export async function invalidateAgentKey({ id: string; isAdmin: boolean; }) { + const esClient = (await context.core).elasticsearch.client; const { invalidated_api_keys: invalidatedAgentKeys } = - await context.core.elasticsearch.client.asCurrentUser.security.invalidateApiKey( - { - body: { ids: [id], owner: !isAdmin }, - } - ); + await esClient.asCurrentUser.security.invalidateApiKey({ + body: { ids: [id], owner: !isAdmin }, + }); return { invalidatedAgentKeys, diff --git a/x-pack/plugins/apm/server/routes/correlations/route.ts b/x-pack/plugins/apm/server/routes/correlations/route.ts index 897ca65c37ca14f..b2bca48574f5dae 100644 --- a/x-pack/plugins/apm/server/routes/correlations/route.ts +++ b/x-pack/plugins/apm/server/routes/correlations/route.ts @@ -57,12 +57,14 @@ const fieldCandidatesRoute = createApmServerRoute({ options: { tags: ['access:apm'] }, handler: async (resources): Promise<{ fieldCandidates: string[] }> => { const { context } = resources; - if (!isActivePlatinumLicense(context.licensing.license)) { + const { license } = await context.licensing; + if (!isActivePlatinumLicense(license)) { throw Boom.forbidden(INVALID_LICENSE); } const { indices } = await setupRequest(resources); - const esClient = resources.context.core.elasticsearch.client.asCurrentUser; + const esClient = (await resources.context.core).elasticsearch.client + .asCurrentUser; return withApmSpan( 'get_correlations_field_candidates', @@ -102,12 +104,14 @@ const fieldStatsRoute = createApmServerRoute({ errors: any[]; }> => { const { context } = resources; - if (!isActivePlatinumLicense(context.licensing.license)) { + const { license } = await context.licensing; + if (!isActivePlatinumLicense(license)) { throw Boom.forbidden(INVALID_LICENSE); } const { indices } = await setupRequest(resources); - const esClient = resources.context.core.elasticsearch.client.asCurrentUser; + const esClient = (await resources.context.core).elasticsearch.client + .asCurrentUser; const { fieldsToSample, ...params } = resources.params.body; @@ -151,12 +155,14 @@ const fieldValueStatsRoute = createApmServerRoute({ import('./../../../common/correlations/field_stats_types').TopValuesStats > => { const { context } = resources; - if (!isActivePlatinumLicense(context.licensing.license)) { + const { license } = await context.licensing; + if (!isActivePlatinumLicense(license)) { throw Boom.forbidden(INVALID_LICENSE); } const { indices } = await setupRequest(resources); - const esClient = resources.context.core.elasticsearch.client.asCurrentUser; + const esClient = (await resources.context.core).elasticsearch.client + .asCurrentUser; const { fieldName, fieldValue, ...params } = resources.params.query; @@ -202,12 +208,14 @@ const fieldValuePairsRoute = createApmServerRoute({ errors: any[]; }> => { const { context } = resources; - if (!isActivePlatinumLicense(context.licensing.license)) { + const { license } = await context.licensing; + if (!isActivePlatinumLicense(license)) { throw Boom.forbidden(INVALID_LICENSE); } const { indices } = await setupRequest(resources); - const esClient = resources.context.core.elasticsearch.client.asCurrentUser; + const esClient = (await resources.context.core).elasticsearch.client + .asCurrentUser; const { fieldCandidates, ...params } = resources.params.body; @@ -260,12 +268,14 @@ const significantCorrelationsRoute = createApmServerRoute({ fallbackResult?: import('./../../../common/correlations/latency_correlations/types').LatencyCorrelation; }> => { const { context } = resources; - if (!isActivePlatinumLicense(context.licensing.license)) { + const { license } = await context.licensing; + if (!isActivePlatinumLicense(license)) { throw Boom.forbidden(INVALID_LICENSE); } const { indices } = await setupRequest(resources); - const esClient = resources.context.core.elasticsearch.client.asCurrentUser; + const esClient = (await resources.context.core).elasticsearch.client + .asCurrentUser; const { fieldValuePairs, ...params } = resources.params.body; @@ -318,12 +328,14 @@ const pValuesRoute = createApmServerRoute({ fallbackResult?: import('./../../../common/correlations/failed_transactions_correlations/types').FailedTransactionsCorrelation; }> => { const { context } = resources; - if (!isActivePlatinumLicense(context.licensing.license)) { + const { license } = await context.licensing; + if (!isActivePlatinumLicense(license)) { throw Boom.forbidden(INVALID_LICENSE); } const { indices } = await setupRequest(resources); - const esClient = resources.context.core.elasticsearch.client.asCurrentUser; + const esClient = (await resources.context.core).elasticsearch.client + .asCurrentUser; const { fieldCandidates, ...params } = resources.params.body; diff --git a/x-pack/plugins/apm/server/routes/data_view/get_dynamic_data_view.ts b/x-pack/plugins/apm/server/routes/data_view/get_dynamic_data_view.ts index 6a0d52eadd22800..8d2c61cce4d8130 100644 --- a/x-pack/plugins/apm/server/routes/data_view/get_dynamic_data_view.ts +++ b/x-pack/plugins/apm/server/routes/data_view/get_dynamic_data_view.ts @@ -23,14 +23,15 @@ export const getDynamicDataView = ({ logger, }: Pick) => { return withApmSpan('get_dynamic_data_view', async () => { + const coreContext = await context.core; const apmIndicies = await getApmIndices({ - savedObjectsClient: context.core.savedObjects.client, + savedObjectsClient: coreContext.savedObjects.client, config, }); const dataViewTitle = getApmDataViewTitle(apmIndicies); const DataViewsFetcher = new IndexPatternsFetcher( - context.core.elasticsearch.client.asCurrentUser + coreContext.elasticsearch.client.asCurrentUser ); // Since `getDynamicDataView` is called in setup_request (and thus by every endpoint) diff --git a/x-pack/plugins/apm/server/routes/environments/route.ts b/x-pack/plugins/apm/server/routes/environments/route.ts index f8be45ecf0d5945..03fb07fd51cb84d 100644 --- a/x-pack/plugins/apm/server/routes/environments/route.ts +++ b/x-pack/plugins/apm/server/routes/environments/route.ts @@ -46,7 +46,8 @@ const environmentsRoute = createApmServerRoute({ end, kuery: '', }); - const size = await context.core.uiSettings.client.get( + const coreContext = await context.core; + const size = await coreContext.uiSettings.client.get( maxSuggestions ); const environments = await getEnvironments({ diff --git a/x-pack/plugins/apm/server/routes/fleet/route.ts b/x-pack/plugins/apm/server/routes/fleet/route.ts index 2b6412647641cf5..76f05d50fff416b 100644 --- a/x-pack/plugins/apm/server/routes/fleet/route.ts +++ b/x-pack/plugins/apm/server/routes/fleet/route.ts @@ -157,7 +157,7 @@ const getUnsupportedApmServerSchemaRoute = createApmServerRoute({ resources ): Promise<{ unsupported: Array<{ key: string; value: any }> }> => { const { context } = resources; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; return { unsupported: await getUnsupportedApmServerSchema({ savedObjectsClient }), }; @@ -185,7 +185,7 @@ const getMigrationCheckRoute = createApmServerRoute({ if (!plugins.fleet || !plugins.security) { throw Boom.internal(FLEET_SECURITY_REQUIRED_MESSAGE); } - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const [fleetPluginStart, securityPluginStart] = await Promise.all([ plugins.fleet.start(), plugins.security.start(), @@ -231,7 +231,7 @@ const createCloudApmPackagePolicyRoute = createApmServerRoute({ if (!plugins.fleet || !plugins.security) { throw Boom.internal(FLEET_SECURITY_REQUIRED_MESSAGE); } - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const coreStart = await resources.core.start(); const esClient = coreStart.elasticsearch.client.asScoped( resources.request diff --git a/x-pack/plugins/apm/server/routes/service_groups/route.ts b/x-pack/plugins/apm/server/routes/service_groups/route.ts index b9e6a238ba2615d..160aea5abfe7032 100644 --- a/x-pack/plugins/apm/server/routes/service_groups/route.ts +++ b/x-pack/plugins/apm/server/routes/service_groups/route.ts @@ -28,7 +28,7 @@ const serviceGroupsRoute = createApmServerRoute({ resources ): Promise<{ serviceGroups: SavedServiceGroup[] }> => { const { context } = resources; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const serviceGroups = await getServiceGroups({ savedObjectsClient }); return { serviceGroups }; }, @@ -46,7 +46,7 @@ const serviceGroupRoute = createApmServerRoute({ }, handler: async (resources): Promise<{ serviceGroup: SavedServiceGroup }> => { const { context, params } = resources; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const serviceGroup = await getServiceGroup({ savedObjectsClient, serviceGroupId: params.query.serviceGroup, @@ -75,7 +75,7 @@ const serviceGroupSaveRoute = createApmServerRoute({ handler: async (resources): Promise => { const { context, params } = resources; const { start, end, serviceGroupId } = params.query; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const setup = await setupRequest(resources); const items = await lookupServices({ setup, @@ -107,7 +107,7 @@ const serviceGroupDeleteRoute = createApmServerRoute({ handler: async (resources): Promise => { const { context, params } = resources; const { serviceGroupId } = params.query; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; await deleteServiceGroup({ savedObjectsClient, serviceGroupId, diff --git a/x-pack/plugins/apm/server/routes/service_map/route.ts b/x-pack/plugins/apm/server/routes/service_map/route.ts index b357958d219a9fa..0bad4c251fddbe8 100644 --- a/x-pack/plugins/apm/server/routes/service_map/route.ts +++ b/x-pack/plugins/apm/server/routes/service_map/route.ts @@ -88,12 +88,14 @@ const serviceMapRoute = createApmServerRoute({ if (!config.serviceMapEnabled) { throw Boom.notFound(); } - if (!isActivePlatinumLicense(context.licensing.license)) { + + const licensingContext = await context.licensing; + if (!isActivePlatinumLicense(licensingContext.license)) { throw Boom.forbidden(invalidLicenseMessage); } notifyFeatureUsage({ - licensingPlugin: context.licensing, + licensingPlugin: licensingContext, featureName: 'serviceMaps', }); @@ -107,7 +109,7 @@ const serviceMapRoute = createApmServerRoute({ }, } = params; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const [setup, serviceGroup] = await Promise.all([ setupRequest(resources), serviceGroupId @@ -164,7 +166,9 @@ const serviceMapServiceNodeRoute = createApmServerRoute({ if (!config.serviceMapEnabled) { throw Boom.notFound(); } - if (!isActivePlatinumLicense(context.licensing.license)) { + + const licensingContext = await context.licensing; + if (!isActivePlatinumLicense(licensingContext.license)) { throw Boom.forbidden(invalidLicenseMessage); } const setup = await setupRequest(resources); @@ -226,7 +230,8 @@ const serviceMapBackendNodeRoute = createApmServerRoute({ if (!config.serviceMapEnabled) { throw Boom.notFound(); } - if (!isActivePlatinumLicense(context.licensing.license)) { + const licensingContext = await context.licensing; + if (!isActivePlatinumLicense(licensingContext.license)) { throw Boom.forbidden(invalidLicenseMessage); } const setup = await setupRequest(resources); diff --git a/x-pack/plugins/apm/server/routes/services/route.ts b/x-pack/plugins/apm/server/routes/services/route.ts index 0bcdca6e3cb891d..63a52da218d1ab6 100644 --- a/x-pack/plugins/apm/server/routes/services/route.ts +++ b/x-pack/plugins/apm/server/routes/services/route.ts @@ -113,7 +113,7 @@ const servicesRoute = createApmServerRoute({ serviceGroup: serviceGroupId, probability, } = params.query; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const [setup, serviceGroup] = await Promise.all([ setupRequest(resources), @@ -403,6 +403,7 @@ const serviceAnnotationsRoute = createApmServerRoute({ const { params, plugins, context, request, logger } = resources; const { serviceName } = params.path; const { environment, start, end } = params.query; + const esClient = (await context.core).elasticsearch.client; const { observability } = plugins; @@ -431,7 +432,7 @@ const serviceAnnotationsRoute = createApmServerRoute({ searchAggregatedTransactions, serviceName, annotationsClient, - client: context.core.elasticsearch.client.asCurrentUser, + client: esClient.asCurrentUser, logger, start, end, @@ -1238,7 +1239,8 @@ const sortedAndFilteredServicesRoute = createApmServerRoute({ }; } - const savedObjectsClient = resources.context.core.savedObjects.client; + const savedObjectsClient = (await resources.context.core).savedObjects + .client; const [setup, serviceGroup] = await Promise.all([ setupRequest(resources), diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts index 3618647717e50d3..72869ef165fa242 100644 --- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts +++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts @@ -269,6 +269,7 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({ }> => { const setup = await setupRequest(resources); const { context, params } = resources; + const coreContext = await context.core; const { serviceName, start, end } = params.query; const searchAggregatedTransactions = await getSearchAggregatedTransactions({ @@ -278,7 +279,7 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({ start, end, }); - const size = await context.core.uiSettings.client.get( + const size = await coreContext.uiSettings.client.get( maxSuggestions ); const environments = await getEnvironments({ diff --git a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts index 52e60b0191230d7..fa15ef06ff16a2b 100644 --- a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts +++ b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts @@ -37,8 +37,9 @@ const anomalyDetectionJobsRoute = createApmServerRoute({ }> => { const setup = await setupRequest(resources); const { context } = resources; + const licensingContext = await context.licensing; - if (!isActivePlatinumLicense(context.licensing.license)) { + if (!isActivePlatinumLicense(licensingContext.license)) { throw Boom.forbidden(ML_ERRORS.INVALID_LICENSE); } @@ -69,17 +70,18 @@ const createAnomalyDetectionJobsRoute = createApmServerRoute({ handler: async (resources): Promise<{ jobCreated: true }> => { const { params, context, logger } = resources; const { environments } = params.body; + const licensingContext = await context.licensing; const setup = await setupRequest(resources); - if (!isActivePlatinumLicense(context.licensing.license)) { + if (!isActivePlatinumLicense(licensingContext.license)) { throw Boom.forbidden(ML_ERRORS.INVALID_LICENSE); } await createAnomalyDetectionJobs(setup, environments, logger); notifyFeatureUsage({ - licensingPlugin: context.licensing, + licensingPlugin: licensingContext, featureName: 'ml', }); @@ -93,13 +95,14 @@ const anomalyDetectionEnvironmentsRoute = createApmServerRoute({ options: { tags: ['access:apm'] }, handler: async (resources): Promise<{ environments: string[] }> => { const setup = await setupRequest(resources); + const coreContext = await resources.context.core; const searchAggregatedTransactions = await getSearchAggregatedTransactions({ apmEventClient: setup.apmEventClient, config: setup.config, kuery: '', }); - const size = await resources.context.core.uiSettings.client.get( + const size = await coreContext.uiSettings.client.get( maxSuggestions ); const environments = await getAllEnvironments({ diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts index 840c15ac1bbcd02..bebb92d6b64453e 100644 --- a/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts +++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts @@ -74,9 +74,8 @@ export async function getApmIndexSettings({ ReturnType >; try { - apmIndicesSavedObject = await getApmIndicesSavedObject( - context.core.savedObjects.client - ); + const soClient = (await context.core).savedObjects.client; + apmIndicesSavedObject = await getApmIndicesSavedObject(soClient); } catch (error: any) { if (error.output && error.output.statusCode === 404) { apmIndicesSavedObject = {}; diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts index cc9f8ef76e4de4a..796c4312eb2eaf1 100644 --- a/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts +++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts @@ -46,8 +46,9 @@ const apmIndicesRoute = createApmServerRoute({ import('./../../../../../observability/common/typings').ApmIndicesConfig > => { const { context, config } = resources; + const savedObjectsClient = (await context.core).savedObjects.client; return await getApmIndices({ - savedObjectsClient: context.core.savedObjects.client, + savedObjectsClient, config, }); }, @@ -80,7 +81,7 @@ const saveApmIndicesRoute = createApmServerRoute({ > => { const { params, context } = resources; const { body } = params; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; return await saveApmIndices(savedObjectsClient, body); }, }); diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts index ca111a50ce924ed..1bd6328bdcee5e7 100644 --- a/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts +++ b/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts @@ -54,7 +54,9 @@ const listCustomLinksRoute = createApmServerRoute({ >; }> => { const { context, params } = resources; - if (!isActiveGoldLicense(context.licensing.license)) { + const licensingContext = await context.licensing; + + if (!isActiveGoldLicense(licensingContext.license)) { throw Boom.forbidden(INVALID_LICENSE); } const setup = await setupRequest(resources); @@ -76,14 +78,16 @@ const createCustomLinkRoute = createApmServerRoute({ options: { tags: ['access:apm', 'access:apm_write'] }, handler: async (resources): Promise => { const { context, params } = resources; - if (!isActiveGoldLicense(context.licensing.license)) { + const licensingContext = await context.licensing; + + if (!isActiveGoldLicense(licensingContext.license)) { throw Boom.forbidden(INVALID_LICENSE); } const setup = await setupRequest(resources); const customLink = params.body; notifyFeatureUsage({ - licensingPlugin: context.licensing, + licensingPlugin: licensingContext, featureName: 'customLinks', }); @@ -104,8 +108,9 @@ const updateCustomLinkRoute = createApmServerRoute({ }, handler: async (resources): Promise => { const { params, context } = resources; + const licensingContext = await context.licensing; - if (!isActiveGoldLicense(context.licensing.license)) { + if (!isActiveGoldLicense(licensingContext.license)) { throw Boom.forbidden(INVALID_LICENSE); } const setup = await setupRequest(resources); @@ -133,8 +138,9 @@ const deleteCustomLinkRoute = createApmServerRoute({ }, handler: async (resources): Promise<{ result: string }> => { const { context, params } = resources; + const licensingContext = await context.licensing; - if (!isActiveGoldLicense(context.licensing.license)) { + if (!isActiveGoldLicense(licensingContext.license)) { throw Boom.forbidden(INVALID_LICENSE); } const setup = await setupRequest(resources); diff --git a/x-pack/plugins/apm/server/routes/suggestions/route.ts b/x-pack/plugins/apm/server/routes/suggestions/route.ts index 85e58a815f0d9bd..b49204cd86fc684 100644 --- a/x-pack/plugins/apm/server/routes/suggestions/route.ts +++ b/x-pack/plugins/apm/server/routes/suggestions/route.ts @@ -27,7 +27,8 @@ const suggestionsRoute = createApmServerRoute({ config: setup.config, kuery: '', }); - const size = await context.core.uiSettings.client.get( + const coreContext = await context.core; + const size = await coreContext.uiSettings.client.get( maxSuggestions ); const suggestions = await getSuggestions({ diff --git a/x-pack/plugins/apm/server/routes/typings.ts b/x-pack/plugins/apm/server/routes/typings.ts index dac98c9fd4e14aa..9764b427ee7d707 100644 --- a/x-pack/plugins/apm/server/routes/typings.ts +++ b/x-pack/plugins/apm/server/routes/typings.ts @@ -7,7 +7,7 @@ import { CoreSetup, - RequestHandlerContext, + CustomRequestHandlerContext, Logger, KibanaRequest, CoreStart, @@ -24,11 +24,11 @@ import { } from '../types'; import { UxUIFilters } from '../../common/ux_ui_filter'; -export interface ApmPluginRequestHandlerContext extends RequestHandlerContext { +export type ApmPluginRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; alerting: AlertingApiRequestHandlerContext; rac: RacApiRequestHandlerContext; -} +}>; export interface APMRouteCreateOptions { options: { diff --git a/x-pack/plugins/banners/server/routes/info.ts b/x-pack/plugins/banners/server/routes/info.ts index 94574d538c286d1..17d60cdbc532f1b 100644 --- a/x-pack/plugins/banners/server/routes/info.ts +++ b/x-pack/plugins/banners/server/routes/info.ts @@ -21,11 +21,11 @@ export const registerInfoRoute = (router: BannersRouter, config: BannersConfigTy }, }, async (ctx, req, res) => { - const allowed = isValidLicense(ctx.licensing.license); + const allowed = isValidLicense((await ctx.licensing).license); const bannerConfig = req.auth.isAuthenticated && config.disableSpaceBanners === false - ? await getBannerConfig(ctx.core.uiSettings.client) + ? await getBannerConfig((await ctx.core).uiSettings.client) : config; return res.ok({ diff --git a/x-pack/plugins/banners/server/types.ts b/x-pack/plugins/banners/server/types.ts index e72a5ec99d24331..992a182378d6320 100644 --- a/x-pack/plugins/banners/server/types.ts +++ b/x-pack/plugins/banners/server/types.ts @@ -5,11 +5,11 @@ * 2.0. */ -import { RequestHandlerContext, IRouter } from '@kbn/core/server'; +import { CustomRequestHandlerContext, IRouter } from '@kbn/core/server'; import { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; -export interface BannersRequestHandlerContext extends RequestHandlerContext { +export type BannersRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; export type BannersRouter = IRouter; diff --git a/x-pack/plugins/canvas/server/mocks/workpad_route_context.ts b/x-pack/plugins/canvas/server/mocks/workpad_route_context.ts index 13e4e34b20b6695..fb5ad3285e76612 100644 --- a/x-pack/plugins/canvas/server/mocks/workpad_route_context.ts +++ b/x-pack/plugins/canvas/server/mocks/workpad_route_context.ts @@ -5,9 +5,10 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { CanvasRouteHandlerContext } from '../workpad_route_context'; -export interface MockWorkpadRouteContext extends CanvasRouteHandlerContext { +export interface MockWorkpadRouteContext extends AwaitedProperties { canvas: { workpad: { create: jest.Mock; diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/create.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/create.test.ts index e1175191a4c2c64..69bb51de7d5c549 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/create.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/create.test.ts @@ -6,7 +6,8 @@ */ import sinon from 'sinon'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { AwaitedProperties } from '@kbn/utility-types'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants'; import { initializeCreateCustomElementRoute } from './create'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; @@ -18,7 +19,7 @@ const mockRouteContext = { client: savedObjectsClientMock.create(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; const mockedUUID = '123abc'; const now = new Date(); @@ -54,7 +55,11 @@ describe('POST custom element', () => { body: mockCustomElement, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ ok: true }); @@ -82,7 +87,11 @@ describe('POST custom element', () => { throw mockRouteContext.core.savedObjects.client.errors.createBadRequestError('bad request'); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(400); }); diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/create.ts b/x-pack/plugins/canvas/server/routes/custom_elements/create.ts index 72780ee35e972bc..8164c124e27dcec 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/create.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/create.ts @@ -34,7 +34,8 @@ export function initializeCreateCustomElementRoute(deps: RouteInitializerDeps) { const now = new Date().toISOString(); const { id, ...payload } = customElement; - await context.core.savedObjects.client.create( + const soClient = (await context.core).savedObjects.client; + await soClient.create( CUSTOM_ELEMENT_TYPE, { ...payload, diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/delete.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/delete.test.ts index 95d300ca07edae3..e989f1c7741f649 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/delete.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/delete.test.ts @@ -5,10 +5,11 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants'; import { initializeDeleteCustomElementRoute } from './delete'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { getMockedRouterDeps } from '../test_helpers'; const mockRouteContext = { @@ -17,7 +18,7 @@ const mockRouteContext = { client: savedObjectsClientMock.create(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; describe('DELETE custom element', () => { let routeHandler: RequestHandler; @@ -39,7 +40,11 @@ describe('DELETE custom element', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ ok: true }); @@ -62,7 +67,11 @@ describe('DELETE custom element', () => { throw mockRouteContext.core.savedObjects.client.errors.createBadRequestError('bad request'); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(400); }); diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/delete.ts b/x-pack/plugins/canvas/server/routes/custom_elements/delete.ts index 8e1ae3335c27dbe..60092f2a721f97a 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/delete.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/delete.ts @@ -23,7 +23,8 @@ export function initializeDeleteCustomElementRoute(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - await context.core.savedObjects.client.delete(CUSTOM_ELEMENT_TYPE, request.params.id); + const soClient = (await context.core).savedObjects.client; + await soClient.delete(CUSTOM_ELEMENT_TYPE, request.params.id); return response.ok({ body: okResponse }); }) ); diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/find.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/find.test.ts index e84d7ec758978b8..65a9d528a849df7 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/find.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/find.test.ts @@ -5,9 +5,10 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { initializeFindCustomElementsRoute } from './find'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { getMockedRouterDeps } from '../test_helpers'; const mockRouteContext = { @@ -16,7 +17,7 @@ const mockRouteContext = { client: savedObjectsClientMock.create(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; describe('Find custom element', () => { let routeHandler: RequestHandler; @@ -52,7 +53,11 @@ describe('Find custom element', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(findMock.mock.calls[0][0].search).toBe(`${name}* | ${name}`); expect(findMock.mock.calls[0][0].perPage).toBe(perPage); @@ -88,7 +93,11 @@ describe('Find custom element', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot(` diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/find.ts b/x-pack/plugins/canvas/server/routes/custom_elements/find.ts index edc72208d80756c..0f7f492cef87c49 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/find.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/find.ts @@ -24,7 +24,7 @@ export function initializeFindCustomElementsRoute(deps: RouteInitializerDeps) { }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const { name, page, perPage } = request.query; try { diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/get.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/get.test.ts index 5f70876bd5f6dc4..e12b1840d58c4e6 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/get.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/get.test.ts @@ -5,10 +5,11 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants'; import { initializeGetCustomElementRoute } from './get'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { getMockedRouterDeps } from '../test_helpers'; const mockRouteContext = { @@ -17,7 +18,7 @@ const mockRouteContext = { client: savedObjectsClientMock.create(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; describe('GET custom element', () => { let routeHandler: RequestHandler; @@ -48,7 +49,11 @@ describe('GET custom element', () => { mockRouteContext.core.savedObjects.client = savedObjectsClient; - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot(` @@ -84,7 +89,11 @@ describe('GET custom element', () => { }); mockRouteContext.core.savedObjects.client = savedObjectsClient; - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.payload).toMatchInlineSnapshot(` Object { diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/get.ts b/x-pack/plugins/canvas/server/routes/custom_elements/get.ts index 0fd66da28fab4fc..06696ca017ca8d6 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/get.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/get.ts @@ -23,7 +23,8 @@ export function initializeGetCustomElementRoute(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - const customElement = await context.core.savedObjects.client.get( + const soClient = (await context.core).savedObjects.client; + const customElement = await soClient.get( CUSTOM_ELEMENT_TYPE, request.params.id ); diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/update.test.ts b/x-pack/plugins/canvas/server/routes/custom_elements/update.test.ts index cb984931d548f47..cc24f5ad708abe1 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/update.test.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/update.test.ts @@ -6,11 +6,12 @@ */ import sinon from 'sinon'; +import { AwaitedProperties } from '@kbn/utility-types'; import { CustomElement } from '../../../types'; import { CUSTOM_ELEMENT_TYPE } from '../../../common/lib/constants'; import { initializeUpdateCustomElementRoute } from './update'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { okResponse } from '../ok_response'; import { getMockedRouterDeps } from '../test_helpers'; @@ -20,7 +21,7 @@ const mockRouteContext = { client: savedObjectsClientMock.create(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; const now = new Date(); const nowIso = now.toISOString(); @@ -82,7 +83,11 @@ describe('PUT custom element', () => { mockRouteContext.core.savedObjects.client = savedObjectsClient; - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual(okResponse); @@ -117,7 +122,11 @@ describe('PUT custom element', () => { ); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(404); }); @@ -144,7 +153,11 @@ describe('PUT custom element', () => { throw mockRouteContext.core.savedObjects.client.errors.createBadRequestError('bad request'); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(400); }); diff --git a/x-pack/plugins/canvas/server/routes/custom_elements/update.ts b/x-pack/plugins/canvas/server/routes/custom_elements/update.ts index 1604c7b4083090c..d0c1b8072e1d0c7 100644 --- a/x-pack/plugins/canvas/server/routes/custom_elements/update.ts +++ b/x-pack/plugins/canvas/server/routes/custom_elements/update.ts @@ -37,14 +37,14 @@ export function initializeUpdateCustomElementRoute(deps: RouteInitializerDeps) { const id = request.params.id; const now = new Date().toISOString(); + const soClient = (await context.core).savedObjects.client; - const customElementObject = - await context.core.savedObjects.client.get( - CUSTOM_ELEMENT_TYPE, - id - ); + const customElementObject = await soClient.get( + CUSTOM_ELEMENT_TYPE, + id + ); - await context.core.savedObjects.client.create( + await soClient.create( CUSTOM_ELEMENT_TYPE, { ...customElementObject.attributes, diff --git a/x-pack/plugins/canvas/server/routes/es_fields/es_fields.test.ts b/x-pack/plugins/canvas/server/routes/es_fields/es_fields.test.ts index ec664df330d3114..06a30af03c921ef 100644 --- a/x-pack/plugins/canvas/server/routes/es_fields/es_fields.test.ts +++ b/x-pack/plugins/canvas/server/routes/es_fields/es_fields.test.ts @@ -5,9 +5,10 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { initializeESFieldsRoute } from './es_fields'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; -import { httpServerMock, elasticsearchServiceMock } from '@kbn/core/server/mocks'; +import { httpServerMock, elasticsearchServiceMock, coreMock } from '@kbn/core/server/mocks'; import { getMockedRouterDeps } from '../test_helpers'; const mockRouteContext = { @@ -16,7 +17,7 @@ const mockRouteContext = { client: elasticsearchServiceMock.createScopedClusterClient(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; const path = `api/canvas/workpad/find`; @@ -71,7 +72,11 @@ describe('Retrieve ES Fields', () => { fieldCapsMock.mockResolvedValueOnce(mockResults); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot(` @@ -99,7 +104,11 @@ describe('Retrieve ES Fields', () => { fieldCapsMock.mockResolvedValueOnce(mockResults); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot('Object {}'); @@ -127,7 +136,11 @@ describe('Retrieve ES Fields', () => { fieldCapsMock.mockResolvedValueOnce(mockResults); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot(`Object {}`); @@ -148,7 +161,11 @@ describe('Retrieve ES Fields', () => { fieldCapsMock.mockRejectedValueOnce(new Error('Index not found')); await expect( - routeHandler(mockRouteContext, request, kibanaResponseFactory) + routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ) ).rejects.toThrowError('Index not found'); }); }); diff --git a/x-pack/plugins/canvas/server/routes/es_fields/es_fields.ts b/x-pack/plugins/canvas/server/routes/es_fields/es_fields.ts index f9523cee0ce4d1e..1923d4648a2a3a1 100644 --- a/x-pack/plugins/canvas/server/routes/es_fields/es_fields.ts +++ b/x-pack/plugins/canvas/server/routes/es_fields/es_fields.ts @@ -28,7 +28,7 @@ export function initializeESFieldsRoute(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const { index, fields } = request.query; const config = { diff --git a/x-pack/plugins/canvas/server/routes/templates/list.test.ts b/x-pack/plugins/canvas/server/routes/templates/list.test.ts index eb9703a33a40103..a1480eb0eaea14d 100644 --- a/x-pack/plugins/canvas/server/routes/templates/list.test.ts +++ b/x-pack/plugins/canvas/server/routes/templates/list.test.ts @@ -6,9 +6,10 @@ */ import { badRequest } from '@hapi/boom'; +import { AwaitedProperties } from '@kbn/utility-types'; import { initializeListTemplates } from './list'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { getMockedRouterDeps } from '../test_helpers'; const mockRouteContext = { @@ -17,7 +18,7 @@ const mockRouteContext = { client: savedObjectsClientMock.create(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; describe('Find workpad', () => { let routeHandler: RequestHandler; @@ -50,7 +51,11 @@ describe('Find workpad', () => { path: `api/canvas/templates/list`, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot(` @@ -77,7 +82,11 @@ describe('Find workpad', () => { path: `api/canvas/templates/list`, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(400); expect(response.payload).toMatchInlineSnapshot(` diff --git a/x-pack/plugins/canvas/server/routes/templates/list.ts b/x-pack/plugins/canvas/server/routes/templates/list.ts index 2bff143f127bc9c..c0e32fb3722b11f 100644 --- a/x-pack/plugins/canvas/server/routes/templates/list.ts +++ b/x-pack/plugins/canvas/server/routes/templates/list.ts @@ -21,7 +21,7 @@ export function initializeListTemplates(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const templates = await savedObjectsClient.find({ type: TEMPLATE_TYPE, diff --git a/x-pack/plugins/canvas/server/routes/workpad/create.test.ts b/x-pack/plugins/canvas/server/routes/workpad/create.test.ts index 175a1084ec1a46e..304d7864950e470 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/create.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/create.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { AwaitedProperties } from '@kbn/utility-types'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { workpadRouteContextMock, MockWorkpadRouteContext } from '../../mocks'; import { initializeCreateWorkpadRoute } from './create'; import { kibanaResponseFactory, RequestHandler } from '@kbn/core/server'; @@ -18,7 +19,7 @@ let mockRouteContext = { }, }, canvas: workpadRouteContextMock.create(), -} as unknown as MockWorkpadRouteContext; +} as unknown as AwaitedProperties; jest.mock('uuid/v4', () => jest.fn().mockReturnValue('123abc')); @@ -33,7 +34,7 @@ describe('POST workpad', () => { }, }, canvas: workpadRouteContextMock.create(), - } as unknown as MockWorkpadRouteContext; + } as unknown as AwaitedProperties; const routerDeps = getMockedRouterDeps(); initializeCreateWorkpadRoute(routerDeps); @@ -57,7 +58,11 @@ describe('POST workpad', () => { body: mockWorkpad, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ ok: true, id }); @@ -75,7 +80,11 @@ describe('POST workpad', () => { throw mockRouteContext.core.savedObjects.client.errors.createBadRequestError('bad request'); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(400); }); @@ -109,7 +118,11 @@ describe('POST workpad', () => { body: cloneFromTemplateBody, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ ok: true, id }); diff --git a/x-pack/plugins/canvas/server/routes/workpad/create.ts b/x-pack/plugins/canvas/server/routes/workpad/create.ts index 8460939c730c8b2..dec03c8945ac66d 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/create.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/create.ts @@ -50,14 +50,16 @@ export function initializeCreateWorkpadRoute(deps: RouteInitializerDeps) { let workpad = request.body as CanvasWorkpad; if (isCreateFromTemplate(request.body)) { - const templateSavedObject = await context.core.savedObjects.client.get( + const soClient = (await context.core).savedObjects.client; + const templateSavedObject = await soClient.get( TEMPLATE_TYPE, request.body.templateId ); workpad = templateSavedObject.attributes.template; } - const createdObject = await context.canvas.workpad.create(workpad); + const canvasContext = await context.canvas; + const createdObject = await canvasContext.workpad.create(workpad); return response.ok({ body: { ...okResponse, id: createdObject.id }, diff --git a/x-pack/plugins/canvas/server/routes/workpad/delete.test.ts b/x-pack/plugins/canvas/server/routes/workpad/delete.test.ts index fdd390d2954a958..f29bad869a8a6f8 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/delete.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/delete.test.ts @@ -5,10 +5,11 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { CANVAS_TYPE } from '../../../common/lib/constants'; import { initializeDeleteWorkpadRoute } from './delete'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { getMockedRouterDeps } from '../test_helpers'; const mockRouteContext = { @@ -17,7 +18,7 @@ const mockRouteContext = { client: savedObjectsClientMock.create(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; describe('DELETE workpad', () => { let routeHandler: RequestHandler; @@ -39,7 +40,11 @@ describe('DELETE workpad', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ ok: true }); @@ -59,7 +64,11 @@ describe('DELETE workpad', () => { throw mockRouteContext.core.savedObjects.client.errors.createBadRequestError('bad request'); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(400); }); diff --git a/x-pack/plugins/canvas/server/routes/workpad/delete.ts b/x-pack/plugins/canvas/server/routes/workpad/delete.ts index 9075f651abb5a4d..0a1f69e273d05b8 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/delete.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/delete.ts @@ -23,7 +23,8 @@ export function initializeDeleteWorkpadRoute(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - context.core.savedObjects.client.delete(CANVAS_TYPE, request.params.id); + const soClient = (await context.core).savedObjects.client; + await soClient.delete(CANVAS_TYPE, request.params.id); return response.ok({ body: okResponse }); }) ); diff --git a/x-pack/plugins/canvas/server/routes/workpad/find.test.ts b/x-pack/plugins/canvas/server/routes/workpad/find.test.ts index 8a54889413d8090..39626e95c3f0633 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/find.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/find.test.ts @@ -5,9 +5,10 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { initializeFindWorkpadsRoute } from './find'; import { kibanaResponseFactory, RequestHandlerContext, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { getMockedRouterDeps } from '../test_helpers'; const mockRouteContext = { @@ -16,7 +17,7 @@ const mockRouteContext = { client: savedObjectsClientMock.create(), }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; describe('Find workpad', () => { let routeHandler: RequestHandler; @@ -52,7 +53,11 @@ describe('Find workpad', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(findMock.mock.calls[0][0].search).toBe(`${name}* | ${name}`); expect(findMock.mock.calls[0][0].perPage).toBe(perPage); @@ -88,7 +93,11 @@ describe('Find workpad', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot(` diff --git a/x-pack/plugins/canvas/server/routes/workpad/find.ts b/x-pack/plugins/canvas/server/routes/workpad/find.ts index c8953bfab8a7277..43db20ee11db592 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/find.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/find.ts @@ -24,7 +24,7 @@ export function initializeFindWorkpadsRoute(deps: RouteInitializerDeps) { }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const { name, page, perPage } = request.query; try { diff --git a/x-pack/plugins/canvas/server/routes/workpad/get.test.ts b/x-pack/plugins/canvas/server/routes/workpad/get.test.ts index 735bbfc7209af7b..217072d04532184 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/get.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/get.test.ts @@ -5,10 +5,11 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { CANVAS_TYPE } from '../../../common/lib/constants'; import { initializeGetWorkpadRoute } from './get'; import { kibanaResponseFactory, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { workpadWithGroupAsElement } from '../../../__fixtures__/workpads'; import { CanvasWorkpad } from '../../../types'; import { getMockedRouterDeps } from '../test_helpers'; @@ -16,7 +17,7 @@ import { workpadRouteContextMock, MockWorkpadRouteContext } from '../../mocks'; const mockRouteContext = { canvas: workpadRouteContextMock.create(), -} as unknown as MockWorkpadRouteContext; +} as unknown as AwaitedProperties; describe('GET workpad', () => { let routeHandler: RequestHandler; @@ -48,7 +49,11 @@ describe('GET workpad', () => { references: [], }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot(` @@ -83,7 +88,11 @@ describe('GET workpad', () => { references: [], }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); const workpad = response.payload as CanvasWorkpad; expect(response.status).toBe(200); @@ -108,7 +117,11 @@ describe('GET workpad', () => { throw savedObjectsClient.errors.createGenericNotFoundError(CANVAS_TYPE, id); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.payload).toMatchInlineSnapshot(` Object { diff --git a/x-pack/plugins/canvas/server/routes/workpad/get.ts b/x-pack/plugins/canvas/server/routes/workpad/get.ts index 8fc31e9850dbc0e..fe38b768f64a19e 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/get.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/get.ts @@ -23,7 +23,8 @@ export function initializeGetWorkpadRoute(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - const workpad = await context.canvas.workpad.get(request.params.id); + const canvasContext = await context.canvas; + const workpad = await canvasContext.workpad.get(request.params.id); shimWorkpad(workpad); diff --git a/x-pack/plugins/canvas/server/routes/workpad/import.ts b/x-pack/plugins/canvas/server/routes/workpad/import.ts index d8438920aeb5d23..4734e1e554f6454 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/import.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/import.ts @@ -32,7 +32,8 @@ export function initializeImportWorkpadRoute(deps: RouteInitializerDeps) { catchErrorHandler(async (context, request, response) => { const workpad = request.body as ImportedCanvasWorkpad; - const createdObject = await context.canvas.workpad.import(workpad); + const canvasContext = await context.canvas; + const createdObject = await canvasContext.workpad.import(workpad); return response.ok({ body: { ...okResponse, id: createdObject.id }, diff --git a/x-pack/plugins/canvas/server/routes/workpad/resolve.test.ts b/x-pack/plugins/canvas/server/routes/workpad/resolve.test.ts index 94e3f9dd0346250..80fde2fadc18bc4 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/resolve.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/resolve.test.ts @@ -5,10 +5,11 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { CANVAS_TYPE } from '../../../common/lib/constants'; import { initializeResolveWorkpadRoute } from './resolve'; import { kibanaResponseFactory, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { workpadWithGroupAsElement } from '../../../__fixtures__/workpads'; import { CanvasWorkpad } from '../../../types'; import { getMockedRouterDeps } from '../test_helpers'; @@ -16,7 +17,7 @@ import { workpadRouteContextMock, MockWorkpadRouteContext } from '../../mocks'; const mockRouteContext = { canvas: workpadRouteContextMock.create(), -} as unknown as MockWorkpadRouteContext; +} as unknown as AwaitedProperties; describe('RESOLVE workpad', () => { let routeHandler: RequestHandler; @@ -55,7 +56,11 @@ describe('RESOLVE workpad', () => { alias_target_id: aliasId, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toMatchInlineSnapshot(` @@ -97,7 +102,11 @@ describe('RESOLVE workpad', () => { outcome: 'exactMatch', }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); const workpad = response.payload.workpad as CanvasWorkpad; expect(response.status).toBe(200); @@ -122,7 +131,11 @@ describe('RESOLVE workpad', () => { throw savedObjectsClient.errors.createGenericNotFoundError(CANVAS_TYPE, id); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.payload).toMatchInlineSnapshot(` Object { diff --git a/x-pack/plugins/canvas/server/routes/workpad/resolve.ts b/x-pack/plugins/canvas/server/routes/workpad/resolve.ts index dbd65e30482f8cb..d2a4b71f35af9d3 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/resolve.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/resolve.ts @@ -23,7 +23,8 @@ export function initializeResolveWorkpadRoute(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - const resolved = await context.canvas.workpad.resolve(request.params.id); + const canvasContext = await context.canvas; + const resolved = await canvasContext.workpad.resolve(request.params.id); const { saved_object: workpad } = resolved; shimWorkpad(workpad); diff --git a/x-pack/plugins/canvas/server/routes/workpad/update.test.ts b/x-pack/plugins/canvas/server/routes/workpad/update.test.ts index a0aaa05b0f71882..2467ed56bdc3740 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/update.test.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/update.test.ts @@ -5,11 +5,12 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import sinon from 'sinon'; import { CANVAS_TYPE } from '../../../common/lib/constants'; import { initializeUpdateWorkpadRoute, initializeUpdateWorkpadAssetsRoute } from './update'; import { kibanaResponseFactory, RequestHandler } from '@kbn/core/server'; -import { savedObjectsClientMock, httpServerMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, httpServerMock, coreMock } from '@kbn/core/server/mocks'; import { workpads } from '../../../__fixtures__/workpads'; import { okResponse } from '../ok_response'; import { getMockedRouterDeps } from '../test_helpers'; @@ -22,7 +23,7 @@ const mockRouteContext = { }, }, canvas: workpadRouteContextMock.create(), -} as unknown as MockWorkpadRouteContext; +} as unknown as AwaitedProperties; const workpad = workpads[0]; const now = new Date(); @@ -62,7 +63,11 @@ describe('PUT workpad', () => { mockRouteContext.canvas.workpad.update.mockResolvedValue(true); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual(okResponse); @@ -85,7 +90,11 @@ describe('PUT workpad', () => { ); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(404); }); @@ -104,7 +113,11 @@ describe('PUT workpad', () => { throw mockRouteContext.core.savedObjects.client.errors.createBadRequestError('bad request'); }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(400); }); @@ -160,7 +173,11 @@ describe('update assets', () => { references: [], }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler( + coreMock.createCustomRequestHandlerContext(mockRouteContext), + request, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(mockRouteContext.canvas.workpad.update).toBeCalledWith(id, { diff --git a/x-pack/plugins/canvas/server/routes/workpad/update.ts b/x-pack/plugins/canvas/server/routes/workpad/update.ts index 9d115c83c1def64..d74e57f824f5124 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/update.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/update.ts @@ -40,7 +40,8 @@ export function initializeUpdateWorkpadRoute(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - await context.canvas.workpad.update(request.params.id, request.body as CanvasWorkpad); + const canvasContext = await context.canvas; + await canvasContext.workpad.update(request.params.id, request.body as CanvasWorkpad); return response.ok({ body: okResponse, @@ -65,7 +66,8 @@ export function initializeUpdateWorkpadRoute(deps: RouteInitializerDeps) { }, }, catchErrorHandler(async (context, request, response) => { - await context.canvas.workpad.update(request.params.id, request.body as CanvasWorkpad); + const canvasContext = await context.canvas; + await canvasContext.workpad.update(request.params.id, request.body as CanvasWorkpad); return response.ok({ body: okResponse, @@ -101,7 +103,8 @@ export function initializeUpdateWorkpadAssetsRoute(deps: RouteInitializerDeps) { assets: AssetsRecordSchema.validate(request.body), }; - await context.canvas.workpad.update(request.params.id, workpadAssets as CanvasWorkpad); + const canvasContext = await context.canvas; + await canvasContext.workpad.update(request.params.id, workpadAssets as CanvasWorkpad); return response.ok({ body: okResponse, diff --git a/x-pack/plugins/canvas/server/workpad_route_context.test.ts b/x-pack/plugins/canvas/server/workpad_route_context.test.ts index a1da10b09a91dfe..290eed19d0fc59d 100644 --- a/x-pack/plugins/canvas/server/workpad_route_context.test.ts +++ b/x-pack/plugins/canvas/server/workpad_route_context.test.ts @@ -7,9 +7,10 @@ import sinon from 'sinon'; import { fromExpression } from '@kbn/interpreter'; +import { AwaitedProperties } from '@kbn/utility-types'; import { createWorkpadRouteContext } from './workpad_route_context'; import { RequestHandlerContext, SavedObjectReference } from '@kbn/core/server'; -import { savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { savedObjectsClientMock, coreMock } from '@kbn/core/server/mocks'; import { CanvasWorkpad } from '../types'; import { CANVAS_TYPE } from '../common/lib/constants'; @@ -26,7 +27,7 @@ const mockContext = { client: savedObjectsClient, }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; const workpadRouteContext = createWorkpadRouteContext({ expressions: mockedExpressionService as any, @@ -86,7 +87,7 @@ describe('workpad route context', () => { }; const canvasContext = await workpadRouteContext( - mockContext, + coreMock.createCustomRequestHandlerContext(mockContext), undefined as any, undefined as any ); @@ -120,7 +121,7 @@ describe('workpad route context', () => { it('injects references to the saved object', async () => { const id = 'so-id'; const canvasContext = await workpadRouteContext( - mockContext, + coreMock.createCustomRequestHandlerContext(mockContext), undefined as any, undefined as any ); @@ -145,7 +146,7 @@ describe('workpad route context', () => { it('injects references to the saved object', async () => { const id = 'so-id'; const canvasContext = await workpadRouteContext( - mockContext, + coreMock.createCustomRequestHandlerContext(mockContext), undefined as any, undefined as any ); @@ -172,7 +173,7 @@ describe('workpad route context', () => { const createdDate = new Date(2020, 1, 1).toISOString(); const canvasContext = await workpadRouteContext( - mockContext, + coreMock.createCustomRequestHandlerContext(mockContext), undefined as any, undefined as any ); diff --git a/x-pack/plugins/canvas/server/workpad_route_context.ts b/x-pack/plugins/canvas/server/workpad_route_context.ts index c154dd66d76be89..0ae1699b8f57f8e 100644 --- a/x-pack/plugins/canvas/server/workpad_route_context.ts +++ b/x-pack/plugins/canvas/server/workpad_route_context.ts @@ -6,7 +6,7 @@ */ import { - RequestHandlerContext, + CustomRequestHandlerContext, RequestHandlerContextProvider, SavedObject, SavedObjectsResolveResponse, @@ -18,7 +18,7 @@ import { injectReferences, extractReferences } from './saved_objects/workpad_ref import { getId } from '../common/lib/get_id'; import { CanvasWorkpad, ImportedCanvasWorkpad } from '../types'; -export interface CanvasRouteHandlerContext extends RequestHandlerContext { +export type CanvasRouteHandlerContext = CustomRequestHandlerContext<{ canvas: { workpad: { create: (attributes: CanvasWorkpad) => Promise>; @@ -31,7 +31,7 @@ export interface CanvasRouteHandlerContext extends RequestHandlerContext { ) => Promise>; }; }; -} +}>; interface Deps { expressions: ExpressionsServiceStart; @@ -40,109 +40,107 @@ interface Deps { export const createWorkpadRouteContext: ( deps: Deps ) => RequestHandlerContextProvider = ({ expressions }) => { - return (context) => ({ - workpad: { - create: async (workpad: CanvasWorkpad) => { - const now = new Date().toISOString(); - const { id: maybeId, ...attributes } = workpad; - - const id = maybeId ? maybeId : getId('workpad'); - - const { workpad: extractedAttributes, references } = extractReferences( - attributes, - expressions - ); - - return await context.core.savedObjects.client.create( - CANVAS_TYPE, - { - ...extractedAttributes, - '@timestamp': now, - '@created': now, - }, - { id, references } - ); - }, - import: async (workpad: ImportedCanvasWorkpad) => { - const now = new Date().toISOString(); - const { id: maybeId, ...workpadWithoutId } = workpad; - - // Functionality of running migrations on import of workpads was implemented in v8.1.0. - // As only attributes of the saved object workpad are exported, to run migrations it is necessary - // to specify the minimal version of possible migrations to execute them. It is v8.0.0 in the current case. - const DEFAULT_MIGRATION_VERSION = { [CANVAS_TYPE]: '8.0.0' }; - const DEFAULT_CORE_MIGRATION_VERSION = '8.0.0'; - - const id = maybeId ? maybeId : getId('workpad'); - - return await context.core.savedObjects.client.create( - CANVAS_TYPE, - { - isWriteable: true, - ...workpadWithoutId, - '@timestamp': now, - '@created': now, - }, - { - migrationVersion: DEFAULT_MIGRATION_VERSION, - coreMigrationVersion: DEFAULT_CORE_MIGRATION_VERSION, + return async (context) => { + const soClient = (await context.core).savedObjects.client; + return { + workpad: { + create: async (workpad: CanvasWorkpad) => { + const now = new Date().toISOString(); + const { id: maybeId, ...attributes } = workpad; + + const id = maybeId ? maybeId : getId('workpad'); + + const { workpad: extractedAttributes, references } = extractReferences( + attributes, + expressions + ); + + return await soClient.create( + CANVAS_TYPE, + { + ...extractedAttributes, + '@timestamp': now, + '@created': now, + }, + { id, references } + ); + }, + import: async (workpad: ImportedCanvasWorkpad) => { + const now = new Date().toISOString(); + const { id: maybeId, ...workpadWithoutId } = workpad; + + // Functionality of running migrations on import of workpads was implemented in v8.1.0. + // As only attributes of the saved object workpad are exported, to run migrations it is necessary + // to specify the minimal version of possible migrations to execute them. It is v8.0.0 in the current case. + const DEFAULT_MIGRATION_VERSION = { [CANVAS_TYPE]: '8.0.0' }; + const DEFAULT_CORE_MIGRATION_VERSION = '8.0.0'; + + const id = maybeId ? maybeId : getId('workpad'); + + return await soClient.create( + CANVAS_TYPE, + { + isWriteable: true, + ...workpadWithoutId, + '@timestamp': now, + '@created': now, + }, + { + migrationVersion: DEFAULT_MIGRATION_VERSION, + coreMigrationVersion: DEFAULT_CORE_MIGRATION_VERSION, + id, + } + ); + }, + get: async (id: string) => { + const workpad = await soClient.get(CANVAS_TYPE, id); + + workpad.attributes = injectReferences( + workpad.attributes, + workpad.references, + expressions + ); + + return workpad; + }, + resolve: async (id: string) => { + const resolved = await soClient.resolve(CANVAS_TYPE, id); + + resolved.saved_object.attributes = injectReferences( + resolved.saved_object.attributes, + resolved.saved_object.references, + expressions + ); + + return resolved; + }, + update: async (id: string, { id: omittedId, ...workpad }: Partial) => { + const now = new Date().toISOString(); + + const workpadObject = await soClient.get(CANVAS_TYPE, id); + + const injectedAttributes = injectReferences( + workpadObject.attributes, + workpadObject.references, + expressions + ); + + const updatedAttributes = { + ...injectedAttributes, + ...workpad, + '@timestamp': now, // always update the modified time + '@created': workpadObject.attributes['@created'], // ensure created is not modified + } as WorkpadAttributes; + + const extracted = extractReferences(updatedAttributes, expressions); + + return await soClient.create(CANVAS_TYPE, extracted.workpad, { + overwrite: true, id, - } - ); - }, - get: async (id: string) => { - const workpad = await context.core.savedObjects.client.get( - CANVAS_TYPE, - id - ); - - workpad.attributes = injectReferences(workpad.attributes, workpad.references, expressions); - - return workpad; - }, - resolve: async (id: string) => { - const resolved = await context.core.savedObjects.client.resolve( - CANVAS_TYPE, - id - ); - - resolved.saved_object.attributes = injectReferences( - resolved.saved_object.attributes, - resolved.saved_object.references, - expressions - ); - - return resolved; - }, - update: async (id: string, { id: omittedId, ...workpad }: Partial) => { - const now = new Date().toISOString(); - - const workpadObject = await context.core.savedObjects.client.get( - CANVAS_TYPE, - id - ); - - const injectedAttributes = injectReferences( - workpadObject.attributes, - workpadObject.references, - expressions - ); - - const updatedAttributes = { - ...injectedAttributes, - ...workpad, - '@timestamp': now, // always update the modified time - '@created': workpadObject.attributes['@created'], // ensure created is not modified - } as WorkpadAttributes; - - const extracted = extractReferences(updatedAttributes, expressions); - - return await context.core.savedObjects.client.create(CANVAS_TYPE, extracted.workpad, { - overwrite: true, - id, - references: extracted.references, - }); + references: extracted.references, + }); + }, }, - }, - }); + }; + }; }; diff --git a/x-pack/plugins/cases/server/plugin.ts b/x-pack/plugins/cases/server/plugin.ts index 52d413cb1ef836e..4ec2415bae54d89 100644 --- a/x-pack/plugins/cases/server/plugin.ts +++ b/x-pack/plugins/cases/server/plugin.ts @@ -6,12 +6,12 @@ */ import { - CoreSetup, - CoreStart, IContextProvider, KibanaRequest, Logger, PluginInitializerContext, + CoreSetup, + CoreStart, } from '@kbn/core/server'; import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; @@ -198,10 +198,11 @@ export class CasePlugin { return { getCasesClient: async () => { const [{ savedObjects }] = await core.getStartServices(); + const coreContext = await context.core; return this.clientFactory.create({ request, - scopedClusterClient: context.core.elasticsearch.client.asCurrentUser, + scopedClusterClient: coreContext.elasticsearch.client.asCurrentUser, savedObjectsService: savedObjects, }); }, diff --git a/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts index 00a368e834a0a25..8a9c02cf574d718 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/alerts/get_cases.ts @@ -24,7 +24,8 @@ export const getCasesByAlertIdRoute = createCasesRoute({ try { const alertID = request.params.alert_id; - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const options = request.query as CasesByAlertIDRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts index a63d07037de01b4..5a397841f976d7d 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/delete_cases.ts @@ -21,7 +21,8 @@ export const deleteCaseRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); await client.cases.delete(request.query.ids); return response.noContent(); diff --git a/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts index 711c6909df46c0e..2a42bb3fa3353bc 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/find_cases.ts @@ -15,7 +15,8 @@ export const findCaseRoute = createCasesRoute({ path: `${CASES_URL}/_find`, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const options = request.query as CasesFindRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/get_case.ts b/x-pack/plugins/cases/server/routes/api/cases/get_case.ts index f0e53e82f14940d..736b9b973ce7d9e 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/get_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/get_case.ts @@ -41,7 +41,8 @@ export const getCaseRoute = createCasesRoute({ ); } - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const id = request.params.case_id; return response.ok({ @@ -70,7 +71,8 @@ export const resolveCaseRoute = createCasesRoute({ params, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const id = request.params.case_id; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts b/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts index c148a45220a74de..bb9649aaa092c60 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/patch_cases.ts @@ -15,7 +15,8 @@ export const patchCaseRoute = createCasesRoute({ path: CASES_URL, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const cases = request.body as CasesPatchRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/post_case.ts b/x-pack/plugins/cases/server/routes/api/cases/post_case.ts index 226d0308a3152b2..8c4d43274f21ac0 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/post_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/post_case.ts @@ -15,7 +15,8 @@ export const postCaseRoute = createCasesRoute({ path: CASES_URL, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const theCase = request.body as CasePostRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/cases/push_case.ts b/x-pack/plugins/cases/server/routes/api/cases/push_case.ts index 175838a9d313c0e..9ee30ed34f2a57d 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/push_case.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/push_case.ts @@ -21,7 +21,8 @@ export const pushCaseRoute: CaseRoute = createCasesRoute({ path: CASE_PUSH_URL, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const params = pipe( CasePushRequestParamsRt.decode(request.params), diff --git a/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts b/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts index ee413d73565ee1f..56465fd7be1c489 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/reporters/get_reporters.ts @@ -15,7 +15,8 @@ export const getReportersRoute = createCasesRoute({ path: CASE_REPORTERS_URL, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); const options = request.query as AllReportersFindRequest; return response.ok({ body: await client.cases.getReporters({ ...options }) }); diff --git a/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts b/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts index 7dfa948aa623cdb..8c2071750f5e607 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/tags/get_tags.ts @@ -15,7 +15,8 @@ export const getTagsRoute = createCasesRoute({ path: CASE_TAGS_URL, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); const options = request.query as AllTagsFindRequest; return response.ok({ body: await client.cases.getTags({ ...options }) }); diff --git a/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts b/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts index 0a1ebd3b66a74a1..317ebaec20a1323 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/delete_all_comments.ts @@ -20,7 +20,8 @@ export const deleteAllCommentsRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); await client.attachments.deleteAll({ caseID: request.params.case_id, diff --git a/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts index 220fbffc76cc03b..775fabb846408ba 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/delete_comment.ts @@ -22,7 +22,8 @@ export const deleteCommentRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); await client.attachments.delete({ attachmentID: request.params.comment_id, caseID: request.params.case_id, diff --git a/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts b/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts index 14c6090d62ea179..23a7ecb60153458 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/find_comments.ts @@ -32,7 +32,8 @@ export const findCommentsRoute = createCasesRoute({ fold(throwErrors(Boom.badRequest), identity) ); - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.attachments.find({ caseID: request.params.case_id, diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts b/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts index 4fa793059ed630f..a0b0da466e7ce60 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_alerts.ts @@ -23,7 +23,8 @@ export const getAllAlertsAttachedToCaseRoute = createCasesRoute({ try { const caseId = request.params.case_id; - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); return response.ok({ body: await casesClient.attachments.getAllAlertsAttachToCase({ caseId }), diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts index 44f8f59550fb3e9..72b8f7e6ac98b76 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_all_comment.ts @@ -23,9 +23,10 @@ export const getAllCommentsRoute = createCasesRoute({ }), }, options: { deprecated: true }, - handler: async ({ context, request, response, logger, kibanaVersion }) => { + handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.attachments.getAll({ diff --git a/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts index 91adf832f1ea69c..2a863f3ee4df4f0 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/get_comment.ts @@ -22,7 +22,8 @@ export const getCommentRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.attachments.get({ diff --git a/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts index ebc17daa2561104..4bb6493475a9cfa 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/patch_comment.ts @@ -31,7 +31,8 @@ export const patchCommentRoute = createCasesRoute({ fold(throwErrors(Boom.badRequest), identity) ); - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.attachments.update({ diff --git a/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts b/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts index 1ececb3653741dd..f501f3a42580179 100644 --- a/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts +++ b/x-pack/plugins/cases/server/routes/api/comments/post_comment.ts @@ -21,7 +21,8 @@ export const postCommentRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const caseId = request.params.case_id; const comment = request.body as CommentRequest; diff --git a/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts index 8dabf7862fc88c6..72ca1f6a3832422 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/get_configure.ts @@ -15,7 +15,8 @@ export const getCaseConfigureRoute = createCasesRoute({ path: CASE_CONFIGURE_URL, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); const options = request.query as GetConfigureFindRequest; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts b/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts index da99cd19065d6ab..4c28b896bd85530 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/get_connectors.ts @@ -17,7 +17,8 @@ export const getConnectorsRoute = createCasesRoute({ path: `${CASE_CONFIGURE_CONNECTORS_URL}/_find`, handler: async ({ context, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.configure.getConnectors() }); } catch (error) { diff --git a/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts index 40b0d5123f4294e..b6754dc6da8f647 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/patch_configure.ts @@ -30,7 +30,8 @@ export const patchCaseConfigureRoute = createCasesRoute({ fold(throwErrors(Boom.badRequest), identity) ); - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); const configuration = request.body as CasesConfigurePatch; return response.ok({ diff --git a/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts b/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts index bb64175fb52adf9..102d618fdc05287 100644 --- a/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts +++ b/x-pack/plugins/cases/server/routes/api/configure/post_configure.ts @@ -25,7 +25,8 @@ export const postCaseConfigureRoute = createCasesRoute({ fold(throwErrors(Boom.badRequest), identity) ); - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.configure.create(query), diff --git a/x-pack/plugins/cases/server/routes/api/internal/bulk_create_attachments.ts b/x-pack/plugins/cases/server/routes/api/internal/bulk_create_attachments.ts index 1940cd442eb27c3..cd2facd2391e3d7 100644 --- a/x-pack/plugins/cases/server/routes/api/internal/bulk_create_attachments.ts +++ b/x-pack/plugins/cases/server/routes/api/internal/bulk_create_attachments.ts @@ -23,7 +23,8 @@ export const bulkCreateAttachmentsRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const casesContext = await context.cases; + const casesClient = await casesContext.getCasesClient(); const caseId = request.params.case_id; const attachments = request.body as BulkCreateCommentRequest; diff --git a/x-pack/plugins/cases/server/routes/api/metrics/get_case_metrics.ts b/x-pack/plugins/cases/server/routes/api/metrics/get_case_metrics.ts index b86b84410abe62d..13bfa2093f6232c 100644 --- a/x-pack/plugins/cases/server/routes/api/metrics/get_case_metrics.ts +++ b/x-pack/plugins/cases/server/routes/api/metrics/get_case_metrics.ts @@ -24,7 +24,8 @@ export const getCaseMetricRoute = createCasesRoute({ }, handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.metrics.getCaseMetrics({ caseId: request.params.case_id, diff --git a/x-pack/plugins/cases/server/routes/api/stats/get_status.ts b/x-pack/plugins/cases/server/routes/api/stats/get_status.ts index c245f435835f636..d35d366534c14bc 100644 --- a/x-pack/plugins/cases/server/routes/api/stats/get_status.ts +++ b/x-pack/plugins/cases/server/routes/api/stats/get_status.ts @@ -19,9 +19,10 @@ export const getStatusRoute: CaseRoute = createCasesRoute({ method: 'get', path: CASE_STATUS_URL, options: { deprecated: true }, - handler: async ({ context, request, response, logger, kibanaVersion }) => { + handler: async ({ context, request, response }) => { try { - const client = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const client = await caseContext.getCasesClient(); return response.ok({ body: await client.metrics.getStatusTotalsByType(request.query as CasesStatusRequest), }); diff --git a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts index ae686969974ea64..257db8ab70f0018 100644 --- a/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts +++ b/x-pack/plugins/cases/server/routes/api/user_actions/get_all_user_actions.ts @@ -23,9 +23,10 @@ export const getUserActionsRoute = createCasesRoute({ }), }, options: { deprecated: true }, - handler: async ({ context, request, response, logger, kibanaVersion }) => { + handler: async ({ context, request, response }) => { try { - const casesClient = await context.cases.getCasesClient(); + const caseContext = await context.cases; + const casesClient = await caseContext.getCasesClient(); const caseId = request.params.case_id; return response.ok({ diff --git a/x-pack/plugins/cases/server/types.ts b/x-pack/plugins/cases/server/types.ts index 962dc9c85231d8b..2154aec6f53247e 100644 --- a/x-pack/plugins/cases/server/types.ts +++ b/x-pack/plugins/cases/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import { ActionTypeConfig, ActionTypeSecrets, @@ -22,9 +22,9 @@ export interface CaseRequestContext { /** * @internal */ -export interface CasesRequestHandlerContext extends RequestHandlerContext { +export type CasesRequestHandlerContext = CustomRequestHandlerContext<{ cases: CaseRequestContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/cloud_security_posture/server/plugin.ts b/x-pack/plugins/cloud_security_posture/server/plugin.ts index 99900d4aed0d4ed..754d496965c2046 100755 --- a/x-pack/plugins/cloud_security_posture/server/plugin.ts +++ b/x-pack/plugins/cloud_security_posture/server/plugin.ts @@ -48,9 +48,11 @@ export class CspPlugin > { private readonly logger: Logger; + constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); } + private readonly CspAppService = new CspAppService(); public setup( @@ -88,11 +90,8 @@ export class CspPlugin request: KibanaRequest ): Promise => { if (packagePolicy.package?.name === CIS_KUBERNETES_PACKAGE_NAME) { - await onPackagePolicyPostCreateCallback( - this.logger, - packagePolicy, - context.core.savedObjects.client - ); + const soClient = (await context.core).savedObjects.client; + await onPackagePolicyPostCreateCallback(this.logger, packagePolicy, soClient); } return packagePolicy; @@ -117,5 +116,6 @@ export class CspPlugin return {}; } + public stop() {} } diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts index f0c1dc6e1bf96f2..2112701f42d4a47 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts @@ -146,12 +146,12 @@ export const defineGetBenchmarksRoute = (router: CspRouter, cspContext: CspAppCo validate: { query: benchmarksInputSchema }, }, async (context, request, response) => { - if (!context.fleet.authz.fleet.all) { + if (!(await context.fleet).authz.fleet.all) { return response.forbidden(); } try { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; const { query } = request; const agentService = cspContext.service.agentService; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts index c271208120ae45f..d1c0d7c0eb01465 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/compliance_dashboard/compliance_dashboard.ts @@ -44,7 +44,7 @@ export const defineGetComplianceDashboardRoute = ( }, async (context, _, response) => { try { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; const { id: pitId } = await esClient.openPointInTime({ index: LATEST_FINDINGS_INDEX_PATTERN, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts index 91bc47a19dad949..63fac62d6b4e11e 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts @@ -106,13 +106,14 @@ export const defineUpdateRulesConfigRoute = (router: CspRouter, cspContext: CspA validate: { query: configurationUpdateInputSchema }, }, async (context, request, response) => { - if (!context.fleet.authz.fleet.all) { + if (!(await context.fleet).authz.fleet.all) { return response.forbidden(); } try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const soClient = coreContext.savedObjects.client; const packagePolicyService = cspContext.service.packagePolicyService; const packagePolicyId = request.query.package_policy_id; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.ts b/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.ts index 832a9266441ff06..4c9851be902b3bd 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/findings/findings.ts @@ -111,12 +111,12 @@ export const defineFindingsIndexRoute = (router: CspRouter, cspContext: CspAppCo validate: { query: findingsInputSchema }, }, async (context, request, response) => { - if (!context.fleet.authz.fleet.all) { + if (!(await context.fleet).authz.fleet.all) { return response.forbidden(); } try { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; const options = buildOptionsRequest(request.query); const latestCycleIds = diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts index 3fe320fe5bdd4b5..d01ecb03dbaed2f 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts @@ -34,7 +34,7 @@ export const registerCreateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id, ...rest } = request.body; const body = serializeAutoFollowPattern(rest as AutoFollowPattern); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts index 63ade6d1bd070b7..95da1239061b131 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts @@ -30,7 +30,7 @@ export const registerDeleteRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts index 7cd9508bd7372dc..006199673410e94 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts @@ -23,7 +23,7 @@ export const registerFetchRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { patterns } = await client.asCurrentUser.ccr.getAutoFollowPattern(); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts index a5a70805d518d3e..0a0c2f4317d77c7 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts @@ -31,7 +31,7 @@ export const registerGetRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; try { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts index 1428e33dee660a4..b355d37fc5919e7 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts @@ -29,7 +29,7 @@ export const registerPauseRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts index 912ecd689054d1d..79d31f84398f198 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts @@ -29,7 +29,7 @@ export const registerResumeRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts index 98a716eb88cc674..0a0ec51ad44d111 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts @@ -39,7 +39,7 @@ export const registerUpdateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const body = serializeAutoFollowPattern(request.body as AutoFollowPattern); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts index dbee279a013360a..e4b80b273d4eb61 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts @@ -22,7 +22,7 @@ export const registerPermissionsRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; if (!license.isEsSecurityEnabled) { // If security has been disabled in elasticsearch.yml. we'll just let the user use CCR diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts index bab31c53a83a2eb..b9bf86d877a691f 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts @@ -23,7 +23,7 @@ export const registerStatsRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { auto_follow_stats: autoFollowStats } = await client.asCurrentUser.ccr.stats(); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts index 0aae8f9c115bcb0..84b6096cb3f5b01 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts @@ -44,7 +44,7 @@ export const registerCreateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name, ...rest } = request.body; const body = removeEmptyFields(serializeFollowerIndex(rest as FollowerIndex)); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts index 7bbe2c8c05d4aad..da71d96669efb5b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts @@ -23,7 +23,7 @@ export const registerFetchRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { follower_indices: followerIndices } = await client.asCurrentUser.ccr.followInfo({ diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts index c33ed97c289f0fd..44babd1bbcc467f 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts @@ -30,7 +30,7 @@ export const registerGetRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; try { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts index 6c888e0a6e8bd06..3d77ffefec9fe3f 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts @@ -27,7 +27,7 @@ export const registerPauseRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts index 206de7d62fb3842..da01b3d0e891fa3 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts @@ -27,7 +27,7 @@ export const registerResumeRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts index e240a10df068430..f7987029ebc7725 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts @@ -27,7 +27,7 @@ export const registerUnfollowRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; const ids = id.split(','); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts index 0bacbd5fb3450fc..3c0850ac5984c43 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts @@ -44,7 +44,7 @@ export const registerUpdateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { id } = request.params; // We need to first pause the follower and then resume it by passing the advanced settings diff --git a/x-pack/plugins/data_enhanced/server/routes/session.test.ts b/x-pack/plugins/data_enhanced/server/routes/session.test.ts index 507bb173baf6776..c6625a3491886be 100644 --- a/x-pack/plugins/data_enhanced/server/routes/session.test.ts +++ b/x-pack/plugins/data_enhanced/server/routes/session.test.ts @@ -9,10 +9,7 @@ import type { MockedKeys } from '@kbn/utility-types/jest'; import type { CoreSetup, Logger } from '@kbn/core/server'; import { coreMock, httpServerMock } from '@kbn/core/server/mocks'; -import type { - PluginStart as DataPluginStart, - DataRequestHandlerContext, -} from '@kbn/data-plugin/server'; +import type { PluginStart as DataPluginStart } from '@kbn/data-plugin/server'; import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; import { registerSessionRoutes } from './session'; @@ -25,7 +22,7 @@ enum PostHandlerIndex { describe('registerSessionRoutes', () => { let mockCoreSetup: MockedKeys>; - let mockContext: jest.Mocked; + let mockContext: ReturnType; let mockLogger: Logger; beforeEach(() => { @@ -46,7 +43,7 @@ describe('registerSessionRoutes', () => { const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value; const [, saveHandler] = mockRouter.post.mock.calls[PostHandlerIndex.SAVE]; - saveHandler(mockContext, mockRequest, mockResponse); + await saveHandler(mockContext, mockRequest, mockResponse); expect(mockContext.search!.saveSession).toHaveBeenCalledWith(sessionId, { name }); }); @@ -61,7 +58,7 @@ describe('registerSessionRoutes', () => { const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value; const [[, getHandler]] = mockRouter.get.mock.calls; - getHandler(mockContext, mockRequest, mockResponse); + await getHandler(mockContext, mockRequest, mockResponse); expect(mockContext.search!.getSession).toHaveBeenCalledWith(id); }); @@ -80,7 +77,7 @@ describe('registerSessionRoutes', () => { const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value; const [, findHandler] = mockRouter.post.mock.calls[PostHandlerIndex.FIND]; - findHandler(mockContext, mockRequest, mockResponse); + await findHandler(mockContext, mockRequest, mockResponse); expect(mockContext.search!.findSessions).toHaveBeenCalledWith(body); }); @@ -98,7 +95,7 @@ describe('registerSessionRoutes', () => { const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value; const [, updateHandler] = mockRouter.put.mock.calls[0]; - updateHandler(mockContext, mockRequest, mockResponse); + await updateHandler(mockContext, mockRequest, mockResponse); expect(mockContext.search!.updateSession).toHaveBeenCalledWith(id, body); }); @@ -113,7 +110,7 @@ describe('registerSessionRoutes', () => { const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value; const [, cancelHandler] = mockRouter.post.mock.calls[PostHandlerIndex.CANCEL]; - cancelHandler(mockContext, mockRequest, mockResponse); + await cancelHandler(mockContext, mockRequest, mockResponse); expect(mockContext.search!.cancelSession).toHaveBeenCalledWith(id); }); @@ -145,7 +142,7 @@ describe('registerSessionRoutes', () => { const mockRouter = mockCoreSetup.http.createRouter.mock.results[0].value; const [, extendHandler] = mockRouter.post.mock.calls[PostHandlerIndex.EXTEND]; - extendHandler(mockContext, mockRequest, mockResponse); + await extendHandler(mockContext, mockRequest, mockResponse); expect(mockContext.search.extendSession).toHaveBeenCalledWith(id, new Date(expires)); }); diff --git a/x-pack/plugins/data_enhanced/server/routes/session.ts b/x-pack/plugins/data_enhanced/server/routes/session.ts index 399c9b236b35ac4..a0eea258c4db5e3 100644 --- a/x-pack/plugins/data_enhanced/server/routes/session.ts +++ b/x-pack/plugins/data_enhanced/server/routes/session.ts @@ -36,7 +36,8 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger: request.body; try { - const response = await context.search!.saveSession(sessionId, { + const searchContext = await context.search; + const response = await searchContext.saveSession(sessionId, { name, appId, expires, @@ -70,7 +71,8 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger: async (context, request, res) => { const { id } = request.params; try { - const response = await context.search!.getSession(id); + const searchContext = await context.search; + const response = await searchContext!.getSession(id); return res.ok({ body: response, @@ -104,7 +106,8 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger: async (context, request, res) => { const { page, perPage, sortField, sortOrder, filter, searchFields, search } = request.body; try { - const response = await context.search!.findSessions({ + const searchContext = await context.search; + const response = await searchContext!.findSessions({ page, perPage, sortField, @@ -139,7 +142,8 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger: async (context, request, res) => { const { id } = request.params; try { - await context.search!.deleteSession(id); + const searchContext = await context.search; + await searchContext.deleteSession(id); return res.ok(); } catch (e) { @@ -165,7 +169,8 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger: async (context, request, res) => { const { id } = request.params; try { - await context.search!.cancelSession(id); + const searchContext = await context.search; + await searchContext.cancelSession(id); return res.ok(); } catch (e) { @@ -196,7 +201,8 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger: const { id } = request.params; const { name, expires } = request.body; try { - const response = await context.search!.updateSession(id, { name, expires }); + const searchContext = await context.search; + const response = await searchContext.updateSession(id, { name, expires }); return res.ok({ body: response, @@ -227,7 +233,8 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger: const { id } = request.params; const { expires } = request.body; try { - const response = await context.search!.extendSession(id, new Date(expires)); + const searchContext = await context.search; + const response = await searchContext.extendSession(id, new Date(expires)); return res.ok({ body: response, diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts index 28359bc90052f81..65868e4d1793557 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts @@ -12,7 +12,7 @@ export function registerListRoute({ router }: RouteDependencies) { router.get( { path: '/internal/enterprise_search/indices', validate: false }, async (context, _, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const indices = await fetchIndices(client); return response.ok({ diff --git a/x-pack/plugins/event_log/server/routes/find.ts b/x-pack/plugins/event_log/server/routes/find.ts index fd940d0f64ad508..4c9ab70bbe3a525 100644 --- a/x-pack/plugins/event_log/server/routes/find.ts +++ b/x-pack/plugins/event_log/server/routes/find.ts @@ -38,7 +38,7 @@ export const findRoute = (router: EventLogRouter, systemLogger: Logger) => { if (!context.eventLog) { return res.badRequest({ body: 'RouteHandlerContext is not registered for eventLog' }); } - const eventLogClient = context.eventLog.getEventLogClient(); + const eventLogClient = (await context.eventLog).getEventLogClient(); const { params: { id, type }, query, diff --git a/x-pack/plugins/event_log/server/routes/find_by_ids.ts b/x-pack/plugins/event_log/server/routes/find_by_ids.ts index 85346b1e87be52e..a33a03c8242c482 100644 --- a/x-pack/plugins/event_log/server/routes/find_by_ids.ts +++ b/x-pack/plugins/event_log/server/routes/find_by_ids.ts @@ -44,7 +44,7 @@ export const findByIdsRoute = (router: EventLogRouter, systemLogger: Logger) => if (!context.eventLog) { return res.badRequest({ body: 'RouteHandlerContext is not registered for eventLog' }); } - const eventLogClient = context.eventLog.getEventLogClient(); + const eventLogClient = (await context.eventLog).getEventLogClient(); const { params: { type }, body: { ids, legacyIds }, diff --git a/x-pack/plugins/event_log/server/types.ts b/x-pack/plugins/event_log/server/types.ts index 10a472e802b9fa3..1336245741bd662 100644 --- a/x-pack/plugins/event_log/server/types.ts +++ b/x-pack/plugins/event_log/server/types.ts @@ -6,7 +6,7 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; -import type { IRouter, KibanaRequest, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, KibanaRequest, CustomRequestHandlerContext } from '@kbn/core/server'; export type { IEvent, IValidatedEvent } from '../generated/schemas'; export { EventSchema, ECS_VERSION } from '../generated/schemas'; @@ -16,6 +16,7 @@ import { AggregateEventsBySavedObjectResult, QueryEventsBySavedObjectResult, } from './es/cluster_client_adapter'; + export type { QueryEventsBySavedObjectResult, AggregateEventsBySavedObjectResult, @@ -79,9 +80,9 @@ export interface EventLogApiRequestHandlerContext { /** * @internal */ -export interface EventLogRequestHandlerContext extends RequestHandlerContext { +export type EventLogRequestHandlerContext = CustomRequestHandlerContext<{ eventLog: EventLogApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/features/server/routes/index.test.ts b/x-pack/plugins/features/server/routes/index.test.ts index 4d61d131cc0acad..31cb1358f63fa50 100644 --- a/x-pack/plugins/features/server/routes/index.test.ts +++ b/x-pack/plugins/features/server/routes/index.test.ts @@ -15,10 +15,9 @@ import { RequestHandler } from '@kbn/core/server'; import { FeatureKibanaPrivileges, KibanaFeatureConfig, SubFeatureConfig } from '../../common'; function createContextMock(licenseType: LicenseType = 'platinum') { - return { - core: coreMock.createRequestHandlerContext(), + return coreMock.createCustomRequestHandlerContext({ licensing: licensingMock.createRequestHandlerContext({ license: { type: licenseType } }), - }; + }); } function createPrivilege(partial: Partial = {}): FeatureKibanaPrivileges { @@ -138,7 +137,7 @@ describe('GET /api/features', () => { it('returns a list of available features, sorted by their configured order', async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler(createContextMock(), { query: {} } as any, mockResponse); + await routeHandler(createContextMock(), { query: {} } as any, mockResponse); expect(mockResponse.ok).toHaveBeenCalledTimes(1); const [call] = mockResponse.ok.mock.calls; @@ -173,7 +172,7 @@ describe('GET /api/features', () => { it(`by default does not return features that arent allowed by current license`, async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler(createContextMock('basic'), { query: {} } as any, mockResponse); + await routeHandler(createContextMock('basic'), { query: {} } as any, mockResponse); expect(mockResponse.ok).toHaveBeenCalledTimes(1); const [call] = mockResponse.ok.mock.calls; @@ -204,7 +203,7 @@ describe('GET /api/features', () => { it(`ignoreValidLicenses=false does not return features that arent allowed by current license`, async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler( + await routeHandler( createContextMock('basic'), { query: { ignoreValidLicenses: false } } as any, mockResponse @@ -239,7 +238,7 @@ describe('GET /api/features', () => { it(`ignoreValidLicenses=true returns features that arent allowed by current license`, async () => { const mockResponse = httpServerMock.createResponseFactory(); - routeHandler( + await routeHandler( createContextMock('basic'), { query: { ignoreValidLicenses: true } } as any, mockResponse diff --git a/x-pack/plugins/features/server/routes/index.ts b/x-pack/plugins/features/server/routes/index.ts index 1f2b833663f1a53..bb78f07bc56ccf3 100644 --- a/x-pack/plugins/features/server/routes/index.ts +++ b/x-pack/plugins/features/server/routes/index.ts @@ -26,8 +26,8 @@ export function defineRoutes({ router, featureRegistry }: RouteDefinitionParams) query: schema.object({ ignoreValidLicenses: schema.boolean({ defaultValue: false }) }), }, }, - (context, request, response) => { - const currentLicense = context.licensing!.license; + async (context, request, response) => { + const { license: currentLicense } = await context.licensing; const allFeatures = featureRegistry.getAllKibanaFeatures( currentLicense, diff --git a/x-pack/plugins/features/server/types.ts b/x-pack/plugins/features/server/types.ts index 826d4282cc4258f..99a6c96e4332215 100644 --- a/x-pack/plugins/features/server/types.ts +++ b/x-pack/plugins/features/server/types.ts @@ -5,15 +5,15 @@ * 2.0. */ -import type { RequestHandlerContext, IRouter } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, IRouter } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; /** * @internal */ -export interface FeaturesRequestHandlerContext extends RequestHandlerContext { +export type FeaturesRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/file_upload/server/routes.ts b/x-pack/plugins/file_upload/server/routes.ts index 0abab34ebef7b4f..76d6443f47f5473 100644 --- a/x-pack/plugins/file_upload/server/routes.ts +++ b/x-pack/plugins/file_upload/server/routes.ts @@ -102,11 +102,8 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge }, async (context, request, response) => { try { - const result = await analyzeFile( - context.core.elasticsearch.client, - request.body, - request.query - ); + const esClient = (await context.core).elasticsearch.client; + const result = await analyzeFile(esClient, request.body, request.query); return response.ok({ body: result }); } catch (e) { return response.customError(wrapError(e)); @@ -142,6 +139,7 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge try { const { id } = request.query; const { index, data, settings, mappings, ingestPipeline } = request.body; + const esClient = (await context.core).elasticsearch.client; // `id` being `undefined` tells us that this is a new import due to create a new index. // follow-up import calls to just add additional data will include the `id` of the created @@ -151,7 +149,7 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge } const result = await importData( - context.core.elasticsearch.client, + esClient, id, index, settings, @@ -182,9 +180,8 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge }, async (context, request, response) => { try { - const indexExists = await context.core.elasticsearch.client.asCurrentUser.indices.exists( - request.body - ); + const esClient = (await context.core).elasticsearch.client; + const indexExists = await esClient.asCurrentUser.indices.exists(request.body); return response.ok({ body: { exists: indexExists } }); } catch (e) { return response.customError(wrapError(e)); @@ -225,8 +222,9 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge async (context, request, response) => { try { const { index, timeFieldName, query, runtimeMappings } = request.body; + const esClient = (await context.core).elasticsearch.client; const resp = await getTimeFieldRange( - context.core.elasticsearch.client, + esClient, index, timeFieldName, query, diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index 8fd23dfbbac8314..01fe5b48f9e319d 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -75,7 +75,7 @@ export const createAppContextStartContractMock = ( }; export const createFleetRequestHandlerContextMock = (): jest.Mocked< - FleetRequestHandlerContext['fleet'] + Awaited > => { return { authz: createFleetAuthzMock(), diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index 20d55409e50d2d7..c9e3b9388087d19 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -319,12 +319,11 @@ export class FleetPlugin PLUGIN_ID, async (context, request) => { const plugin = this; + const esClient = (await context.core).elasticsearch.client; return { get agentClient() { - const agentService = plugin.setupAgentService( - context.core.elasticsearch.client.asInternalUser - ); + const agentService = plugin.setupAgentService(esClient.asInternalUser); return { asCurrentUser: agentService.asScoped(request), @@ -382,6 +381,7 @@ export class FleetPlugin this.telemetryEventsSender.setup(deps.telemetry); } + public start(core: CoreStart, plugins: FleetStartDeps): FleetStartContract { appContextService.start({ elasticsearch: core.elasticsearch, diff --git a/x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts b/x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts index 265fe4d9e42217c..4f3cad9edab2629 100644 --- a/x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent/actions_handlers.ts @@ -24,7 +24,7 @@ export const postNewAgentActionHandlerBuilder = function ( > { return async (context, request, response) => { try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const agent = await actionsService.getAgent(esClient, request.params.agentId); diff --git a/x-pack/plugins/fleet/server/routes/agent/handlers.ts b/x-pack/plugins/fleet/server/routes/agent/handlers.ts index b0c6a975dfead01..b9e82e844e81bc9 100644 --- a/x-pack/plugins/fleet/server/routes/agent/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent/handlers.ts @@ -32,8 +32,9 @@ import * as AgentService from '../../services/agents'; export const getAgentHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const body: GetOneAgentResponse = { @@ -55,7 +56,8 @@ export const getAgentHandler: RequestHandler< export const deleteAgentHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await AgentService.deleteAgent(esClient, request.params.agentId); @@ -82,7 +84,8 @@ export const updateAgentHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await AgentService.updateAgent(esClient, request.params.agentId, { @@ -108,7 +111,8 @@ export const getAgentsHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const { agents, total, page, perPage } = await AgentService.getAgentsByKuery(esClient, { @@ -143,8 +147,9 @@ export const putAgentsReassignHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await AgentService.reassignAgent( soClient, @@ -172,8 +177,9 @@ export const postBulkAgentsReassignHandler: RequestHandler< }); } - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const agentOptions = Array.isArray(request.body.agents) ? { agentIds: request.body.agents } : { kuery: request.body.agents }; @@ -204,7 +210,8 @@ export const getAgentStatusForAgentPolicyHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const results = await AgentService.getAgentStatusForAgentPolicy( esClient, @@ -224,7 +231,8 @@ export const getAgentDataHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; try { let items; diff --git a/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts b/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts index 57752ae5caf6e03..f9d27ff71ed9db5 100644 --- a/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts @@ -25,8 +25,9 @@ export const postAgentUnenrollHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await AgentService.unenrollAgent(soClient, esClient, request.params.agentId, { force: request.body?.force, @@ -52,8 +53,9 @@ export const postBulkAgentsUnenrollHandler: RequestHandler< }); } - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const agentOptions = Array.isArray(request.body.agents) ? { agentIds: request.body.agents } : { kuery: request.body.agents }; diff --git a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts index dd3375257469029..13df9222c95246e 100644 --- a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts @@ -22,8 +22,9 @@ export const postAgentUpgradeHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const { version, source_uri: sourceUri, force } = request.body; const kibanaVersion = appContextService.getKibanaVersion(); try { @@ -77,8 +78,9 @@ export const postBulkAgentsUpgradeHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const { version, source_uri: sourceUri, agents, force } = request.body; const kibanaVersion = appContextService.getKibanaVersion(); try { diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index 34dc29d89e6c41c..7b6c2dce0ef04d5 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -45,8 +45,10 @@ export const getAgentPoliciesHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const { full: withPackagePolicies = false, ...restOfQuery } = request.query; try { const { items, total, page, perPage } = await agentPolicyService.list(soClient, { @@ -81,7 +83,8 @@ export const getAgentPoliciesHandler: FleetRequestHandler< export const getOneAgentPolicyHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; try { const agentPolicy = await agentPolicyService.get(soClient, request.params.agentPolicyId); if (agentPolicy) { @@ -107,13 +110,15 @@ export const createAgentPolicyHandler: FleetRequestHandler< TypeOf, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined; const withSysMonitoring = request.query.sys_monitoring ?? false; const monitoringEnabled = request.body.monitoring_enabled; const { has_fleet_server: hasFleetServer, ...newPolicy } = request.body; - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; try { const body: CreateAgentPolicyResponse = { item: await createAgentPolicyWithPackages({ @@ -141,8 +146,9 @@ export const updateAgentPolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = await appContextService.getSecurity()?.authc.getCurrentUser(request); const { force, ...data } = request.body; try { @@ -170,8 +176,9 @@ export const copyAgentPolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = await appContextService.getSecurity()?.authc.getCurrentUser(request); try { const agentPolicy = await agentPolicyService.copy( @@ -198,8 +205,9 @@ export const deleteAgentPoliciesHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const body: DeleteAgentPolicyResponse = await agentPolicyService.delete( soClient, @@ -218,7 +226,8 @@ export const getFullAgentPolicy: FleetRequestHandler< TypeOf, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; if (request.query.kubernetes === true) { try { @@ -273,7 +282,8 @@ export const downloadFullAgentPolicy: FleetRequestHandler< TypeOf, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; const { params: { agentPolicyId }, } = request; diff --git a/x-pack/plugins/fleet/server/routes/app/index.ts b/x-pack/plugins/fleet/server/routes/app/index.ts index fa4841c50e5bf39..9afa422d2511ed4 100644 --- a/x-pack/plugins/fleet/server/routes/app/index.ts +++ b/x-pack/plugins/fleet/server/routes/app/index.ts @@ -28,7 +28,8 @@ export const getCheckPermissionsHandler: FleetRequestHandler< if (!appContextService.getSecurityLicense().isEnabled()) { return response.ok({ body: missingSecurityBody }); } else { - if (!context.fleet.authz.fleet.all) { + const fleetContext = await context.fleet; + if (!fleetContext.authz.fleet.all) { return response.ok({ body: { success: false, @@ -38,7 +39,7 @@ export const getCheckPermissionsHandler: FleetRequestHandler< } // check the manage_service_account cluster privilege else if (request.query.fleetServerSetup) { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; const { has_all_requested: hasAllPrivileges } = await esClient.security.hasPrivileges({ body: { cluster: ['manage_service_account'] }, }); @@ -59,7 +60,7 @@ export const getCheckPermissionsHandler: FleetRequestHandler< export const generateServiceTokenHandler: RequestHandler = async (context, request, response) => { // Generate the fleet server service token as the current user as the internal user do not have the correct permissions - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; try { const tokenResponse = await esClient.transport.request<{ created?: boolean; diff --git a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts index d7081a91453f97e..2d01344a930aa13 100644 --- a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts @@ -39,7 +39,8 @@ interface ESDataStreamInfo { export const getListHandler: RequestHandler = async (context, request, response) => { // Query datastreams as the current user as the Kibana internal user may not have all the required permission - const esClient = context.core.elasticsearch.client.asCurrentUser; + const { savedObjects, elasticsearch } = await context.core; + const esClient = elasticsearch.client.asCurrentUser; const body: GetDataStreamsResponse = { data_streams: [], @@ -54,7 +55,7 @@ export const getListHandler: RequestHandler = async (context, request, response) ] = await Promise.all([ esClient.indices.getDataStream({ name: DATA_STREAM_INDEX_PATTERN }), esClient.indices.dataStreamsStats({ name: DATA_STREAM_INDEX_PATTERN, human: true }), - getPackageSavedObjects(context.core.savedObjects.client), + getPackageSavedObjects(savedObjects.client), ]); const dataStreamsInfoByName = keyBy(dataStreamsInfo, 'name'); @@ -81,7 +82,7 @@ export const getListHandler: RequestHandler = async (context, request, response) allDashboards[pkgSavedObject.id] = dashboards; return allDashboards; }, {}); - const allDashboardSavedObjectsResponse = await context.core.savedObjects.client.bulkGet<{ + const allDashboardSavedObjectsResponse = await savedObjects.client.bulkGet<{ title?: string; }>( Object.values(dashboardIdsByPackageName).flatMap((dashboardIds) => diff --git a/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts b/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts index 1dc088cfe9a3e8e..613bf1ad99be998 100644 --- a/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts +++ b/x-pack/plugins/fleet/server/routes/enrollment_api_key/handler.ts @@ -29,7 +29,7 @@ export const getEnrollmentApiKeysHandler: RequestHandler< TypeOf > = async (context, request, response) => { // Use kibana_system and depend on authz checks on HTTP layer to prevent abuse - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { const { items, total, page, perPage } = await APIKeyService.listEnrollmentApiKeys(esClient, { @@ -55,8 +55,9 @@ export const postEnrollmentApiKeyHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const { elasticsearch, savedObjects } = await context.core; + const soClient = savedObjects.client; + const esClient = elasticsearch.client.asInternalUser; try { // validate policy id await agentPolicyService.get(soClient, request.body.policy_id).catch((err) => { @@ -84,7 +85,7 @@ export const postEnrollmentApiKeyHandler: RequestHandler< export const deleteEnrollmentApiKeyHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { await APIKeyService.deleteEnrollmentApiKey(esClient, request.params.keyId); @@ -105,7 +106,7 @@ export const getOneEnrollmentApiKeyHandler: RequestHandler< TypeOf > = async (context, request, response) => { // Use kibana_system and depend on authz checks on HTTP layer to prevent abuse - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { const apiKey = await APIKeyService.getEnrollmentAPIKey(esClient, request.params.keyId); const body: GetOneEnrollmentAPIKeyResponse = { item: apiKey }; diff --git a/x-pack/plugins/fleet/server/routes/epm/handlers.ts b/x-pack/plugins/fleet/server/routes/epm/handlers.ts index 62a9661c328ab90..38bacfc69019419 100644 --- a/x-pack/plugins/fleet/server/routes/epm/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/epm/handlers.ts @@ -83,7 +83,7 @@ export const getListHandler: FleetRequestHandler< TypeOf > = async (context, request, response) => { try { - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const res = await getPackages({ savedObjectsClient, ...request.query, @@ -102,7 +102,7 @@ export const getListHandler: FleetRequestHandler< export const getLimitedListHandler: FleetRequestHandler = async (context, request, response) => { try { - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const res = await getLimitedPackages({ savedObjectsClient }); const body: GetLimitedPackagesResponse = { items: res, @@ -121,7 +121,7 @@ export const getFileHandler: FleetRequestHandler< > = async (context, request, response) => { try { const { pkgName, pkgVersion, filePath } = request.params; - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const installation = await getInstallation({ savedObjectsClient, pkgName }); const useLocalFile = pkgVersion === installation?.version; @@ -194,7 +194,7 @@ export const getInfoHandler: FleetRequestHandler< TypeOf > = async (context, request, response) => { try { - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const { pkgName, pkgVersion } = request.params; if (pkgVersion && !semverValid(pkgVersion)) { throw new IngestManagerError('Package version is not a valid semver'); @@ -219,7 +219,7 @@ export const updatePackageHandler: FleetRequestHandler< TypeOf > = async (context, request, response) => { try { - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const { pkgName } = request.params; const res = await updatePackage({ savedObjectsClient, pkgName, ...request.body }); @@ -238,7 +238,7 @@ export const getStatsHandler: FleetRequestHandler< > = async (context, request, response) => { try { const { pkgName } = request.params; - const savedObjectsClient = context.fleet.epm.internalSoClient; + const savedObjectsClient = (await context.fleet).epm.internalSoClient; const body: GetStatsResponse = { response: await getPackageUsageStats({ savedObjectsClient, pkgName }), }; @@ -253,11 +253,13 @@ export const installPackageFromRegistryHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const savedObjectsClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const { pkgName, pkgVersion } = request.params; - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; const res = await installPackage({ installSource: 'registry', savedObjectsClient, @@ -301,9 +303,11 @@ export const bulkInstallPackagesFromRegistryHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const savedObjectsClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; - const spaceId = context.fleet.spaceId; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; + const spaceId = fleetContext.spaceId; const bulkInstalledResponses = await bulkInstallPackages({ savedObjectsClient, esClient, @@ -329,11 +333,13 @@ export const installPackageByUploadHandler: FleetRequestHandler< body: { message: 'Requires Enterprise license' }, }); } - const savedObjectsClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const contentType = request.headers['content-type'] as string; // from types it could also be string[] or undefined but this is checked later const archiveBuffer = Buffer.from(request.body); - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; const res = await installPackage({ installSource: 'upload', savedObjectsClient, @@ -363,8 +369,10 @@ export const deletePackageHandler: FleetRequestHandler< > = async (context, request, response) => { try { const { pkgName, pkgVersion } = request.params; - const savedObjectsClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const res = await removeInstallation({ savedObjectsClient, pkgName, diff --git a/x-pack/plugins/fleet/server/routes/output/handler.ts b/x-pack/plugins/fleet/server/routes/output/handler.ts index 7f97477d89306a1..a995a3eeb41dcea 100644 --- a/x-pack/plugins/fleet/server/routes/output/handler.ts +++ b/x-pack/plugins/fleet/server/routes/output/handler.ts @@ -26,7 +26,7 @@ import { agentPolicyService } from '../../services'; import { generateLogstashApiKey, canCreateLogstashApiKey } from '../../services/api_keys'; export const getOutputsHandler: RequestHandler = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { const outputs = await outputService.list(soClient); @@ -46,7 +46,7 @@ export const getOutputsHandler: RequestHandler = async (context, request, respon export const getOneOuputHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { const output = await outputService.get(soClient, request.params.outputId); @@ -71,8 +71,9 @@ export const putOuputHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await outputService.update(soClient, request.params.outputId, request.body); const output = await outputService.get(soClient, request.params.outputId); @@ -103,8 +104,9 @@ export const postOuputHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { const { id, ...data } = request.body; const output = await outputService.create(soClient, data, { id }); @@ -125,7 +127,7 @@ export const postOuputHandler: RequestHandler< export const deleteOutputHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { await outputService.delete(soClient, request.params.outputId); @@ -146,7 +148,7 @@ export const deleteOutputHandler: RequestHandler< }; export const postLogstashApiKeyHandler: RequestHandler = async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; try { const hasCreatePrivileges = await canCreateLogstashApiKey(esClient); if (!hasCreatePrivileges) { diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts index 1041dcc0579aaed..2f814a0da15d46e 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.test.ts @@ -93,7 +93,7 @@ describe('When calling package policy', () => { let routerMock: jest.Mocked; let routeHandler: FleetRequestHandler; let routeConfig: RouteConfig; - let context: jest.Mocked; + let context: FleetRequestHandlerContext; let response: ReturnType; beforeEach(() => { diff --git a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts index e0dc77fc57dcb3e..ad46f25ff91dec6 100644 --- a/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/package_policy/handlers.ts @@ -35,7 +35,7 @@ export const getPackagePoliciesHandler: RequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { const { items, total, page, perPage } = await packagePolicyService.list( soClient, @@ -57,7 +57,7 @@ export const getPackagePoliciesHandler: RequestHandler< export const getOnePackagePolicyHandler: RequestHandler< TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; const { packagePolicyId } = request.params; const notFoundResponse = () => response.notFound({ body: { message: `Package policy ${packagePolicyId} not found` } }); @@ -87,11 +87,13 @@ export const createPackagePolicyHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = fleetContext.epm.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined; const { force, ...newPolicy } = request.body; - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; try { const newPackagePolicy = await packagePolicyService.enrichPolicyWithDefaultsFromPackage( soClient, @@ -140,8 +142,9 @@ export const updatePackagePolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined; const packagePolicy = await packagePolicyService.get(soClient, request.params.packagePolicyId); @@ -206,8 +209,9 @@ export const deletePackagePolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined; try { const body: DeletePackagePoliciesResponse = await packagePolicyService.delete( @@ -241,8 +245,9 @@ export const upgradePackagePolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined; try { const body: UpgradePackagePolicyResponse = await packagePolicyService.upgrade( @@ -273,7 +278,7 @@ export const dryRunUpgradePackagePolicyHandler: RequestHandler< unknown, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; + const soClient = (await context.core).savedObjects.client; try { const body: UpgradePackagePolicyDryRunResponse = []; const { packagePolicyIds } = request.body; diff --git a/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts b/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts index aa9d6acbbc47271..bd0ed690ec6fe3e 100644 --- a/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts +++ b/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts @@ -23,10 +23,12 @@ export const updatePreconfigurationHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const fleetContext = await context.fleet; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; const defaultOutput = await outputService.ensureDefaultOutput(soClient); - const spaceId = context.fleet.spaceId; + const spaceId = fleetContext.spaceId; const { agentPolicies, packages } = request.body; try { @@ -49,8 +51,9 @@ export const resetOnePreconfigurationHandler: FleetRequestHandler< undefined, undefined > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await resetPreconfiguredAgentPolicies(soClient, esClient, request.params.agentPolicyId); @@ -65,8 +68,9 @@ export const resetPreconfigurationHandler: FleetRequestHandler< undefined, undefined > = async (context, request, response) => { - const soClient = context.core.savedObjects.client; - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; try { await resetPreconfiguredAgentPolicies(soClient, esClient); diff --git a/x-pack/plugins/fleet/server/routes/settings/index.ts b/x-pack/plugins/fleet/server/routes/settings/index.ts index a6203de097c7bee..07bd3342ade1df9 100644 --- a/x-pack/plugins/fleet/server/routes/settings/index.ts +++ b/x-pack/plugins/fleet/server/routes/settings/index.ts @@ -15,7 +15,7 @@ import { settingsService, agentPolicyService, appContextService } from '../../se import type { FleetAuthzRouter } from '../security'; export const getSettingsHandler: FleetRequestHandler = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; + const soClient = (await context.fleet).epm.internalSoClient; try { const settings = await settingsService.getSettings(soClient); @@ -39,8 +39,8 @@ export const putSettingsHandler: FleetRequestHandler< undefined, TypeOf > = async (context, request, response) => { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const soClient = (await context.fleet).epm.internalSoClient; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const user = await appContextService.getSecurity()?.authc.getCurrentUser(request); try { diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts index 971684daff6501c..400c18e85415b71 100644 --- a/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts +++ b/x-pack/plugins/fleet/server/routes/setup/handlers.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { httpServerMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; +import type { AwaitedProperties } from '@kbn/utility-types'; +import { httpServerMock, savedObjectsClientMock, coreMock } from '@kbn/core/server/mocks'; import type { PostFleetSetupResponse } from '../../../common'; import { RegistryError } from '../../errors'; @@ -29,7 +30,7 @@ jest.mock('../../services/setup', () => { const mockSetupFleet = setupFleet as jest.MockedFunction; describe('FleetSetupHandler', () => { - let context: FleetRequestHandlerContext; + let context: AwaitedProperties>; let response: ReturnType; let request: ReturnType; @@ -69,7 +70,7 @@ describe('FleetSetupHandler', () => { nonFatalErrors: [], }) ); - await fleetSetupHandler(context, request, response); + await fleetSetupHandler(coreMock.createCustomRequestHandlerContext(context), request, response); const expectedBody: PostFleetSetupResponse = { isInitialized: true, @@ -81,7 +82,7 @@ describe('FleetSetupHandler', () => { it('POST /setup fails w/500 on custom error', async () => { mockSetupFleet.mockImplementation(() => Promise.reject(new Error('SO method mocked to throw'))); - await fleetSetupHandler(context, request, response); + await fleetSetupHandler(coreMock.createCustomRequestHandlerContext(context), request, response); expect(response.customError).toHaveBeenCalledTimes(1); expect(response.customError).toHaveBeenCalledWith({ @@ -97,7 +98,7 @@ describe('FleetSetupHandler', () => { Promise.reject(new RegistryError('Registry method mocked to throw')) ); - await fleetSetupHandler(context, request, response); + await fleetSetupHandler(coreMock.createCustomRequestHandlerContext(context), request, response); expect(response.customError).toHaveBeenCalledTimes(1); expect(response.customError).toHaveBeenCalledWith({ statusCode: 502, diff --git a/x-pack/plugins/fleet/server/routes/setup/handlers.ts b/x-pack/plugins/fleet/server/routes/setup/handlers.ts index dac5828329a22bd..59a3516aac83a7a 100644 --- a/x-pack/plugins/fleet/server/routes/setup/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/setup/handlers.ts @@ -17,8 +17,9 @@ export const getFleetStatusHandler: FleetRequestHandler = async (context, reques const isApiKeysEnabled = await appContextService .getSecurity() .authc.apiKeys.areAPIKeysEnabled(); + const coreContext = await context.core; const isFleetServerSetup = await hasFleetServers( - context.core.elasticsearch.client.asInternalUser + coreContext.elasticsearch.client.asInternalUser ); const missingRequirements: GetFleetStatusResponse['missing_requirements'] = []; @@ -52,8 +53,8 @@ export const getFleetStatusHandler: FleetRequestHandler = async (context, reques export const fleetSetupHandler: FleetRequestHandler = async (context, request, response) => { try { - const soClient = context.fleet.epm.internalSoClient; - const esClient = context.core.elasticsearch.client.asInternalUser; + const soClient = (await context.fleet).epm.internalSoClient; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const setupStatus = await setupFleet(soClient, esClient); const body: PostFleetSetupResponse = { ...setupStatus, diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index 53218e7cda8f9a7..c84701bf5d5e973 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -9,6 +9,7 @@ import { elasticsearchServiceMock, savedObjectsClientMock, httpServerMock, + coreMock, } from '@kbn/core/server/mocks'; import { produce } from 'immer'; import type { @@ -1270,7 +1271,7 @@ describe('Package policy service', () => { await packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, - context, + coreMock.createCustomRequestHandlerContext(context), request ); expect(callbackCallingOrder).toEqual(['a', 'b']); @@ -1283,7 +1284,7 @@ describe('Package policy service', () => { await packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, - context, + coreMock.createCustomRequestHandlerContext(context), request ); @@ -1330,7 +1331,7 @@ describe('Package policy service', () => { await packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, - context, + coreMock.createCustomRequestHandlerContext(context), request ); } catch (e) { @@ -1349,7 +1350,7 @@ describe('Package policy service', () => { packagePolicyService.runExternalCallbacks( 'packagePolicyCreate', newPackagePolicy, - context, + coreMock.createCustomRequestHandlerContext(context), request ) ).rejects.toThrow('callbackThree threw error on purpose'); @@ -1438,15 +1439,16 @@ describe('Package policy service', () => { appContextService.addExternalCallback('packagePolicyPostCreate', callbackA); appContextService.addExternalCallback('packagePolicyPostCreate', callbackB); + const requestContext = coreMock.createCustomRequestHandlerContext(context); await packagePolicyService.runExternalCallbacks( 'packagePolicyPostCreate', packagePolicy, - context, + requestContext, request ); - expect(callbackA).toHaveBeenCalledWith(packagePolicy, context, request); - expect(callbackB).toHaveBeenCalledWith(packagePolicy, context, request); + expect(callbackA).toHaveBeenCalledWith(packagePolicy, requestContext, request); + expect(callbackB).toHaveBeenCalledWith(packagePolicy, requestContext, request); expect(callbackCallingOrder).toEqual(['a', 'b']); }); }); @@ -3326,6 +3328,7 @@ describe('Package policy service', () => { beforeEach(() => { savedObjectsClient = savedObjectsClientMock.create(); }); + function mockPackage(pkgName: string) { const mockPackagePolicy = createPackagePolicyMock(); @@ -3346,6 +3349,7 @@ describe('Package policy service', () => { attributes, }); } + it('should return success if package and policy versions match', async () => { mockPackage('apache'); diff --git a/x-pack/plugins/fleet/server/types/request_context.ts b/x-pack/plugins/fleet/server/types/request_context.ts index 0621319ba011c62..f9972c6262348f6 100644 --- a/x-pack/plugins/fleet/server/types/request_context.ts +++ b/x-pack/plugins/fleet/server/types/request_context.ts @@ -8,7 +8,7 @@ import type { KibanaResponseFactory, RequestHandler, - RequestHandlerContext, + CustomRequestHandlerContext, RouteMethod, SavedObjectsClientContract, IRouter, @@ -18,7 +18,7 @@ import type { FleetAuthz } from '../../common/authz'; import type { AgentClient } from '../services'; /** @internal */ -export interface FleetRequestHandlerContext extends RequestHandlerContext { +export type FleetRequestHandlerContext = CustomRequestHandlerContext<{ fleet: { /** {@link FleetAuthz} */ authz: FleetAuthz; @@ -36,7 +36,7 @@ export interface FleetRequestHandlerContext extends RequestHandlerContext { }; spaceId: string; }; -} +}>; /** * Convenience type for request handlers in Fleet that includes the FleetRequestHandlerContext type diff --git a/x-pack/plugins/global_search/server/mocks.ts b/x-pack/plugins/global_search/server/mocks.ts index b27c9f7a9e6b8b7..948ea49b95fa97c 100644 --- a/x-pack/plugins/global_search/server/mocks.ts +++ b/x-pack/plugins/global_search/server/mocks.ts @@ -52,7 +52,10 @@ const createRequestHandlerContextMock = (): jest.Mocked { async (ctx, req, res) => { const { params, options } = req.body; try { - const allResults = await ctx - .globalSearch!.find(params, { ...options, aborted$: req.events.aborted$ }) + const globalSearch = await ctx.globalSearch; + const allResults = await globalSearch + .find(params, { ...options, aborted$: req.events.aborted$ }) .pipe( map((batch) => batch.results), reduce((acc, results) => [...acc, ...results]) diff --git a/x-pack/plugins/global_search/server/routes/get_searchable_types.ts b/x-pack/plugins/global_search/server/routes/get_searchable_types.ts index 3db7a4ee7517445..f456c0e665f192b 100644 --- a/x-pack/plugins/global_search/server/routes/get_searchable_types.ts +++ b/x-pack/plugins/global_search/server/routes/get_searchable_types.ts @@ -14,7 +14,8 @@ export const registerInternalSearchableTypesRoute = (router: GlobalSearchRouter) validate: false, }, async (ctx, req, res) => { - const types = await ctx.globalSearch!.getSearchableTypes(); + const globalSearch = await ctx.globalSearch; + const types = await globalSearch.getSearchableTypes(); return res.ok({ body: { types, diff --git a/x-pack/plugins/global_search/server/types.ts b/x-pack/plugins/global_search/server/types.ts index 5f20f4f181db351..10a7bafe850dd7d 100644 --- a/x-pack/plugins/global_search/server/types.ts +++ b/x-pack/plugins/global_search/server/types.ts @@ -12,7 +12,7 @@ import type { SavedObjectsClientContract, Capabilities, IRouter, - RequestHandlerContext, + CustomRequestHandlerContext, } from '@kbn/core/server'; import { GlobalSearchBatchedResults, @@ -29,9 +29,9 @@ export type GlobalSearchPluginStart = Pick; /** * @internal diff --git a/x-pack/plugins/graph/server/routes/explore.ts b/x-pack/plugins/graph/server/routes/explore.ts index b3dddfb21cb920d..6a6072e17274c40 100644 --- a/x-pack/plugins/graph/server/routes/explore.ts +++ b/x-pack/plugins/graph/server/routes/explore.ts @@ -34,50 +34,44 @@ export function registerExploreRoute({ }), }, }, - router.handleLegacyErrors( - async ( - { - core: { - elasticsearch: { client: esClient }, + router.handleLegacyErrors(async ({ core }, request, response) => { + verifyApiAccess(licenseState); + licenseState.notifyUsage('Graph'); + + const { + elasticsearch: { client: esClient }, + } = await core; + try { + return response.ok({ + body: { + resp: await esClient.asCurrentUser.transport.request({ + path: '/' + encodeURIComponent(request.body.index) + '/_graph/explore', + body: request.body.query, + method: 'POST', + }), }, - }, - request, - response - ) => { - verifyApiAccess(licenseState); - licenseState.notifyUsage('Graph'); - try { - return response.ok({ - body: { - resp: await esClient.asCurrentUser.transport.request({ - path: '/' + encodeURIComponent(request.body.index) + '/_graph/explore', - body: request.body.query, - method: 'POST', - }), - }, + }); + } catch (error) { + if (error instanceof errors.ResponseError) { + const errorBody: ErrorResponse = error.body; + const relevantCause = (errorBody.error?.root_cause ?? []).find((cause) => { + return ( + cause.reason.includes('Fielddata is disabled on text fields') || + cause.reason.includes('No support for examining floating point') || + cause.reason.includes('Sample diversifying key must be a single valued-field') || + cause.reason.includes('Failed to parse query') || + cause.reason.includes('Text fields are not optimised for operations') || + cause.type === 'parsing_exception' + ); }); - } catch (error) { - if (error instanceof errors.ResponseError) { - const errorBody: ErrorResponse = error.body; - const relevantCause = (errorBody.error?.root_cause ?? []).find((cause) => { - return ( - cause.reason.includes('Fielddata is disabled on text fields') || - cause.reason.includes('No support for examining floating point') || - cause.reason.includes('Sample diversifying key must be a single valued-field') || - cause.reason.includes('Failed to parse query') || - cause.reason.includes('Text fields are not optimised for operations') || - cause.type === 'parsing_exception' - ); - }); - if (relevantCause) { - throw Boom.badRequest(relevantCause.reason); - } + if (relevantCause) { + throw Boom.badRequest(relevantCause.reason); } - - throw error; } + + throw error; } - ) + }) ); } diff --git a/x-pack/plugins/graph/server/routes/search.ts b/x-pack/plugins/graph/server/routes/search.ts index 8d5827fe13316c3..2bdb956196ed428 100644 --- a/x-pack/plugins/graph/server/routes/search.ts +++ b/x-pack/plugins/graph/server/routes/search.ts @@ -27,40 +27,33 @@ export function registerSearchRoute({ }), }, }, - router.handleLegacyErrors( - async ( - { - core: { - uiSettings: { client: uiSettings }, - elasticsearch: { client: esClient }, + router.handleLegacyErrors(async ({ core }, request, response) => { + verifyApiAccess(licenseState); + licenseState.notifyUsage('Graph'); + const { + uiSettings: { client: uiSettings }, + elasticsearch: { client: esClient }, + } = await core; + const includeFrozen = await uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); + try { + return response.ok({ + body: { + resp: await esClient.asCurrentUser.search({ + index: request.body.index, + body: request.body.body, + track_total_hits: true, + ...(includeFrozen ? { ignore_throttled: false } : {}), + }), }, - }, - request, - response - ) => { - verifyApiAccess(licenseState); - licenseState.notifyUsage('Graph'); - const includeFrozen = await uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); - try { - return response.ok({ - body: { - resp: await esClient.asCurrentUser.search({ - index: request.body.index, - body: request.body.body, - track_total_hits: true, - ...(includeFrozen ? { ignore_throttled: false } : {}), - }), - }, - }); - } catch (error) { - return response.customError({ - statusCode: error.statusCode || 500, - body: { - message: error.message, - }, - }); - } + }); + } catch (error) { + return response.customError({ + statusCode: error.statusCode || 500, + body: { + message: error.message, + }, + }); } - ) + }) ); } diff --git a/x-pack/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.ts b/x-pack/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.ts index fb20812f3307ebc..3154a1880f4a9ed 100644 --- a/x-pack/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.ts +++ b/x-pack/plugins/grokdebugger/server/routes/api/grokdebugger/register_grok_simulate_route.ts @@ -34,11 +34,11 @@ export function registerGrokSimulateRoute(framework: KibanaFramework) { }, async (requestContext, request, response) => { try { + const esClient = (await requestContext.core).elasticsearch.client; const grokdebuggerRequest = GrokdebuggerRequest.fromDownstreamJSON(request.body); - const simulateResponseFromES = - await requestContext.core.elasticsearch.client.asCurrentUser.ingest.simulate({ - body: grokdebuggerRequest.upstreamJSON, - }); + const simulateResponseFromES = await esClient.asCurrentUser.ingest.simulate({ + body: grokdebuggerRequest.upstreamJSON, + }); const grokdebuggerResponse = GrokdebuggerResponse.fromUpstreamJSON(simulateResponseFromES); return response.ok({ body: grokdebuggerResponse, diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts index da4668ab3ead382..1d4821e10211c9a 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_add_policy_route.ts @@ -45,12 +45,8 @@ export function registerAddPolicyRoute({ const { indexName, policyName, alias = '' } = body; try { - await addLifecyclePolicy( - context.core.elasticsearch.client.asCurrentUser, - indexName, - policyName, - alias - ); + const esClient = (await context.core).elasticsearch.client; + await addLifecyclePolicy(esClient.asCurrentUser, indexName, policyName, alias); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts index 08ea60cb806aebf..cec5da7aad90c8d 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_remove_route.ts @@ -39,7 +39,8 @@ export function registerRemoveRoute({ const { indexNames } = body; try { - await removeLifecycle(context.core.elasticsearch.client.asCurrentUser, indexNames); + const esClient = (await context.core).elasticsearch.client; + await removeLifecycle(esClient.asCurrentUser, indexNames); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts index d229e82504c9dae..42bcffcbd81223a 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/index/register_retry_route.ts @@ -36,7 +36,8 @@ export function registerRetryRoute({ router, license, lib: { handleEsError } }: const { indexNames } = body; try { - await retryLifecycle(context.core.elasticsearch.client.asCurrentUser, indexNames); + const esClient = (await context.core).elasticsearch.client; + await retryLifecycle(esClient.asCurrentUser, indexNames); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts index 3cf26ca96595abe..13393182d052896 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_details_route.ts @@ -42,7 +42,8 @@ export function registerDetailsRoute({ const { nodeAttrs } = params; try { - const statsResponse = await context.core.elasticsearch.client.asCurrentUser.nodes.stats(); + const esClient = (await context.core).elasticsearch.client; + const statsResponse = await esClient.asCurrentUser.nodes.stats(); const okResponse = { body: findMatchingNodes(statsResponse, nodeAttrs) }; return response.ok(okResponse); } catch (error) { diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts index cf892ddff67bfca..a9b17c25110b0ec 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/nodes/register_list_route.ts @@ -88,14 +88,14 @@ export function registerListRoute({ { path: addBasePath('/nodes/list'), validate: false }, license.guardApiRoute(async (context, request, response) => { try { - const settingsResponse = - await context.core.elasticsearch.client.asCurrentUser.transport.request({ - method: 'GET', - path: '/_nodes/settings', - querystring: { - format: 'json', - }, - }); + const esClient = (await context.core).elasticsearch.client; + const settingsResponse = await esClient.asCurrentUser.transport.request({ + method: 'GET', + path: '/_nodes/settings', + querystring: { + format: 'json', + }, + }); const body: ListNodesRouteResponse = convertSettingsIntoLists( settingsResponse as Settings, disallowedNodeAttributes diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts index 909f6ca7bf5a8c8..65c37120e552f13 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts @@ -55,7 +55,8 @@ export function registerCreateRoute({ const { name, ...rest } = body; try { - await createPolicy(context.core.elasticsearch.client.asCurrentUser, name, rest); + const esClient = (await context.core).elasticsearch.client; + await createPolicy(esClient.asCurrentUser, name, rest); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts index 9927f093aef253c..d113e646f0b3880 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_delete_route.ts @@ -36,7 +36,8 @@ export function registerDeleteRoute({ const { policyNames } = params; try { - await deletePolicies(context.core.elasticsearch.client.asCurrentUser, policyNames); + const esClient = (await context.core).elasticsearch.client; + await deletePolicies(esClient.asCurrentUser, policyNames); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts index 09f28679d58b2cf..9526aca51d33ff5 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_fetch_route.ts @@ -62,7 +62,7 @@ export function registerFetchRoute({ router, license, lib: { handleEsError } }: router.get( { path: addBasePath('/policies'), validate: false }, license.guardApiRoute(async (context, request, response) => { - const { asCurrentUser } = context.core.elasticsearch.client; + const { asCurrentUser } = (await context.core).elasticsearch.client; try { const policiesResponse = await fetchPolicies(asCurrentUser); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_policies/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_policies/register_fetch_route.ts index ebe8a2388a02521..5a0190828789603 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_policies/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_policies/register_fetch_route.ts @@ -13,8 +13,8 @@ export function registerFetchRoute({ router, license, lib: { handleEsError } }: { path: addBasePath('/snapshot_policies'), validate: false }, license.guardApiRoute(async (context, request, response) => { try { - const policiesByName = - await context.core.elasticsearch.client.asCurrentUser.slm.getLifecycle(); + const esClient = (await context.core).elasticsearch.client; + const policiesByName = await esClient.asCurrentUser.slm.getLifecycle(); return response.ok({ body: Object.keys(policiesByName) }); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_repositories/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_repositories/register_fetch_route.ts index a4bdbd5fc7afc98..45a55cfce5da1b1 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_repositories/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/snapshot_repositories/register_fetch_route.ts @@ -28,7 +28,8 @@ export const registerFetchRoute = ({ router, license }: RouteDependencies) => { } try { - const esResult = await ctx.core.elasticsearch.client.asCurrentUser.snapshot.getRepository({ + const esClient = (await ctx.core).elasticsearch.client; + const esResult = await esClient.asCurrentUser.snapshot.getRepository({ name: '*', }); const repos: ListSnapshotReposResponse = { diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts index 8b8b50834c69a47..3f6b4ce843e8972 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_add_policy_route.ts @@ -106,8 +106,9 @@ export function registerAddPolicyRoute({ const { templateName, policyName, aliasName } = body; const isLegacy = (request.query as TypeOf).legacy === 'true'; try { + const esClient = (await context.core).elasticsearch.client; const updatedTemplate = await updateIndexTemplate( - context.core.elasticsearch.client.asCurrentUser, + esClient.asCurrentUser, isLegacy, templateName, policyName, diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts index dfa3f0c6b64c995..e70f2ed2bdac0da 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/templates/register_fetch_route.ts @@ -88,10 +88,8 @@ export function registerFetchRoute({ router, license, lib: { handleEsError } }: license.guardApiRoute(async (context, request, response) => { const isLegacy = (request.query as TypeOf).legacy === 'true'; try { - const templates = await fetchTemplates( - context.core.elasticsearch.client.asCurrentUser, - isLegacy - ); + const esClient = (await context.core).elasticsearch.client; + const templates = await fetchTemplates(esClient.asCurrentUser, isLegacy); const okResponse = { body: filterTemplates(templates, isLegacy) }; return response.ok(okResponse); } catch (error) { diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_create_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_create_route.ts index cc98035f37c5c28..adfa0d61859f15c 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_create_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_create_route.ts @@ -24,7 +24,7 @@ export const registerCreateRoute = ({ }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const serializedComponentTemplate = serializeComponentTemplate(request.body); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_delete_route.ts index 34a644d6071625e..c06f90821b3374c 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_delete_route.ts @@ -26,7 +26,7 @@ export const registerDeleteRoute = ({ }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { names } = request.params; const componentNames = names.split(','); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_get_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_get_route.ts index caca3c8ce853f66..73224c0356ad591 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_get_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_get_route.ts @@ -24,7 +24,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep router.get( { path: addBasePath('/component_templates'), validate: false }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { component_templates: componentTemplates } = @@ -58,7 +58,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name } = request.params; try { diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts index d2fe85d219ef155..a8b488fb54c9adb 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.ts @@ -41,7 +41,7 @@ export const registerPrivilegesRoute = ({ return response.ok({ body: privilegesResult }); } - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const { has_all_requested: hasAllPrivileges, cluster } = diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_update_route.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_update_route.ts index 016e379165d4923..1a9e642cd934283 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_update_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_update_route.ts @@ -29,7 +29,7 @@ export const registerUpdateRoute = ({ }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name } = request.params; const { template, version, _meta } = request.body; diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts index 0602aaaaafc6c2e..dcdb4056cb6810e 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts @@ -21,7 +21,7 @@ export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDep validate: { body: bodySchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { dataStreams } = request.body as TypeOf; const responseBody: { dataStreamsDeleted: string[]; errors: any[] } = { diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts index a698be6f913d358..a562cc5f4cc528f 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts @@ -103,7 +103,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: router.get( { path: addBasePath('/data_streams'), validate: { query: querySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const includeStats = (request.query as TypeOf).includeStats === 'true'; @@ -152,7 +152,7 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: }, async (context, request, response) => { const { name } = request.params as TypeOf; - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const [{ data_streams: dataStreams }, { data_streams: dataStreamsStats }] = await Promise.all([getDataStreams(client, name), getDataStreamsStats(client, name)]); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts index 9e7c4a82bca591e..a46a23b8fe4799b 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts @@ -18,7 +18,7 @@ export function registerClearCacheRoute({ router, lib: { handleEsError } }: Rout router.post( { path: addBasePath('/indices/clear_cache'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts index 7d549dadd010c69..69d33b7fc799900 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts @@ -18,7 +18,7 @@ export function registerCloseRoute({ router, lib: { handleEsError } }: RouteDepe router.post( { path: addBasePath('/indices/close'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts index 8f9771185805907..b72a2059beb1d9b 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts @@ -18,7 +18,7 @@ export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDep router.post( { path: addBasePath('/indices/delete'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts index d8215849d2de5e8..cc07b92e709074b 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts @@ -18,7 +18,7 @@ export function registerFlushRoute({ router, lib: { handleEsError } }: RouteDepe router.post( { path: addBasePath('/indices/flush'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts index d9bdd572b63f339..af07a7371cf65b9 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts @@ -24,7 +24,7 @@ export function registerForcemergeRoute({ router, lib: { handleEsError } }: Rout }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { maxNumSegments, indices = [] } = request.body as typeof bodySchema.type; const params = { expand_wildcards: 'none' as const, diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts index cbdfee665cfec0a..48c1800aba95e48 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts @@ -17,7 +17,7 @@ export function registerListRoute({ router.get( { path: addBasePath('/indices'), validate: false }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const indices = await fetchIndices(client, indexDataEnricher); return response.ok({ body: indices }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts index b7aa023c27433c6..dde9e72af39d73e 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts @@ -18,7 +18,7 @@ export function registerOpenRoute({ router, lib: { handleEsError } }: RouteDepen router.post( { path: addBasePath('/indices/open'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts index ba7d3f19dbb2376..2483cd534b80e4a 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts @@ -18,7 +18,7 @@ export function registerRefreshRoute({ router, lib: { handleEsError } }: RouteDe router.post( { path: addBasePath('/indices/refresh'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; const params = { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts index 05951629bcb2dd2..42b78fe246ba825 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts @@ -25,7 +25,7 @@ export function registerReloadRoute({ router.post( { path: addBasePath('/indices/reload'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexNames = [] } = (request.body as typeof bodySchema.type) ?? {}; try { diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts index e0447efe1090f25..3636a0707df8ce8 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts @@ -18,7 +18,7 @@ export function registerUnfreezeRoute({ router, lib: { handleEsError } }: RouteD router.post( { path: addBasePath('/indices/unfreeze'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indices = [] } = request.body as typeof bodySchema.type; try { diff --git a/x-pack/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts b/x-pack/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts index c2dbcc92144b24a..641ad26417f67d8 100644 --- a/x-pack/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts @@ -25,7 +25,7 @@ export function registerMappingRoute({ router, lib: { handleEsError } }: RouteDe router.get( { path: addBasePath('/mapping/{indexName}'), validate: { params: paramsSchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexName } = request.params as typeof paramsSchema.type; const params = { expand_wildcards: 'none' as const, diff --git a/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.ts b/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.ts index 8702a6bdd203791..08a0684f69c972b 100644 --- a/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.ts @@ -13,7 +13,7 @@ export function registerNodesRoute({ router, lib: { handleEsError } }: RouteDepe router.get( { path: addBasePath('/nodes/plugins'), validate: {} }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const body = await client.asCurrentUser.nodes.info(); diff --git a/x-pack/plugins/index_management/server/routes/api/settings/register_load_route.ts b/x-pack/plugins/index_management/server/routes/api/settings/register_load_route.ts index fc8600182dd1322..bcdf29af65856a9 100644 --- a/x-pack/plugins/index_management/server/routes/api/settings/register_load_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/settings/register_load_route.ts @@ -25,7 +25,7 @@ export function registerLoadRoute({ router, lib: { handleEsError } }: RouteDepen router.get( { path: addBasePath('/settings/{indexName}'), validate: { params: paramsSchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexName } = request.params as typeof paramsSchema.type; const params = { expand_wildcards: 'none' as const, diff --git a/x-pack/plugins/index_management/server/routes/api/settings/register_update_route.ts b/x-pack/plugins/index_management/server/routes/api/settings/register_update_route.ts index 31f04a20c5dbeaf..cfb0be50e048480 100644 --- a/x-pack/plugins/index_management/server/routes/api/settings/register_update_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/settings/register_update_route.ts @@ -23,7 +23,7 @@ export function registerUpdateRoute({ router, lib: { handleEsError } }: RouteDep validate: { body: bodySchema, params: paramsSchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexName } = request.params as typeof paramsSchema.type; const params = { ignore_unavailable: true, diff --git a/x-pack/plugins/index_management/server/routes/api/stats/register_stats_route.ts b/x-pack/plugins/index_management/server/routes/api/stats/register_stats_route.ts index a81aba00901ebc3..8e361d8488ba377 100644 --- a/x-pack/plugins/index_management/server/routes/api/stats/register_stats_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/stats/register_stats_route.ts @@ -33,7 +33,7 @@ export function registerStatsRoute({ router, lib: { handleEsError } }: RouteDepe router.get( { path: addBasePath('/stats/{indexName}'), validate: { params: paramsSchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { indexName } = request.params as typeof paramsSchema.type; const params = { expand_wildcards: 'none' as const, diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts index 7463f41cb18acee..0b903d4356ec447 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts @@ -19,7 +19,7 @@ export function registerCreateRoute({ router, lib: { handleEsError } }: RouteDep router.post( { path: addBasePath('/index_templates'), validate: { body: bodySchema } }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const template = request.body as TemplateDeserialized; try { diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts index 585408bbfe23308..b6c289f3a72a8b3 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts @@ -28,7 +28,7 @@ export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDep validate: { body: bodySchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { templates } = request.body as TypeOf; const responseBody: { templatesDeleted: Array; diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts index f8966b1355ffe0f..32661bb308876ad 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts @@ -21,7 +21,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep router.get( { path: addBasePath('/index_templates'), validate: false }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(client); @@ -66,7 +66,7 @@ export function registerGetOneRoute({ router, lib: { handleEsError } }: RouteDep validate: { params: paramsSchema, query: querySchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name } = request.params as TypeOf; const isLegacy = (request.query as TypeOf).legacy === 'true'; diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_simulate_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_simulate_route.ts index 13833cb8893629b..3dc6201f0831c41 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_simulate_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_simulate_route.ts @@ -19,7 +19,7 @@ export function registerSimulateRoute({ router, lib: { handleEsError } }: RouteD validate: { body: bodySchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const template = request.body as TypeOf; try { diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts index 7d89d0ff8af0903..30b93f2e59ec03a 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts @@ -25,7 +25,7 @@ export function registerUpdateRoute({ router, lib: { handleEsError } }: RouteDep validate: { body: bodySchema, params: paramsSchema }, }, async (context, request, response) => { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const { name } = request.params as typeof paramsSchema.type; const template = request.body as TemplateDeserialized; diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts index 28592e430c163cb..7aa4b433c477c2e 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -124,7 +124,7 @@ export class KibanaFramework { endpoint: string, params: CallWithRequestParams ) { - const { elasticsearch, uiSettings } = requestContext.core; + const { elasticsearch, uiSettings } = await requestContext.core; const includeFrozen = await uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); if (endpoint === 'msearch') { @@ -200,9 +200,10 @@ export class KibanaFramework { public async getIndexPatternsServiceWithRequestContext( requestContext: InfraPluginRequestHandlerContext ) { + const { savedObjects, elasticsearch } = await requestContext.core; return await this.createIndexPatternsService( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser + savedObjects.client, + elasticsearch.client.asCurrentUser ); } diff --git a/x-pack/plugins/infra/server/lib/domains/fields_domain.ts b/x-pack/plugins/infra/server/lib/domains/fields_domain.ts index 0997d9517fa8d61..b80fa9d796021fe 100644 --- a/x-pack/plugins/infra/server/lib/domains/fields_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/fields_domain.ts @@ -20,10 +20,8 @@ export class InfraFieldsDomain { sourceId: string, indexType: 'METRICS' ): Promise { - const { configuration } = await this.libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const { configuration } = await this.libs.sources.getSourceConfiguration(soClient, sourceId); const fields = await this.adapter.getIndexFields(requestContext, configuration.metricAlias); diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts index ef6b7122aa4de33..1e0daad376a1a55 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -42,6 +42,7 @@ export interface LogEntriesParams { cursor?: { before: LogEntryCursor | 'last' } | { after: LogEntryCursor | 'first' }; highlightTerm?: string; } + export interface LogEntriesAroundParams { startTimestamp: number; endTimestamp: number; @@ -130,11 +131,9 @@ export class InfraLogEntriesDomain { columnOverrides?: LogViewColumnConfiguration[] ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }> { const [, , { logViews }] = await this.libs.getStartServices(); + const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews - .getClient( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser - ) + .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) .getResolvedLogView(sourceId); const columnDefinitions = columnOverrides ?? resolvedLogView.columns; @@ -192,11 +191,9 @@ export class InfraLogEntriesDomain { filterQuery?: LogEntryQuery ): Promise { const [, , { logViews }] = await this.libs.getStartServices(); + const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews - .getClient( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser - ) + .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) .getResolvedLogView(sourceId); const dateRangeBuckets = await this.adapter.getContainedLogSummaryBuckets( requestContext, @@ -219,11 +216,9 @@ export class InfraLogEntriesDomain { filterQuery?: LogEntryQuery ): Promise { const [, , { logViews }] = await this.libs.getStartServices(); + const { savedObjects, elasticsearch } = await requestContext.core; const resolvedLogView = await logViews - .getClient( - requestContext.core.savedObjects.client, - requestContext.core.elasticsearch.client.asCurrentUser - ) + .getClient(savedObjects.client, elasticsearch.client.asCurrentUser) .getResolvedLogView(sourceId); const messageFormattingRules = compileFormattingRules( getBuiltinRules(resolvedLogView.messageField) diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts index feb0f6b5b999844..22bf5466ee3b44e 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_anomalies.ts @@ -96,7 +96,9 @@ async function getCompatibleAnomaliesJobIds( } export async function getLogEntryAnomalies( - context: InfraPluginRequestHandlerContext & { infra: Required }, + context: InfraPluginRequestHandlerContext & { + infra: Promise>; + }, sourceId: string, startTime: number, endTime: number, @@ -106,13 +108,14 @@ export async function getLogEntryAnomalies( ) { const finalizeLogEntryAnomaliesSpan = startTracingSpan('get log entry anomalies'); + const infraContext = await context.infra; const { jobIds, timing: { spans: jobSpans }, } = await getCompatibleAnomaliesJobIds( - context.infra.spaceId, + infraContext.spaceId, sourceId, - context.infra.mlAnomalyDetectors + infraContext.mlAnomalyDetectors ); if (jobIds.length === 0) { @@ -127,7 +130,7 @@ export async function getLogEntryAnomalies( hasMoreEntries, timing: { spans: fetchLogEntryAnomaliesSpans }, } = await fetchLogEntryAnomalies( - context.infra.mlSystem, + infraContext.mlSystem, jobIds, startTime, endTime, @@ -151,13 +154,13 @@ export async function getLogEntryAnomalies( }, []); const logEntryCategoriesCountJobId = getJobId( - context.infra.spaceId, + infraContext.spaceId, sourceId, logEntryCategoriesJobTypes[0] ); const { logEntryCategoriesById } = await fetchLogEntryCategories( - context, + { infra: infraContext }, logEntryCategoriesCountJobId, categoryIds ); @@ -325,7 +328,9 @@ async function fetchLogEntryAnomalies( } export async function getLogEntryExamples( - context: InfraPluginRequestHandlerContext & { infra: Required }, + context: InfraPluginRequestHandlerContext & { + infra: Promise>; + }, sourceId: string, startTime: number, endTime: number, @@ -336,9 +341,10 @@ export async function getLogEntryExamples( categoryId?: string ) { const finalizeLogEntryExamplesSpan = startTracingSpan('get log entry rate example log entries'); + const infraContext = await context.infra; const jobId = getJobId( - context.infra.spaceId, + infraContext.spaceId, sourceId, categoryId != null ? logEntryCategoriesJobTypes[0] : logEntryRateJobTypes[0] ); @@ -346,7 +352,7 @@ export async function getLogEntryExamples( const { mlJob, timing: { spans: fetchMlJobSpans }, - } = await fetchMlJob(context.infra.mlAnomalyDetectors, jobId); + } = await fetchMlJob(infraContext.mlAnomalyDetectors, jobId); const customSettings = decodeOrThrow(jobCustomSettingsRT)(mlJob.custom_settings); const indices = customSettings?.logs_source_config?.indexPattern; @@ -388,7 +394,9 @@ export async function getLogEntryExamples( } export async function fetchLogEntryExamples( - context: InfraPluginRequestHandlerContext & { infra: Required }, + context: InfraPluginRequestHandlerContext & { + infra: Promise>; + }, sourceId: string, indices: string, runtimeMappings: estypes.MappingRuntimeFields, @@ -403,6 +411,7 @@ export async function fetchLogEntryExamples( ) { const finalizeEsSearchSpan = startTracingSpan('Fetch log rate examples from ES'); + const infraContext = await context.infra; let categoryQuery: string | undefined; // Examples should be further scoped to a specific ML category @@ -410,13 +419,13 @@ export async function fetchLogEntryExamples( const parsedCategoryId = parseInt(categoryId, 10); const logEntryCategoriesCountJobId = getJobId( - context.infra.spaceId, + infraContext.spaceId, sourceId, logEntryCategoriesJobTypes[0] ); const { logEntryCategoriesById } = await fetchLogEntryCategories( - context, + { infra: infraContext }, logEntryCategoriesCountJobId, [parsedCategoryId] ); diff --git a/x-pack/plugins/infra/server/lib/source_status.ts b/x-pack/plugins/infra/server/lib/source_status.ts index 8c6d7d1ad451fa6..9e492e448ab92c2 100644 --- a/x-pack/plugins/infra/server/lib/source_status.ts +++ b/x-pack/plugins/infra/server/lib/source_status.ts @@ -18,38 +18,34 @@ export class InfraSourceStatus { requestContext: InfraPluginRequestHandlerContext, sourceId: string ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const sourceConfiguration = await this.libs.sources.getSourceConfiguration(soClient, sourceId); const indexNames = await this.adapter.getIndexNames( requestContext, sourceConfiguration.configuration.metricAlias ); return indexNames; } + public async hasMetricAlias( requestContext: InfraPluginRequestHandlerContext, sourceId: string ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const sourceConfiguration = await this.libs.sources.getSourceConfiguration(soClient, sourceId); const hasAlias = await this.adapter.hasAlias( requestContext, sourceConfiguration.configuration.metricAlias ); return hasAlias; } + public async hasMetricIndices( requestContext: InfraPluginRequestHandlerContext, sourceId: string ): Promise { - const sourceConfiguration = await this.libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const sourceConfiguration = await this.libs.sources.getSourceConfiguration(soClient, sourceId); const indexStatus = await this.adapter.getIndexStatus( requestContext, sourceConfiguration.configuration.metricAlias @@ -65,7 +61,9 @@ export interface InfraSourceStatusAdapter { requestContext: InfraPluginRequestHandlerContext, aliasName: string ): Promise; + hasAlias(requestContext: InfraPluginRequestHandlerContext, aliasName: string): Promise; + getIndexStatus( requestContext: InfraPluginRequestHandlerContext, indexNames: string diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index a0d0b617f3f4167..8eb2bac57dc5684 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -190,12 +190,10 @@ export class InfraServerPlugin core.http.registerRouteHandlerContext( 'infra', - (context, request) => { - const mlSystem = plugins.ml?.mlSystemProvider(request, context.core.savedObjects.client); - const mlAnomalyDetectors = plugins.ml?.anomalyDetectorsProvider( - request, - context.core.savedObjects.client - ); + async (context, request) => { + const soClient = (await context.core).savedObjects.client; + const mlSystem = plugins.ml?.mlSystemProvider(request, soClient); + const mlAnomalyDetectors = plugins.ml?.anomalyDetectorsProvider(request, soClient); const spaceId = plugins.spaces?.spacesService.getSpaceId(request) || 'default'; return { @@ -240,5 +238,6 @@ export class InfraServerPlugin logViews, }; } + stop() {} } diff --git a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts index 1b5ed62a006be93..a83854817866f7b 100644 --- a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts @@ -47,7 +47,7 @@ export const initGetHostsAnomaliesRoute = ({ framework }: InfraBackendLibs) => { const { sort, pagination } = getSortAndPagination(sortParam, paginationParam); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: anomalies, @@ -55,7 +55,7 @@ export const initGetHostsAnomaliesRoute = ({ framework }: InfraBackendLibs) => { hasMoreEntries, timing, } = await getMetricsHostsAnomalies({ - context: requestContext.infra, + context: await infraMlContext.infra, sourceId, anomalyThreshold, startTime, diff --git a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts index 667760d1d409e37..55cc6c40983257f 100644 --- a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts @@ -45,7 +45,7 @@ export const initGetK8sAnomaliesRoute = ({ framework }: InfraBackendLibs) => { const { sort, pagination } = getSortAndPagination(sortParam, paginationParam); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: anomalies, @@ -53,7 +53,7 @@ export const initGetK8sAnomaliesRoute = ({ framework }: InfraBackendLibs) => { hasMoreEntries, timing, } = await getMetricK8sAnomalies({ - context: requestContext.infra, + context: await infraMlContext.infra, sourceId, anomalyThreshold, startTime, diff --git a/x-pack/plugins/infra/server/routes/inventory_metadata/index.ts b/x-pack/plugins/infra/server/routes/inventory_metadata/index.ts index 70d29773f76c5d5..c6ed81ccd825630 100644 --- a/x-pack/plugins/infra/server/routes/inventory_metadata/index.ts +++ b/x-pack/plugins/infra/server/routes/inventory_metadata/index.ts @@ -38,10 +38,8 @@ export const initInventoryMetaRoute = (libs: InfraBackendLibs) => { fold(throwErrors(Boom.badRequest), identity) ); - const { configuration } = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const { configuration } = await libs.sources.getSourceConfiguration(soClient, sourceId); const awsMetadata = await getCloudMetadata( framework, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts index d0a18727b68133e..dd6254cf560e2e9 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies.ts @@ -42,7 +42,7 @@ export const initGetLogEntryAnomaliesRoute = ({ framework }: InfraBackendLibs) = const { sort, pagination } = getSortAndPagination(sortParam, paginationParam); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryAnomalies, @@ -50,7 +50,7 @@ export const initGetLogEntryAnomaliesRoute = ({ framework }: InfraBackendLibs) = hasMoreEntries, timing, } = await getLogEntryAnomalies( - requestContext, + infraMlContext, sourceId, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts index 9d3b9f22a839e5e..1d1f620063b2ebb 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_anomalies_datasets.ts @@ -35,10 +35,10 @@ export const initGetLogEntryAnomaliesDatasetsRoute = ({ framework }: InfraBacken } = request.body; try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { datasets, timing } = await getLogEntryAnomaliesDatasets( - requestContext, + { infra: await infraMlContext.infra }, sourceId, startTime, endTime diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts index d3660aa16c1f8fc..6e2e8e8a6c2ada0 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_categories.ts @@ -39,10 +39,10 @@ export const initGetLogEntryCategoriesRoute = ({ framework }: InfraBackendLibs) } = request.body; try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: topLogEntryCategories, timing } = await getTopLogEntryCategories( - requestContext, + { infra: await infraMlContext.infra }, sourceId, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts index 76103c936dd6d14..de5ac9dac4b0754 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets.ts @@ -35,10 +35,10 @@ export const initGetLogEntryCategoryDatasetsRoute = ({ framework }: InfraBackend } = request.body; try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryCategoryDatasets, timing } = await getLogEntryCategoryDatasets( - requestContext, + { infra: await infraMlContext.infra }, sourceId, startTime, endTime diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets_stats.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets_stats.ts index 01a98ce43833b68..5844405ec062d05 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets_stats.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_datasets_stats.ts @@ -36,10 +36,10 @@ export const initGetLogEntryCategoryDatasetsStatsRoute = ({ framework }: InfraBa } = request.body; try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: datasetStats, timing } = await getLatestLogEntriesCategoriesDatasetsStats( - requestContext, + { infra: await infraMlContext.infra }, jobIds, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts index 14787406319dbc9..b51aed45b7e1163 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_category_examples.ts @@ -43,10 +43,10 @@ export const initGetLogEntryCategoryExamplesRoute = ({ const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(sourceId); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryCategoryExamples, timing } = await getLogEntryCategoryExamples( - requestContext, + { infra: await infraMlContext.infra, core: await infraMlContext.core }, sourceId, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts index f11e9e46bf4c619..fb82a2cd90df5b6 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/results/log_entry_examples.ts @@ -44,10 +44,10 @@ export const initGetLogEntryExamplesRoute = ({ const resolvedLogView = await logViews.getScopedClient(request).getResolvedLogView(sourceId); try { - assertHasInfraMlPlugins(requestContext); + const infraMlContext = await assertHasInfraMlPlugins(requestContext); const { data: logEntryExamples, timing } = await getLogEntryExamples( - requestContext, + infraMlContext, sourceId, startTime, endTime, diff --git a/x-pack/plugins/infra/server/routes/metadata/index.ts b/x-pack/plugins/infra/server/routes/metadata/index.ts index 39021ba51c9d910..18ee48ed5ad090f 100644 --- a/x-pack/plugins/infra/server/routes/metadata/index.ts +++ b/x-pack/plugins/infra/server/routes/metadata/index.ts @@ -42,10 +42,8 @@ export const initMetadataRoute = (libs: InfraBackendLibs) => { fold(throwErrors(Boom.badRequest), identity) ); - const { configuration } = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const { configuration } = await libs.sources.getSourceConfiguration(soClient, sourceId); const metricsMetadata = await getMetricMetadata( framework, requestContext, diff --git a/x-pack/plugins/infra/server/routes/metrics_sources/index.ts b/x-pack/plugins/infra/server/routes/metrics_sources/index.ts index cba520e6d53c0eb..a0cd0afbca50c8a 100644 --- a/x-pack/plugins/infra/server/routes/metrics_sources/index.ts +++ b/x-pack/plugins/infra/server/routes/metrics_sources/index.ts @@ -33,9 +33,10 @@ export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => }, async (requestContext, request, response) => { const { sourceId } = request.params; + const soClient = (await requestContext.core).savedObjects.client; const [source, metricIndicesExist, indexFields] = await Promise.all([ - libs.sources.getSourceConfiguration(requestContext.core.savedObjects.client, sourceId), + libs.sources.getSourceConfiguration(soClient, sourceId), libs.sourceStatus.hasMetricIndices(requestContext, sourceId), libs.fields.getFields(requestContext, sourceId, 'METRICS'), ]); @@ -72,10 +73,8 @@ export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => const patchedSourceConfigurationProperties = request.body; try { - const sourceConfiguration = await sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const sourceConfiguration = await sources.getSourceConfiguration(soClient, sourceId); if (sourceConfiguration.origin === 'internal') { response.conflict({ @@ -86,13 +85,13 @@ export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => const sourceConfigurationExists = sourceConfiguration.origin === 'stored'; const patchedSourceConfiguration = await (sourceConfigurationExists ? sources.updateSourceConfiguration( - requestContext.core.savedObjects.client, + soClient, sourceId, // @ts-ignore patchedSourceConfigurationProperties ) : sources.createSourceConfiguration( - requestContext.core.savedObjects.client, + soClient, sourceId, // @ts-ignore patchedSourceConfigurationProperties @@ -151,10 +150,8 @@ export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => const { sourceId } = request.params; const client = createSearchClient(requestContext, framework); - const source = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, sourceId); const results = await hasData(source.configuration.metricAlias, client); diff --git a/x-pack/plugins/infra/server/routes/node_details/index.ts b/x-pack/plugins/infra/server/routes/node_details/index.ts index 8e305226112bd3b..cd92c902a110eda 100644 --- a/x-pack/plugins/infra/server/routes/node_details/index.ts +++ b/x-pack/plugins/infra/server/routes/node_details/index.ts @@ -38,10 +38,8 @@ export const initNodeDetailsRoute = (libs: InfraBackendLibs) => { NodeDetailsRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity) ); - const source = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, sourceId); UsageCollector.countNode(nodeType); diff --git a/x-pack/plugins/infra/server/routes/overview/index.ts b/x-pack/plugins/infra/server/routes/overview/index.ts index fa0e0f4d09affa3..9736fd0d7c22ea4 100644 --- a/x-pack/plugins/infra/server/routes/overview/index.ts +++ b/x-pack/plugins/infra/server/routes/overview/index.ts @@ -24,10 +24,8 @@ export const initOverviewRoute = (libs: InfraBackendLibs) => { async (requestContext, request, response) => { const options = request.body; const client = createSearchClient(requestContext, framework); - const source = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - options.sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, options.sourceId); const topNResponse = await queryTopNodes(options, client, source); diff --git a/x-pack/plugins/infra/server/routes/snapshot/index.ts b/x-pack/plugins/infra/server/routes/snapshot/index.ts index 06b2104e0e17eb3..99cde598b19e4b7 100644 --- a/x-pack/plugins/infra/server/routes/snapshot/index.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/index.ts @@ -37,10 +37,8 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => { fold(throwErrors(Boom.badRequest), identity) ); - const source = await libs.sources.getSourceConfiguration( - requestContext.core.savedObjects.client, - snapshotRequest.sourceId - ); + const soClient = (await requestContext.core).savedObjects.client; + const source = await libs.sources.getSourceConfiguration(soClient, snapshotRequest.sourceId); const compositeSize = libs.configuration.inventory.compositeSize; const [, , { logViews }] = await libs.getStartServices(); const logQueryFields: LogQueryFields | undefined = await logViews diff --git a/x-pack/plugins/infra/server/types.ts b/x-pack/plugins/infra/server/types.ts index a791c15d9e6b98e..e3792c8977cfe7a 100644 --- a/x-pack/plugins/infra/server/types.ts +++ b/x-pack/plugins/infra/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { CoreSetup, RequestHandlerContext } from '@kbn/core/server'; +import type { CoreSetup, CustomRequestHandlerContext } from '@kbn/core/server'; import type { SearchRequestHandlerContext } from '@kbn/data-plugin/server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; import type { InfraStaticSourceConfiguration } from '../common/source_configuration/source_configuration'; @@ -47,7 +47,7 @@ export type InfraRequestHandlerContext = InfraMlRequestHandlerContext & /** * @internal */ -export interface InfraPluginRequestHandlerContext extends RequestHandlerContext { +export type InfraPluginRequestHandlerContext = CustomRequestHandlerContext<{ infra: InfraRequestHandlerContext; search: SearchRequestHandlerContext; -} +}>; diff --git a/x-pack/plugins/infra/server/utils/request_context.ts b/x-pack/plugins/infra/server/utils/request_context.ts index 8924a03549adc50..f0546c88439900a 100644 --- a/x-pack/plugins/infra/server/utils/request_context.ts +++ b/x-pack/plugins/infra/server/utils/request_context.ts @@ -7,7 +7,7 @@ /* eslint-disable max-classes-per-file */ -import { InfraMlRequestHandlerContext, InfraRequestHandlerContext } from '../types'; +import { InfraRequestHandlerContext } from '../types'; export class MissingContextValuesError extends Error { constructor(message?: string) { @@ -23,22 +23,31 @@ export class NoMlPluginError extends Error { } } -export function assertHasInfraPlugins( - context: Context -): asserts context is Context & { infra: Context['infra'] } { +export function assertHasInfraPlugins< + Context extends { infra?: Promise } +>(context: Context): asserts context is Context & { infra: Context['infra'] } { if (context.infra == null) { throw new MissingContextValuesError('Failed to access "infra" context values.'); } } -export function assertHasInfraMlPlugins( +export async function assertHasInfraMlPlugins< + Context extends { infra?: Promise } +>( context: Context -): asserts context is Context & { - infra: Context['infra'] & Required; -} { +): Promise< + Context & { + infra: Promise>; + } +> { assertHasInfraPlugins(context); - if (context.infra?.mlAnomalyDetectors == null || context.infra?.mlSystem == null) { + const infraContext = await context.infra; + if (infraContext?.mlAnomalyDetectors == null || infraContext?.mlSystem == null) { throw new NoMlPluginError('Failed to access ML plugin.'); } + + return context as Context & { + infra: Promise>; + }; } diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts index 90893b2841cc0da..1e59151f738850e 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts @@ -30,7 +30,7 @@ export const registerCreateRoute = ({ }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const pipeline = req.body as Pipeline; // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts index 1ffa5adabd83b35..1b2fdd1444400e4 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/delete.ts @@ -23,7 +23,7 @@ export const registerDeleteRoute = ({ router }: RouteDependencies): void => { }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { names } = req.params; const pipelineNames = names.split(','); diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts index d9f27ed84f89984..b5aff114e44d2f6 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts @@ -27,7 +27,7 @@ export const registerDocumentsRoute = ({ }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { index, id } = req.params; try { diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts index 7da2cf3e6a13a1a..c053c80e6571347 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts @@ -18,7 +18,7 @@ const paramsSchema = schema.object({ export const registerGetRoutes = ({ router, lib: { handleEsError } }: RouteDependencies): void => { // Get all pipelines router.get({ path: API_BASE_PATH, validate: false }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; try { const pipelines = await clusterClient.asCurrentUser.ingest.getPipeline(); @@ -44,7 +44,7 @@ export const registerGetRoutes = ({ router, lib: { handleEsError } }: RouteDepen }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params; try { diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts index 114a5b8840336d9..175ef4eb37179ef 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts @@ -36,7 +36,7 @@ export const registerPrivilegesRoute = ({ router, config }: RouteDependencies) = return res.ok({ body: privilegesResult }); } - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { has_all_requested: hasAllPrivileges, cluster } = await clusterClient.asCurrentUser.security.hasPrivileges({ diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts index 9e4e894e2c7cb49..a313afbc2a2c5e2 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts @@ -29,7 +29,7 @@ export const registerSimulateRoute = ({ }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { pipeline, documents, verbose } = req.body; diff --git a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts index 51983f12e6a6015..5b1b032c8aedb3a 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts @@ -30,7 +30,7 @@ export const registerUpdateRoute = ({ }, }, async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params; // eslint-disable-next-line @typescript-eslint/naming-convention const { description, processors, version, on_failure } = req.body; diff --git a/x-pack/plugins/lens/server/routes/existing_fields.ts b/x-pack/plugins/lens/server/routes/existing_fields.ts index 542cdb33df8ab99..61df3bb458912cb 100644 --- a/x-pack/plugins/lens/server/routes/existing_fields.ts +++ b/x-pack/plugins/lens/server/routes/existing_fields.ts @@ -136,7 +136,8 @@ async function fetchFieldExistence({ }); } - const metaFields: string[] = await context.core.uiSettings.client.get(UI_SETTINGS.META_FIELDS); + const uiSettingsClient = (await context.core).uiSettings.client; + const metaFields: string[] = await uiSettingsClient.get(UI_SETTINGS.META_FIELDS); const dataView = await dataViewsService.get(indexPatternId); const allFields = buildFieldList(dataView, metaFields); const existingFieldList = await dataViewsService.getFieldsForIndexPattern(dataView, { @@ -169,7 +170,8 @@ async function legacyFetchFieldExistenceSampling({ timeFieldName?: string; includeFrozen: boolean; }) { - const metaFields: string[] = await context.core.uiSettings.client.get(UI_SETTINGS.META_FIELDS); + const coreContext = await context.core; + const metaFields: string[] = await coreContext.uiSettings.client.get(UI_SETTINGS.META_FIELDS); const indexPattern = await dataViewsService.get(indexPatternId); const fields = buildFieldList(indexPattern, metaFields); @@ -179,7 +181,7 @@ async function legacyFetchFieldExistenceSampling({ fromDate, toDate, dslQuery, - client: context.core.elasticsearch.client.asCurrentUser, + client: coreContext.elasticsearch.client.asCurrentUser, index: indexPattern.title, timeFieldName: timeFieldName || indexPattern.timeFieldName, fields, diff --git a/x-pack/plugins/lens/server/routes/field_stats.ts b/x-pack/plugins/lens/server/routes/field_stats.ts index 1da732ab60ab272..35a15ea44be67d9 100644 --- a/x-pack/plugins/lens/server/routes/field_stats.ts +++ b/x-pack/plugins/lens/server/routes/field_stats.ts @@ -39,7 +39,7 @@ export async function initFieldsRoute(setup: CoreSetup) { }, }, async (context, req, res) => { - const requestClient = context.core.elasticsearch.client.asCurrentUser; + const requestClient = (await context.core).elasticsearch.client.asCurrentUser; const { fromDate, toDate, fieldName, dslQuery, size } = req.body; const [{ savedObjects, elasticsearch }, { dataViews }] = await setup.getStartServices(); diff --git a/x-pack/plugins/lens/server/routes/telemetry.ts b/x-pack/plugins/lens/server/routes/telemetry.ts index 8ef45a5029e930f..01c843cf5489dda 100644 --- a/x-pack/plugins/lens/server/routes/telemetry.ts +++ b/x-pack/plugins/lens/server/routes/telemetry.ts @@ -33,7 +33,7 @@ export async function initLensUsageRoute(setup: CoreSetup) const { events, suggestionEvents } = req.body; try { - const client = context.core.savedObjects.client; + const client = (await context.core).savedObjects.client; const allEvents: Array<{ type: 'lens-ui-telemetry'; diff --git a/x-pack/plugins/license_management/server/routes/api/license/register_license_route.ts b/x-pack/plugins/license_management/server/routes/api/license/register_license_route.ts index 03e57b1a12cd9dc..0a9bbacaff4d5ac 100644 --- a/x-pack/plugins/license_management/server/routes/api/license/register_license_route.ts +++ b/x-pack/plugins/license_management/server/routes/api/license/register_license_route.ts @@ -26,7 +26,7 @@ export function registerLicenseRoute({ }, }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ body: await putLicense({ diff --git a/x-pack/plugins/license_management/server/routes/api/license/register_permissions_route.ts b/x-pack/plugins/license_management/server/routes/api/license/register_permissions_route.ts index 01aae5cd6d4418e..8372273726911f9 100644 --- a/x-pack/plugins/license_management/server/routes/api/license/register_permissions_route.ts +++ b/x-pack/plugins/license_management/server/routes/api/license/register_permissions_route.ts @@ -15,7 +15,7 @@ export function registerPermissionsRoute({ config: { isSecurityEnabled }, }: RouteDependencies) { router.post({ path: addBasePath('/permissions'), validate: false }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ diff --git a/x-pack/plugins/license_management/server/routes/api/license/register_start_basic_route.ts b/x-pack/plugins/license_management/server/routes/api/license/register_start_basic_route.ts index 60e72d297b2ed3e..fa9f13ade07a1dd 100644 --- a/x-pack/plugins/license_management/server/routes/api/license/register_start_basic_route.ts +++ b/x-pack/plugins/license_management/server/routes/api/license/register_start_basic_route.ts @@ -21,7 +21,7 @@ export function registerStartBasicRoute({ validate: { query: schema.object({ acknowledge: schema.string() }) }, }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ body: await startBasic({ diff --git a/x-pack/plugins/license_management/server/routes/api/license/register_start_trial_routes.ts b/x-pack/plugins/license_management/server/routes/api/license/register_start_trial_routes.ts index 43ab7c5eafdb536..5ff25f4d21308b1 100644 --- a/x-pack/plugins/license_management/server/routes/api/license/register_start_trial_routes.ts +++ b/x-pack/plugins/license_management/server/routes/api/license/register_start_trial_routes.ts @@ -15,7 +15,7 @@ export function registerStartTrialRoutes({ plugins: { licensing }, }: RouteDependencies) { router.get({ path: addBasePath('/start_trial'), validate: false }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ body: await canStartTrial(client) }); } catch (error) { @@ -24,7 +24,7 @@ export function registerStartTrialRoutes({ }); router.post({ path: addBasePath('/start_trial'), validate: false }, async (ctx, req, res) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; try { return res.ok({ body: await startTrial({ client, licensing }), diff --git a/x-pack/plugins/licensing/server/routes/info.ts b/x-pack/plugins/licensing/server/routes/info.ts index 9db7a1c8ca1bae4..1cbc7b63989669c 100644 --- a/x-pack/plugins/licensing/server/routes/info.ts +++ b/x-pack/plugins/licensing/server/routes/info.ts @@ -8,9 +8,12 @@ import { LicensingRouter } from '../types'; export function registerInfoRoute(router: LicensingRouter) { - router.get({ path: '/api/licensing/info', validate: false }, (context, request, response) => { - return response.ok({ - body: context.licensing.license, - }); - }); + router.get( + { path: '/api/licensing/info', validate: false }, + async (context, request, response) => { + return response.ok({ + body: (await context.licensing).license, + }); + } + ); } diff --git a/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts b/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts index 2cc4a64b63a3ffb..a33cf4284245d96 100644 --- a/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts +++ b/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts @@ -22,7 +22,7 @@ export function registerNotifyFeatureUsageRoute(router: LicensingRouter) { async (context, request, response) => { const { featureName, lastUsed } = request.body; - context.licensing.featureUsage.notifyUsage(featureName, lastUsed); + (await context.licensing).featureUsage.notifyUsage(featureName, lastUsed); return response.ok({ body: { diff --git a/x-pack/plugins/licensing/server/types.ts b/x-pack/plugins/licensing/server/types.ts index 59bb2dd5b1045c2..83b39cb663715dc 100644 --- a/x-pack/plugins/licensing/server/types.ts +++ b/x-pack/plugins/licensing/server/types.ts @@ -6,7 +6,7 @@ */ import { Observable } from 'rxjs'; -import type { IClusterClient, IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IClusterClient, IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import { ILicense } from '../common/types'; import { FeatureUsageServiceSetup, FeatureUsageServiceStart } from './services'; @@ -35,9 +35,9 @@ export interface LicensingApiRequestHandlerContext { /** * @internal */ -export interface LicensingRequestHandlerContext extends RequestHandlerContext { +export type LicensingRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/licensing/server/wrap_route_with_license_check.ts b/x-pack/plugins/licensing/server/wrap_route_with_license_check.ts index 2358e24b6793a81..0adcf3f3b612083 100644 --- a/x-pack/plugins/licensing/server/wrap_route_with_license_check.ts +++ b/x-pack/plugins/licensing/server/wrap_route_with_license_check.ts @@ -28,7 +28,8 @@ export function wrapRouteWithLicenseCheck, response: KibanaResponseFactory ) => { - const licenseCheckResult = checkLicense(context.licensing.license); + const { license } = await context.licensing; + const licenseCheckResult = checkLicense(license); if (licenseCheckResult.valid) { return handler(context, request, response); diff --git a/x-pack/plugins/lists/server/plugin.ts b/x-pack/plugins/lists/server/plugin.ts index c5cef49e48735ff..688469ea063bd3f 100644 --- a/x-pack/plugins/lists/server/plugin.ts +++ b/x-pack/plugins/lists/server/plugin.ts @@ -103,13 +103,11 @@ export class ListPlugin implements Plugin { const { spaces, config, security, extensionPoints } = this; const { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { - client: { asCurrentUser: esClient }, - }, + savedObjects: { client: savedObjectsClient }, + elasticsearch: { + client: { asCurrentUser: esClient }, }, - } = context; + } = await context.core; if (config == null) { throw new TypeError('Configuration is required for this plugin to operate'); } else { diff --git a/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts index 46c139d1f373254..d6272626618ecb9 100644 --- a/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts @@ -47,7 +47,7 @@ export const createEndpointListItemRoute = (router: ListsPluginRouter): void => os_types: osTypes, type, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionListItem = await exceptionLists.getEndpointListItem({ id: undefined, itemId, diff --git a/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts b/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts index 134682d3a42831f..1868a47952a6d36 100644 --- a/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts @@ -36,7 +36,7 @@ export const createEndpointListRoute = (router: ListsPluginRouter): void => { async (context, _, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const createdList = await exceptionLists.createEndpointList(); // We always return ok on a create endpoint list route but with an empty body as // an additional fetch of the full list would be slower and the UI has everything hard coded diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts index 968f341b9decf5a..1659fc2645f1678 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts @@ -51,7 +51,7 @@ export const createExceptionListItemRoute = (router: ListsPluginRouter): void => os_types: osTypes, type, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionList = await exceptionLists.getExceptionList({ id: undefined, listId, diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_route.ts index 22be6432a70c106..8d59d8492c822bb 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_route.ts @@ -46,7 +46,7 @@ export const createExceptionListRoute = (router: ListsPluginRouter): void => { type, version, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionList = await exceptionLists.getExceptionList({ id: undefined, listId, diff --git a/x-pack/plugins/lists/server/routes/create_list_index_route.ts b/x-pack/plugins/lists/server/routes/create_list_index_route.ts index cebd6140c36aa2e..ee6a3003a0f0f41 100644 --- a/x-pack/plugins/lists/server/routes/create_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_index_route.ts @@ -29,7 +29,7 @@ export const createListIndexRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const listIndexExists = await lists.getListIndexExists(); const listItemIndexExists = await lists.getListItemIndexExists(); diff --git a/x-pack/plugins/lists/server/routes/create_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_list_item_route.ts index bbdc507ebdb699a..de798aea97fd648 100644 --- a/x-pack/plugins/lists/server/routes/create_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_item_route.ts @@ -31,7 +31,7 @@ export const createListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, value, meta } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.getList({ id: listId }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/create_list_route.ts b/x-pack/plugins/lists/server/routes/create_list_route.ts index b259fe31b931dcf..5e2ddea4aa4b260 100644 --- a/x-pack/plugins/lists/server/routes/create_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_route.ts @@ -38,7 +38,7 @@ export const createListRoute = (router: ListsPluginRouter): void => { try { const { name, description, deserializer, id, serializer, type, meta, version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const listExists = await lists.getListIndexExists(); if (!listExists) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts index 650d2d11b0d1f69..94456cea0c3287d 100644 --- a/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts @@ -40,7 +40,7 @@ export const deleteEndpointListItemRoute = (router: ListsPluginRouter): void => async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { item_id: itemId, id } = request.query; if (itemId == null && id == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts index 7ec220bfb3a601c..5aea87e5e9efbd7 100644 --- a/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts @@ -40,7 +40,7 @@ export const deleteExceptionListItemRoute = (router: ListsPluginRouter): void => async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { item_id: itemId, id, namespace_type: namespaceType } = request.query; if (itemId == null && id == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts b/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts index b4928d0262528c7..26c45c8055a961c 100644 --- a/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts @@ -40,7 +40,7 @@ export const deleteExceptionListRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { list_id: listId, id, namespace_type: namespaceType } = request.query; if (listId == null && id == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/delete_list_index_route.ts b/x-pack/plugins/lists/server/routes/delete_list_index_route.ts index 448c6c769216426..85c6cf96c85abee 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_index_route.ts @@ -45,7 +45,7 @@ export const deleteListIndexRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const listIndexExists = await lists.getListIndexExists(); const listItemIndexExists = await lists.getListItemIndexExists(); diff --git a/x-pack/plugins/lists/server/routes/delete_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_list_item_route.ts index cd6c0ee038b4d99..bf03f083bd74234 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_item_route.ts @@ -35,7 +35,7 @@ export const deleteListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, value } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); if (id != null) { const deleted = await lists.deleteListItem({ id }); if (deleted == null) { diff --git a/x-pack/plugins/lists/server/routes/delete_list_route.ts b/x-pack/plugins/lists/server/routes/delete_list_route.ts index 6ddcce94d82e8ad..57923699c25eb39 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_route.ts @@ -42,8 +42,8 @@ export const deleteListRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); - const exceptionLists = getExceptionListClient(context); + const lists = await getListClient(context); + const exceptionLists = await getExceptionListClient(context); const { id, deleteReferences, ignoreReferences } = request.query; let deleteExceptionItemResponses; diff --git a/x-pack/plugins/lists/server/routes/export_exception_list_route.ts b/x-pack/plugins/lists/server/routes/export_exception_list_route.ts index f13e84c6e58ddb5..03c7b416ab54f58 100644 --- a/x-pack/plugins/lists/server/routes/export_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/export_exception_list_route.ts @@ -29,7 +29,7 @@ export const exportExceptionsRoute = (router: ListsPluginRouter): void => { try { const { id, list_id: listId, namespace_type: namespaceType } = request.query; - const exceptionListsClient = getExceptionListClient(context); + const exceptionListsClient = await getExceptionListClient(context); const exportContent = await exceptionListsClient.exportExceptionListAndItems({ id, diff --git a/x-pack/plugins/lists/server/routes/export_list_item_route.ts b/x-pack/plugins/lists/server/routes/export_list_item_route.ts index 413c911560e1073..f542909327f1ce0 100644 --- a/x-pack/plugins/lists/server/routes/export_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/export_list_item_route.ts @@ -32,7 +32,7 @@ export const exportListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { list_id: listId } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.getList({ id: listId }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts index 6516e88877384b3..c91a7d882355b5c 100644 --- a/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts @@ -35,7 +35,7 @@ export const findEndpointListItemRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { filter, page, diff --git a/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts index 67450ca02bb2061..b28ebf26b012cbc 100644 --- a/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts @@ -35,7 +35,7 @@ export const findExceptionListItemRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { filter, list_id: listId, diff --git a/x-pack/plugins/lists/server/routes/find_exception_list_route.ts b/x-pack/plugins/lists/server/routes/find_exception_list_route.ts index e49b9c39d2f0471..9365c07e876a245 100644 --- a/x-pack/plugins/lists/server/routes/find_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/find_exception_list_route.ts @@ -34,7 +34,7 @@ export const findExceptionListRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const { filter, page, diff --git a/x-pack/plugins/lists/server/routes/find_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_list_item_route.ts index b0a4a386e21e87d..37e3ede6582be48 100644 --- a/x-pack/plugins/lists/server/routes/find_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_list_item_route.ts @@ -35,7 +35,7 @@ export const findListItemRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const { cursor, filter: filterOrUndefined, diff --git a/x-pack/plugins/lists/server/routes/find_list_route.ts b/x-pack/plugins/lists/server/routes/find_list_route.ts index 98697cc79030ca3..89ed27941d8ad07 100644 --- a/x-pack/plugins/lists/server/routes/find_list_route.ts +++ b/x-pack/plugins/lists/server/routes/find_list_route.ts @@ -29,7 +29,7 @@ export const findListRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const { cursor, filter: filterOrUndefined, diff --git a/x-pack/plugins/lists/server/routes/import_exceptions_route.ts b/x-pack/plugins/lists/server/routes/import_exceptions_route.ts index 9db8c27c5397da2..78e0d571b2dc296 100644 --- a/x-pack/plugins/lists/server/routes/import_exceptions_route.ts +++ b/x-pack/plugins/lists/server/routes/import_exceptions_route.ts @@ -43,7 +43,7 @@ export const importExceptionsRoute = (router: ListsPluginRouter, config: ConfigT }, }, async (context, request, response) => { - const exceptionListsClient = getExceptionListClient(context); + const exceptionListsClient = await getExceptionListClient(context); const siemResponse = buildSiemResponse(response); try { diff --git a/x-pack/plugins/lists/server/routes/import_list_item_route.ts b/x-pack/plugins/lists/server/routes/import_list_item_route.ts index a911a6bc26eb078..0af6035e40b5dd0 100644 --- a/x-pack/plugins/lists/server/routes/import_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/import_list_item_route.ts @@ -44,7 +44,7 @@ export const importListItemRoute = (router: ListsPluginRouter, config: ConfigTyp try { const stream = createStreamFromBuffer(request.body); const { deserializer, list_id: listId, serializer, type } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); const listExists = await lists.getListIndexExists(); if (!listExists) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/patch_list_item_route.ts b/x-pack/plugins/lists/server/routes/patch_list_item_route.ts index 7bbcab1b1dd6225..45d02f5c9d3ac4b 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_item_route.ts @@ -31,7 +31,7 @@ export const patchListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { value, id, meta, _version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const listItem = await lists.updateListItem({ _version, id, diff --git a/x-pack/plugins/lists/server/routes/patch_list_route.ts b/x-pack/plugins/lists/server/routes/patch_list_route.ts index da2ea0b65e41340..6b23fb1da897826 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_route.ts @@ -31,7 +31,7 @@ export const patchListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { name, description, id, meta, _version, version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.updateList({ _version, description, id, meta, name, version }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts index aed51fbb4a5d0c4..053e74dee48c87c 100644 --- a/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts @@ -41,7 +41,7 @@ export const readEndpointListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, item_id: itemId } = request.query; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id != null || itemId != null) { const exceptionListItem = await exceptionLists.getEndpointListItem({ id, diff --git a/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts index d1afb35d41a3028..7ea8c02be96db4e 100644 --- a/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts @@ -41,7 +41,7 @@ export const readExceptionListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, item_id: itemId, namespace_type: namespaceType } = request.query; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id != null || itemId != null) { const exceptionListItem = await exceptionLists.getExceptionListItem({ id, diff --git a/x-pack/plugins/lists/server/routes/read_exception_list_route.ts b/x-pack/plugins/lists/server/routes/read_exception_list_route.ts index 3b652db6fab634c..22ef6e636720f18 100644 --- a/x-pack/plugins/lists/server/routes/read_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/read_exception_list_route.ts @@ -40,7 +40,7 @@ export const readExceptionListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, namespace_type: namespaceType } = request.query; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id != null || listId != null) { const exceptionList = await exceptionLists.getExceptionList({ id, diff --git a/x-pack/plugins/lists/server/routes/read_list_index_route.ts b/x-pack/plugins/lists/server/routes/read_list_index_route.ts index 6fd15e628edb016..061c8486db358a6 100644 --- a/x-pack/plugins/lists/server/routes/read_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_index_route.ts @@ -29,7 +29,7 @@ export const readListIndexRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { - const lists = getListClient(context); + const lists = await getListClient(context); const listIndexExists = await lists.getListIndexExists(); const listItemIndexExists = await lists.getListItemIndexExists(); diff --git a/x-pack/plugins/lists/server/routes/read_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_list_item_route.ts index 2cb2c4e042884ad..a663cfe9b8d0829 100644 --- a/x-pack/plugins/lists/server/routes/read_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_item_route.ts @@ -35,7 +35,7 @@ export const readListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, value } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); if (id != null) { const listItem = await lists.getListItem({ id }); if (listItem == null) { diff --git a/x-pack/plugins/lists/server/routes/read_list_route.ts b/x-pack/plugins/lists/server/routes/read_list_route.ts index e4806f274d511ad..86761b5c98835d1 100644 --- a/x-pack/plugins/lists/server/routes/read_list_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_route.ts @@ -31,7 +31,7 @@ export const readListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id } = request.query; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.getList({ id }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/read_privileges_route.ts b/x-pack/plugins/lists/server/routes/read_privileges_route.ts index 0fc72e6cc4341fc..51ffaa9713b62f2 100644 --- a/x-pack/plugins/lists/server/routes/read_privileges_route.ts +++ b/x-pack/plugins/lists/server/routes/read_privileges_route.ts @@ -25,8 +25,8 @@ export const readPrivilegesRoute = (router: ListsPluginRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const lists = getListClient(context); + const esClient = (await context.core).elasticsearch.client.asCurrentUser; + const lists = await getListClient(context); const clusterPrivilegesLists = await readPrivileges(esClient, lists.getListIndex()); const clusterPrivilegesListItems = await readPrivileges(esClient, lists.getListItemIndex()); const privileges = merge( diff --git a/x-pack/plugins/lists/server/routes/summary_exception_list_route.ts b/x-pack/plugins/lists/server/routes/summary_exception_list_route.ts index 932681eb30d2f51..f44161a25d3728a 100644 --- a/x-pack/plugins/lists/server/routes/summary_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/summary_exception_list_route.ts @@ -41,7 +41,7 @@ export const summaryExceptionListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { id, list_id: listId, namespace_type: namespaceType, filter } = request.query; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id != null || listId != null) { const exceptionListSummary = await exceptionLists.getExceptionListSummary({ filter, diff --git a/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts index 2c960736460dd79..e1e117f6c560420 100644 --- a/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts @@ -50,7 +50,7 @@ export const updateEndpointListItemRoute = (router: ListsPluginRouter): void => item_id: itemId, tags, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionListItem = await exceptionLists.updateEndpointListItem({ _version, comments, diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts index 910d78e68061e73..a997ac132e7cfd0 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts @@ -63,7 +63,7 @@ export const updateExceptionListItemRoute = (router: ListsPluginRouter): void => statusCode: 404, }); } else { - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); const exceptionListItem = await exceptionLists.updateExceptionListItem({ _version, comments, diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts index 43279e1f1045de0..b41a43a0f7c6d55 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts @@ -53,7 +53,7 @@ export const updateExceptionListRoute = (router: ListsPluginRouter): void => { type, version, } = request.body; - const exceptionLists = getExceptionListClient(context); + const exceptionLists = await getExceptionListClient(context); if (id == null && listId == null) { return siemResponse.error({ body: 'either id or list_id need to be defined', diff --git a/x-pack/plugins/lists/server/routes/update_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_list_item_route.ts index 07ba8539ae624b6..37c9848f9ddcd10 100644 --- a/x-pack/plugins/lists/server/routes/update_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_item_route.ts @@ -31,7 +31,7 @@ export const updateListItemRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { value, id, meta, _version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const listItem = await lists.updateListItem({ _version, id, diff --git a/x-pack/plugins/lists/server/routes/update_list_route.ts b/x-pack/plugins/lists/server/routes/update_list_route.ts index 47ab77b444196fb..bbf49df7e689a95 100644 --- a/x-pack/plugins/lists/server/routes/update_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_route.ts @@ -31,7 +31,7 @@ export const updateListRoute = (router: ListsPluginRouter): void => { const siemResponse = buildSiemResponse(response); try { const { name, description, id, meta, _version, version } = request.body; - const lists = getListClient(context); + const lists = await getListClient(context); const list = await lists.updateList({ _version, description, id, meta, name, version }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/utils/get_exception_list_client.ts b/x-pack/plugins/lists/server/routes/utils/get_exception_list_client.ts index 46a02180d731957..e4c948a11ddae55 100644 --- a/x-pack/plugins/lists/server/routes/utils/get_exception_list_client.ts +++ b/x-pack/plugins/lists/server/routes/utils/get_exception_list_client.ts @@ -9,10 +9,10 @@ import type { ListsRequestHandlerContext } from '../../types'; import { ErrorWithStatusCode } from '../../error_with_status_code'; import { ExceptionListClient } from '../../services/exception_lists/exception_list_client'; -export const getExceptionListClient = ( +export const getExceptionListClient = async ( context: ListsRequestHandlerContext -): ExceptionListClient => { - const exceptionLists = context.lists?.getExceptionListClient(); +): Promise => { + const exceptionLists = (await context.lists)?.getExceptionListClient(); if (exceptionLists == null) { throw new ErrorWithStatusCode('Exception lists is not found as a plugin', 404); } else { diff --git a/x-pack/plugins/lists/server/routes/utils/get_list_client.ts b/x-pack/plugins/lists/server/routes/utils/get_list_client.ts index 1c6e995f3fac657..988014868180984 100644 --- a/x-pack/plugins/lists/server/routes/utils/get_list_client.ts +++ b/x-pack/plugins/lists/server/routes/utils/get_list_client.ts @@ -9,8 +9,8 @@ import { ListClient } from '../../services/lists/list_client'; import { ErrorWithStatusCode } from '../../error_with_status_code'; import type { ListsRequestHandlerContext } from '../../types'; -export const getListClient = (context: ListsRequestHandlerContext): ListClient => { - const lists = context.lists?.getListClient(); +export const getListClient = async (context: ListsRequestHandlerContext): Promise => { + const lists = (await context.lists)?.getListClient(); if (lists == null) { throw new ErrorWithStatusCode('Lists is not found as a plugin', 404); } else { diff --git a/x-pack/plugins/lists/server/types.ts b/x-pack/plugins/lists/server/types.ts index 15bbe0d47b6c01e..78fdd0e8534a62f 100644 --- a/x-pack/plugins/lists/server/types.ts +++ b/x-pack/plugins/lists/server/types.ts @@ -6,10 +6,10 @@ */ import { + CustomRequestHandlerContext, ElasticsearchClient, IContextProvider, IRouter, - RequestHandlerContext, SavedObjectsClientContract, } from '@kbn/core/server'; import type { SecurityPluginStart } from '@kbn/security-plugin/server'; @@ -24,6 +24,7 @@ import type { export type ContextProvider = IContextProvider; export type ListsPluginStart = void; + export interface PluginsStart { security: SecurityPluginStart | undefined | null; spaces: SpacesPluginStart | undefined | null; @@ -60,9 +61,9 @@ export interface ListsApiRequestHandlerContext { /** * @internal */ -export interface ListsRequestHandlerContext extends RequestHandlerContext { +export type ListsRequestHandlerContext = CustomRequestHandlerContext<{ lists?: ListsApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/logstash/server/routes/cluster/load.ts b/x-pack/plugins/logstash/server/routes/cluster/load.ts index e3937071cb98c07..d0967ee12376322 100644 --- a/x-pack/plugins/logstash/server/routes/cluster/load.ts +++ b/x-pack/plugins/logstash/server/routes/cluster/load.ts @@ -18,7 +18,7 @@ export function registerClusterLoadRoute(router: LogstashPluginRouter) { }, wrapRouteWithLicenseCheck(checkLicense, async (context, request, response) => { try { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const info = await client.asCurrentUser.info(); return response.ok({ body: { diff --git a/x-pack/plugins/logstash/server/routes/pipeline/delete.ts b/x-pack/plugins/logstash/server/routes/pipeline/delete.ts index 1fb21c0e870135a..ba9ea73850cc4e1 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/delete.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/delete.ts @@ -24,7 +24,7 @@ export function registerPipelineDeleteRoute(router: LogstashPluginRouter) { checkLicense, router.handleLegacyErrors(async (context, request, response) => { const { id } = request.params; - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; try { await client.asCurrentUser.logstash.deletePipeline({ id }); diff --git a/x-pack/plugins/logstash/server/routes/pipeline/load.ts b/x-pack/plugins/logstash/server/routes/pipeline/load.ts index 44811aba0b208c4..8a657207414d9dd 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/load.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/load.ts @@ -26,7 +26,7 @@ export function registerPipelineLoadRoute(router: LogstashPluginRouter) { checkLicense, router.handleLegacyErrors(async (context, request, response) => { const { id } = request.params; - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const result = await client.asCurrentUser.logstash.getPipeline({ id }, { ignore: [404] }); diff --git a/x-pack/plugins/logstash/server/routes/pipeline/save.ts b/x-pack/plugins/logstash/server/routes/pipeline/save.ts index 703edb95a43ffd9..5c50dac7e050c89 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/save.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/save.ts @@ -42,7 +42,7 @@ export function registerPipelineSaveRoute( username = user?.username; } - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const pipeline = Pipeline.fromDownstreamJSON(request.body, request.params.id, username); await client.asCurrentUser.logstash.putPipeline({ diff --git a/x-pack/plugins/logstash/server/routes/pipelines/delete.ts b/x-pack/plugins/logstash/server/routes/pipelines/delete.ts index 4aac23a2921fd8a..777b86ea6528478 100644 --- a/x-pack/plugins/logstash/server/routes/pipelines/delete.ts +++ b/x-pack/plugins/logstash/server/routes/pipelines/delete.ts @@ -45,7 +45,7 @@ export function registerPipelinesDeleteRoute(router: LogstashPluginRouter) { wrapRouteWithLicenseCheck( checkLicense, router.handleLegacyErrors(async (context, request, response) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const results = await deletePipelines(client, request.body.pipelineIds); return response.ok({ body: { results } }); diff --git a/x-pack/plugins/logstash/server/routes/pipelines/list.ts b/x-pack/plugins/logstash/server/routes/pipelines/list.ts index 884b923eaf87e77..cb1a14cbbd423d1 100644 --- a/x-pack/plugins/logstash/server/routes/pipelines/list.ts +++ b/x-pack/plugins/logstash/server/routes/pipelines/list.ts @@ -33,7 +33,7 @@ export function registerPipelinesListRoute(router: LogstashPluginRouter) { checkLicense, router.handleLegacyErrors(async (context, request, response) => { try { - const { client } = context.core.elasticsearch; + const { client } = (await context.core).elasticsearch; const pipelinesRecord = (await fetchPipelines(client.asCurrentUser)) as Record< string, any diff --git a/x-pack/plugins/logstash/server/types.ts b/x-pack/plugins/logstash/server/types.ts index 69db9753f1e381b..d9a9f90101f4053 100644 --- a/x-pack/plugins/logstash/server/types.ts +++ b/x-pack/plugins/logstash/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; export interface PipelineListItemOptions { @@ -18,9 +18,9 @@ export interface PipelineListItemOptions { /** * @internal */ -export interface LogstashRequestHandlerContext extends RequestHandlerContext { +export type LogstashRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts index c08bdc8b0d7ea88..7f2eacc257fc515 100644 --- a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts +++ b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts @@ -49,16 +49,17 @@ export function initIndexingRoutes({ }, }, async (context, request, response) => { + const coreContext = await context.core; const { index, mappings } = request.body; const indexPatternsService = await dataPlugin.indexPatterns.indexPatternsServiceFactory( - context.core.savedObjects.client, - context.core.elasticsearch.client.asCurrentUser, + coreContext.savedObjects.client, + coreContext.elasticsearch.client.asCurrentUser, request ); const result = await createDocSource( index, mappings, - context.core.elasticsearch.client, + coreContext.elasticsearch.client, indexPatternsService ); if (result.success) { @@ -92,10 +93,11 @@ export function initIndexingRoutes({ }, }, async (context, request, response) => { + const coreContext = await context.core; const result = await writeDataToIndex( request.body.index, request.body.data, - context.core.elasticsearch.client.asCurrentUser + coreContext.elasticsearch.client.asCurrentUser ); if (result.success) { return response.ok({ body: result }); @@ -123,7 +125,8 @@ export function initIndexingRoutes({ }, async (context, request, response) => { try { - const resp = await context.core.elasticsearch.client.asCurrentUser.delete({ + const coreContext = await context.core; + const resp = await coreContext.elasticsearch.client.asCurrentUser.delete({ index: request.body.index, id: request.params.featureId, refresh: true, @@ -173,9 +176,10 @@ export function initIndexingRoutes({ }, }, async (context, request, response) => { + const coreContext = await context.core; return await getMatchingIndexes( request.query.indexPattern, - context.core.elasticsearch.client, + coreContext.elasticsearch.client, response, logger ); @@ -194,8 +198,9 @@ export function initIndexingRoutes({ async (context, request, response) => { const { index } = request.query; try { + const coreContext = await context.core; const mappingsResp = - await context.core.elasticsearch.client.asCurrentUser.indices.getMapping({ + await coreContext.elasticsearch.client.asCurrentUser.indices.getMapping({ index: request.query.index, }); const isDrawingIndex = diff --git a/x-pack/plugins/maps/server/mvt/get_grid_tile.ts b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts index e88a0f0314931bc..eb0ddc9e13143af 100644 --- a/x-pack/plugins/maps/server/mvt/get_grid_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts @@ -57,13 +57,14 @@ export async function getEsGridTile({ runtime_mappings: requestBody.runtime_mappings, }; + const esClient = (await context.core).elasticsearch.client; const tile = await core.executionContext.withContext( makeExecutionContext({ description: 'mvt:get_grid_tile', url, }), async () => { - return await context.core.elasticsearch.client.asCurrentUser.transport.request( + return await esClient.asCurrentUser.transport.request( { method: 'GET', path, diff --git a/x-pack/plugins/maps/server/mvt/get_tile.ts b/x-pack/plugins/maps/server/mvt/get_tile.ts index b4ae9e6b698d665..340a71128b43ae9 100644 --- a/x-pack/plugins/maps/server/mvt/get_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_tile.ts @@ -57,13 +57,14 @@ export async function getEsTile({ track_total_hits: requestBody.size + 1, }; + const esClient = (await context.core).elasticsearch.client; const tile = await core.executionContext.withContext( makeExecutionContext({ description: 'mvt:get_tile', url, }), async () => { - return await context.core.elasticsearch.client.asCurrentUser.transport.request( + return await esClient.asCurrentUser.transport.request( { method: 'GET', path, diff --git a/x-pack/plugins/maps/server/routes.ts b/x-pack/plugins/maps/server/routes.ts index d74deec8eab6729..427f403927d5d93 100644 --- a/x-pack/plugins/maps/server/routes.ts +++ b/x-pack/plugins/maps/server/routes.ts @@ -73,7 +73,8 @@ export async function initRoutes(coreSetup: CoreSetup, logger: Logger): Promise< } try { - const resp = await context.core.elasticsearch.client.asCurrentUser.indices.getSettings({ + const coreContext = await context.core; + const resp = await coreContext.elasticsearch.client.asCurrentUser.indices.getSettings({ index: query.indexPatternTitle, }); const indexPatternSettings = getIndexPatternSettings( diff --git a/x-pack/plugins/ml/server/lib/route_guard.ts b/x-pack/plugins/ml/server/lib/route_guard.ts index cd500cfda17cc3b..fa3fb88a109bbe5 100644 --- a/x-pack/plugins/ml/server/lib/route_guard.ts +++ b/x-pack/plugins/ml/server/lib/route_guard.ts @@ -8,7 +8,7 @@ import type { KibanaRequest, KibanaResponseFactory, - RequestHandlerContext, + CustomRequestHandlerContext, IScopedClusterClient, RequestHandler, SavedObjectsClientContract, @@ -25,9 +25,9 @@ import type { MlLicense } from '../../common/license'; import { MlClient, getMlClient } from './ml_client'; import { getDataViewsServiceFactory } from './data_views_utils'; -type MLRequestHandlerContext = RequestHandlerContext & { +type MLRequestHandlerContext = CustomRequestHandlerContext<{ alerting?: AlertingApiRequestHandlerContext; -}; +}>; type Handler

= (handlerParams: { client: IScopedClusterClient; @@ -73,12 +73,13 @@ export class RouteGuard { public fullLicenseAPIGuard(handler: Handler) { return this._guard(() => this._mlLicense.isFullLicense(), handler); } + public basicLicenseAPIGuard(handler: Handler) { return this._guard(() => this._mlLicense.isMinimumLicense(), handler); } private _guard(check: () => boolean, handler: Handler) { - return ( + return async ( context: MLRequestHandlerContext, request: KibanaRequest, response: KibanaResponseFactory @@ -87,7 +88,8 @@ export class RouteGuard { return response.forbidden(); } - const client = context.core.elasticsearch.client; + const { elasticsearch, savedObjects } = await context.core; + const client = elasticsearch.client; const mlSavedObjectClient = this._getMlSavedObjectClient(request); const internalSavedObjectsClient = this._getInternalSavedObjectClient(); if (mlSavedObjectClient === null || internalSavedObjectsClient === null) { @@ -114,7 +116,7 @@ export class RouteGuard { mlClient: getMlClient(client, mlSavedObjectService), getDataViewsService: getDataViewsServiceFactory( this._getDataViews, - context.core.savedObjects.client, + savedObjects.client, client, request ), diff --git a/x-pack/plugins/ml/server/routes/alerting.ts b/x-pack/plugins/ml/server/routes/alerting.ts index 1dd11375cdd3c8a..59091e1c8dfb0ec 100644 --- a/x-pack/plugins/ml/server/routes/alerting.ts +++ b/x-pack/plugins/ml/server/routes/alerting.ts @@ -36,7 +36,7 @@ export function alertingRoutes( routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response, client, context }) => { try { const alertingService = sharedServicesProviders.alertingServiceProvider( - context.core.savedObjects.client, + (await context.core).savedObjects.client, request ); diff --git a/x-pack/plugins/ml/server/routes/job_service.ts b/x-pack/plugins/ml/server/routes/job_service.ts index e67095d022901be..5504682406a0021 100644 --- a/x-pack/plugins/ml/server/routes/job_service.ts +++ b/x-pack/plugins/ml/server/routes/job_service.ts @@ -268,11 +268,8 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response, context }) => { try { - const { jobsSummary } = jobServiceProvider( - client, - mlClient, - context.alerting?.getRulesClient() - ); + const alerting = await context.alerting; + const { jobsSummary } = jobServiceProvider(client, mlClient, alerting?.getRulesClient()); const { jobIds } = request.body; const resp = await jobsSummary(jobIds); @@ -304,10 +301,11 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, response, context }) => { try { + const alerting = await context.alerting; const { getJobIdsWithGeo } = jobServiceProvider( client, mlClient, - context.alerting?.getRulesClient() + alerting?.getRulesClient() ); const resp = await getJobIdsWithGeo(); @@ -409,10 +407,11 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ client, mlClient, request, response, context }) => { try { + const alerting = await context.alerting; const { createFullJobsList } = jobServiceProvider( client, mlClient, - context.alerting?.getRulesClient() + alerting?.getRulesClient() ); const { jobIds } = request.body; const resp = await createFullJobsList(jobIds); diff --git a/x-pack/plugins/ml/server/routes/modules.ts b/x-pack/plugins/ml/server/routes/modules.ts index fb8a2efed8745a5..757012ba1404129 100644 --- a/x-pack/plugins/ml/server/routes/modules.ts +++ b/x-pack/plugins/ml/server/routes/modules.ts @@ -190,11 +190,12 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { }) => { try { const { indexPatternTitle } = request.params; + const soClient = (await context.core).savedObjects.client; const dataViewService = await getDataViewsService(); const results = await recognize( client, mlClient, - context.core.savedObjects.client, + soClient, dataViewService, mlSavedObjectService, request, @@ -344,11 +345,12 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { // the moduleId will be an empty string. moduleId = undefined; } + const soClient = (await context.core).savedObjects.client; const dataViewService = await getDataViewsService(); const results = await getModule( client, mlClient, - context.core.savedObjects.client, + soClient, dataViewService, mlSavedObjectService, request, @@ -541,13 +543,13 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { estimateModelMemory, applyToAllSpaces, } = request.body as TypeOf; - + const soClient = (await context.core).savedObjects.client; const dataViewService = await getDataViewsService(); const result = await setup( client, mlClient, - context.core.savedObjects.client, + soClient, dataViewService, mlSavedObjectService, request, @@ -648,11 +650,12 @@ export function dataRecognizer({ router, routeGuard }: RouteInitialization) { }) => { try { const { moduleId } = request.params; + const soClient = (await context.core).savedObjects.client; const dataViewService = await getDataViewsService(); const result = await dataRecognizerJobsExist( client, mlClient, - context.core.savedObjects.client, + soClient, dataViewService, mlSavedObjectService, request, diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index ef2cc93bff652b6..433a3358558dab3 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -326,14 +326,16 @@ export class MonitoringPlugin res: KibanaResponseFactory ) => { const plugins = (await getCoreServices())[1]; + const coreContext = await context.core; + const actionContext = await context.actions; const legacyRequest: LegacyRequest = { ...req, logger: this.log, getLogger: this.getLogger, payload: req.body, getKibanaStatsCollector: () => this.legacyShimDependencies.kibanaStatsCollector, - getUiSettingsService: () => context.core.uiSettings.client, - getActionTypeRegistry: () => context.actions?.listTypes(), + getUiSettingsService: () => coreContext.uiSettings.client, + getActionTypeRegistry: () => actionContext?.listTypes(), getRulesClient: () => { try { return plugins.alerting.getRulesClientWithRequest(req); @@ -372,7 +374,7 @@ export class MonitoringPlugin const client = name === 'monitoring' ? cluster.asScoped(req).asCurrentUser - : context.core.elasticsearch.client.asCurrentUser; + : coreContext.elasticsearch.client.asCurrentUser; return await Globals.app.getLegacyClusterShim(client, endpoint, params); }, }), diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts index e23e636fe5676c9..918821513756525 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts @@ -24,6 +24,10 @@ export function enableAlertsRoute(server: LegacyServer, npRoute: RouteDependenci }, async (context, request, response) => { try { + const alertingContext = await context.alerting; + const infraContext = await context.infra; + const actionContext = await context.actions; + const alerts = AlertsFactory.getAll(); if (alerts.length) { const { isSufficientlySecure, hasPermanentEncryptionKey } = npRoute.alerting @@ -33,7 +37,7 @@ export function enableAlertsRoute(server: LegacyServer, npRoute: RouteDependenci if (!isSufficientlySecure || !hasPermanentEncryptionKey) { server.log.info( - `Skipping rule creation for "${context.infra.spaceId}" space; Stack Monitoring rules require API keys to be enabled and an encryption key to be configured.` + `Skipping rule creation for "${infraContext.spaceId}" space; Stack Monitoring rules require API keys to be enabled and an encryption key to be configured.` ); return response.ok({ body: { @@ -44,9 +48,9 @@ export function enableAlertsRoute(server: LegacyServer, npRoute: RouteDependenci } } - const rulesClient = context.alerting?.getRulesClient(); - const actionsClient = context.actions?.getActionsClient(); - const types = context.actions?.listTypes(); + const rulesClient = alertingContext?.getRulesClient(); + const actionsClient = actionContext?.getActionsClient(); + const types = actionContext?.listTypes(); if (!rulesClient || !actionsClient || !types) { return response.ok({ body: undefined }); } @@ -92,7 +96,7 @@ export function enableAlertsRoute(server: LegacyServer, npRoute: RouteDependenci } server.log.info( - `Created ${createdAlerts.length} alerts for "${context.infra.spaceId}" space` + `Created ${createdAlerts.length} alerts for "${infraContext.spaceId}" space` ); return response.ok({ body: { createdAlerts, disabledWatcherClusterAlerts } }); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts index 27b21c342f03702..a145d9292163494 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/status.ts @@ -34,7 +34,7 @@ export function alertStatusRoute(server: any, npRoute: RouteDependencies) { try { const { clusterUuid } = request.params; const { alertTypeIds, filters } = request.body; - const rulesClient = context.alerting?.getRulesClient(); + const rulesClient = (await context.alerting)?.getRulesClient(); if (!rulesClient) { return response.ok({ body: undefined }); } diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts index d456826176e9b41..8bee3f273e1072e 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts @@ -43,7 +43,7 @@ const queryBody = { }; const checkLatestMonitoringIsLegacy = async (context: RequestHandlerContext, index: string) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const result = await client.search>({ index, body: queryBody, diff --git a/x-pack/plugins/monitoring/server/types.ts b/x-pack/plugins/monitoring/server/types.ts index ee7deb63ec84818..bcd40fe38e415ab 100644 --- a/x-pack/plugins/monitoring/server/types.ts +++ b/x-pack/plugins/monitoring/server/types.ts @@ -10,7 +10,7 @@ import type { IRouter, Logger, ICustomClusterClient, - RequestHandlerContext, + CustomRequestHandlerContext, ElasticsearchClient, } from '@kbn/core/server'; import type Boom from '@hapi/boom'; @@ -58,12 +58,12 @@ export interface PluginsSetup { cloud?: CloudSetup; } -export interface RequestHandlerContextMonitoringPlugin extends RequestHandlerContext { +export type RequestHandlerContextMonitoringPlugin = CustomRequestHandlerContext<{ actions?: ActionsApiRequestHandlerContext; alerting?: AlertingApiRequestHandlerContext; infra: InfraRequestHandlerContext; ruleRegistry?: RacApiRequestHandlerContext; -} +}>; export interface PluginsStart { alerting: AlertingPluginStartContract; @@ -177,6 +177,7 @@ export interface Bucket { export interface Aggregation { buckets: Bucket[]; } + export interface ClusterSettingsReasonResponse { found: boolean; reason?: { @@ -227,10 +228,12 @@ export interface PipelineResponse { throughput?: PipelineMetricsProcessed; }; } + export interface PipelinesResponse { pipelines: PipelineResponse[]; totalPipelineCount: number; } + export interface PipelineMetrics { bucket_size: string; timeRange: { @@ -248,6 +251,7 @@ export interface PipelineMetrics { isDerivative: boolean; }; } + export type PipelineMetricsRes = PipelineMetrics & { data: Array<[number, { [key: string]: number }]>; }; diff --git a/x-pack/plugins/monitoring_collection/server/routes/dynamic_route.ts b/x-pack/plugins/monitoring_collection/server/routes/dynamic_route.ts index 0e11e1495ba5e25..944037dd17a7bed 100644 --- a/x-pack/plugins/monitoring_collection/server/routes/dynamic_route.ts +++ b/x-pack/plugins/monitoring_collection/server/routes/dynamic_route.ts @@ -47,9 +47,10 @@ export function registerDynamicRoute({ }, async (context, req, res) => { const type = req.params.type; + const esClient = (await context.core).elasticsearch.client; const [data, clusterUuid, kibana] = await Promise.all([ getMetric(type), - getESClusterUuid(context.core.elasticsearch.client), + getESClusterUuid(esClient), getKibanaStats({ config, getStatus }), ]); diff --git a/x-pack/plugins/observability/server/lib/annotations/bootstrap_annotations.ts b/x-pack/plugins/observability/server/lib/annotations/bootstrap_annotations.ts index 45fe9fd4b920c4c..cb3f350cb24f8be 100644 --- a/x-pack/plugins/observability/server/lib/annotations/bootstrap_annotations.ts +++ b/x-pack/plugins/observability/server/lib/annotations/bootstrap_annotations.ts @@ -25,7 +25,7 @@ export type ScopedAnnotationsClientFactory = Awaited< ReturnType >['getScopedAnnotationsClient']; -export type ScopedAnnotationsClient = ReturnType; +export type ScopedAnnotationsClient = Awaited>; export type AnnotationsAPI = Awaited>; export async function bootstrapAnnotations({ index, core, context }: Params) { @@ -38,15 +38,19 @@ export async function bootstrapAnnotations({ index, core, context }: Params) { }); return { - getScopedAnnotationsClient: ( - requestContext: RequestHandlerContext & { licensing: LicensingApiRequestHandlerContext }, + getScopedAnnotationsClient: async ( + requestContext: RequestHandlerContext & { + licensing: Promise; + }, request: KibanaRequest ) => { + const esClient = (await requestContext.core).elasticsearch.client; + const { license } = await requestContext.licensing; return createAnnotationsClient({ index, - esClient: requestContext.core.elasticsearch.client.asCurrentUser, + esClient: esClient.asCurrentUser, logger, - license: requestContext.licensing?.license, + license, }); }, }; diff --git a/x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts b/x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts index 216c83feb53df10..6eb0ba6d6e96c71 100644 --- a/x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts +++ b/x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts @@ -57,13 +57,14 @@ export function registerAnnotationAPIs({ }); } - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; + const license = (await context.licensing)?.license; const client = createAnnotationsClient({ index, esClient, logger, - license: context.licensing?.license, + license, }); try { diff --git a/x-pack/plugins/observability/server/types.ts b/x-pack/plugins/observability/server/types.ts index 0a3e2054f92138f..75f67d933f68115 100644 --- a/x-pack/plugins/observability/server/types.ts +++ b/x-pack/plugins/observability/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; @@ -20,10 +20,10 @@ export type { /** * @internal */ -export interface ObservabilityRequestHandlerContext extends RequestHandlerContext { +export type ObservabilityRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; alerting: AlertingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/osquery/server/routes/action/create_action_route.ts b/x-pack/plugins/osquery/server/routes/action/create_action_route.ts index ee9338fc5010835..a67b6ee95b9d3b0 100644 --- a/x-pack/plugins/osquery/server/routes/action/create_action_route.ts +++ b/x-pack/plugins/osquery/server/routes/action/create_action_route.ts @@ -35,8 +35,9 @@ export const createActionRoute = (router: IRouter, osqueryContext: OsqueryAppCon }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; - const soClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; + const soClient = coreContext.savedObjects.client; const internalSavedObjectsClient = await getInternalSavedObjectsClient( osqueryContext.getStartServices ); diff --git a/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts b/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts index d2b590f08f4534c..2b8c8b0de23d5be 100644 --- a/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts +++ b/x-pack/plugins/osquery/server/routes/asset/get_assets_status_route.ts @@ -25,7 +25,7 @@ export const getAssetsStatusRoute = (router: IRouter, osqueryContext: OsqueryApp options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; let installation; diff --git a/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts b/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts index a852d02d0115b2a..9990c8dbc7b82d7 100644 --- a/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts +++ b/x-pack/plugins/osquery/server/routes/asset/update_assets_route.ts @@ -30,7 +30,7 @@ export const updateAssetsRoute = (router: IRouter, osqueryContext: OsqueryAppCon options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; let installation; diff --git a/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts index 14158a4d5fb081e..bf341520785824f 100644 --- a/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/create_pack_route.ts @@ -60,8 +60,9 @@ export const createPackRoute = (router: IRouter, osqueryContext: OsqueryAppConte options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; const internalSavedObjectsClient = await getInternalSavedObjectsClient( osqueryContext.getStartServices ); diff --git a/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts index a32a0feac4784c2..9fc8713348c14ee 100644 --- a/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/delete_pack_route.ts @@ -28,8 +28,9 @@ export const deletePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; const packagePolicyService = osqueryContext.service.getPackagePolicyService(); const currentPackSO = await savedObjectsClient.get<{ name: string }>( diff --git a/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts index 333a6a7cdeecfee..b9e2326d941b9e2 100644 --- a/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/find_pack_route.ts @@ -34,7 +34,8 @@ export const findPackRoute = (router: IRouter, osqueryContext: OsqueryAppContext options: { tags: [`access:${PLUGIN_ID}-readPacks`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const soClientResponse = await savedObjectsClient.find({ type: packSavedObjectType, diff --git a/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts index 53845de3f48ab6e..bd9f27a569af8cc 100644 --- a/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/read_pack_route.ts @@ -29,7 +29,8 @@ export const readPackRoute = (router: IRouter, osqueryContext: OsqueryAppContext options: { tags: [`access:${PLUGIN_ID}-readPacks`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const { attributes, references, ...rest } = await savedObjectsClient.get( diff --git a/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts b/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts index c37e7fb184b50ed..82d880c70fbd65f 100644 --- a/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts +++ b/x-pack/plugins/osquery/server/routes/pack/update_pack_route.ts @@ -70,8 +70,9 @@ export const updatePackRoute = (router: IRouter, osqueryContext: OsqueryAppConte options: { tags: [`access:${PLUGIN_ID}-writePacks`] }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const savedObjectsClient = coreContext.savedObjects.client; const internalSavedObjectsClient = await getInternalSavedObjectsClient( osqueryContext.getStartServices ); diff --git a/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts index 9a62ad3e2a380ff..e8bcb9d6bb3b206 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/create_saved_query_route.ts @@ -30,7 +30,8 @@ export const createSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; // eslint-disable-next-line @typescript-eslint/naming-convention const { id, description, platform, query, version, interval, ecs_mapping } = request.body; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts index c8c08904a240b71..c2a2ad7fa8619a8 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/delete_saved_query_route.ts @@ -22,7 +22,8 @@ export const deleteSavedQueryRoute = (router: IRouter) => { options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; await savedObjectsClient.delete(savedQuerySavedObjectType, request.params.id, { refresh: 'wait_for', diff --git a/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts index cd1200a5d777854..a2b85dbf539d9de 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/find_saved_query_route.ts @@ -29,7 +29,8 @@ export const findSavedQueryRoute = (router: IRouter) => { options: { tags: [`access:${PLUGIN_ID}-readSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const savedQueries = await savedObjectsClient.find<{ ecs_mapping: Array<{ field: string; value: string }>; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts index 7887fdce22f0c10..1c206464d1f6500 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/read_saved_query_route.ts @@ -23,7 +23,8 @@ export const readSavedQueryRoute = (router: IRouter) => { options: { tags: [`access:${PLUGIN_ID}-readSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const savedQuery = await savedObjectsClient.get<{ ecs_mapping: Array<{ key: string; value: Record }>; diff --git a/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts b/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts index 5ac4ad711c2a640..1d2bf153afd7fbc 100644 --- a/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts +++ b/x-pack/plugins/osquery/server/routes/saved_query/update_saved_query_route.ts @@ -48,7 +48,8 @@ export const updateSavedQueryRoute = (router: IRouter, osqueryContext: OsqueryAp options: { tags: [`access:${PLUGIN_ID}-writeSavedQueries`] }, }, async (context, request, response) => { - const savedObjectsClient = context.core.savedObjects.client; + const coreContext = await context.core; + const savedObjectsClient = coreContext.savedObjects.client; const currentUser = await osqueryContext.security.authc.getCurrentUser(request)?.username; const { diff --git a/x-pack/plugins/osquery/server/routes/status/create_status_route.ts b/x-pack/plugins/osquery/server/routes/status/create_status_route.ts index 613ad6e7720af8a..019582addabb538 100644 --- a/x-pack/plugins/osquery/server/routes/status/create_status_route.ts +++ b/x-pack/plugins/osquery/server/routes/status/create_status_route.ts @@ -27,7 +27,8 @@ export const createStatusRoute = (router: IRouter, osqueryContext: OsqueryAppCon options: { tags: [`access:${PLUGIN_ID}-read`] }, }, async (context, request, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const coreContext = await context.core; + const esClient = coreContext.elasticsearch.client.asInternalUser; const internalSavedObjectsClient = await getInternalSavedObjectsClient( osqueryContext.getStartServices ); diff --git a/x-pack/plugins/painless_lab/server/routes/api/execute.ts b/x-pack/plugins/painless_lab/server/routes/api/execute.ts index 58cb9f4328d2979..88f2156a5fb4c14 100644 --- a/x-pack/plugins/painless_lab/server/routes/api/execute.ts +++ b/x-pack/plugins/painless_lab/server/routes/api/execute.ts @@ -25,7 +25,7 @@ export function registerExecuteRoute({ router, license }: RouteDependencies) { const body = req.body; try { - const client = ctx.core.elasticsearch.client.asCurrentUser; + const client = (await ctx.core).elasticsearch.client.asCurrentUser; const response = await client.scriptsPainlessExecute( { // @ts-expect-error `ExecutePainlessScriptRequest.body` does not allow `string` diff --git a/x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts b/x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts index 3fe04be97abfcfe..a1f256802fb577e 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/add_route.test.ts @@ -104,7 +104,11 @@ describe('ADD remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ acknowledged: true }); @@ -161,7 +165,11 @@ describe('ADD remote clusters', () => { serverName: 'foobar', }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ acknowledged: true }); @@ -205,7 +213,11 @@ describe('ADD remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(409); expect(response.payload).toEqual({ @@ -222,7 +234,11 @@ describe('ADD remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(400); expect(response.payload).toEqual({ diff --git a/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts index 85e8193a0eb2e90..50fb15ef3282975 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/add_route.ts @@ -41,7 +41,7 @@ export const register = (deps: RouteDependencies): void => { response ) => { try { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = request.body; diff --git a/x-pack/plugins/remote_clusters/server/routes/api/delete_route.test.ts b/x-pack/plugins/remote_clusters/server/routes/api/delete_route.test.ts index 0dc48d82cdb0913..ed92c78f9d09d38 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/delete_route.test.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/delete_route.test.ts @@ -117,7 +117,11 @@ describe('DELETE remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ @@ -163,7 +167,11 @@ describe('DELETE remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ @@ -240,7 +248,11 @@ describe('DELETE remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ diff --git a/x-pack/plugins/remote_clusters/server/routes/api/delete_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/delete_route.ts index 9d24efc1a554c16..8e11a0cbe24613b 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/delete_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/delete_route.ts @@ -34,7 +34,7 @@ export const register = (deps: RouteDependencies): void => { response ) => { try { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { nameOrNames } = request.params; const names = nameOrNames.split(','); diff --git a/x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts b/x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts index 9bb877b8bff1bd2..c3628af8c2efc5f 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/get_route.test.ts @@ -101,7 +101,11 @@ describe('GET remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual([ @@ -128,7 +132,11 @@ describe('GET remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual([]); @@ -152,7 +160,11 @@ describe('GET remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(406); expect(response.payload).toEqual({ @@ -191,7 +203,11 @@ describe('GET remote clusters', () => { headers: { authorization: 'foo' }, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(406); diff --git a/x-pack/plugins/remote_clusters/server/routes/api/get_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/get_route.ts index 7b12ad8d4418cdb..8923e9be7d9fdbe 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/get_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/get_route.ts @@ -21,7 +21,7 @@ export const register = (deps: RouteDependencies): void => { const allHandler: RequestHandler = async (ctx, request, response) => { try { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const clusterSettings = await clusterClient.asCurrentUser.cluster.getSettings(); const transientClusterNames = Object.keys( diff --git a/x-pack/plugins/remote_clusters/server/routes/api/update_route.test.ts b/x-pack/plugins/remote_clusters/server/routes/api/update_route.test.ts index 65939be965c1521..951d8c5d806e415 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/update_route.test.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/update_route.test.ts @@ -110,7 +110,11 @@ describe('UPDATE remote clusters', () => { const mockRequest = createMockRequest(); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ @@ -187,7 +191,11 @@ describe('UPDATE remote clusters', () => { proxySocketConnections: 18, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ @@ -234,7 +242,11 @@ describe('UPDATE remote clusters', () => { mode: 'sniff', }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(404); expect(response.payload).toEqual({ @@ -265,7 +277,11 @@ describe('UPDATE remote clusters', () => { mode: 'sniff', }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(400); expect(response.payload).toEqual({ diff --git a/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts b/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts index db9b3184ac1e7de..e186262ade21c85 100644 --- a/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts +++ b/x-pack/plugins/remote_clusters/server/routes/api/update_route.ts @@ -47,7 +47,7 @@ export const register = (deps: RouteDependencies): void => { response ) => { try { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = request.params; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts index efe905eedd9ae7d..31924d0d89cf582 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/execute_job.ts @@ -39,7 +39,7 @@ export const runTaskFnFactory: RunTaskFnFactory = function e ...immediateJobParams, }; - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const uiSettings = await reporting.getUiSettingsServiceFactory(savedObjectsClient); const dataPluginStart = await reporting.getDataService(); const fieldFormatsRegistry = await getFieldFormats().fieldFormatServiceFactory(uiSettings); diff --git a/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts b/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts index ecb8dc16435f312..dd04cd20ddac251 100644 --- a/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts +++ b/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts @@ -27,9 +27,7 @@ export const registerDeprecationsRoutes = (reporting: ReportingCore, logger: Log return handler(ctx, req, res); } - const { - core: { elasticsearch }, - } = ctx; + const { elasticsearch } = await ctx.core; const store = await reporting.getStore(); @@ -63,47 +61,40 @@ export const registerDeprecationsRoutes = (reporting: ReportingCore, logger: Log path: API_GET_ILM_POLICY_STATUS, validate: false, }, - authzWrapper( - async ( - { - core: { - elasticsearch: { client: scopedClient }, - }, - }, - _req, - res - ) => { - const checkIlmMigrationStatus = () => { - return deprecations.checkIlmMigrationStatus({ - reportingCore: reporting, - // We want to make the current status visible to all reporting users - elasticsearchClient: scopedClient.asInternalUser, - }); - }; + authzWrapper(async ({ core }, _req, res) => { + const { + elasticsearch: { client: scopedClient }, + } = await core; + const checkIlmMigrationStatus = () => { + return deprecations.checkIlmMigrationStatus({ + reportingCore: reporting, + // We want to make the current status visible to all reporting users + elasticsearchClient: scopedClient.asInternalUser, + }); + }; - try { - const response: IlmPolicyStatusResponse = { - status: await checkIlmMigrationStatus(), - }; - return res.ok({ body: response }); - } catch (e) { - logger.error(e); - return res.customError({ - statusCode: e?.statusCode ?? 500, - body: { message: e.message }, - }); - } + try { + const response: IlmPolicyStatusResponse = { + status: await checkIlmMigrationStatus(), + }; + return res.ok({ body: response }); + } catch (e) { + logger.error(e); + return res.customError({ + statusCode: e?.statusCode ?? 500, + body: { message: e.message }, + }); } - ) + }) ); router.put( { path: API_MIGRATE_ILM_POLICY_URL, validate: false }, - authzWrapper(async ({ core: { elasticsearch } }, _req, res) => { + authzWrapper(async ({ core }, _req, res) => { const store = await reporting.getStore(); const { client: { asCurrentUser: client }, - } = elasticsearch; + } = (await core).elasticsearch; const scopedIlmPolicyManager = IlmPolicyManager.create({ client, diff --git a/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts b/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts index 97b85f8d2d5cdb5..f3e771555c5a31a 100644 --- a/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts +++ b/x-pack/plugins/reporting/server/routes/lib/request_handler.test.ts @@ -76,7 +76,7 @@ describe('Handle request to generate', () => { (mockResponseFactory.badRequest as jest.Mock) = jest.fn((args: unknown) => args); mockContext = getMockContext(); - mockContext.reporting = {} as ReportingSetup; + mockContext.reporting = Promise.resolve({} as ReportingSetup); requestHandler = new RequestHandler( reportingCore, diff --git a/x-pack/plugins/reporting/server/types.ts b/x-pack/plugins/reporting/server/types.ts index b272f9687c14bcc..f660690c6a755d3 100644 --- a/x-pack/plugins/reporting/server/types.ts +++ b/x-pack/plugins/reporting/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, Logger, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, Logger, CustomRequestHandlerContext } from '@kbn/core/server'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import type { DataPluginStart } from '@kbn/data-plugin/server/plugin'; import { FieldFormatsStart } from '@kbn/field-formats-plugin/server'; @@ -113,10 +113,9 @@ export interface ReportingStartDeps { taskManager: TaskManagerStartContract; } -export interface ReportingRequestHandlerContext { +export type ReportingRequestHandlerContext = CustomRequestHandlerContext<{ reporting: ReportingStart | null; - core: RequestHandlerContext['core']; -} +}>; export type ReportingPluginRouter = IRouter; diff --git a/x-pack/plugins/rollup/server/routes/api/indices/register_get_route.ts b/x-pack/plugins/rollup/server/routes/api/indices/register_get_route.ts index 485c1301b4d9bbd..99312936adba4ff 100644 --- a/x-pack/plugins/rollup/server/routes/api/indices/register_get_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/indices/register_get_route.ts @@ -23,7 +23,7 @@ export const registerGetRoute = ({ }, license.guardApiRoute(async (context, request, response) => { try { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; const data = await clusterClient.asCurrentUser.rollup.getRollupIndexCaps({ index: '_all', }); diff --git a/x-pack/plugins/rollup/server/routes/api/indices/register_validate_index_pattern_route.ts b/x-pack/plugins/rollup/server/routes/api/indices/register_validate_index_pattern_route.ts index dec51870f2f5726..8eaea73e42b37c2 100644 --- a/x-pack/plugins/rollup/server/routes/api/indices/register_validate_index_pattern_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/indices/register_validate_index_pattern_route.ts @@ -67,7 +67,7 @@ export const registerValidateIndexPatternRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { indexPattern } = request.params; const [fieldCapabilities, rollupIndexCapabilities] = await Promise.all([ diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_create_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_create_route.ts index ca067d08339811d..21c0681f8458c23 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_create_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_create_route.ts @@ -29,7 +29,7 @@ export const registerCreateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { id, ...rest } = request.body.job; // Create job. diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_delete_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_delete_route.ts index 7e22b5c4ead10aa..f6b530ef2fc0e33 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_delete_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_delete_route.ts @@ -24,7 +24,7 @@ export const registerDeleteRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { jobIds } = request.body; const data = await Promise.all( diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_get_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_get_route.ts index cc0b138aeb835b9..d74a2907254d7b9 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_get_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_get_route.ts @@ -19,7 +19,7 @@ export const registerGetRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const data = await clusterClient.asCurrentUser.rollup.getJobs({ id: '_all' }); return response.ok({ body: data }); diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_start_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_start_route.ts index 133c0cb34c9f5bb..85e2a508f04a92f 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_start_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_start_route.ts @@ -29,7 +29,7 @@ export const registerStartRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { jobIds } = request.body; diff --git a/x-pack/plugins/rollup/server/routes/api/jobs/register_stop_route.ts b/x-pack/plugins/rollup/server/routes/api/jobs/register_stop_route.ts index 164273f604b430f..617023413eea38b 100644 --- a/x-pack/plugins/rollup/server/routes/api/jobs/register_stop_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/jobs/register_stop_route.ts @@ -27,7 +27,7 @@ export const registerStopRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { jobIds } = request.body; // For our API integration tests we need to wait for the jobs to be stopped diff --git a/x-pack/plugins/rollup/server/routes/api/search/register_search_route.ts b/x-pack/plugins/rollup/server/routes/api/search/register_search_route.ts index ab144c1f424400e..98116e8288866eb 100644 --- a/x-pack/plugins/rollup/server/routes/api/search/register_search_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/search/register_search_route.ts @@ -27,7 +27,7 @@ export const registerSearchRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const requests = request.body.map(({ index, query }: { index: string; query?: any }) => clusterClient.asCurrentUser.rollup.rollupSearch({ diff --git a/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts b/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts index 4d297c56fe28b0d..a1a316200e5ee41 100644 --- a/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts +++ b/x-pack/plugins/rule_registry/server/routes/bulk_update_alerts.ts @@ -52,7 +52,8 @@ export const bulkUpdateAlertsRoute = (router: IRouter) }, async (context, req, response) => { try { - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const { status, ids, index, query } = req.body; if (ids != null && ids.length > 1000) { diff --git a/x-pack/plugins/rule_registry/server/routes/find.ts b/x-pack/plugins/rule_registry/server/routes/find.ts index abf465fc5238d58..eca0a6c2a055179 100644 --- a/x-pack/plugins/rule_registry/server/routes/find.ts +++ b/x-pack/plugins/rule_registry/server/routes/find.ts @@ -43,7 +43,8 @@ export const findAlertsByQueryRoute = (router: IRouter // eslint-disable-next-line @typescript-eslint/naming-convention const { query, aggs, _source, track_total_hits, size, index } = request.body; - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const alerts = await alertsClient.find({ query, diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts index 86e2b25850aafd4..2dc2d1ec2db7dcf 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts @@ -40,7 +40,8 @@ export const getAlertByIdRoute = (router: IRouter) => }, async (context, request, response) => { try { - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const { id, index } = request.query; const alert = await alertsClient.get({ id, index }); if (alert == null) { diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts index 650c47f53f69257..3da040de6696324 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts @@ -34,7 +34,8 @@ export const getAlertsIndexRoute = (router: IRouter) = }, async (context, request, response) => { try { - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const { features } = request.query; const indexName = await alertsClient.getAuthorizedAlertsIndices( features?.split(',') ?? validFeatureIds diff --git a/x-pack/plugins/rule_registry/server/routes/update_alert_by_id.ts b/x-pack/plugins/rule_registry/server/routes/update_alert_by_id.ts index 1dcf7d28380dd53..69f6b338bfda8eb 100644 --- a/x-pack/plugins/rule_registry/server/routes/update_alert_by_id.ts +++ b/x-pack/plugins/rule_registry/server/routes/update_alert_by_id.ts @@ -42,7 +42,8 @@ export const updateAlertByIdRoute = (router: IRouter) }, async (context, req, response) => { try { - const alertsClient = await context.rac.getAlertsClient(); + const racContext = await context.rac; + const alertsClient = await racContext.getAlertsClient(); const { status, ids, index, _version } = req.body; const updatedAlert = await alertsClient.update({ diff --git a/x-pack/plugins/rule_registry/server/types.ts b/x-pack/plugins/rule_registry/server/types.ts index b634d352aaf8eae..6a7d5b849c771eb 100644 --- a/x-pack/plugins/rule_registry/server/types.ts +++ b/x-pack/plugins/rule_registry/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { RequestHandlerContext } from '@kbn/core/server'; +import { CustomRequestHandlerContext } from '@kbn/core/server'; import { AlertInstanceContext, AlertInstanceState, @@ -68,6 +68,6 @@ export interface RacApiRequestHandlerContext { /** * @internal */ -export interface RacRequestHandlerContext extends RequestHandlerContext { +export type RacRequestHandlerContext = CustomRequestHandlerContext<{ rac: RacApiRequestHandlerContext; -} +}>; diff --git a/x-pack/plugins/saved_objects_tagging/server/plugin.ts b/x-pack/plugins/saved_objects_tagging/server/plugin.ts index bc43d4d65c828c1..05a2bb31514f14a 100644 --- a/x-pack/plugins/saved_objects_tagging/server/plugin.ts +++ b/x-pack/plugins/saved_objects_tagging/server/plugin.ts @@ -35,7 +35,7 @@ export class SavedObjectTaggingPlugin implements Plugin<{}, {}, SetupDeps, {}> { http.registerRouteHandlerContext( 'tags', async (context, req, res) => { - return new TagsRequestHandlerContext(req, context.core, security); + return new TagsRequestHandlerContext(req, await context.core, security); } ); diff --git a/x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts b/x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts index 09c9f77d695726f..00f0de038851cf2 100644 --- a/x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts +++ b/x-pack/plugins/saved_objects_tagging/server/request_handler_context.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { RequestHandlerContext, KibanaRequest } from '@kbn/core/server'; +import type { CoreRequestHandlerContext, KibanaRequest } from '@kbn/core/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { ITagsClient } from '../common/types'; import { ITagsRequestHandlerContext } from './types'; @@ -17,7 +17,7 @@ export class TagsRequestHandlerContext implements ITagsRequestHandlerContext { constructor( private readonly request: KibanaRequest, - private readonly coreContext: RequestHandlerContext['core'], + private readonly coreContext: CoreRequestHandlerContext, private readonly security?: SecurityPluginSetup ) {} diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/find_assignable_objects.ts b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/find_assignable_objects.ts index 8bda50940cc21a2..2fd6dfe56b33eb0 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/find_assignable_objects.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/find_assignable_objects.ts @@ -22,7 +22,7 @@ export const registerFindAssignableObjectsRoute = (router: TagsPluginRouter) => }, }, router.handleLegacyErrors(async (ctx, req, res) => { - const { assignmentService } = ctx.tags!; + const { assignmentService } = await ctx.tags; const { query } = req; const results = await assignmentService.findAssignableObjects({ diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/get_assignable_types.ts b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/get_assignable_types.ts index 385de4eb9fb64d6..bd82e7d31bc7f3b 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/get_assignable_types.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/get_assignable_types.ts @@ -15,7 +15,7 @@ export const registerGetAssignableTypesRoute = (router: TagsPluginRouter) => { validate: {}, }, router.handleLegacyErrors(async (ctx, req, res) => { - const { assignmentService } = ctx.tags!; + const { assignmentService } = await ctx.tags; const types = await assignmentService.getAssignableTypes(); return res.ok({ diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/update_tags_assignments.ts b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/update_tags_assignments.ts index c6c98ebd7b68680..5bc1f844c4d3638 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/assignments/update_tags_assignments.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/assignments/update_tags_assignments.ts @@ -37,7 +37,7 @@ export const registerUpdateTagsAssignmentsRoute = (router: TagsPluginRouter) => }, router.handleLegacyErrors(async (ctx, req, res) => { try { - const { assignmentService } = ctx.tags!; + const { assignmentService } = await ctx.tags; const { tags, assign, unassign } = req.body; await assignmentService.updateTagAssignments({ diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/internal/bulk_delete.ts b/x-pack/plugins/saved_objects_tagging/server/routes/internal/bulk_delete.ts index e70819346681067..ea4471f7d1243b3 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/internal/bulk_delete.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/internal/bulk_delete.ts @@ -20,7 +20,7 @@ export const registerInternalBulkDeleteRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const { ids: tagIds } = req.body; - const client = ctx.tags!.tagsClient; + const client = (await ctx.tags).tagsClient; for (const tagId of tagIds) { await client.delete(tagId); diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/internal/find_tags.ts b/x-pack/plugins/saved_objects_tagging/server/routes/internal/find_tags.ts index 0506b9051e46710..32318f39b5a0c04 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/internal/find_tags.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/internal/find_tags.ts @@ -26,7 +26,7 @@ export const registerInternalFindTagsRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const { query } = req; - const { client, typeRegistry } = ctx.core.savedObjects; + const { client, typeRegistry } = (await ctx.core).savedObjects; const findResponse = await client.find({ page: query.page, diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/create_tag.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/create_tag.ts index 0001ff422a2bcba..7b9e6a32d3aea14 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/create_tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/create_tag.ts @@ -23,7 +23,8 @@ export const registerCreateTagRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { try { - const tag = await ctx.tags!.tagsClient.create(req.body); + const { tagsClient } = await ctx.tags; + const tag = await tagsClient.create(req.body); return res.ok({ body: { tag, diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/delete_tag.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/delete_tag.ts index 42077eb05d13e28..505ecfd4974a01f 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/delete_tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/delete_tag.ts @@ -20,7 +20,8 @@ export const registerDeleteTagRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const { id } = req.params; - await ctx.tags!.tagsClient.delete(id); + const { tagsClient } = await ctx.tags; + await tagsClient.delete(id); return res.ok(); }) ); diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_all_tags.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_all_tags.ts index af3b39f26f2a909..011d764983faf60 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_all_tags.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_all_tags.ts @@ -14,7 +14,8 @@ export const registerGetAllTagsRoute = (router: TagsPluginRouter) => { validate: {}, }, router.handleLegacyErrors(async (ctx, req, res) => { - const tags = await ctx.tags!.tagsClient.getAll(); + const { tagsClient } = await ctx.tags; + const tags = await tagsClient.getAll(); return res.ok({ body: { tags, diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_tag.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_tag.ts index 8080b6ea22a6f99..4488d4dae6e2b4e 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/get_tag.ts @@ -20,7 +20,8 @@ export const registerGetTagRoute = (router: TagsPluginRouter) => { }, router.handleLegacyErrors(async (ctx, req, res) => { const { id } = req.params; - const tag = await ctx.tags!.tagsClient.get(id); + const { tagsClient } = await ctx.tags; + const tag = await tagsClient.get(id); return res.ok({ body: { tag, diff --git a/x-pack/plugins/saved_objects_tagging/server/routes/tags/update_tag.ts b/x-pack/plugins/saved_objects_tagging/server/routes/tags/update_tag.ts index d357c42d1924f24..67b7d7a6acbda5e 100644 --- a/x-pack/plugins/saved_objects_tagging/server/routes/tags/update_tag.ts +++ b/x-pack/plugins/saved_objects_tagging/server/routes/tags/update_tag.ts @@ -27,7 +27,8 @@ export const registerUpdateTagRoute = (router: TagsPluginRouter) => { router.handleLegacyErrors(async (ctx, req, res) => { const { id } = req.params; try { - const tag = await ctx.tags!.tagsClient.update(id, req.body); + const { tagsClient } = await ctx.tags; + const tag = await tagsClient.update(id, req.body); return res.ok({ body: { tag, diff --git a/x-pack/plugins/saved_objects_tagging/server/types.ts b/x-pack/plugins/saved_objects_tagging/server/types.ts index 92618c7d3fb532e..366f2779b6a8184 100644 --- a/x-pack/plugins/saved_objects_tagging/server/types.ts +++ b/x-pack/plugins/saved_objects_tagging/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import { ITagsClient } from '../common/types'; import { IAssignmentService } from './services'; @@ -17,9 +17,9 @@ export interface ITagsRequestHandlerContext { /** * @internal */ -export interface TagsHandlerContext extends RequestHandlerContext { +export type TagsHandlerContext = CustomRequestHandlerContext<{ tags: ITagsRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/searchprofiler/server/routes/profile.ts b/x-pack/plugins/searchprofiler/server/routes/profile.ts index 22c97e240a3b956..9e76bf0df96a1f9 100644 --- a/x-pack/plugins/searchprofiler/server/routes/profile.ts +++ b/x-pack/plugins/searchprofiler/server/routes/profile.ts @@ -43,7 +43,7 @@ export const register = ({ router, getLicenseStatus, log }: RouteDependencies) = }; try { - const client = ctx.core.elasticsearch.client.asCurrentUser; + const client = (await ctx.core).elasticsearch.client.asCurrentUser; const resp = await client.search(body); return response.ok({ diff --git a/x-pack/plugins/security/server/routes/api_keys/create.test.ts b/x-pack/plugins/security/server/routes/api_keys/create.test.ts index e88b4f0537d0c1b..dbf4c93639e478e 100644 --- a/x-pack/plugins/security/server/routes/api_keys/create.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/create.test.ts @@ -9,12 +9,11 @@ import Boom from '@hapi/boom'; import type { RequestHandler } from '@kbn/core/server'; import { kibanaResponseFactory } from '@kbn/core/server'; -import { httpServerMock } from '@kbn/core/server/mocks'; +import { coreMock, httpServerMock } from '@kbn/core/server/mocks'; import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; import type { InternalAuthenticationServiceStart } from '../../authentication'; import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; -import type { SecurityRequestHandlerContext } from '../../types'; import { routeDefinitionParamsMock } from '../index.mock'; import { defineCreateApiKeyRoutes } from './create'; @@ -22,9 +21,9 @@ describe('Create API Key route', () => { function getMockContext( licenseCheckResult: { state: string; message?: string } = { state: 'valid' } ) { - return { + return coreMock.createCustomRequestHandlerContext({ licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } }, - } as unknown as SecurityRequestHandlerContext; + }); } let routeHandler: RequestHandler; @@ -53,7 +52,7 @@ describe('Create API Key route', () => { expect(response.status).toBe(403); expect(response.payload).toEqual({ message: 'test forbidden message' }); - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect((await mockContext.licensing).license.check).toHaveBeenCalledWith('security', 'basic'); }); test('returns error from cluster client', async () => { diff --git a/x-pack/plugins/security/server/routes/api_keys/enabled.test.ts b/x-pack/plugins/security/server/routes/api_keys/enabled.test.ts index d768a421316f1f6..7beef71256c4615 100644 --- a/x-pack/plugins/security/server/routes/api_keys/enabled.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/enabled.test.ts @@ -9,12 +9,11 @@ import Boom from '@hapi/boom'; import type { RequestHandler } from '@kbn/core/server'; import { kibanaResponseFactory } from '@kbn/core/server'; -import { httpServerMock } from '@kbn/core/server/mocks'; +import { coreMock, httpServerMock } from '@kbn/core/server/mocks'; import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; import type { InternalAuthenticationServiceStart } from '../../authentication'; import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; -import type { SecurityRequestHandlerContext } from '../../types'; import { routeDefinitionParamsMock } from '../index.mock'; import { defineEnabledApiKeysRoutes } from './enabled'; @@ -22,9 +21,9 @@ describe('API keys enabled', () => { function getMockContext( licenseCheckResult: { state: string; message?: string } = { state: 'valid' } ) { - return { + return coreMock.createCustomRequestHandlerContext({ licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } }, - } as unknown as SecurityRequestHandlerContext; + }); } let routeHandler: RequestHandler; @@ -53,7 +52,7 @@ describe('API keys enabled', () => { expect(response.status).toBe(403); expect(response.payload).toEqual({ message: 'test forbidden message' }); - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect((await mockContext.licensing).license.check).toHaveBeenCalledWith('security', 'basic'); }); test('returns error from cluster client', async () => { diff --git a/x-pack/plugins/security/server/routes/api_keys/get.test.ts b/x-pack/plugins/security/server/routes/api_keys/get.test.ts index f05f4d5c37337d3..c34a67ff1bfcbe1 100644 --- a/x-pack/plugins/security/server/routes/api_keys/get.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/get.test.ts @@ -28,13 +28,17 @@ describe('Get API keys', () => { ) => { test(description, async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } } as any, + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, }; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext as any, + }); if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.getApiKey.mockResponse( + mockCoreContext.elasticsearch.client.asCurrentUser.security.getApiKey.mockResponse( // @ts-expect-error unknown type apiResponse() ); @@ -57,10 +61,10 @@ describe('Get API keys', () => { if (apiResponse) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.getApiKey + mockCoreContext.elasticsearch.client.asCurrentUser.security.getApiKey ).toHaveBeenCalledWith({ owner: !isAdmin }); } - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); }); }; diff --git a/x-pack/plugins/security/server/routes/api_keys/get.ts b/x-pack/plugins/security/server/routes/api_keys/get.ts index 5907dacb21a9b06..db0d02a20c687eb 100644 --- a/x-pack/plugins/security/server/routes/api_keys/get.ts +++ b/x-pack/plugins/security/server/routes/api_keys/get.ts @@ -29,10 +29,10 @@ export function defineGetApiKeysRoutes({ router }: RouteDefinitionParams) { createLicensedRouteHandler(async (context, request, response) => { try { const isAdmin = request.query.isAdmin === 'true'; - const apiResponse = - await context.core.elasticsearch.client.asCurrentUser.security.getApiKey({ - owner: !isAdmin, - }); + const esClient = (await context.core).elasticsearch.client; + const apiResponse = await esClient.asCurrentUser.security.getApiKey({ + owner: !isAdmin, + }); const validKeys = apiResponse.api_keys.filter(({ invalidated }) => !invalidated); diff --git a/x-pack/plugins/security/server/routes/api_keys/invalidate.test.ts b/x-pack/plugins/security/server/routes/api_keys/invalidate.test.ts index 386e894eb3354b6..c6f4594e8fb3c8e 100644 --- a/x-pack/plugins/security/server/routes/api_keys/invalidate.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/invalidate.test.ts @@ -29,13 +29,17 @@ describe('Invalidate API keys', () => { ) => { test(description, async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } } as any, - }; + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); for (const apiResponse of apiResponses) { - mockContext.core.elasticsearch.client.asCurrentUser.security.invalidateApiKey.mockImplementationOnce( + mockCoreContext.elasticsearch.client.asCurrentUser.security.invalidateApiKey.mockImplementationOnce( (async () => ({ body: await apiResponse() })) as any ); } @@ -58,11 +62,11 @@ describe('Invalidate API keys', () => { if (Array.isArray(asserts.apiArguments)) { for (const apiArguments of asserts.apiArguments) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.invalidateApiKey + mockCoreContext.elasticsearch.client.asCurrentUser.security.invalidateApiKey ).toHaveBeenCalledWith(apiArguments); } } - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); }); }; diff --git a/x-pack/plugins/security/server/routes/api_keys/invalidate.ts b/x-pack/plugins/security/server/routes/api_keys/invalidate.ts index 179df26a874b85e..58f25bbf80b4f63 100644 --- a/x-pack/plugins/security/server/routes/api_keys/invalidate.ts +++ b/x-pack/plugins/security/server/routes/api_keys/invalidate.ts @@ -35,13 +35,14 @@ export function defineInvalidateApiKeysRoutes({ router }: RouteDefinitionParams) await Promise.all( request.body.apiKeys.map(async (key) => { try { + const esClient = (await context.core).elasticsearch.client; const body: { ids: string[]; owner?: boolean } = { ids: [key.id] }; if (!request.body.isAdmin) { body.owner = true; } // Send the request to invalidate the API key and return an error if it could not be deleted. - await context.core.elasticsearch.client.asCurrentUser.security.invalidateApiKey({ + await esClient.asCurrentUser.security.invalidateApiKey({ body, }); return { key, error: undefined }; diff --git a/x-pack/plugins/security/server/routes/api_keys/privileges.test.ts b/x-pack/plugins/security/server/routes/api_keys/privileges.test.ts index 06e978e94758c00..52d1d59a486da53 100644 --- a/x-pack/plugins/security/server/routes/api_keys/privileges.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/privileges.test.ts @@ -34,17 +34,21 @@ describe('Check API keys privileges', () => { ) => { test(description, async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } } as any, - }; + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); const authc = authenticationServiceMock.createStart(); authc.apiKeys.areAPIKeysEnabled.mockResolvedValue(areAPIKeysEnabled); mockRouteDefinitionParams.getAuthenticationService.mockReturnValue(authc); if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResponseImplementation( + mockCoreContext.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResponseImplementation( // @ts-expect-error unknown return () => { return { @@ -70,11 +74,11 @@ describe('Check API keys privileges', () => { if (asserts.apiArguments) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.hasPrivileges + mockCoreContext.elasticsearch.client.asCurrentUser.security.hasPrivileges ).toHaveBeenCalledWith(asserts.apiArguments); } - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); }); }; diff --git a/x-pack/plugins/security/server/routes/api_keys/privileges.ts b/x-pack/plugins/security/server/routes/api_keys/privileges.ts index 7fa92e21ddba67d..09210e1d00d3713 100644 --- a/x-pack/plugins/security/server/routes/api_keys/privileges.ts +++ b/x-pack/plugins/security/server/routes/api_keys/privileges.ts @@ -20,6 +20,7 @@ export function defineCheckPrivilegesRoutes({ }, createLicensedRouteHandler(async (context, request, response) => { try { + const esClient = (await context.core).elasticsearch.client; const [ { cluster: { @@ -30,7 +31,7 @@ export function defineCheckPrivilegesRoutes({ }, areApiKeysEnabled, ] = await Promise.all([ - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + esClient.asCurrentUser.security.hasPrivileges({ body: { cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'] }, }), getAuthenticationService().apiKeys.areAPIKeysEnabled(), diff --git a/x-pack/plugins/security/server/routes/authorization/privileges/get.test.ts b/x-pack/plugins/security/server/routes/authorization/privileges/get.test.ts index 30a740cc3a9840f..fca0a0e4388f4e1 100644 --- a/x-pack/plugins/security/server/routes/authorization/privileges/get.test.ts +++ b/x-pack/plugins/security/server/routes/authorization/privileges/get.test.ts @@ -6,7 +6,7 @@ */ import { kibanaResponseFactory } from '@kbn/core/server'; -import { httpServerMock } from '@kbn/core/server/mocks'; +import { coreMock, httpServerMock } from '@kbn/core/server/mocks'; import type { LicenseCheck } from '@kbn/licensing-plugin/server'; import type { RawKibanaPrivileges } from '../../../../common/model'; @@ -66,15 +66,18 @@ describe('GET privileges', () => { query: includeActions ? { includeActions: 'true' } : undefined, headers, }); - const mockContext = { - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } }, - } as unknown as SecurityRequestHandlerContext; + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, + }; + const mockContext = coreMock.createCustomRequestHandlerContext({ + licensing: mockLicensingContext, + }) as unknown as SecurityRequestHandlerContext; const response = await handler(mockContext, mockRequest, kibanaResponseFactory); expect(response.status).toBe(asserts.statusCode); expect(response.payload).toEqual(asserts.result); - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); }); }; diff --git a/x-pack/plugins/security/server/routes/authorization/privileges/get_builtin.ts b/x-pack/plugins/security/server/routes/authorization/privileges/get_builtin.ts index 40b67aa08b0736f..e51e8e1d5ae5149 100644 --- a/x-pack/plugins/security/server/routes/authorization/privileges/get_builtin.ts +++ b/x-pack/plugins/security/server/routes/authorization/privileges/get_builtin.ts @@ -11,8 +11,8 @@ export function defineGetBuiltinPrivilegesRoutes({ router }: RouteDefinitionPara router.get( { path: '/internal/security/esPrivileges/builtin', validate: false }, async (context, request, response) => { - const privileges = - await context.core.elasticsearch.client.asCurrentUser.security.getBuiltinPrivileges(); + const esClient = (await context.core).elasticsearch.client; + const privileges = await esClient.asCurrentUser.security.getBuiltinPrivileges(); // Exclude the `none` privilege, as it doesn't make sense as an option within the Kibana UI privileges.cluster = privileges.cluster.filter((privilege) => privilege !== 'none'); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/delete.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/delete.test.ts index 3f5a17fd385894a..dfe2af12a23e400 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/delete.test.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/delete.test.ts @@ -28,13 +28,17 @@ describe('DELETE role', () => { ) => { test(description, async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } } as any, - }; + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.deleteRole.mockImplementation( + mockCoreContext.elasticsearch.client.asCurrentUser.security.deleteRole.mockImplementation( (async () => ({ body: await apiResponse() })) as any ); } @@ -56,10 +60,10 @@ describe('DELETE role', () => { if (apiResponse) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.deleteRole + mockCoreContext.elasticsearch.client.asCurrentUser.security.deleteRole ).toHaveBeenCalledWith({ name }); } - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); }); }; diff --git a/x-pack/plugins/security/server/routes/authorization/roles/delete.ts b/x-pack/plugins/security/server/routes/authorization/roles/delete.ts index e30221b2e9e9899..b484fd0151841da 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/delete.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/delete.ts @@ -21,7 +21,8 @@ export function defineDeleteRolesRoutes({ router }: RouteDefinitionParams) { }, createLicensedRouteHandler(async (context, request, response) => { try { - await context.core.elasticsearch.client.asCurrentUser.security.deleteRole({ + const esClient = (await context.core).elasticsearch.client; + await esClient.asCurrentUser.security.deleteRole({ name: request.params.name, }); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/get.test.ts index 1a7e56e157558c6..90457c71b90a7d8 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/get.test.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/get.test.ts @@ -34,13 +34,17 @@ describe('GET role', () => { mockRouteDefinitionParams.authz.applicationName = application; mockRouteDefinitionParams.getFeatures = jest.fn().mockResolvedValue([]); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } } as any, - }; + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementation( + mockCoreContext.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementation( (() => ({ body: apiResponse() })) as any ); } @@ -62,11 +66,11 @@ describe('GET role', () => { if (apiResponse) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole + mockCoreContext.elasticsearch.client.asCurrentUser.security.getRole ).toHaveBeenCalledWith({ name }); } - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); }); }; diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get.ts b/x-pack/plugins/security/server/routes/authorization/roles/get.ts index 125966d887e04d8..9ae385b1ab3fb62 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/get.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/get.ts @@ -22,9 +22,10 @@ export function defineGetRolesRoutes({ router, authz, getFeatures }: RouteDefini }, createLicensedRouteHandler(async (context, request, response) => { try { + const esClient = (await context.core).elasticsearch.client; const [features, elasticsearchRoles] = await Promise.all([ getFeatures(), - await context.core.elasticsearch.client.asCurrentUser.security.getRole({ + await esClient.asCurrentUser.security.getRole({ name: request.params.name, }), ]); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get_all.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/get_all.test.ts index 3c7c8a0ebf6b139..a7833f803afa1e7 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/get_all.test.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/get_all.test.ts @@ -34,13 +34,17 @@ describe('GET all roles', () => { mockRouteDefinitionParams.authz.applicationName = application; mockRouteDefinitionParams.getFeatures = jest.fn().mockResolvedValue([]); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } } as any, - }; + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementation( + mockCoreContext.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementation( (() => ({ body: apiResponse() })) as any ); } @@ -61,10 +65,10 @@ describe('GET all roles', () => { if (apiResponse) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole + mockCoreContext.elasticsearch.client.asCurrentUser.security.getRole ).toHaveBeenCalled(); } - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); }); }; diff --git a/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts b/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts index f34b6a0893660f7..20f967db598f3b3 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/get_all.ts @@ -15,9 +15,10 @@ export function defineGetAllRolesRoutes({ router, authz, getFeatures }: RouteDef { path: '/api/security/role', validate: false }, createLicensedRouteHandler(async (context, request, response) => { try { + const esClient = (await context.core).elasticsearch.client; const [features, elasticsearchRoles] = await Promise.all([ getFeatures(), - await context.core.elasticsearch.client.asCurrentUser.security.getRole(), + await esClient.asCurrentUser.security.getRole(), ]); // Transform elasticsearch roles into Kibana roles and return in a list sorted by the role name. diff --git a/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts index 425115da1e20bf9..9abef4a5e85c540 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts @@ -75,19 +75,23 @@ const putRoleTest = ( mockRouteDefinitionParams.authz.applicationName = application; mockRouteDefinitionParams.authz.privileges.get.mockReturnValue(privilegeMap); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } } as any, - }; + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); if (apiResponses?.get) { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementationOnce( + mockCoreContext.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementationOnce( (() => ({ body: apiResponses?.get() })) as any ); } if (apiResponses?.put) { - mockContext.core.elasticsearch.client.asCurrentUser.security.putRole.mockResponseImplementationOnce( + mockCoreContext.elasticsearch.client.asCurrentUser.security.putRole.mockResponseImplementationOnce( (() => ({ body: apiResponses?.put() })) as any ); } @@ -154,15 +158,15 @@ const putRoleTest = ( if (asserts.apiArguments?.get) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole + mockCoreContext.elasticsearch.client.asCurrentUser.security.getRole ).toHaveBeenCalledWith(...asserts.apiArguments?.get); } if (asserts.apiArguments?.put) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.putRole + mockCoreContext.elasticsearch.client.asCurrentUser.security.putRole ).toHaveBeenCalledWith(...asserts.apiArguments?.put); } - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); if (asserts.recordSubFeaturePrivilegeUsage) { expect( diff --git a/x-pack/plugins/security/server/routes/authorization/roles/put.ts b/x-pack/plugins/security/server/routes/authorization/roles/put.ts index 60e24dcfec1c193..03fbdf30dc7674a 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/put.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/put.ts @@ -66,12 +66,10 @@ export function definePutRolesRoutes({ const { name } = request.params; try { + const esClient = (await context.core).elasticsearch.client; const [features, rawRoles] = await Promise.all([ getFeatures(), - context.core.elasticsearch.client.asCurrentUser.security.getRole( - { name: request.params.name }, - { ignore: [404] } - ), + esClient.asCurrentUser.security.getRole({ name: request.params.name }, { ignore: [404] }), ]); const { validationErrors } = validateKibanaPrivileges(features, request.body.kibana); @@ -91,7 +89,7 @@ export function definePutRolesRoutes({ rawRoles[name] ? rawRoles[name].applications : [] ); - await context.core.elasticsearch.client.asCurrentUser.security.putRole({ + await esClient.asCurrentUser.security.putRole({ name: request.params.name, // @ts-expect-error RoleIndexPrivilege is not compatible. grant is required in IndicesPrivileges.field_security body, diff --git a/x-pack/plugins/security/server/routes/deprecations/kibana_user_role.ts b/x-pack/plugins/security/server/routes/deprecations/kibana_user_role.ts index bb07ece2c75b941..036d1f141f99770 100644 --- a/x-pack/plugins/security/server/routes/deprecations/kibana_user_role.ts +++ b/x-pack/plugins/security/server/routes/deprecations/kibana_user_role.ts @@ -27,8 +27,9 @@ export function defineKibanaUserRoleDeprecationRoutes({ router, logger }: RouteD }, createLicensedRouteHandler(async (context, request, response) => { let users: estypes.SecurityGetUserResponse; + const esClient = (await context.core).elasticsearch.client; try { - users = await context.core.elasticsearch.client.asCurrentUser.security.getUser(); + users = await esClient.asCurrentUser.security.getUser(); } catch (err) { if (getErrorStatusCode(err) === 403) { logger.warn( @@ -65,7 +66,7 @@ export function defineKibanaUserRoleDeprecationRoutes({ router, logger }: RouteD } try { - await context.core.elasticsearch.client.asCurrentUser.security.putUser({ + await esClient.asCurrentUser.security.putUser({ username: userToUpdate.username, body: { ...userToUpdate, roles }, }); @@ -89,10 +90,10 @@ export function defineKibanaUserRoleDeprecationRoutes({ router, logger }: RouteD validate: false, }, createLicensedRouteHandler(async (context, request, response) => { + const esClient = (await context.core).elasticsearch.client; let roleMappings: estypes.SecurityGetRoleMappingResponse; try { - roleMappings = - await context.core.elasticsearch.client.asCurrentUser.security.getRoleMapping(); + roleMappings = await esClient.asCurrentUser.security.getRoleMapping(); } catch (err) { logger.error(`Failed to retrieve role mappings: ${getDetailedErrorMessage(err)}.`); return response.customError(wrapIntoCustomErrorResponse(err)); @@ -119,7 +120,7 @@ export function defineKibanaUserRoleDeprecationRoutes({ router, logger }: RouteD } try { - await context.core.elasticsearch.client.asCurrentUser.security.putRoleMapping({ + await esClient.asCurrentUser.security.putRoleMapping({ name: mappingNameToUpdate, body: { ...mappingToUpdate, roles }, }); diff --git a/x-pack/plugins/security/server/routes/index.mock.ts b/x-pack/plugins/security/server/routes/index.mock.ts index 939ed36ab04d2e1..3cda2a0ec9bc5f2 100644 --- a/x-pack/plugins/security/server/routes/index.mock.ts +++ b/x-pack/plugins/security/server/routes/index.mock.ts @@ -51,8 +51,9 @@ export const routeDefinitionParamsMock = { }; export const securityRequestHandlerContextMock = { - create: (): SecurityRequestHandlerContext => ({ - core: coreMock.createRequestHandlerContext(), - licensing: licensingMock.createRequestHandlerContext(), - }), + create: (): SecurityRequestHandlerContext => + coreMock.createCustomRequestHandlerContext({ + core: coreMock.createRequestHandlerContext(), + licensing: licensingMock.createRequestHandlerContext(), + }), }; diff --git a/x-pack/plugins/security/server/routes/indices/get_fields.ts b/x-pack/plugins/security/server/routes/indices/get_fields.ts index da1a74256005322..b0ec51339e08077 100644 --- a/x-pack/plugins/security/server/routes/indices/get_fields.ts +++ b/x-pack/plugins/security/server/routes/indices/get_fields.ts @@ -18,14 +18,14 @@ export function defineGetFieldsRoutes({ router }: RouteDefinitionParams) { }, async (context, request, response) => { try { - const indexMappings = - await context.core.elasticsearch.client.asCurrentUser.indices.getFieldMapping({ - index: request.params.query, - fields: '*', - allow_no_indices: false, - include_defaults: true, - filter_path: '*.mappings.*.mapping.*.type', - }); + const esClient = (await context.core).elasticsearch.client; + const indexMappings = await esClient.asCurrentUser.indices.getFieldMapping({ + index: request.params.query, + fields: '*', + allow_no_indices: false, + include_defaults: true, + filter_path: '*.mappings.*.mapping.*.type', + }); // The flow is the following (see response format at https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-field-mapping.html): // 1. Iterate over all matched indices. diff --git a/x-pack/plugins/security/server/routes/licensed_route_handler.ts b/x-pack/plugins/security/server/routes/licensed_route_handler.ts index cf631c64c4a3124..59cb6150cd4cf99 100644 --- a/x-pack/plugins/security/server/routes/licensed_route_handler.ts +++ b/x-pack/plugins/security/server/routes/licensed_route_handler.ts @@ -19,12 +19,12 @@ export const createLicensedRouteHandler = < >( handler: RequestHandler ) => { - const licensedRouteHandler: RequestHandler = ( + const licensedRouteHandler: RequestHandler = async ( context, request, responseToolkit ) => { - const { license } = context.licensing; + const { license } = await context.licensing; const licenseCheck = license.check('security', 'basic'); if (licenseCheck.state === 'unavailable' || licenseCheck.state === 'invalid') { return responseToolkit.forbidden({ body: { message: licenseCheck.message! } }); diff --git a/x-pack/plugins/security/server/routes/role_mapping/delete.test.ts b/x-pack/plugins/security/server/routes/role_mapping/delete.test.ts index 9a63c16a6ef4aa0..63e0d602cf1224a 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/delete.test.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/delete.test.ts @@ -14,11 +14,16 @@ import { defineRoleMappingDeleteRoutes } from './delete'; describe('DELETE role mappings', () => { it('allows a role mapping to be deleted', async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue({ state: 'valid' }) } } as any, - }; - mockContext.core.elasticsearch.client.asCurrentUser.security.deleteRoleMapping.mockResponse({ + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { check: jest.fn().mockReturnValue({ state: 'valid' }) }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); + + mockCoreContext.elasticsearch.client.asCurrentUser.security.deleteRoleMapping.mockResponse({ acknowledged: true, } as any); @@ -39,24 +44,27 @@ describe('DELETE role mappings', () => { expect(response.status).toBe(200); expect(response.payload).toEqual({ acknowledged: true }); expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.deleteRoleMapping + mockCoreContext.elasticsearch.client.asCurrentUser.security.deleteRoleMapping ).toHaveBeenCalledWith({ name }); }); describe('failure', () => { it('returns result of license check', async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { - license: { - check: jest.fn().mockReturnValue({ - state: 'invalid', - message: 'test forbidden message', - }), - }, - } as any, - }; + + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { + check: jest.fn().mockReturnValue({ + state: 'invalid', + message: 'test forbidden message', + }), + }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); defineRoleMappingDeleteRoutes(mockRouteDefinitionParams); @@ -75,7 +83,7 @@ describe('DELETE role mappings', () => { expect(response.status).toBe(403); expect(response.payload).toEqual({ message: 'test forbidden message' }); expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.deleteRoleMapping + mockCoreContext.elasticsearch.client.asCurrentUser.security.deleteRoleMapping ).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/security/server/routes/role_mapping/delete.ts b/x-pack/plugins/security/server/routes/role_mapping/delete.ts index c413ca012fb6dd2..e305de6e4fcb491 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/delete.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/delete.ts @@ -23,10 +23,10 @@ export function defineRoleMappingDeleteRoutes({ router }: RouteDefinitionParams) }, createLicensedRouteHandler(async (context, request, response) => { try { - const deleteResponse = - await context.core.elasticsearch.client.asCurrentUser.security.deleteRoleMapping({ - name: request.params.name, - }); + const esClient = (await context.core).elasticsearch.client; + const deleteResponse = await esClient.asCurrentUser.security.deleteRoleMapping({ + name: request.params.name, + }); return response.ok({ body: deleteResponse }); } catch (error) { const wrappedError = wrapError(error); diff --git a/x-pack/plugins/security/server/routes/role_mapping/feature_check.test.ts b/x-pack/plugins/security/server/routes/role_mapping/feature_check.test.ts index 9aa0639b74ce628..0efe93d21c1b213 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/feature_check.test.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/feature_check.test.ts @@ -48,18 +48,23 @@ describe('GET role mappings feature check', () => { ) => { test(description, async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockContext = { - core: coreMock.createRequestHandlerContext(), - licensing: { license: { check: jest.fn().mockReturnValue(licenseCheckResult) } } as any, - }; + const mockCoreContext = coreMock.createRequestHandlerContext(); + const mockLicensingContext = { + license: { + check: jest.fn().mockReturnValue(licenseCheckResult), + }, + } as any; + const mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, + licensing: mockLicensingContext, + }); - mockContext.core.elasticsearch.client.asInternalUser.nodes.info.mockImplementation( - (async () => nodeSettingsResponse()) as any - ); - mockContext.core.elasticsearch.client.asInternalUser.transport.request.mockImplementation( + mockCoreContext.elasticsearch.client.asInternalUser.nodes.info.mockImplementation((async () => + nodeSettingsResponse()) as any); + mockCoreContext.elasticsearch.client.asInternalUser.transport.request.mockImplementation( (async () => xpackUsageResponse()) as any ); - mockContext.core.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResolvedValue({ + mockCoreContext.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResolvedValue({ has_all_requested: canManageRoleMappings, } as any); @@ -77,7 +82,7 @@ describe('GET role mappings feature check', () => { expect(response.status).toBe(asserts.statusCode); expect(response.payload).toEqual(asserts.result); - expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); }); }; diff --git a/x-pack/plugins/security/server/routes/role_mapping/feature_check.ts b/x-pack/plugins/security/server/routes/role_mapping/feature_check.ts index 46e0c608b7b0a59..9715f92cb5a3755 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/feature_check.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/feature_check.ts @@ -43,8 +43,9 @@ export function defineRoleMappingFeatureCheckRoute({ router, logger }: RouteDefi validate: false, }, createLicensedRouteHandler(async (context, request, response) => { + const esClient = (await context.core).elasticsearch.client; const { has_all_requested: canManageRoleMappings } = - await context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + await esClient.asCurrentUser.security.hasPrivileges({ body: { cluster: ['manage_security'] }, }); @@ -56,10 +57,7 @@ export function defineRoleMappingFeatureCheckRoute({ router, logger }: RouteDefi }); } - const enabledFeatures = await getEnabledRoleMappingsFeatures( - context.core.elasticsearch.client.asInternalUser, - logger - ); + const enabledFeatures = await getEnabledRoleMappingsFeatures(esClient.asInternalUser, logger); return response.ok({ body: { diff --git a/x-pack/plugins/security/server/routes/role_mapping/get.test.ts b/x-pack/plugins/security/server/routes/role_mapping/get.test.ts index 2b7dcf857bf574d..564f93d302353e6 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/get.test.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/get.test.ts @@ -80,7 +80,11 @@ describe('GET role mappings', () => { headers, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual([ { @@ -159,7 +163,11 @@ describe('GET role mappings', () => { headers, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ name: 'mapping1', @@ -194,7 +202,11 @@ describe('GET role mappings', () => { headers, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(403); expect(response.payload).toEqual({ message: 'test forbidden message' }); expect( @@ -223,7 +235,11 @@ describe('GET role mappings', () => { headers, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(404); expect( mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping diff --git a/x-pack/plugins/security/server/routes/role_mapping/get.ts b/x-pack/plugins/security/server/routes/role_mapping/get.ts index 005ba083db579ec..ac6e7efaa8b0ac6 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/get.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/get.ts @@ -28,10 +28,10 @@ export function defineRoleMappingGetRoutes(params: RouteDefinitionParams) { const expectSingleEntity = typeof request.params.name === 'string'; try { - const roleMappingsResponse = - await context.core.elasticsearch.client.asCurrentUser.security.getRoleMapping({ - name: request.params.name, - }); + const esClient = (await context.core).elasticsearch.client; + const roleMappingsResponse = await esClient.asCurrentUser.security.getRoleMapping({ + name: request.params.name, + }); const mappings = Object.entries(roleMappingsResponse).map(([name, mapping]) => { return { diff --git a/x-pack/plugins/security/server/routes/role_mapping/post.test.ts b/x-pack/plugins/security/server/routes/role_mapping/post.test.ts index e85438ec2603124..a6acc866b2d0733 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/post.test.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/post.test.ts @@ -45,7 +45,11 @@ describe('POST role mappings', () => { headers, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(200); expect(response.payload).toEqual({ created: true }); @@ -91,7 +95,11 @@ describe('POST role mappings', () => { headers, }); - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); + const response = await handler( + coreMock.createCustomRequestHandlerContext(mockContext), + mockRequest, + kibanaResponseFactory + ); expect(response.status).toBe(403); expect(response.payload).toEqual({ message: 'test forbidden message' }); diff --git a/x-pack/plugins/security/server/routes/role_mapping/post.ts b/x-pack/plugins/security/server/routes/role_mapping/post.ts index 1a276e46e24274b..79bd8b3d3f2c0c2 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/post.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/post.ts @@ -44,11 +44,11 @@ export function defineRoleMappingPostRoutes({ router }: RouteDefinitionParams) { }, createLicensedRouteHandler(async (context, request, response) => { try { - const saveResponse = - await context.core.elasticsearch.client.asCurrentUser.security.putRoleMapping({ - name: request.params.name, - body: request.body, - }); + const esClient = (await context.core).elasticsearch.client; + const saveResponse = await esClient.asCurrentUser.security.putRoleMapping({ + name: request.params.name, + body: request.body, + }); return response.ok({ body: saveResponse }); } catch (error) { const wrappedError = wrapError(error); diff --git a/x-pack/plugins/security/server/routes/security_checkup/get_state.ts b/x-pack/plugins/security/server/routes/security_checkup/get_state.ts index 8c4e69cb87c814d..2946c3fa5dee326 100644 --- a/x-pack/plugins/security/server/routes/security_checkup/get_state.ts +++ b/x-pack/plugins/security/server/routes/security_checkup/get_state.ts @@ -31,12 +31,10 @@ export function defineSecurityCheckupGetStateRoutes({ router.get( { path: '/internal/security/security_checkup/state', validate: false }, async (context, _request, response) => { + const esClient = (await context.core).elasticsearch.client; let displayAlert = false; if (showInsecureClusterWarning) { - displayAlert = await doesClusterHaveUserData( - context.core.elasticsearch.client.asInternalUser, - logger - ); + displayAlert = await doesClusterHaveUserData(esClient.asInternalUser, logger); } const state: SecurityCheckupState = { diff --git a/x-pack/plugins/security/server/routes/users/change_password.test.ts b/x-pack/plugins/security/server/routes/users/change_password.test.ts index e51824a4332de1d..19f84ce46162707 100644 --- a/x-pack/plugins/security/server/routes/users/change_password.test.ts +++ b/x-pack/plugins/security/server/routes/users/change_password.test.ts @@ -32,13 +32,14 @@ describe('Change password', () => { let routeHandler: RequestHandler; let routeConfig: RouteConfig; let mockContext: DeeplyMockedKeys; + let mockCoreContext: ReturnType; function checkPasswordChangeAPICall(username: string, headers?: Headers) { expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.changePassword + mockCoreContext.elasticsearch.client.asCurrentUser.security.changePassword ).toHaveBeenCalledTimes(1); expect( - mockContext.core.elasticsearch.client.asCurrentUser.security.changePassword + mockCoreContext.elasticsearch.client.asCurrentUser.security.changePassword ).toHaveBeenCalledWith( { username, body: { password: 'new-password' } }, headers && { headers } @@ -59,10 +60,11 @@ describe('Change password', () => { authc.login.mockResolvedValue(AuthenticationResult.succeeded(mockAuthenticatedUser())); session.get.mockResolvedValue(sessionMock.createValue()); - mockContext = { - core: coreMock.createRequestHandlerContext(), + mockCoreContext = coreMock.createRequestHandlerContext(); + mockContext = coreMock.createCustomRequestHandlerContext({ + core: mockCoreContext, licensing: { license: { check: jest.fn().mockReturnValue({ state: 'valid' }) } }, - } as any; + }) as any; defineChangeUserPasswordRoutes(routeParamsMock); @@ -113,7 +115,7 @@ describe('Change password', () => { const changePasswordFailure = new errors.ResponseError( securityMock.createApiResponse({ statusCode: 401, body: {} }) ); - mockContext.core.elasticsearch.client.asCurrentUser.security.changePassword.mockRejectedValue( + mockCoreContext.elasticsearch.client.asCurrentUser.security.changePassword.mockRejectedValue( changePasswordFailure ); @@ -150,7 +152,7 @@ describe('Change password', () => { it('returns 500 if password update request fails with non-401 error.', async () => { const failureReason = new Error('Request failed.'); - mockContext.core.elasticsearch.client.asCurrentUser.security.changePassword.mockRejectedValue( + mockCoreContext.elasticsearch.client.asCurrentUser.security.changePassword.mockRejectedValue( failureReason ); @@ -232,7 +234,7 @@ describe('Change password', () => { it('returns 500 if password update request fails.', async () => { const failureReason = new Error('Request failed.'); - mockContext.core.elasticsearch.client.asCurrentUser.security.changePassword.mockRejectedValue( + mockCoreContext.elasticsearch.client.asCurrentUser.security.changePassword.mockRejectedValue( failureReason ); diff --git a/x-pack/plugins/security/server/routes/users/change_password.ts b/x-pack/plugins/security/server/routes/users/change_password.ts index 4dddd0cb07588d4..51df3e906a606df 100644 --- a/x-pack/plugins/security/server/routes/users/change_password.ts +++ b/x-pack/plugins/security/server/routes/users/change_password.ts @@ -59,7 +59,8 @@ export function defineChangeUserPasswordRoutes({ : undefined; try { - await context.core.elasticsearch.client.asCurrentUser.security.changePassword( + const esClient = (await context.core).elasticsearch.client; + await esClient.asCurrentUser.security.changePassword( { username, body: { password: newPassword } }, options ); diff --git a/x-pack/plugins/security/server/routes/users/create_or_update.ts b/x-pack/plugins/security/server/routes/users/create_or_update.ts index 75838240e79f3a2..de6adad78b4e8bd 100644 --- a/x-pack/plugins/security/server/routes/users/create_or_update.ts +++ b/x-pack/plugins/security/server/routes/users/create_or_update.ts @@ -30,7 +30,8 @@ export function defineCreateOrUpdateUserRoutes({ router }: RouteDefinitionParams }, createLicensedRouteHandler(async (context, request, response) => { try { - await context.core.elasticsearch.client.asCurrentUser.security.putUser({ + const esClient = (await context.core).elasticsearch.client; + await esClient.asCurrentUser.security.putUser({ username: request.params.username, body: request.body, }); diff --git a/x-pack/plugins/security/server/routes/users/delete.ts b/x-pack/plugins/security/server/routes/users/delete.ts index cc86b522f1c491f..429adb368574a93 100644 --- a/x-pack/plugins/security/server/routes/users/delete.ts +++ b/x-pack/plugins/security/server/routes/users/delete.ts @@ -21,7 +21,8 @@ export function defineDeleteUserRoutes({ router }: RouteDefinitionParams) { }, createLicensedRouteHandler(async (context, request, response) => { try { - await context.core.elasticsearch.client.asCurrentUser.security.deleteUser({ + const esClient = (await context.core).elasticsearch.client; + await esClient.asCurrentUser.security.deleteUser({ username: request.params.username, }); diff --git a/x-pack/plugins/security/server/routes/users/disable.ts b/x-pack/plugins/security/server/routes/users/disable.ts index d68da8b8490fc51..87f61daca8c955d 100644 --- a/x-pack/plugins/security/server/routes/users/disable.ts +++ b/x-pack/plugins/security/server/routes/users/disable.ts @@ -21,7 +21,8 @@ export function defineDisableUserRoutes({ router }: RouteDefinitionParams) { }, createLicensedRouteHandler(async (context, request, response) => { try { - await context.core.elasticsearch.client.asCurrentUser.security.disableUser({ + const esClient = (await context.core).elasticsearch.client; + await esClient.asCurrentUser.security.disableUser({ username: request.params.username, }); diff --git a/x-pack/plugins/security/server/routes/users/enable.ts b/x-pack/plugins/security/server/routes/users/enable.ts index 8a522e63f7fd6fd..a8a9d62bee938bf 100644 --- a/x-pack/plugins/security/server/routes/users/enable.ts +++ b/x-pack/plugins/security/server/routes/users/enable.ts @@ -21,7 +21,8 @@ export function defineEnableUserRoutes({ router }: RouteDefinitionParams) { }, createLicensedRouteHandler(async (context, request, response) => { try { - await context.core.elasticsearch.client.asCurrentUser.security.enableUser({ + const esClient = (await context.core).elasticsearch.client; + await esClient.asCurrentUser.security.enableUser({ username: request.params.username, }); diff --git a/x-pack/plugins/security/server/routes/users/get.ts b/x-pack/plugins/security/server/routes/users/get.ts index 3f2804e3c161667..ed18c8437627d92 100644 --- a/x-pack/plugins/security/server/routes/users/get.ts +++ b/x-pack/plugins/security/server/routes/users/get.ts @@ -21,8 +21,9 @@ export function defineGetUserRoutes({ router }: RouteDefinitionParams) { }, createLicensedRouteHandler(async (context, request, response) => { try { + const esClient = (await context.core).elasticsearch.client; const username = request.params.username; - const users = await context.core.elasticsearch.client.asCurrentUser.security.getUser({ + const users = await esClient.asCurrentUser.security.getUser({ username, }); diff --git a/x-pack/plugins/security/server/routes/users/get_all.ts b/x-pack/plugins/security/server/routes/users/get_all.ts index ce9d84aca2a0966..eae066418934072 100644 --- a/x-pack/plugins/security/server/routes/users/get_all.ts +++ b/x-pack/plugins/security/server/routes/users/get_all.ts @@ -14,11 +14,10 @@ export function defineGetAllUsersRoutes({ router }: RouteDefinitionParams) { { path: '/internal/security/users', validate: false }, createLicensedRouteHandler(async (context, request, response) => { try { + const esClient = (await context.core).elasticsearch.client; return response.ok({ // Return only values since keys (user names) are already duplicated there. - body: Object.values( - await context.core.elasticsearch.client.asCurrentUser.security.getUser() - ), + body: Object.values(await esClient.asCurrentUser.security.getUser()), }); } catch (error) { return response.customError(wrapIntoCustomErrorResponse(error)); diff --git a/x-pack/plugins/security/server/types.ts b/x-pack/plugins/security/server/types.ts index 1f8e2d0ca0b950f..6227696a9fbc75d 100644 --- a/x-pack/plugins/security/server/types.ts +++ b/x-pack/plugins/security/server/types.ts @@ -5,15 +5,15 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, IRouter } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; /** * @internal */ -export interface SecurityRequestHandlerContext extends RequestHandlerContext { +export type SecurityRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/security_solution/public/common/components/authentication/__snapshots__/authentications_host_table.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/authentication/__snapshots__/authentications_host_table.test.tsx.snap index b0a55bb72acb899..ff496768397c1c2 100644 --- a/x-pack/plugins/security_solution/public/common/components/authentication/__snapshots__/authentications_host_table.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/authentication/__snapshots__/authentications_host_table.test.tsx.snap @@ -19,6 +19,14 @@ exports[`Authentication Host Table Component rendering it renders the host authe user-select: text; } +.c1.toggle-expand .header-section-content { + height: 48px; +} + +.c1.toggle-expand .header-section-titles { + margin-top: 16px; +} + .c0 { position: relative; } @@ -52,7 +60,7 @@ exports[`Authentication Host Table Component rendering it renders the host authe data-test-subj="authentications-host-table-loading-false" >

{ + const actual = jest.requireActual('@elastic/charts'); + return { + ...actual, + Chart: jest.fn(({ children, ...props }) => ( +
+ {children} +
+ )), + Partition: jest.fn((props) =>
), + Settings: jest.fn((props) =>
), + }; +}); + +jest.mock('uuid', () => { + const actual = jest.requireActual('uuid'); + + return { + ...actual, + v4: jest.fn().mockReturnValue('test-uuid'), + }; +}); + +jest.mock('../../../overview/components/detection_response/alerts_by_status/chart_label', () => { + return { + ChartLabel: jest.fn((props) => ), + }; +}); + +jest.mock('./draggable_legend', () => { + return { + DraggableLegend: jest.fn((props) => ), + }; +}); + +jest.mock('./common', () => { + return { + useTheme: jest.fn(() => ({ + eui: { + euiScrollBar: 0, + euiColorDarkShade: '#fff', + euiScrollBarCorner: '#ccc', + }, + })), + }; +}); + +const testColors = { + critical: '#EF6550', + high: '#EE9266', + medium: '#F3B689', + low: '#F8D9B2', +}; + +describe('DonutChart', () => { + const props: DonutChartProps = { + data: parsedMockAlertsData?.open?.severities, + label: 'Open', + link: null, + title: , + fillColor: jest.fn(() => '#ccc'), + totalCount: parsedMockAlertsData?.open?.total, + legendItems: (['critical', 'high', 'medium', 'low'] as Severity[]).map((d) => ({ + color: testColors[d], + dataProviderId: escapeDataProviderId(`draggable-legend-item-${uuid.v4()}-${d}`), + timelineId: undefined, + field: 'kibana.alert.severity', + value: d, + })), + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + test('should render Chart', () => { + const { container } = render(); + expect(container.querySelector(`[data-test-subj="es-chart"]`)).toBeInTheDocument(); + }); + + test('should render chart Settings', () => { + const { container } = render(); + expect(container.querySelector(`[data-test-subj="es-chart-settings"]`)).toBeInTheDocument(); + + expect((Settings as jest.Mock).mock.calls[0][0]).toEqual({ + baseTheme: { + eui: { + euiColorDarkShade: '#fff', + euiScrollBar: 0, + euiScrollBarCorner: '#ccc', + }, + }, + theme: { + chartMargins: { bottom: 0, left: 0, right: 0, top: 0 }, + partition: { + circlePadding: 4, + emptySizeRatio: 0.8, + idealFontSizeJump: 1.1, + outerSizeRatio: 1, + }, + }, + }); + }); + + test('should render an empty chart', () => { + const testProps = { + ...props, + data: parsedMockAlertsData?.acknowledged?.severities, + label: 'Acknowledged', + title: , + totalCount: parsedMockAlertsData?.acknowledged?.total, + }; + const { container } = render(); + expect(container.querySelector(`[data-test-subj="empty-donut"]`)).toBeInTheDocument(); + }); + + test('should render chart Partition', () => { + const { container } = render(); + expect(container.querySelector(`[data-test-subj="es-chart-partition"]`)).toBeInTheDocument(); + expect((Partition as jest.Mock).mock.calls[0][0].data).toEqual( + parsedMockAlertsData?.open?.severities + ); + expect((Partition as jest.Mock).mock.calls[0][0].layout).toEqual('sunburst'); + }); + + test('should render chart legend', () => { + const { container } = render(); + expect(container.querySelector(`[data-test-subj="draggable-legend"]`)).toBeInTheDocument(); + expect((DraggableLegend as unknown as jest.Mock).mock.calls[0][0].legendItems).toEqual([ + { + color: '#EF6550', + dataProviderId: 'draggable-legend-item-test-uuid-critical', + field: 'kibana.alert.severity', + timelineId: undefined, + value: 'critical', + }, + { + color: '#EE9266', + dataProviderId: 'draggable-legend-item-test-uuid-high', + field: 'kibana.alert.severity', + timelineId: undefined, + value: 'high', + }, + { + color: '#F3B689', + dataProviderId: 'draggable-legend-item-test-uuid-medium', + field: 'kibana.alert.severity', + timelineId: undefined, + value: 'medium', + }, + { + color: '#F8D9B2', + dataProviderId: 'draggable-legend-item-test-uuid-low', + field: 'kibana.alert.severity', + timelineId: undefined, + value: 'low', + }, + ]); + }); + + test('should NOT render chart legend if showLegend is false', () => { + const testProps = { + ...props, + legendItems: null, + }; + const { container } = render(); + expect(container.querySelector(`[data-test-subj="legend"]`)).not.toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/charts/donutchart.tsx b/x-pack/plugins/security_solution/public/common/components/charts/donutchart.tsx new file mode 100644 index 000000000000000..2708fefc765221a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/charts/donutchart.tsx @@ -0,0 +1,149 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiText, useEuiTheme } from '@elastic/eui'; +import React, { useMemo } from 'react'; + +import { + Chart, + Datum, + Partition, + Settings, + PartitionLayout, + defaultPartitionValueFormatter, + NodeColorAccessor, + PartialTheme, +} from '@elastic/charts'; +import styled from 'styled-components'; +import { useTheme } from './common'; +import { DraggableLegend } from './draggable_legend'; +import { LegendItem } from './draggable_legend_item'; +import { DonutChartEmpty } from './donutchart_empty'; + +export const NO_LEGEND_DATA: LegendItem[] = []; + +const donutTheme: PartialTheme = { + chartMargins: { top: 0, bottom: 0, left: 0, right: 0 }, + partition: { + idealFontSizeJump: 1.1, + outerSizeRatio: 1, + emptySizeRatio: 0.8, + circlePadding: 4, + }, +}; + +interface DonutChartData { + key: string; + value: number; + group?: string; + label?: string; +} + +export type FillColor = string | NodeColorAccessor; +export interface DonutChartProps { + data: DonutChartData[] | null | undefined; + fillColor: FillColor; + height?: number; + label: string; + legendItems?: LegendItem[] | null | undefined; + link?: string | null; + title: React.ReactElement | string | number | null; + totalCount: number | null | undefined; +} + +/* Make this position absolute in order to overlap the text onto the donut */ +const DonutTextWrapper = styled(EuiFlexGroup)` + top: 34%; + width: 100%; + max-width: 77px; + position: absolute; + z-index: 1; +`; + +const StyledEuiFlexItem = styled(EuiFlexItem)` + position: relative; + align-items: center; +`; + +export const DonutChart = ({ + data, + fillColor, + height = 90, + label, + legendItems, + link, + title, + totalCount, +}: DonutChartProps) => { + const theme = useTheme(); + const { euiTheme } = useEuiTheme(); + const emptyLabelStyle = useMemo( + () => ({ + color: euiTheme.colors.disabled, + }), + [euiTheme.colors.disabled] + ); + return ( + + + + {title} + + {data ? ( + + {label} + + ) : ( + + {label} + + )} + + + {data == null || totalCount == null || totalCount === 0 ? ( + + ) : ( + + + d.value as number} + valueFormatter={(d: number) => `${defaultPartitionValueFormatter(d)}`} + layers={[ + { + groupByRollup: (d: Datum) => d.label ?? d.key, + nodeLabel: (d: Datum) => d, + shape: { + fillColor, + }, + }, + ]} + /> + + )} + + {legendItems && legendItems?.length > 0 && ( + + + + )} + + ); +}; diff --git a/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.test.tsx new file mode 100644 index 000000000000000..858347226272fae --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.test.tsx @@ -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 { render } from '@testing-library/react'; +import React from 'react'; +import { DonutChartEmpty } from './donutchart_empty'; + +describe('DonutChartEmpty', () => { + test('render', () => { + const { container } = render(); + expect(container.querySelector(`[data-test-subj="empty-donut"]`)).toBeInTheDocument(); + expect(container.querySelector(`[data-test-subj="empty-donut-small"]`)).toBeInTheDocument(); + }); + + test('does Not render', () => { + const props = { + size: 90, + donutWidth: 90, + }; + const { container } = render(); + expect(container.querySelector(`[data-test-subj="empty-donut"]`)).not.toBeInTheDocument(); + expect(container.querySelector(`[data-test-subj="empty-donut-small"]`)).not.toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx b/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx new file mode 100644 index 000000000000000..a378f94bfbe1ecd --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/charts/donutchart_empty.tsx @@ -0,0 +1,44 @@ +/* + * 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 React from 'react'; +import styled from 'styled-components'; + +interface DonutChartEmptyProps { + size?: number; + donutWidth?: number; +} + +export const emptyDonutColor = '#FAFBFD'; + +const BigRing = styled.div` + border-radius: 50%; + ${({ size }) => + `height: ${size}px; + width: ${size}px; + background-color: ${emptyDonutColor}; + text-align: center; + line-height: ${size}px;`} +`; + +const SmallRing = styled.div` + border-radius: 50%; + ${({ size }) => ` + height: ${size}px; + width: ${size}px; + background-color: white; + display: inline-block; + vertical-align: middle;`} +`; + +const EmptyDonutChartComponent: React.FC = ({ size = 90, donutWidth = 20 }) => + size - donutWidth > 0 ? ( + + + + ) : null; + +export const DonutChartEmpty = React.memo(EmptyDonutChartComponent); diff --git a/x-pack/plugins/security_solution/public/common/components/charts/legend.tsx b/x-pack/plugins/security_solution/public/common/components/charts/legend.tsx new file mode 100644 index 000000000000000..d01d9057c6979f7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/charts/legend.tsx @@ -0,0 +1,43 @@ +/* + * 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. + */ + +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui'; +import React from 'react'; + +import { LegendItem } from './legend_item'; + +const LegendComponent: React.FC<{ + legendItems: LegendItem[]; +}> = ({ legendItems }) => { + if (legendItems.length === 0) { + return null; + } + + return ( + + + {legendItems.map((item, i) => ( + + + + + ))} + + + ); +}; + +LegendComponent.displayName = 'LegendComponent'; + +export const Legend = React.memo(LegendComponent); diff --git a/x-pack/plugins/security_solution/public/common/components/charts/legend_item.tsx b/x-pack/plugins/security_solution/public/common/components/charts/legend_item.tsx new file mode 100644 index 000000000000000..867a48294c09b81 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/charts/legend_item.tsx @@ -0,0 +1,61 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiText } from '@elastic/eui'; +import React from 'react'; +import styled from 'styled-components'; + +import { EMPTY_VALUE_LABEL } from './translation'; +import { hasValueToDisplay } from '../../utils/validators'; + +export interface LegendItem { + color?: string; + field: string; + value: string | number; +} + +const LegendText = styled.span` + font-size: 10.5px; +`; + +/** + * Renders the value or a placeholder in case the value is empty + */ +const ValueWrapper = React.memo<{ value: LegendItem['value'] }>(({ value }) => + hasValueToDisplay(value) ? ( + {value} + ) : ( + {EMPTY_VALUE_LABEL} + ) +); + +ValueWrapper.displayName = 'ValueWrapper'; + +const LegendItemComponent: React.FC<{ + legendItem: LegendItem; +}> = ({ legendItem }) => { + const { color, value } = legendItem; + + return ( + + + {color != null && ( + + + + )} + + + + + + ); +}; + +LegendItemComponent.displayName = 'LegendItemComponent'; + +export const LegendItem = React.memo(LegendItemComponent); diff --git a/x-pack/plugins/security_solution/public/resolver/view/submenu.test.tsx b/x-pack/plugins/security_solution/public/common/components/formatted_number/index.test.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/resolver/view/submenu.test.tsx rename to x-pack/plugins/security_solution/public/common/components/formatted_number/index.test.tsx index 8cfaf3fe7167047..bbf53c5a38aaaee 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/formatted_number/index.test.tsx @@ -5,9 +5,9 @@ * 2.0. */ -import { compactNotationParts } from './submenu'; +import { compactNotationParts } from '.'; -describe('The Resolver node pills number presentation', () => { +describe('compactNotationParts', () => { describe('When given a small number under 1000', () => { it('does not change the presentation of small numbers', () => { expect(compactNotationParts(1)).toEqual([1, '', '']); diff --git a/x-pack/plugins/security_solution/public/common/components/formatted_number/index.tsx b/x-pack/plugins/security_solution/public/common/components/formatted_number/index.tsx new file mode 100644 index 000000000000000..ebab730d5a96f96 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/formatted_number/index.tsx @@ -0,0 +1,81 @@ +/* + * 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 { EuiI18nNumber } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import React, { useMemo } from 'react'; + +/** + * Until browser support accomodates the `notation="compact"` feature of Intl.NumberFormat... + * exported for testing + * @param num The number to format + * @returns [mantissa ("12" in "12k+"), Scalar of compact notation (k,M,B,T), remainder indicator ("+" in "12k+")] + */ +export function compactNotationParts( + num: number +): [mantissa: number, compactNotation: string, remainderIndicator: string] { + if (!Number.isFinite(num)) { + return [num, '', '']; + } + + // "scale" here will be a term indicating how many thousands there are in the number + // e.g. 1001 will be 1000, 1000002 will be 1000000, etc. + const scale = Math.pow(10, 3 * Math.min(Math.floor(Math.floor(Math.log10(num)) / 3), 4)); + + const compactPrefixTranslations = { + compactThousands: i18n.translate('xpack.securitySolution.formattedNumber.compactThousands', { + defaultMessage: 'k', + }), + compactMillions: i18n.translate('xpack.securitySolution.formattedNumber.compactMillions', { + defaultMessage: 'M', + }), + + compactBillions: i18n.translate('xpack.securitySolution.formattedNumber.compactBillions', { + defaultMessage: 'B', + }), + + compactTrillions: i18n.translate('xpack.securitySolution.formattedNumber.compactTrillions', { + defaultMessage: 'T', + }), + }; + const prefixMap: Map = new Map([ + [1, ''], + [1000, compactPrefixTranslations.compactThousands], + [1000000, compactPrefixTranslations.compactMillions], + [1000000000, compactPrefixTranslations.compactBillions], + [1000000000000, compactPrefixTranslations.compactTrillions], + ]); + const hasRemainder = i18n.translate('xpack.securitySolution.formattedNumber.compactOverflow', { + defaultMessage: '+', + }); + const prefix = prefixMap.get(scale) ?? ''; + return [Math.floor(num / scale), prefix, (num / scale) % 1 > Number.EPSILON ? hasRemainder : '']; +} + +const FormattedCountComponent: React.FC<{ count: number | null }> = ({ count }) => { + const [mantissa, scale, hasRemainder] = useMemo(() => compactNotationParts(count || 0), [count]); + + if (count == null) { + return null; + } + + if (count === 0) { + return <>{0}; + } + + return ( + , scale, hasRemainder }} + /> + ); +}; + +export const FormattedCount = React.memo(FormattedCountComponent); diff --git a/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap index 45a6e20cf087d7f..4447f631c157238 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap @@ -2,6 +2,8 @@ exports[`HeaderSection it renders 1`] = `
diff --git a/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx index a03999479e398ce..d835f4b2b236aac 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx @@ -231,6 +231,28 @@ describe('HeaderSection', () => { expect(wrapper.find('[data-test-subj="header-section-filters"]').first().exists()).toBe(true); expect(wrapper.find('[data-test-subj="inspect-icon-button"]').first().exists()).toBe(true); }); + + test('it appends `toggle-expand` class to Header when toggleStatus = true', () => { + const wrapper = mount( + + +

{'Test children'}

+
+
+ ); + + expect(wrapper.find('[data-test-subj="header-section"]').first().prop('className')).toBe( + 'toggle-expand siemHeaderSection' + ); + }); + test('it does not render anything but title when toggleStatus = false', () => { const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx index 7997dfa83e27b2f..86cdc45312cf2e0 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx @@ -16,6 +16,7 @@ import { import React, { useCallback } from 'react'; import styled, { css } from 'styled-components'; +import classnames from 'classnames'; import { InspectButton } from '../inspect'; import { Subtitle } from '../subtitle'; @@ -24,11 +25,23 @@ import * as i18n from '../../containers/query_toggle/translations'; interface HeaderProps { border?: boolean; height?: number; + className?: string; + $hideSubtitle?: boolean; } -const Header = styled.header.attrs(() => ({ - className: 'siemHeaderSection', -}))` +const Header = styled.header` + &.toggle-expand { + .header-section-content { + height: 48px; + } + + ${({ $hideSubtitle, theme }) => + !$hideSubtitle && + `.header-section-titles { + margin-top: ${theme.eui.paddingSizes.m}; + }`} + } + ${({ height }) => height && css` @@ -91,17 +104,33 @@ const HeaderSectionComponent: React.FC = ({ toggleQuery(!toggleStatus); } }, [toggleQuery, toggleStatus]); + + const classNames = classnames({ + 'toggle-expand': toggleStatus, + siemHeaderSection: true, + }); return ( -
+
- + - + {toggleQuery && ( { +describe('useAddToExistingCase', () => { const mockCases = mockCasesContract(); const mockOnAddToCaseClicked = jest.fn(); const timeRange = { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_add_to_new_case.test.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_add_to_new_case.test.tsx index 35a05281b9325d2..7b5a8b09e5f5e13 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_add_to_new_case.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/use_add_to_new_case.test.tsx @@ -12,7 +12,7 @@ import { useAddToNewCase } from './use_add_to_new_case'; jest.mock('../../lib/kibana/kibana_react'); -describe('', () => { +describe('useAddToNewCase', () => { const mockCases = mockCasesContract(); const timeRange = { from: '2022-03-06T16:00:00.000Z', diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx new file mode 100644 index 000000000000000..4c8280f90304dae --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.test.tsx @@ -0,0 +1,122 @@ +/* + * 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 React from 'react'; +import { render } from '@testing-library/react'; +import { AlertsByStatus } from './alerts_by_status'; +import { parsedMockAlertsData } from './mock_data'; +import { useKibana } from '../../../../common/lib/kibana/kibana_react'; +import { mockCasesContract } from '@kbn/cases-plugin/public/mocks'; +import { CASES_FEATURE_ID } from '../../../../../common/constants'; +import { TestProviders } from '../../../../common/mock/test_providers'; +import { useAlertsByStatus } from './use_alerts_by_status'; + +jest.mock('../../../../common/lib/kibana/kibana_react'); + +jest.mock('./chart_label', () => { + return { + ChartLabel: jest.fn((props) => ), + }; +}); +jest.mock('./use_alerts_by_status', () => ({ + useAlertsByStatus: jest.fn().mockReturnValue({ + items: [], + isLoading: true, + }), +})); +describe('AlertsByStatus', () => { + const mockCases = mockCasesContract(); + + const props = { + showInspectButton: true, + signalIndexName: 'mock-signal-index', + }; + + beforeEach(() => { + jest.clearAllMocks(); + (useKibana as jest.Mock).mockReturnValue({ + services: { + cases: mockCases, + application: { + capabilities: { [CASES_FEATURE_ID]: { crud_cases: true, read_cases: true } }, + getUrlForApp: jest.fn(), + }, + theme: {}, + }, + }); + (useAlertsByStatus as jest.Mock).mockReturnValue({ + items: [], + isLoading: true, + }); + }); + + test('render HoverVisibilityContainer', () => { + const { container } = render( + + + + ); + expect( + container.querySelector(`[data-test-subj="hoverVisibilityContainer"]`) + ).toBeInTheDocument(); + }); + test('render HistogramPanel', () => { + const { container } = render( + + + + ); + expect( + container.querySelector(`[data-test-subj="detection-response-alerts-by-status-panel"]`) + ).toBeInTheDocument(); + }); + + test('render HeaderSection', () => { + const { container } = render( + + + + ); + expect(container.querySelector(`[data-test-subj="header-section"]`)).toBeInTheDocument(); + }); + + test('render Legend', () => { + const testProps = { + ...props, + isInitialLoading: false, + }; + (useAlertsByStatus as jest.Mock).mockReturnValue({ + items: parsedMockAlertsData, + isLoading: false, + }); + + const { container } = render( + + + + ); + expect(container.querySelector(`[data-test-subj="legend"]`)).toBeInTheDocument(); + }); + + test('render toggle query button', () => { + const testProps = { + ...props, + isInitialLoading: false, + }; + + (useAlertsByStatus as jest.Mock).mockReturnValue({ + items: parsedMockAlertsData, + isLoading: false, + }); + + const { container } = render( + + + + ); + expect(container.querySelector(`[data-test-subj="query-toggle-header"]`)).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx new file mode 100644 index 000000000000000..963b12a35dbf054 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/alerts_by_status.tsx @@ -0,0 +1,214 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiProgress, EuiSpacer, EuiText } from '@elastic/eui'; +import React, { useCallback, useMemo } from 'react'; +import { ShapeTreeNode } from '@elastic/charts'; +import { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import styled from 'styled-components'; +import { DonutChart, FillColor } from '../../../../common/components/charts/donutchart'; +import { SecurityPageName } from '../../../../../common/constants'; +import { useNavigation } from '../../../../common/lib/kibana'; +import { HeaderSection } from '../../../../common/components/header_section'; +import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; +import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; +import { LegendItem } from '../../../../common/components/charts/legend_item'; +import { useAlertsByStatus } from './use_alerts_by_status'; +import { + ALERTS, + ALERTS_TITLE, + STATUS_ACKNOWLEDGED, + STATUS_CLOSED, + STATUS_CRITICAL_LABEL, + STATUS_HIGH_LABEL, + STATUS_LOW_LABEL, + STATUS_MEDIUM_LABEL, + STATUS_OPEN, +} from '../translations'; +import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { getDetectionEngineUrl, useFormatUrl } from '../../../../common/components/link_to'; +import { VIEW_ALERTS } from '../../../pages/translations'; +import { LastUpdatedAt, SEVERITY_COLOR } from '../utils'; +import { FormattedCount } from '../../../../common/components/formatted_number'; +import { ChartLabel } from './chart_label'; +import { Legend } from '../../../../common/components/charts/legend'; +import { emptyDonutColor } from '../../../../common/components/charts/donutchart_empty'; +import { LinkButton } from '../../../../common/components/links'; + +const donutHeight = 120; +const StyledFlexItem = styled(EuiFlexItem)` + padding: 0 4px; +`; + +const StyledLegendFlexItem = styled(EuiFlexItem)` + padding-left: 32px; + padding-top: 45px; +`; + +interface AlertsByStatusProps { + signalIndexName: string | null; +} + +const legendField = 'kibana.alert.severity'; +const chartConfigs: Array<{ key: Severity; label: string; color: string }> = [ + { key: 'critical', label: STATUS_CRITICAL_LABEL, color: SEVERITY_COLOR.critical }, + { key: 'high', label: STATUS_HIGH_LABEL, color: SEVERITY_COLOR.high }, + { key: 'medium', label: STATUS_MEDIUM_LABEL, color: SEVERITY_COLOR.medium }, + { key: 'low', label: STATUS_LOW_LABEL, color: SEVERITY_COLOR.low }, +]; +const DETECTION_RESPONSE_ALERTS_BY_STATUS_ID = 'detection-response-alerts-by-status'; + +export const AlertsByStatus = ({ signalIndexName }: AlertsByStatusProps) => { + const { toggleStatus, setToggleStatus } = useQueryToggle(DETECTION_RESPONSE_ALERTS_BY_STATUS_ID); + const { formatUrl, search: urlSearch } = useFormatUrl(SecurityPageName.alerts); + const { navigateTo } = useNavigation(); + const goToAlerts = useCallback( + (ev) => { + ev.preventDefault(); + navigateTo({ + deepLinkId: SecurityPageName.alerts, + path: getDetectionEngineUrl(urlSearch), + }); + }, + [navigateTo, urlSearch] + ); + + const detailsButtonOptions = useMemo( + () => ({ + name: VIEW_ALERTS, + href: formatUrl(getDetectionEngineUrl()), + onClick: goToAlerts, + }), + [formatUrl, goToAlerts] + ); + + const { + items: donutData, + isLoading: loading, + updatedAt, + } = useAlertsByStatus({ + signalIndexName, + queryId: DETECTION_RESPONSE_ALERTS_BY_STATUS_ID, + skip: !toggleStatus, + }); + const legendItems: LegendItem[] = useMemo( + () => + chartConfigs.map((d) => ({ + color: d.color, + field: legendField, + value: d.label, + })), + [] + ); + + const totalAlerts = + loading || donutData == null + ? 0 + : (donutData?.open?.total ?? 0) + + (donutData?.acknowledged?.total ?? 0) + + (donutData?.closed?.total ?? 0); + + const fillColor: FillColor = useCallback((d: ShapeTreeNode) => { + return chartConfigs.find((cfg) => cfg.label === d.dataName)?.color ?? emptyDonutColor; + }, []); + + return ( + <> + + + {loading && ( + + )} + } + inspectMultiple + toggleStatus={toggleStatus} + toggleQuery={setToggleStatus} + > + + + + {detailsButtonOptions.name} + + + + + {toggleStatus && ( + <> + + + + {loading ? ( + + ) : ( + <> + + + + <> + {ALERTS(totalAlerts)} + + )} + + + + + + } + totalCount={donutData?.open?.total ?? 0} + /> + + + } + totalCount={donutData?.acknowledged?.total ?? 0} + /> + + + } + totalCount={donutData?.closed?.total ?? 0} + /> + + + + + {legendItems.length > 0 && } + + + + + )} + + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/chart_label.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/chart_label.tsx new file mode 100644 index 000000000000000..ad609102409d26e --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/chart_label.tsx @@ -0,0 +1,30 @@ +/* + * 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 React from 'react'; +import styled from 'styled-components'; +import { FormattedCount } from '../../../../common/components/formatted_number'; + +interface ChartLabelProps { + count: number | null | undefined; +} + +const PlaceHolder = styled.div` + padding: ${(props) => props.theme.eui.paddingSizes.s}; +`; + +const ChartLabelComponent: React.FC = ({ count }) => { + return count != null ? ( + + + + ) : ( + + ); +}; + +ChartLabelComponent.displayName = 'ChartLabelComponent'; +export const ChartLabel = React.memo(ChartLabelComponent); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/index.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/index.ts new file mode 100644 index 000000000000000..257e690ba72e571 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/index.ts @@ -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 { AlertsByStatus } from './alerts_by_status'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/mock_data.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/mock_data.ts new file mode 100644 index 000000000000000..f8aff3bdc87ac20 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/mock_data.ts @@ -0,0 +1,137 @@ +/* + * 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 { AlertsByStatusResponse, AlertsByStatusAgg, ParsedAlertsData } from './types'; + +export const from = '2022-04-05T12:00:00.000Z'; +export const to = '2022-04-08T12:00:00.000Z'; + +export const mockAlertsData: AlertsByStatusResponse<[], AlertsByStatusAgg> = { + took: 4, + _shards: { + total: 1, + successful: 1, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 10000, + relation: 'gte', + }, + hits: [], + }, + aggregations: { + alertsByStatus: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'open', + doc_count: 28149, + statusBySeverity: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'low', + doc_count: 22717, + }, + { + key: 'high', + doc_count: 5027, + }, + { + key: 'medium', + doc_count: 405, + }, + ], + }, + }, + { + key: 'closed', + doc_count: 4, + statusBySeverity: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { + key: 'high', + doc_count: 4, + }, + { + key: 'low', + doc_count: 0, + }, + ], + }, + }, + ], + }, + }, +}; + +export const parsedMockAlertsData: ParsedAlertsData = { + open: { + total: 28149, + severities: [ + { + key: 'low', + label: 'Low', + value: 22717, + }, + { + key: 'high', + label: 'High', + value: 5027, + }, + { + key: 'medium', + label: 'Medium', + value: 405, + }, + ], + }, + closed: { + total: 4, + severities: [ + { + key: 'high', + label: 'High', + value: 4, + }, + { + key: 'low', + label: 'Low', + value: 0, + }, + ], + }, +}; + +export const alertsByStatusQuery = { + size: 0, + query: { + bool: { + filter: [{ range: { '@timestamp': { gte: from, lte: to } } }], + }, + }, + aggs: { + alertsByStatus: { + terms: { + field: 'kibana.alert.workflow_status', + }, + aggs: { + statusBySeverity: { + terms: { + field: 'kibana.alert.severity', + }, + }, + }, + }, + }, +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/types.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/types.ts new file mode 100644 index 000000000000000..523edf91775fe4f --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/types.ts @@ -0,0 +1,61 @@ +/* + * 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 { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; + +interface StatusBySeverity { + doc_count_error_upper_bound: number; + sum_other_doc_count: number; + buckets: SeverityBucket[]; +} + +interface StatusBucket { + key: Status; + doc_count: number; + statusBySeverity?: StatusBySeverity; +} + +interface SeverityBucket { + key: Severity; + doc_count: number; +} + +export interface AlertsByStatusAgg { + alertsByStatus: { + doc_count_error_upper_bound: number; + sum_other_doc_count: number; + buckets: StatusBucket[]; + }; +} + +export interface AlertsByStatusResponse { + took: number; + _shards: { + total: number; + successful: number; + skipped: number; + failed: number; + }; + aggregations?: Aggregations; + hits: { + total: { + value: number; + relation: string; + }; + hits: Hit[]; + }; +} + +export interface SeverityBuckets { + key: Severity; + value: number; + label?: string; +} +export type ParsedAlertsData = Partial< + Record +> | null; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.test.tsx new file mode 100644 index 000000000000000..68ee64370b26d21 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.test.tsx @@ -0,0 +1,131 @@ +/* + * 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 { renderHook } from '@testing-library/react-hooks'; +import { TestProviders } from '../../../../common/mock'; +import { from, mockAlertsData, alertsByStatusQuery, parsedMockAlertsData, to } from './mock_data'; +import { + useAlertsByStatus, + UseAlertsByStatus, + UseAlertsByStatusProps, +} from './use_alerts_by_status'; + +const dateNow = new Date('2022-04-08T12:00:00.000Z').valueOf(); +const mockDateNow = jest.fn().mockReturnValue(dateNow); +Date.now = jest.fn(() => mockDateNow()) as unknown as DateConstructor['now']; + +const defaultUseQueryAlertsReturn = { + loading: false, + data: null, + setQuery: () => {}, + response: '', + request: '', + refetch: () => {}, +}; +const mockUseQueryAlerts = jest.fn().mockReturnValue(defaultUseQueryAlertsReturn); +jest.mock('../../../../detections/containers/detection_engine/alerts/use_query', () => { + return { + useQueryAlerts: (...props: unknown[]) => mockUseQueryAlerts(...props), + }; +}); + +const mockUseGlobalTime = jest + .fn() + .mockReturnValue({ from, to, setQuery: jest.fn(), deleteQuery: jest.fn() }); +jest.mock('../../../../common/containers/use_global_time', () => { + return { + useGlobalTime: (...props: unknown[]) => mockUseGlobalTime(...props), + }; +}); + +// helper function to render the hook +const renderUseAlertsByStatus = (props: Partial = {}) => + renderHook>( + () => + useAlertsByStatus({ + queryId: 'test', + signalIndexName: 'signal-alerts', + ...props, + }), + { + wrapper: TestProviders, + } + ); + +describe('useAlertsByStatus', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockDateNow.mockReturnValue(dateNow); + mockUseQueryAlerts.mockReturnValue(defaultUseQueryAlertsReturn); + }); + + it('should return default values', () => { + const { result } = renderUseAlertsByStatus(); + + expect(result.current).toEqual({ + items: null, + isLoading: false, + updatedAt: dateNow, + }); + expect(mockUseQueryAlerts).toBeCalledWith({ + query: alertsByStatusQuery, + indexName: 'signal-alerts', + skip: false, + }); + }); + + it('should return parsed items', () => { + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockAlertsData, + }); + + const { result } = renderUseAlertsByStatus(); + + expect(result.current).toEqual({ + items: parsedMockAlertsData, + isLoading: false, + updatedAt: dateNow, + }); + }); + + it('should return new updatedAt', () => { + const newDateNow = new Date('2022-04-08T14:00:00.000Z').valueOf(); + mockDateNow.mockReturnValue(newDateNow); // setUpdatedAt call + mockDateNow.mockReturnValueOnce(dateNow); // initialization call + + mockUseQueryAlerts.mockReturnValue({ + ...defaultUseQueryAlertsReturn, + data: mockAlertsData, + }); + + const { result } = renderUseAlertsByStatus(); + + expect(mockDateNow).toHaveBeenCalled(); + expect(result.current).toEqual({ + items: parsedMockAlertsData, + isLoading: false, + updatedAt: newDateNow, + }); + }); + + it('should skip the query', () => { + const { result } = renderUseAlertsByStatus({ skip: true }); + + expect(mockUseQueryAlerts).toBeCalledWith({ + query: alertsByStatusQuery, + indexName: 'signal-alerts', + skip: true, + }); + + expect(result.current).toEqual({ + items: null, + isLoading: false, + updatedAt: dateNow, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts new file mode 100644 index 000000000000000..979fd6292243f57 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/alerts_by_status/use_alerts_by_status.ts @@ -0,0 +1,151 @@ +/* + * 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 { useCallback, useEffect, useState } from 'react'; +import { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; +import { useGlobalTime } from '../../../../common/containers/use_global_time'; +import { useQueryAlerts } from '../../../../detections/containers/detection_engine/alerts/use_query'; +import { useQueryInspector } from '../../../../common/components/page/manage_query'; +import { AlertsByStatusAgg, AlertsByStatusResponse, ParsedAlertsData } from './types'; +import { + STATUS_CRITICAL_LABEL, + STATUS_HIGH_LABEL, + STATUS_LOW_LABEL, + STATUS_MEDIUM_LABEL, +} from '../translations'; + +export const severityLabels: Record = { + critical: STATUS_CRITICAL_LABEL, + high: STATUS_HIGH_LABEL, + medium: STATUS_MEDIUM_LABEL, + low: STATUS_LOW_LABEL, +}; + +export const getAlertsByStatusQuery = ({ from, to }: { from: string; to: string }) => ({ + size: 0, + query: { + bool: { + filter: [{ range: { '@timestamp': { gte: from, lte: to } } }], + }, + }, + aggs: { + alertsByStatus: { + terms: { + field: 'kibana.alert.workflow_status', + }, + aggs: { + statusBySeverity: { + terms: { + field: 'kibana.alert.severity', + }, + }, + }, + }, + }, +}); + +export const parseAlertsData = ( + response: AlertsByStatusResponse<{}, AlertsByStatusAgg> +): ParsedAlertsData => { + const statusBuckets = response?.aggregations?.alertsByStatus?.buckets ?? []; + + if (statusBuckets.length === 0) { + return null; + } + + return statusBuckets.reduce((parsedAlertsData, statusBucket) => { + const severityBuckets = statusBucket.statusBySeverity?.buckets ?? []; + + return { + ...parsedAlertsData, + [statusBucket.key]: { + total: statusBucket.doc_count, + severities: severityBuckets.map((severityBucket) => ({ + key: severityBucket.key, + value: severityBucket.doc_count, + label: severityLabels[severityBucket.key], + })), + }, + }; + }, {}); +}; + +export interface UseAlertsByStatusProps { + queryId: string; + signalIndexName: string | null; + skip?: boolean; +} + +export type UseAlertsByStatus = (props: UseAlertsByStatusProps) => { + items: ParsedAlertsData; + isLoading: boolean; + updatedAt: number; +}; + +export const useAlertsByStatus: UseAlertsByStatus = ({ + queryId, + signalIndexName, + skip = false, +}) => { + const { to, from, deleteQuery, setQuery } = useGlobalTime(); + const [updatedAt, setUpdatedAt] = useState(Date.now()); + const [items, setItems] = useState(null); + + const { + data, + loading: isLoading, + refetch: refetchQuery, + request, + response, + setQuery: setAlertsQuery, + } = useQueryAlerts<{}, AlertsByStatusAgg>({ + query: getAlertsByStatusQuery({ + from, + to, + }), + indexName: signalIndexName, + skip, + }); + + useEffect(() => { + setAlertsQuery( + getAlertsByStatusQuery({ + from, + to, + }) + ); + }, [setAlertsQuery, from, to]); + + useEffect(() => { + if (data == null) { + setItems(null); + } else { + setItems(parseAlertsData(data)); + } + setUpdatedAt(Date.now()); + }, [data]); + + const refetch = useCallback(() => { + if (!skip && refetchQuery) { + refetchQuery(); + } + }, [skip, refetchQuery]); + + useQueryInspector({ + deleteQuery, + inspect: { + dsl: [request], + response: [response], + }, + refetch, + setQuery, + queryId, + loading: isLoading, + }); + + return { items, isLoading, updatedAt }; +}; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx index 7a053fd0366dd95..a5ddfe25dd98558 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/rule_alerts_table/rule_alerts_table.tsx @@ -28,6 +28,8 @@ import { useRuleAlertsItems, RuleAlertsItem } from './use_rule_alerts_items'; import { useNavigation, NavigateTo, GetAppUrl } from '../../../../common/lib/kibana'; import { SecurityPageName } from '../../../../../common/constants'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; +import { HoverVisibilityContainer } from '../../../../common/components/hover_visibility_container'; +import { BUTTON_CLASS as INPECT_BUTTON_CLASS } from '../../../../common/components/inspect'; export interface RuleAlertsTableProps { signalIndexName: string | null; @@ -106,33 +108,35 @@ export const RuleAlertsTable = React.memo(({ signalIndexNa ); return ( - - } - /> - {toggleStatus && ( - <> - {i18n.NO_ALERTS_FOUND}} titleSize="xs" /> - } - /> - - - {i18n.OPEN_ALL_ALERTS_BUTTON} - - - )} - + + + } + /> + {toggleStatus && ( + <> + {i18n.NO_ALERTS_FOUND}} titleSize="xs" /> + } + /> + + + {i18n.OPEN_ALL_ALERTS_BUTTON} + + + )} + + ); }); RuleAlertsTable.displayName = 'RuleAlertsTable'; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/translations.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/translations.ts index 81e3bff33545d22..c2c5b412f1a9d6f 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/translations.ts +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/translations.ts @@ -7,6 +7,65 @@ import { i18n } from '@kbn/i18n'; +export const STATUS_CRITICAL_LABEL = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.criticalLabel', + { + defaultMessage: 'Critical', + } +); +export const STATUS_HIGH_LABEL = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.highLabel', + { + defaultMessage: 'High', + } +); +export const STATUS_MEDIUM_LABEL = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.mediumLabel', + { + defaultMessage: 'Medium', + } +); +export const STATUS_LOW_LABEL = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.lowLabel', + { + defaultMessage: 'Low', + } +); +export const STATUS_OPEN = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.title.open', + { + defaultMessage: 'Open', + } +); +export const STATUS_ACKNOWLEDGED = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.title.acknowledged', + { + defaultMessage: 'Acknowledged', + } +); +export const STATUS_CLOSED = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.title.closed', + { + defaultMessage: 'Closed', + } +); +export const STATUS_IN_PROGRESS = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.donut.title.inProgress', + { + defaultMessage: 'In progress', + } +); +export const ALERTS = (totalAlerts: number) => + i18n.translate('xpack.securitySolution.detectionResponse.alertsByStatus.totalAlerts', { + values: { totalAlerts }, + defaultMessage: 'total {totalAlerts, plural, =1 {alert} other {alerts}}', + }); +export const ALERTS_TITLE = i18n.translate( + 'xpack.securitySolution.detectionResponse.alertsByStatus.title', + { + defaultMessage: 'Alerts', + } +); export const UPDATING = i18n.translate('xpack.securitySolution.detectionResponse.updating', { defaultMessage: 'Updating...', }); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx new file mode 100644 index 000000000000000..4ceba6677339707 --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/utils.tsx @@ -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 React from 'react'; +import { FormattedRelative } from '@kbn/i18n-react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import * as i18n from './translations'; + +export const SEVERITY_COLOR = { + critical: '#EF6550', + high: '#EE9266', + medium: '#F3B689', + low: '#F8D9B2', +} as const; + +export interface LastUpdatedAtProps { + updatedAt: number; + isUpdating: boolean; +} +export const LastUpdatedAt: React.FC = ({ isUpdating, updatedAt }) => ( + + {isUpdating ? ( + {i18n.UPDATING} + ) : ( + + <>{i18n.UPDATED} + + + )} + +); diff --git a/x-pack/plugins/security_solution/public/overview/pages/detection_response.tsx b/x-pack/plugins/security_solution/public/overview/pages/detection_response.tsx index 719cb88b62043b3..2e0030bafa00e16 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/detection_response.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/detection_response.tsx @@ -18,6 +18,7 @@ import { RuleAlertsTable } from '../components/detection_response/rule_alerts_ta import { LandingPageComponent } from '../../common/components/landing_page'; import * as i18n from './translations'; import { EmptyPage } from '../../common/components/empty_page'; +import { AlertsByStatus } from '../components/detection_response/alerts_by_status'; const NoPrivilegePage: React.FC = () => { const { docLinks } = useKibana().services; @@ -67,7 +68,11 @@ const DetectionResponseComponent = () => { - {canReadAlerts && {'[alerts chart]'}} + {canReadAlerts && ( + + + + )} {canReadCases && {'[cases chart]'}} diff --git a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx index fe25547ef99dcb0..878dbe30a697194 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/submenu.tsx @@ -5,66 +5,17 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; import React, { useMemo, useContext, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; import { useDispatch } from 'react-redux'; -import { EuiI18nNumber } from '@elastic/eui'; import { EventStats } from '../../../common/endpoint/types'; import { useColors } from './use_colors'; import { useLinkProps } from './use_link_props'; import { ResolverAction } from '../store/actions'; import { SideEffectContext } from './side_effect_context'; +import { FormattedCount } from '../../common/components/formatted_number'; /* eslint-disable react/display-name */ -/** - * Until browser support accomodates the `notation="compact"` feature of Intl.NumberFormat... - * exported for testing - * @param num The number to format - * @returns [mantissa ("12" in "12k+"), Scalar of compact notation (k,M,B,T), remainder indicator ("+" in "12k+")] - */ -export function compactNotationParts( - num: number -): [mantissa: number, compactNotation: string, remainderIndicator: string] { - if (!Number.isFinite(num)) { - return [num, '', '']; - } - - // "scale" here will be a term indicating how many thousands there are in the number - // e.g. 1001 will be 1000, 1000002 will be 1000000, etc. - const scale = Math.pow(10, 3 * Math.min(Math.floor(Math.floor(Math.log10(num)) / 3), 4)); - - const compactPrefixTranslations = { - compactThousands: i18n.translate('xpack.securitySolution.endpoint.resolver.compactThousands', { - defaultMessage: 'k', - }), - compactMillions: i18n.translate('xpack.securitySolution.endpoint.resolver.compactMillions', { - defaultMessage: 'M', - }), - - compactBillions: i18n.translate('xpack.securitySolution.endpoint.resolver.compactBillions', { - defaultMessage: 'B', - }), - - compactTrillions: i18n.translate('xpack.securitySolution.endpoint.resolver.compactTrillions', { - defaultMessage: 'T', - }), - }; - const prefixMap: Map = new Map([ - [1, ''], - [1000, compactPrefixTranslations.compactThousands], - [1000000, compactPrefixTranslations.compactMillions], - [1000000000, compactPrefixTranslations.compactBillions], - [1000000000000, compactPrefixTranslations.compactTrillions], - ]); - const hasRemainder = i18n.translate('xpack.securitySolution.endpoint.resolver.compactOverflow', { - defaultMessage: '+', - }); - const prefix = prefixMap.get(scale) ?? ''; - return [Math.floor(num / scale), prefix, (num / scale) % 1 > Number.EPSILON ? hasRemainder : '']; -} - /** * A Submenu that displays a collection of "pills" for each related event * category it has events for. @@ -89,15 +40,7 @@ export const NodeSubMenuComponents = React.memo( return []; } else { return Object.entries(nodeStats.byCategory).map(([category, total]) => { - const [mantissa, scale, hasRemainder] = compactNotationParts(total || 0); - const prefix = ( - , scale, hasRemainder }} - /> - ); + const prefix = ; return { prefix, category, diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx index e2184aaaec77380..ddf35eec86e0479 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_body.test.tsx @@ -29,6 +29,7 @@ describe('OpenTimelineModal', () => { euiBreakpoints: { s: '500px', }, + paddingSizes: { m: '16px' }, }, }); const title = 'All Timelines / Open Timelines'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/title_row/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/title_row/index.test.tsx index d46cad3c43a9881..9e54d708db496f2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/title_row/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/title_row/index.test.tsx @@ -14,7 +14,13 @@ import { TitleRow } from '.'; import { getMockTheme } from '../../../../common/lib/kibana/kibana_react.mock'; const mockTheme = getMockTheme({ - eui: { euiSizeS: '10px', euiLineHeight: 10, euiBreakpoints: { s: '10px' }, euiSize: '10px' }, + eui: { + euiSizeS: '10px', + euiLineHeight: 10, + euiBreakpoints: { s: '10px' }, + euiSize: '10px', + paddingSizes: { m: '16px' }, + }, }); describe('TitleRow', () => { diff --git a/x-pack/plugins/security_solution/server/endpoint/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/mocks.ts index 46e4df691b08654..6d6c83efd70fd97 100644 --- a/x-pack/plugins/security_solution/server/endpoint/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/mocks.ts @@ -5,8 +5,13 @@ * 2.0. */ -import { loggingSystemMock, savedObjectsServiceMock } from '@kbn/core/server/mocks'; -import { IScopedClusterClient, SavedObjectsClientContract } from '@kbn/core/server'; +import type { AwaitedProperties } from '@kbn/utility-types'; +import { + loggingSystemMock, + savedObjectsServiceMock, + ScopedClusterClientMock, +} from '@kbn/core/server/mocks'; +import { SavedObjectsClientContract } from '@kbn/core/server'; import { listMock } from '@kbn/lists-plugin/server/mocks'; import { securityMock } from '@kbn/security-plugin/server/mocks'; import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; @@ -35,7 +40,6 @@ import { import { ManifestManager } from './services/artifacts/manifest_manager/manifest_manager'; import { getManifestManagerMock } from './services/artifacts/manifest_manager/manifest_manager.mock'; import { EndpointAppContext } from './types'; -import { MetadataRequestContext } from './routes/metadata/handlers'; import { SecuritySolutionRequestHandlerContext } from '../types'; import { parseExperimentalConfigValue } from '../../common/experimental_features'; import { requestContextFactoryMock } from '../request_context_factory.mock'; @@ -190,24 +194,22 @@ export const createMockFleetStartContract = (indexPattern: string): FleetStartCo }; }; -export const createMockMetadataRequestContext = (): jest.Mocked => { +export const createMockMetadataRequestContext = () => { return { endpointAppContextService: createMockEndpointAppContextService(), logger: loggingSystemMock.create().get('mock_endpoint_app_context'), - requestHandlerContext: - xpackMocks.createRequestHandlerContext() as unknown as jest.Mocked, + requestHandlerContext: xpackMocks.createRequestHandlerContext() as unknown as jest.Mocked< + AwaitedProperties + >, }; }; export function createRouteHandlerContext( - dataClient: jest.Mocked, + dataClient: ScopedClusterClientMock, savedObjectsClient: jest.Mocked, overrides: { endpointAuthz?: Partial } = {} ) { - const context = requestContextMock.create( - createMockClients(), - overrides - ) as jest.Mocked; + const context = requestContextMock.create(createMockClients(), overrides); context.core.elasticsearch.client = dataClient; context.core.savedObjects.client = savedObjectsClient; return context; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/audit_log.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/audit_log.test.ts index 960969b41966cca..c6dbe24cdb90160 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/audit_log.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/audit_log.test.ts @@ -9,6 +9,7 @@ import { KibanaResponseFactory, RequestHandler, RouteConfig } from '@kbn/core/server'; import { + coreMock, elasticsearchServiceMock, httpServerMock, httpServiceMock, @@ -162,7 +163,9 @@ describe('Action Log API', () => { path.startsWith(ENDPOINT_ACTION_LOG_ROUTE) )!; await routeHandler( - createRouteHandlerContext(esClientMock, savedObjectsClientMock.create()), + coreMock.createCustomRequestHandlerContext( + createRouteHandlerContext(esClientMock, savedObjectsClientMock.create()) + ) as SecuritySolutionRequestHandlerContext, req, mockResponse ); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts index e17f48017ba6d91..85d3fd1f064e2ac 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts @@ -6,6 +6,8 @@ */ /* eslint-disable @typescript-eslint/no-explicit-any */ +import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { AwaitedProperties } from '@kbn/utility-types'; import { KibanaRequest, KibanaResponseFactory, @@ -20,7 +22,6 @@ import { savedObjectsClientMock, } from '@kbn/core/server/mocks'; import { parseExperimentalConfigValue } from '../../../../common/experimental_features'; -import { SecuritySolutionRequestHandlerContext } from '../../../types'; import { EndpointAppContextService } from '../../endpoint_app_context_services'; import { createMockEndpointAppContextServiceSetupContract, @@ -55,6 +56,7 @@ import { CasesClientMock } from '@kbn/cases-plugin/server/client/mocks'; import { EndpointAuthz } from '../../../../common/endpoint/types/authz'; import type { PackageClient } from '@kbn/fleet-plugin/server'; import { createMockPackageService } from '@kbn/fleet-plugin/server/mocks'; +import { SecuritySolutionRequestHandlerContextMock } from '../../../lib/detection_engine/routes/__mocks__/request_context'; interface CallRouteInterface { body?: HostIsolationRequestBody; @@ -122,7 +124,7 @@ describe('Host Isolation', () => { routePrefix: string, opts: CallRouteInterface, indexExists?: { endpointDsExists: boolean } - ) => Promise>; + ) => Promise>; const superUser = { username: 'superuser', roles: ['superuser'], @@ -190,7 +192,7 @@ describe('Host Isolation', () => { routePrefix: string, { body, idxResponse, searchResponse, mockUser, license, authz = {} }: CallRouteInterface, indexExists?: { endpointDsExists: boolean } - ): Promise> => { + ): Promise> => { const asUser = mockUser ? mockUser : superUser; (startContract.security.authc.getCurrentUser as jest.Mock).mockImplementationOnce( () => asUser @@ -204,31 +206,30 @@ describe('Host Isolation', () => { }; // mock _index_template - ctx.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate = jest - .fn() - .mockImplementationOnce(() => { + ctx.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate.mockResponseImplementationOnce( + () => { if (indexExists) { - return Promise.resolve({ + return { body: true, statusCode: 200, - }); + }; } - return Promise.resolve({ + return { body: false, statusCode: 404, - }); - }); + }; + } + ); const withIdxResp = idxResponse ? idxResponse : { statusCode: 201 }; - const mockIndexResponse = jest.fn().mockImplementation(() => Promise.resolve(withIdxResp)); - const mockSearchResponse = jest - .fn() - .mockImplementation(() => - Promise.resolve({ body: legacyMetadataSearchResponseMock(searchResponse) }) - ); - - ctx.core.elasticsearch.client.asInternalUser.index = mockIndexResponse; - ctx.core.elasticsearch.client.asCurrentUser.search = mockSearchResponse; + ctx.core.elasticsearch.client.asInternalUser.index.mockResponseImplementation( + () => withIdxResp + ); + ctx.core.elasticsearch.client.asCurrentUser.search.mockResponseImplementation(() => { + return { + body: legacyMetadataSearchResponseMock(searchResponse), + }; + }); const withLicense = license ? license : Platinum; licenseEmitter.next(withLicense); @@ -241,7 +242,7 @@ describe('Host Isolation', () => { await routeHandler(ctx, mockRequest, mockResponse); - return ctx as unknown as jest.Mocked; + return ctx; }; }); @@ -283,8 +284,9 @@ describe('Host Isolation', () => { searchResponse: metadataResponse, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.agents).toContain(AgentID); }); it('records the user who performed the action to the action record', async () => { @@ -294,8 +296,9 @@ describe('Host Isolation', () => { mockUser: testU, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.user_id).toEqual(testU.username); }); it('records the comment in the action payload', async () => { @@ -304,8 +307,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'], comment: CommentText }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.data.comment).toEqual(CommentText); }); it('creates an action and returns its ID', async () => { @@ -313,8 +317,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'], comment: 'XYZ' }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; const actionID = actionDoc.action_id; expect(mockResponse.ok).toBeCalled(); expect((mockResponse.ok.mock.calls[0][0]?.body as HostIsolationResponse).action).toEqual( @@ -326,8 +331,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'] }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.timeout).toEqual(300); }); it('sends the action to the correct agent when endpoint ID is given', async () => { @@ -339,8 +345,9 @@ describe('Host Isolation', () => { searchResponse: doc, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.agents).toContain(AgentID); }); @@ -349,8 +356,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'] }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.data.command).toEqual('isolate'); }); it('sends the unisolate command payload from the unisolate route', async () => { @@ -358,8 +366,9 @@ describe('Host Isolation', () => { body: { endpoint_ids: ['XYZ'] }, }); const actionDoc: EndpointAction = ( - ctx.core.elasticsearch.client.asInternalUser.index as jest.Mock - ).mock.calls[0][0].body; + ctx.core.elasticsearch.client.asInternalUser.index.mock + .calls[0][0] as estypes.IndexRequest + ).body!; expect(actionDoc.data.command).toEqual('unisolate'); }); @@ -375,14 +384,17 @@ describe('Host Isolation', () => { const indexDoc = ctx.core.elasticsearch.client.asInternalUser.index; const actionDocs: [ - { index: string; body: LogsEndpointAction }, - { index: string; body: EndpointAction } - ] = [(indexDoc as jest.Mock).mock.calls[0][0], (indexDoc as jest.Mock).mock.calls[1][0]]; + { index: string; body?: LogsEndpointAction }, + { index: string; body?: EndpointAction } + ] = [ + indexDoc.mock.calls[0][0] as estypes.IndexRequest, + indexDoc.mock.calls[1][0] as estypes.IndexRequest, + ]; expect(actionDocs[0].index).toEqual(ENDPOINT_ACTIONS_INDEX); expect(actionDocs[1].index).toEqual(AGENT_ACTIONS_INDEX); - expect(actionDocs[0].body.EndpointActions.data.command).toEqual('unisolate'); - expect(actionDocs[1].body.data.command).toEqual('unisolate'); + expect(actionDocs[0].body!.EndpointActions.data.command).toEqual('unisolate'); + expect(actionDocs[1].body!.data.command).toEqual('unisolate'); }); it('handles isolation', async () => { @@ -395,14 +407,17 @@ describe('Host Isolation', () => { ); const indexDoc = ctx.core.elasticsearch.client.asInternalUser.index; const actionDocs: [ - { index: string; body: LogsEndpointAction }, - { index: string; body: EndpointAction } - ] = [(indexDoc as jest.Mock).mock.calls[0][0], (indexDoc as jest.Mock).mock.calls[1][0]]; + { index: string; body?: LogsEndpointAction }, + { index: string; body?: EndpointAction } + ] = [ + indexDoc.mock.calls[0][0] as estypes.IndexRequest, + indexDoc.mock.calls[1][0] as estypes.IndexRequest, + ]; expect(actionDocs[0].index).toEqual(ENDPOINT_ACTIONS_INDEX); expect(actionDocs[1].index).toEqual(AGENT_ACTIONS_INDEX); - expect(actionDocs[0].body.EndpointActions.data.command).toEqual('isolate'); - expect(actionDocs[1].body.data.command).toEqual('isolate'); + expect(actionDocs[0].body!.EndpointActions.data.command).toEqual('isolate'); + expect(actionDocs[1].body!.data.command).toEqual('isolate'); }); it('handles errors', async () => { diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts index 101a55d7acba36a..69954dbd7e7a7a7 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.ts @@ -84,7 +84,7 @@ const createFailedActionResponseEntry = async ({ logger: Logger; }): Promise => { // 8.0+ requires internal user to write to system indices - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { await esClient.index({ index: `${ENDPOINT_ACTION_RESPONSES_DS}-default`, @@ -178,7 +178,7 @@ export const isolationRequestHandler = function ( }); // 8.0+ requires internal user to write to system indices - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; // if the new endpoint indices/data streams exists // write the action request to the new endpoint index diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.ts index 9b134e385be6fdf..bfd17cccb3d0d70 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.ts @@ -47,7 +47,7 @@ export const actionStatusRequestHandler = function ( SecuritySolutionRequestHandlerContext > { return async (context, req, res) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const agentIDs: string[] = Array.isArray(req.query.agent_ids) ? [...new Set(req.query.agent_ids)] : [req.query.agent_ids]; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts index b508469b88f5306..0aaa138c90d31d3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/enrichment.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { coreMock } from '@kbn/core/server/mocks'; import { HostStatus } from '../../../../common/endpoint/types'; import { createMockMetadataRequestContext } from '../../mocks'; import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; @@ -12,13 +13,21 @@ import { enrichHostMetadata, MetadataRequestContext } from './handlers'; import { AgentClient } from '@kbn/fleet-plugin/server'; describe('test document enrichment', () => { - let metaReqCtx: jest.Mocked; + let metaReqCtx: ReturnType; const docGen = new EndpointDocGenerator(); beforeEach(() => { metaReqCtx = createMockMetadataRequestContext(); }); + const getMetadataRequestContext = () => + ({ + ...metaReqCtx, + requestHandlerContext: coreMock.createCustomRequestHandlerContext( + metaReqCtx.requestHandlerContext + ), + } as unknown as MetadataRequestContext); + describe('host status enrichment', () => { let statusFn: jest.Mock; @@ -32,49 +41,70 @@ describe('test document enrichment', () => { it('should return host healthy for online agent', async () => { statusFn.mockImplementation(() => 'online'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.HEALTHY); }); it('should return host offline for offline agent', async () => { statusFn.mockImplementation(() => 'offline'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.OFFLINE); }); it('should return host updating for unenrolling agent', async () => { statusFn.mockImplementation(() => 'unenrolling'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UPDATING); }); it('should return host unhealthy for degraded agent', async () => { statusFn.mockImplementation(() => 'degraded'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UNHEALTHY); }); it('should return host unhealthy for erroring agent', async () => { statusFn.mockImplementation(() => 'error'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UNHEALTHY); }); it('should return host unhealthy for warning agent', async () => { statusFn.mockImplementation(() => 'warning'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UNHEALTHY); }); it('should return host unhealthy for invalid agent', async () => { statusFn.mockImplementation(() => 'asliduasofb'); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.host_status).toEqual(HostStatus.UNHEALTHY); }); }); @@ -109,7 +139,10 @@ describe('test document enrichment', () => { }; }); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.policy_info).toBeDefined(); expect(enrichedHostList.policy_info?.agent.applied.id).toEqual(policyID); expect(enrichedHostList.policy_info?.agent.applied.revision).toEqual(policyRev); @@ -125,7 +158,10 @@ describe('test document enrichment', () => { }; }); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.policy_info).toBeDefined(); expect(enrichedHostList.policy_info?.agent.configured.id).toEqual(policyID); expect(enrichedHostList.policy_info?.agent.configured.revision).toEqual(policyRev); @@ -146,7 +182,10 @@ describe('test document enrichment', () => { }; }); - const enrichedHostList = await enrichHostMetadata(docGen.generateHostMetadata(), metaReqCtx); + const enrichedHostList = await enrichHostMetadata( + docGen.generateHostMetadata(), + getMetadataRequestContext() + ); expect(enrichedHostList.policy_info).toBeDefined(); expect(enrichedHostList.policy_info?.endpoint.id).toEqual(policyID); expect(enrichedHostList.policy_info?.endpoint.revision).toEqual(policyRev); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts index a8d186e126b62b1..1b86924101b68cf 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/handlers.ts @@ -94,7 +94,7 @@ export function getMetadataListRequestHandler( return async (context, request, response) => { const endpointMetadataService = endpointAppContext.service.getEndpointMetadataService(); const fleetServices = endpointAppContext.service.getScopedFleetServices(request); - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; let doesUnitedIndexExist = false; let didUnitedIndexError = false; @@ -168,9 +168,10 @@ export const getMetadataRequestHandler = function ( const endpointMetadataService = endpointAppContext.service.getEndpointMetadataService(); try { + const esClient = (await context.core).elasticsearch.client; return response.ok({ body: await endpointMetadataService.getEnrichedHostMetadata( - context.core.elasticsearch.client.asInternalUser, + esClient.asInternalUser, endpointAppContext.service.getScopedFleetServices(request), request.params.id ), @@ -185,7 +186,7 @@ export function getMetadataTransformStatsHandler( logger: Logger ): RequestHandler { return async (context, _, response) => { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; try { const transformStats = await esClient.transform.getTransformStats({ transform_id: METADATA_TRANSFORMS_PATTERN, @@ -235,19 +236,14 @@ export async function enrichHostMetadata( let hostStatus = HostStatus.UNHEALTHY; let elasticAgentId = hostMetadata?.elastic?.agent?.id; const log = metadataRequestContext.logger; + const coreContext = await metadataRequestContext.requestHandlerContext?.core; try { - if ( - !metadataRequestContext.esClient && - !metadataRequestContext.requestHandlerContext?.core.elasticsearch.client - ) { + if (!metadataRequestContext.esClient && !coreContext?.elasticsearch.client) { throw new Error('esClient not found'); } - if ( - !metadataRequestContext.savedObjectsClient && - !metadataRequestContext.requestHandlerContext?.core.savedObjects - ) { + if (!metadataRequestContext.savedObjectsClient && !coreContext?.savedObjects) { throw new Error('esSavedObjectClient not found'); } } catch (e) { @@ -257,8 +253,8 @@ export async function enrichHostMetadata( const esSavedObjectClient = metadataRequestContext?.savedObjectsClient ?? - (metadataRequestContext.requestHandlerContext?.core.savedObjects - .client as SavedObjectsClientContract); + (coreContext?.savedObjects.client as SavedObjectsClientContract); + const fleetContext = await metadataRequestContext.requestHandlerContext?.fleet; try { /** @@ -270,10 +266,7 @@ export async function enrichHostMetadata( log.warn(`Missing elastic agent id, using host id instead ${elasticAgentId}`); } - const status = - await metadataRequestContext.requestHandlerContext?.fleet?.agentClient.asCurrentUser.getAgentStatusById( - elasticAgentId - ); + const status = await fleetContext?.agentClient.asCurrentUser.getAgentStatusById(elasticAgentId); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion hostStatus = fleetAgentStatusToEndpointHostStatus(status!); } catch (e) { @@ -287,10 +280,7 @@ export async function enrichHostMetadata( let policyInfo: HostInfo['policy_info']; try { - const agent = - await metadataRequestContext.requestHandlerContext?.fleet?.agentClient.asCurrentUser.getAgent( - elasticAgentId - ); + const agent = await fleetContext?.agentClient.asCurrentUser.getAgent(elasticAgentId); const agentPolicy = await metadataRequestContext.endpointAppContextService .getAgentPolicyService() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -338,17 +328,18 @@ async function legacyListMetadataQuery( queryOptions: GetMetadataListRequestQuery ): Promise { const fleetAgentClient = fleetServices.agent; + const coreContext = await context.core; const metadataRequestContext: MetadataRequestContext = { - esClient: context.core.elasticsearch.client, + esClient: coreContext.elasticsearch.client, endpointAppContextService: endpointAppContext.service, logger, requestHandlerContext: context, - savedObjectsClient: context.core.savedObjects.client, + savedObjectsClient: coreContext.savedObjects.client, }; const endpointPolicyIds = endpointPolicies.map((policy) => policy.policy_id); - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = coreContext.elasticsearch.client.asInternalUser; const unenrolledAgentIds = await findAllUnenrolledAgentIds(fleetAgentClient, endpointPolicyIds); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index 95c3e24709cccad..01136fef81884a3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -24,7 +24,10 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { GetHostPolicyResponse, HostPolicyResponse } from '../../../../common/endpoint/types'; import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; import { parseExperimentalConfigValue } from '../../../../common/experimental_features'; -import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; +import { + createMockConfig, + requestContextMock, +} from '../../../lib/detection_engine/routes/__mocks__'; import { Agent } from '@kbn/fleet-plugin/common/types/models'; import { AgentClient, AgentService } from '@kbn/fleet-plugin/server/services'; import { get } from 'lodash'; @@ -59,7 +62,9 @@ describe('test policy response handler', () => { }); await hostPolicyResponseHandler( - createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + requestContextMock.convertContext( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient) + ), mockRequest, mockResponse ); @@ -81,7 +86,9 @@ describe('test policy response handler', () => { }); await hostPolicyResponseHandler( - createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + requestContextMock.convertContext( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient) + ), mockRequest, mockResponse ); @@ -185,7 +192,9 @@ describe('test policy response handler', () => { }); await policySummarysHandler( - createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + requestContextMock.convertContext( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient) + ), mockRequest, mockResponse ); @@ -216,7 +225,9 @@ describe('test policy response handler', () => { }); await agentPolicySummaryHandler( - createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + requestContextMock.convertContext( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient) + ), mockRequest, mockResponse ); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index 8a32580f9669ae5..7ccae199a3ed996 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -22,11 +22,8 @@ export const getHostPolicyResponseHandler = function (): RequestHandler< undefined > { return async (context, request, response) => { - const doc = await getPolicyResponseByAgentId( - policyIndexPattern, - request.query.agentId, - context.core.elasticsearch.client - ); + const client = (await context.core).elasticsearch.client; + const doc = await getPolicyResponseByAgentId(policyIndexPattern, request.query.agentId, client); if (doc) { return response.ok({ body: doc }); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts index 58ccd119c4ddeb0..ef438667c364724 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts @@ -87,7 +87,8 @@ export function handleEntities(): RequestHandler> { return async (context, req, res) => { - const client = context.core.elasticsearch.client; + const client = (await context.core).elasticsearch.client; const fetcher = new Fetcher(client); const body = await fetcher.tree(req.body); return res.ok({ diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.test.ts index 607b9a8c2350870..34f2f7a434fbda2 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { coreMock, httpServerMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { RequestHandler } from '@kbn/core/server'; import { requestContextMock } from '../../lib/detection_engine/routes/__mocks__'; import { EndpointApiNeededAuthz, withEndpointAuthz } from './with_endpoint_authz'; @@ -14,7 +14,7 @@ import { EndpointAuthorizationError } from '../errors'; describe('When using `withEndpointAuthz()`', () => { let mockRequestHandler: jest.Mocked; - let mockContext: jest.Mocked>; + let mockContext: ReturnType; let mockRequest: ReturnType; let mockResponse: ReturnType; let logger: ReturnType; @@ -58,10 +58,10 @@ describe('When using `withEndpointAuthz()`', () => { }, { canCreateArtifactsByPolicy: false }, ], - ])('should grant access when needed authz is %j', (neededAuthz, authzOverrides) => { + ])('should grant access when needed authz is %j', async (neededAuthz, authzOverrides) => { Object.assign(mockContext.securitySolution.endpointAuthz, authzOverrides); - withEndpointAuthz(neededAuthz, logger, mockRequestHandler)( - mockContext, + await withEndpointAuthz(neededAuthz, logger, mockRequestHandler)( + coreMock.createCustomRequestHandlerContext(mockContext), mockRequest, mockResponse ); @@ -85,11 +85,11 @@ describe('When using `withEndpointAuthz()`', () => { }, { canCreateArtifactsByPolicy: false }, ], - ])('should deny access when not authorized for %j', (neededAuthz, authzOverrides) => { + ])('should deny access when not authorized for %j', async (neededAuthz, authzOverrides) => { Object.assign(mockContext.securitySolution.endpointAuthz, authzOverrides); - withEndpointAuthz(neededAuthz, logger, mockRequestHandler)( - mockContext, + await withEndpointAuthz(neededAuthz, logger, mockRequestHandler)( + coreMock.createCustomRequestHandlerContext(mockContext), mockRequest, mockResponse ); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.ts b/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.ts index 0ed4adb01a9b609..14a61a92e52e883 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/with_endpoint_authz.ts @@ -51,7 +51,7 @@ export const withEndpointAuthz = ( SecuritySolutionRequestHandlerContext > = async (context, request, response) => { if (enforceAuthz) { - const endpointAuthz = context.securitySolution.endpointAuthz; + const endpointAuthz = (await context.securitySolution).endpointAuthz; const permissionChecker = (permission: EndpointAuthzKeyList[0]) => endpointAuthz[permission]; // has `all`? diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/metadata.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/metadata.ts index bd2cdd7e45a3ae4..9e21c2c192b829c 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/metadata.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/metadata.ts @@ -18,7 +18,7 @@ export async function getMetadataForEndpoints( requestHandlerContext: SecuritySolutionRequestHandlerContext ): Promise { const query = getESQueryHostMetadataByIDs(endpointIDs); - const esClient = requestHandlerContext.core.elasticsearch.client.asCurrentUser; + const esClient = (await requestHandlerContext.core).elasticsearch.client.asCurrentUser; const { body } = await esClient.search(query as estypes.SearchRequest, { meta: true, }); diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/audit_log_helpers.ts b/x-pack/plugins/security_solution/server/endpoint/utils/audit_log_helpers.ts index 8d9234fab280ff0..3a1e25c32b68374 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/audit_log_helpers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/audit_log_helpers.ts @@ -194,7 +194,7 @@ export const getActionRequestsResult = async ({ let actionRequests: TransportResult, unknown>; try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; actionRequests = await esClient.search(actionsSearchQuery, { ...queryOptions, meta: true }); const actionIds = actionRequests?.body?.hits?.hits?.map((e) => { return logsEndpointActionsRegex.test(e._index) @@ -251,7 +251,7 @@ export const getActionResponsesResult = async ({ let actionResponses: TransportResult, unknown>; try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; actionResponses = await esClient.search(responsesSearchQuery, { ...queryOptions, meta: true }); } catch (error) { logger.error(error); diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.test.ts b/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.test.ts index 43042a332c1d283..eb53a5854c2aaf2 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.test.ts @@ -6,6 +6,7 @@ */ import { + coreMock, elasticsearchServiceMock, savedObjectsClientMock, loggingSystemMock, @@ -18,7 +19,7 @@ import { } from './yes_no_data_stream'; describe('Accurately answers if index template for data stream exists', () => { - let ctxt: jest.Mocked; + let ctxt: ReturnType; beforeEach(() => { ctxt = createRouteHandlerContext( @@ -27,17 +28,17 @@ describe('Accurately answers if index template for data stream exists', () => { ); }); - const mockEsApiResponse = (response: { body: boolean; statusCode: number }) => { - return jest.fn().mockImplementationOnce(() => Promise.resolve(response)); - }; - it('Returns FALSE for a non-existent data stream index template', async () => { - ctxt.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate = mockEsApiResponse({ - body: false, - statusCode: 404, - }); + ctxt.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate.mockResponseImplementation( + () => ({ + body: false, + statusCode: 404, + }) + ); const doesItExist = await doLogsEndpointActionDsExists({ - context: ctxt, + context: coreMock.createCustomRequestHandlerContext( + ctxt + ) as SecuritySolutionRequestHandlerContext, logger: loggingSystemMock.create().get('host-isolation'), dataStreamName: '.test-stream.name', }); @@ -45,12 +46,16 @@ describe('Accurately answers if index template for data stream exists', () => { }); it('Returns TRUE for an existing index', async () => { - ctxt.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate = mockEsApiResponse({ - body: true, - statusCode: 200, - }); + ctxt.core.elasticsearch.client.asInternalUser.indices.existsIndexTemplate.mockResponseImplementation( + () => ({ + body: true, + statusCode: 200, + }) + ); const doesItExist = await doLogsEndpointActionDsExists({ - context: ctxt, + context: coreMock.createCustomRequestHandlerContext( + ctxt + ) as SecuritySolutionRequestHandlerContext, logger: loggingSystemMock.create().get('host-isolation'), dataStreamName: '.test-stream.name', }); @@ -59,7 +64,7 @@ describe('Accurately answers if index template for data stream exists', () => { }); describe('Accurately answers if index exists', () => { - let ctxt: jest.Mocked; + let ctxt: ReturnType; beforeEach(() => { ctxt = createRouteHandlerContext( @@ -68,17 +73,15 @@ describe('Accurately answers if index exists', () => { ); }); - const mockEsApiResponse = (response: { body: boolean; statusCode: number }) => { - return jest.fn().mockImplementationOnce(() => Promise.resolve(response)); - }; - it('Returns FALSE for a non-existent index', async () => { - ctxt.core.elasticsearch.client.asInternalUser.indices.exists = mockEsApiResponse({ + ctxt.core.elasticsearch.client.asInternalUser.indices.exists.mockResponseImplementation(() => ({ body: false, statusCode: 404, - }); + })); const doesItExist = await doesLogsEndpointActionsIndexExist({ - context: ctxt, + context: coreMock.createCustomRequestHandlerContext( + ctxt + ) as SecuritySolutionRequestHandlerContext, logger: loggingSystemMock.create().get('host-isolation'), indexName: '.test-index.name-default', }); @@ -86,12 +89,14 @@ describe('Accurately answers if index exists', () => { }); it('Returns TRUE for an existing index', async () => { - ctxt.core.elasticsearch.client.asInternalUser.indices.exists = mockEsApiResponse({ + ctxt.core.elasticsearch.client.asInternalUser.indices.exists.mockResponseImplementation(() => ({ body: true, statusCode: 200, - }); + })); const doesItExist = await doesLogsEndpointActionsIndexExist({ - context: ctxt, + context: coreMock.createCustomRequestHandlerContext( + ctxt + ) as SecuritySolutionRequestHandlerContext, logger: loggingSystemMock.create().get('host-isolation'), indexName: '.test-index.name-default', }); diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.ts b/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.ts index b84a026f9e8e093..9e94e4ba29c328d 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/yes_no_data_stream.ts @@ -18,7 +18,7 @@ export const doLogsEndpointActionDsExists = async ({ dataStreamName: string; }): Promise => { try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const doesIndexTemplateExist = await esClient.indices.existsIndexTemplate( { name: dataStreamName, @@ -46,7 +46,7 @@ export const doesLogsEndpointActionsIndexExist = async ({ indexName: string; }): Promise => { try { - const esClient = context.core.elasticsearch.client.asInternalUser; + const esClient = (await context.core).elasticsearch.client.asInternalUser; const doesIndexExist = await esClient.indices.exists( { index: indexName, diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts index 80bafe6b4799ae8..17bfa0d584f28f5 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts @@ -33,7 +33,6 @@ import { Subject } from 'rxjs'; import { ILicense } from '@kbn/licensing-plugin/common/types'; import { EndpointDocGenerator } from '../../common/endpoint/generate_data'; import { ProtectionModes } from '../../common/endpoint/types'; -import type { SecuritySolutionRequestHandlerContext } from '../types'; import { getExceptionListClientMock } from '@kbn/lists-plugin/server/services/exception_lists/exception_list_client.mock'; import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; import { ExceptionListClient } from '@kbn/lists-plugin/server'; @@ -50,7 +49,7 @@ import { ALL_ENDPOINT_ARTIFACT_LIST_IDS } from '../../common/endpoint/service/ar describe('ingest_integration tests ', () => { let endpointAppContextMock: EndpointAppContextServiceStartContract; let req: KibanaRequest; - let ctx: SecuritySolutionRequestHandlerContext; + let ctx: ReturnType; const exceptionListClient: ExceptionListClient = getExceptionListClientMock(); let licenseEmitter: Subject; let licenseService: LicenseService; @@ -99,7 +98,7 @@ describe('ingest_integration tests ', () => { exceptionListClient ); - return callback(createNewPackagePolicyMock(), ctx, req); + return callback(createNewPackagePolicyMock(), requestContextMock.convertContext(ctx), req); }; const TEST_POLICY_ID_1 = 'c6d16e42-c32d-4dce-8a88-113cfe276ad1'; @@ -265,9 +264,9 @@ describe('ingest_integration tests ', () => { ); const policyConfig = generator.generatePolicyPackagePolicy(); policyConfig.inputs[0]!.config!.policy.value = mockPolicy; - await expect(() => callback(policyConfig, ctx, req)).rejects.toThrow( - 'Requires Platinum license' - ); + await expect(() => + callback(policyConfig, requestContextMock.convertContext(ctx), req) + ).rejects.toThrow('Requires Platinum license'); }); it('updates successfully if no paid features are turned on in the policy', async () => { const mockPolicy = policyFactoryWithoutPaidFeatures(); @@ -281,7 +280,11 @@ describe('ingest_integration tests ', () => { ); const policyConfig = generator.generatePolicyPackagePolicy(); policyConfig.inputs[0]!.config!.policy.value = mockPolicy; - const updatedPolicyConfig = await callback(policyConfig, ctx, req); + const updatedPolicyConfig = await callback( + policyConfig, + requestContextMock.convertContext(ctx), + req + ); expect(updatedPolicyConfig.inputs[0]!.config!.policy.value).toEqual(mockPolicy); }); }); @@ -302,7 +305,11 @@ describe('ingest_integration tests ', () => { ); const policyConfig = generator.generatePolicyPackagePolicy(); policyConfig.inputs[0]!.config!.policy.value = mockPolicy; - const updatedPolicyConfig = await callback(policyConfig, ctx, req); + const updatedPolicyConfig = await callback( + policyConfig, + requestContextMock.convertContext(ctx), + req + ); expect(updatedPolicyConfig.inputs[0]!.config!.policy.value).toEqual(mockPolicy); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts index ad0c3eace42c85d..60e8f0c8cf85839 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts @@ -6,6 +6,7 @@ */ import type { MockedKeys } from '@kbn/utility-types/jest'; +import type { AwaitedProperties } from '@kbn/utility-types'; import { coreMock } from '@kbn/core/server/mocks'; import { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server'; @@ -62,10 +63,11 @@ export const createMockClients = () => { type MockClients = ReturnType; -type SecuritySolutionRequestHandlerContextMock = - MockedKeys & { - core: MockClients['core']; - }; +export type SecuritySolutionRequestHandlerContextMock = MockedKeys< + AwaitedProperties> +> & { + core: MockClients['core']; +}; const createRequestContextMock = ( clients: MockClients = createMockClients(), @@ -89,6 +91,14 @@ const createRequestContextMock = ( }; }; +const convertRequestContextMock = ( + context: AwaitedProperties +): SecuritySolutionRequestHandlerContext => { + return coreMock.createCustomRequestHandlerContext( + context + ) as unknown as SecuritySolutionRequestHandlerContext; +}; + const createSecuritySolutionRequestContextMock = ( clients: MockClients, overrides: { endpointAuthz?: Partial } = {} @@ -127,6 +137,7 @@ const createTools = () => { export const requestContextMock = { create: createRequestContextMock, + convertContext: convertRequestContextMock, createMockClients, createTools, }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/server.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/server.ts index 85cf6a07f4d89fa..ef2a3016e5f91eb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/server.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/server.ts @@ -17,6 +17,7 @@ interface Route { config: RouteConfig; handler: RequestHandler; } + const getRoute = (routerMock: MockServer['router']): Route => { const routeCalls = [ ...routerMock.get.mock.calls, @@ -41,7 +42,7 @@ class MockServer { constructor( public readonly router = httpServiceMock.createRouter(), private responseMock = responseFactoryMock.create(), - private contextMock = requestContextMock.create(), + private contextMock = requestContextMock.convertContext(requestContextMock.create()), private resultMock = buildResultMock() ) {} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts index 86e06a71b638b3c..d4ad4bb75e41bd1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts @@ -47,11 +47,12 @@ export const createIndexRoute = (router: SecuritySolutionPluginRouter) => { const siemResponse = buildSiemResponse(response); try { - const siemClient = context.securitySolution?.getAppClient(); + const securitySolution = await context.securitySolution; + const siemClient = securitySolution?.getAppClient(); if (!siemClient) { return siemResponse.error({ statusCode: 404 }); } - await createDetectionIndex(context.securitySolution); + await createDetectionIndex(securitySolution); return response.ok({ body: { acknowledged: true } }); } catch (err) { const error = transformError(err); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts index 6eae3908e2156f2..ddaa49782360453 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts @@ -40,9 +40,9 @@ export const deleteIndexRoute = (router: SecuritySolutionPluginRouter) => { const siemResponse = buildSiemResponse(response); try { - const esClient = context.core.elasticsearch.client.asCurrentUser; + const esClient = (await context.core).elasticsearch.client.asCurrentUser; - const siemClient = context.securitySolution?.getAppClient(); + const siemClient = (await context.securitySolution)?.getAppClient(); if (!siemClient) { return siemResponse.error({ statusCode: 404 }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts index 24f05c707e3d4a3..c03f8e000d0f155 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts @@ -32,19 +32,22 @@ export const readIndexRoute = ( const siemResponse = buildSiemResponse(response); try { - const siemClient = context.securitySolution?.getAppClient(); - const esClient = context.core.elasticsearch.client.asCurrentUser; + const core = await context.core; + const securitySolution = await context.securitySolution; + + const siemClient = securitySolution?.getAppClient(); + const esClient = core.elasticsearch.client.asCurrentUser; if (!siemClient) { return siemResponse.error({ statusCode: 404 }); } - const spaceId = context.securitySolution.getSpaceId(); + const spaceId = securitySolution.getSpaceId(); const indexName = ruleDataService.getResourceName(`security.alerts-${spaceId}`); const index = siemClient.getSignalsIndex(); const indexExists = await getBootstrapIndexExists( - context.core.elasticsearch.client.asInternalUser, + core.elasticsearch.client.asInternalUser, index ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts index c4c205e696065e3..002b4c2264eee62 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts @@ -30,7 +30,7 @@ describe('read_privileges route', () => { test('returns 200 when doing a normal request', async () => { const response = await server.inject( getPrivilegeRequest({ auth: { isAuthenticated: false } }), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -38,7 +38,7 @@ describe('read_privileges route', () => { test('returns the payload when doing a normal request', async () => { const response = await server.inject( getPrivilegeRequest({ auth: { isAuthenticated: false } }), - context + requestContextMock.convertContext(context) ); const expectedBody = { ...getMockPrivilegesResult(), @@ -58,7 +58,7 @@ describe('read_privileges route', () => { const response = await server.inject( getPrivilegeRequest({ auth: { isAuthenticated: true } }), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); expect(response.body).toEqual(expectedBody); @@ -70,7 +70,7 @@ describe('read_privileges route', () => { ); const response = await server.inject( getPrivilegeRequest({ auth: { isAuthenticated: false } }), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', status_code: 500 }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts index 22f8ccb39118a42..31ea057facb690b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts @@ -28,15 +28,17 @@ export const readPrivilegesRoute = ( const siemResponse = buildSiemResponse(response); try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const siemClient = context.securitySolution?.getAppClient(); + const core = await context.core; + const securitySolution = await context.securitySolution; + const esClient = core.elasticsearch.client.asCurrentUser; + const siemClient = securitySolution?.getAppClient(); if (!siemClient) { return siemResponse.error({ statusCode: 404 }); } - const spaceId = context.securitySolution.getSpaceId(); - const index = context.securitySolution + const spaceId = securitySolution.getSpaceId(); + const index = securitySolution .getRuleDataService() .getResourceName(`security.alerts-${spaceId}`); const clusterPrivileges = await readPrivileges(esClient, index); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts index d5b301364d4aca0..f80756ce353d695 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts @@ -106,7 +106,7 @@ describe('add_prepackaged_rules_route', () => { describe('status codes', () => { test('returns 200', async () => { const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); @@ -116,7 +116,7 @@ describe('add_prepackaged_rules_route', () => { test('1 rule is installed and 0 are updated when find results are empty', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -129,7 +129,7 @@ describe('add_prepackaged_rules_route', () => { test('1 rule is updated and 0 are installed when we return a single find and the versions are different', async () => { const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -159,7 +159,7 @@ describe('add_prepackaged_rules_route', () => { ], }); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ rules_installed: 0, rules_updated: 1, @@ -178,7 +178,7 @@ describe('add_prepackaged_rules_route', () => { errors: [], }); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ rules_installed: 0, rules_updated: 1, @@ -197,7 +197,7 @@ describe('add_prepackaged_rules_route', () => { errors: [], }); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ rules_installed: 0, rules_updated: 1, @@ -224,7 +224,7 @@ describe('add_prepackaged_rules_route', () => { ], }); const request = addPrepackagedRulesRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ rules_installed: 0, rules_updated: 1, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts index 0042030ea21ef59..b6a6681aad9a1cd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts @@ -54,10 +54,10 @@ export const addPrepackedRulesRoute = (router: SecuritySolutionPluginRouter) => const siemResponse = buildSiemResponse(response); try { - const rulesClient = context.alerting.getRulesClient(); + const rulesClient = (await context.alerting).getRulesClient(); const validated = await createPrepackagedRules( - context.securitySolution, + await context.securitySolution, rulesClient, undefined ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts index 82813b18cbd0478..e3afd247b332160 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts @@ -54,7 +54,10 @@ describe.each([ describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getReadBulkRequest(), context); + const response = await server.inject( + getReadBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); }); @@ -67,7 +70,10 @@ describe.each([ .mockResolvedValue({ valid: false, message: 'mocked validation message' }), }); - const response = await server.inject(createBulkMlRuleRequest(), context); + const response = await server.inject( + createBulkMlRuleRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -86,7 +92,10 @@ describe.each([ getBasicNoShardsSearchResponse() ) ); - const response = await server.inject(getReadBulkRequest(), context); + const response = await server.inject( + getReadBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); @@ -106,7 +115,10 @@ describe.each([ test('returns a duplicate error if rule_id already exists', async () => { clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const response = await server.inject(getReadBulkRequest(), context); + const response = await server.inject( + getReadBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual([ @@ -123,7 +135,10 @@ describe.each([ clients.rulesClient.create.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getReadBulkRequest(), context); + const response = await server.inject( + getReadBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual([ @@ -142,7 +157,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_CREATE, body: [getCreateRulesSchemaMock(), getCreateRulesSchemaMock()], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts index cf4633b9768163c..cbd5b755b5649d1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts @@ -51,13 +51,16 @@ export const createRulesBulkRoute = ( logDeprecatedBulkEndpoint(logger, DETECTION_ENGINE_RULES_BULK_CREATE); const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const esClient = context.core.elasticsearch.client; - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + + const ctx = await context.resolve(['core', 'securitySolution', 'licensing', 'alerting']); + + const rulesClient = ctx.alerting.getRulesClient(); + const esClient = ctx.core.elasticsearch.client; + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts index fb2625f149d86ea..836569a34b9ea9e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts @@ -24,6 +24,7 @@ import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { elasticsearchClientMock } from '@kbn/core/server/elasticsearch/client/mocks'; import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; + jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); describe.each([ @@ -55,21 +56,30 @@ describe.each([ describe('status codes', () => { test('returns 200 with a rule created via RulesClient', async () => { - const response = await server.inject(getCreateRequest(), context); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 if license is not platinum', async () => { (context.licensing.license.hasAtLeast as jest.Mock).mockReturnValue(false); - const response = await server.inject(getCreateRequest(), context); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); }); describe('creating an ML Rule', () => { test('is successful', async () => { - const response = await server.inject(createMlRuleRequest(), context); + const response = await server.inject( + createMlRuleRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -80,7 +90,10 @@ describe.each([ .mockResolvedValue({ valid: false, message: 'mocked validation message' }), }); - const response = await server.inject(createMlRuleRequest(), context); + const response = await server.inject( + createMlRuleRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(403); expect(response.body).toEqual({ message: 'mocked validation message', @@ -96,7 +109,10 @@ describe.each([ getBasicNoShardsSearchResponse() ) ); - const response = await server.inject(getCreateRequest(), context); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(isRuleRegistryEnabled ? 200 : 400); @@ -110,7 +126,10 @@ describe.each([ test('returns a duplicate error if rule_id already exists', async () => { clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); - const response = await server.inject(getCreateRequest(), context); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(409); expect(response.body).toEqual({ @@ -123,7 +142,10 @@ describe.each([ clients.rulesClient.create.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getCreateRequest(), context); + const response = await server.inject( + getCreateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts index fe39c5cb9680e8c..aabcf9722fe9001 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts @@ -46,11 +46,19 @@ export const createRulesRoute = ( } try { - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const esClient = context.core.elasticsearch.client; - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + const ctx = await context.resolve([ + 'core', + 'securitySolution', + 'licensing', + 'alerting', + 'lists', + ]); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const esClient = ctx.core.elasticsearch.client; + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); if (request.body.rule_id != null) { const rule = await readRules({ @@ -74,7 +82,7 @@ export const createRulesRoute = ( ); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, @@ -93,7 +101,7 @@ export const createRulesRoute = ( } // This will create the endpoint list if it does not exist yet - await context.lists?.getExceptionListClient().createEndpointList(); + await ctx.lists?.getExceptionListClient().createEndpointList(); const createdRule = await rulesClient.create({ data: internalRule, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts index c8d1628ded78323..98bdca2db057181 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts @@ -40,40 +40,61 @@ describe.each([ describe('status codes with actionClient and alertClient', () => { test('returns 200 when deleting a single rule with a valid actionClient and alertClient by alertId', async () => { - const response = await server.inject(getDeleteBulkRequest(), context); + const response = await server.inject( + getDeleteBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule and related rule status', async () => { - const response = await server.inject(getDeleteBulkRequest(), context); + const response = await server.inject( + getDeleteBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule with a valid actionClient and alertClient by alertId using POST', async () => { - const response = await server.inject(getDeleteAsPostBulkRequest(), context); + const response = await server.inject( + getDeleteAsPostBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule with a valid actionClient and alertClient by id', async () => { - const response = await server.inject(getDeleteBulkRequestById(), context); + const response = await server.inject( + getDeleteBulkRequestById(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when deleting a single rule with a valid actionClient and alertClient by id using POST', async () => { - const response = await server.inject(getDeleteAsPostBulkRequestById(), context); + const response = await server.inject( + getDeleteAsPostBulkRequestById(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 because the error is in the payload when deleting a single rule that does not exist with a valid actionClient and alertClient', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getDeleteBulkRequest(), context); + const response = await server.inject( + getDeleteBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 404 in the payload when deleting a single rule that does not exist with a valid actionClient and alertClient', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getDeleteBulkRequest(), context); + const response = await server.inject( + getDeleteBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual( expect.arrayContaining([ @@ -93,7 +114,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_DELETE, body: [{}], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -109,7 +130,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_DELETE, body: [{ id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f', rule_id: 'rule_1' }], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts index 674427a0b922951..09b0174bb24b5e0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts @@ -60,9 +60,12 @@ export const deleteRulesBulkRoute = ( logDeprecatedBulkEndpoint(logger, DETECTION_ENGINE_RULES_BULK_DELETE); const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + + const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; const rules = await Promise.all( request.body.map(async (payloadRule) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts index b18e330eab5a4ce..85d7939ba359d22 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts @@ -37,7 +37,10 @@ describe.each([ describe('status codes with actionClient and alertClient', () => { test('returns 200 when deleting a single rule with a valid actionClient and alertClient by alertId', async () => { - const response = await server.inject(getDeleteRequest(), context); + const response = await server.inject( + getDeleteRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -46,14 +49,20 @@ describe.each([ clients.rulesClient.resolve.mockResolvedValue( resolveAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) ); - const response = await server.inject(getDeleteRequestById(), context); + const response = await server.inject( + getDeleteRequestById(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 404 when deleting a single rule that does not exist with a valid actionClient and alertClient', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getDeleteRequest(), context); + const response = await server.inject( + getDeleteRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ @@ -66,7 +75,10 @@ describe.each([ clients.rulesClient.delete.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getDeleteRequest(), context); + const response = await server.inject( + getDeleteRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -82,7 +94,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, query: {}, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: ['either "id" or "rule_id" must be set'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts index 5e2382cfe640a75..ae241a1f8f62bef 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts @@ -47,9 +47,10 @@ export const deleteRulesRoute = ( try { const { id, rule_id: ruleId } = request.query; - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; const rule = await readRules({ isRuleRegistryEnabled, rulesClient, id, ruleId }); const migratedRule = await legacyMigrate({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts index de66a6e5a9d993a..22ca1f84d47c220 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts @@ -45,9 +45,9 @@ export const exportRulesRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const exceptionsClient = context.lists?.getExceptionListClient(); - const savedObjectsClient = context.core.savedObjects.client; + const rulesClient = (await context.alerting).getRulesClient(); + const exceptionsClient = (await context.lists)?.getExceptionListClient(); + const savedObjectsClient = (await context.core).savedObjects.client; try { const exportSizeLimit = config.maxRuleImportExportSize; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts index 6183bc78b916082..bc143bf1c3943d7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts @@ -45,7 +45,10 @@ describe.each([ describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getFindRequest(), context); + const response = await server.inject( + getFindRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -53,7 +56,10 @@ describe.each([ clients.rulesClient.find.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getFindRequest(), context); + const response = await server.inject( + getFindRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts index e3749888c2d8f2d..8927cb018fecbbe 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts @@ -49,9 +49,10 @@ export const findRulesRoute = ( try { const { query } = request; - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const ctx = await context.resolve(['core', 'securitySolution', 'alerting']); + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; const rules = await findRules({ isRuleRegistryEnabled, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts index 10be2ac921c10cb..d3db8e598f2798a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts @@ -95,7 +95,10 @@ describe.each([ describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getPrepackagedRulesStatusRequest(), context); + const response = await server.inject( + getPrepackagedRulesStatusRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -103,7 +106,10 @@ describe.each([ clients.rulesClient.find.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getPrepackagedRulesStatusRequest(), context); + const response = await server.inject( + getPrepackagedRulesStatusRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -116,7 +122,7 @@ describe.each([ test('0 rules installed, 0 custom rules, 1 rules not installed, and 1 rule not updated', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); const request = getPrepackagedRulesStatusRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -133,7 +139,7 @@ describe.each([ test('1 rule installed, 1 custom rules, 0 rules not installed, and 1 rule to not updated', async () => { clients.rulesClient.find.mockResolvedValue(getFindResultWithSingleHit(isRuleRegistryEnabled)); const request = getPrepackagedRulesStatusRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -153,7 +159,7 @@ describe.each([ mockCheckTimelinesStatusBeforeInstallResult ); const request = getPrepackagedRulesStatusRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -173,7 +179,7 @@ describe.each([ mockCheckTimelinesStatusAfterInstallResult ); const request = getPrepackagedRulesStatusRequest(); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts index 4fcf1bd992c6a82..98464c4c6850b48 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts @@ -45,8 +45,9 @@ export const getPrepackagedRulesStatusRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const savedObjectsClient = context.core.savedObjects.client; - const rulesClient = context.alerting.getRulesClient(); + const ctx = await context.resolve(['core', 'alerting']); + const savedObjectsClient = ctx.core.savedObjects.client; + const rulesClient = ctx.alerting.getRulesClient(); const ruleAssetsClient = ruleAssetSavedObjectsClientFactory(savedObjectsClient); try { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.test.ts index b24789d77a9bb93..37b1f413286743f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.test.ts @@ -30,7 +30,10 @@ describe('getRuleExecutionEventsRoute', () => { const executionEvents = getAggregateExecutionEvents(); clients.ruleExecutionLog.getAggregateExecutionEvents.mockResolvedValue(executionEvents); - const response = await server.inject(getRuleExecutionEventsRequest(), context); + const response = await server.inject( + getRuleExecutionEventsRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(executionEvents); @@ -41,7 +44,10 @@ describe('getRuleExecutionEventsRoute', () => { it('returns 500 response with it', async () => { clients.ruleExecutionLog.getAggregateExecutionEvents.mockRejectedValue(new Error('Boom!')); - const response = await server.inject(getRuleExecutionEventsRequest(), context); + const response = await server.inject( + getRuleExecutionEventsRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.ts index 76088cd07b80ede..6bd6610c9c91209 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_rule_execution_events_route.ts @@ -48,7 +48,7 @@ export const getRuleExecutionEventsRoute = (router: SecuritySolutionPluginRouter const siemResponse = buildSiemResponse(response); try { - const executionLog = context.securitySolution.getRuleExecutionLog(); + const executionLog = (await context.securitySolution).getRuleExecutionLog(); const { events, total } = await executionLog.getAggregateExecutionEvents({ ruleId, start, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts index 63c25da1c2d4c7a..4f3113f443eb21d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts @@ -62,7 +62,7 @@ describe.each([ describe('status codes', () => { test('returns 200 when importing a single rule with a valid actionClient and alertClient', async () => { - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); @@ -70,7 +70,10 @@ describe.each([ test('returns 500 if more than 10,000 rules are imported', async () => { const ruleIds = new Array(10001).fill(undefined).map((__, index) => `rule-${index}`); const multiRequest = getImportRulesRequest(buildHapiStream(ruleIdsToNdJsonString(ruleIds))); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -88,7 +91,7 @@ describe.each([ .mockResolvedValue({ valid: false, message: 'mocked validation message' }), }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [ @@ -114,7 +117,7 @@ describe.each([ .mockImplementation(() => { throw new Error('Test error'); }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', status_code: 500 }); @@ -128,7 +131,7 @@ describe.each([ getBasicNoShardsSearchResponse() ) ); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(isRuleRegistryEnabled ? 200 : 400); if (!isRuleRegistryEnabled) { expect(response.body).toEqual({ @@ -146,7 +149,7 @@ describe.each([ }) ); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -157,7 +160,7 @@ describe.each([ test('returns 400 if file extension type is not .ndjson', async () => { const requestPayload = buildHapiStream(ruleIdsToNdJsonString(['rule-1']), 'wrong.html'); const badRequest = getImportRulesRequest(requestPayload); - const response = await server.inject(badRequest, context); + const response = await server.inject(badRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: 'Invalid file extension .html', status_code: 400 }); @@ -169,7 +172,7 @@ describe.each([ clients.rulesClient.create.mockResolvedValue( getAlertMock(isRuleRegistryEnabled, getQueryRuleParams()) ); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [], @@ -184,7 +187,7 @@ describe.each([ test('returns reported conflict if error parsing rule', async () => { const requestPayload = buildHapiStream('this is not a valid ndjson string!'); const badRequest = getImportRulesRequest(requestPayload); - const response = await server.inject(badRequest, context); + const response = await server.inject(badRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -210,7 +213,7 @@ describe.each([ clients.rulesClient.find.mockResolvedValue( getFindResultWithSingleHit(isRuleRegistryEnabled) ); // extant rule - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -238,7 +241,10 @@ describe.each([ const overwriteRequest = getImportRulesRequestOverwriteTrue( buildHapiStream(ruleIdsToNdJsonString(['rule-1'])) ); - const response = await server.inject(overwriteRequest, context); + const response = await server.inject( + overwriteRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -258,7 +264,10 @@ describe.each([ const multiRequest = getImportRulesRequest( buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-2'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -274,7 +283,10 @@ describe.each([ test('returns 200 if many rules are imported successfully', async () => { const ruleIds = new Array(9999).fill(undefined).map((__, index) => `rule-${index}`); const multiRequest = getImportRulesRequest(buildHapiStream(ruleIdsToNdJsonString(ruleIds))); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -298,7 +310,7 @@ describe.each([ const badPayload = buildHapiStream(rulesToNdJsonString(rulesWithoutRuleIds)); const badRequest = getImportRulesRequest(badPayload); - const response = await server.inject(badRequest, context); + const response = await server.inject(badRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -331,7 +343,10 @@ describe.each([ const multiRequest = getImportRulesRequest( buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-1'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ @@ -357,7 +372,10 @@ describe.each([ buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-1'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [], @@ -381,7 +399,10 @@ describe.each([ const multiRequest = getImportRulesRequest( buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-2', 'rule-3'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [ @@ -405,7 +426,10 @@ describe.each([ const multiRequest = getImportRulesRequestOverwriteTrue( buildHapiStream(ruleIdsToNdJsonString(['rule-1', 'rule-2', 'rule-3'])) ); - const response = await server.inject(multiRequest, context); + const response = await server.inject( + multiRequest, + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ errors: [], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts index b0f09a8c76d3cea..6eabed2f9dd3af6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts @@ -76,18 +76,27 @@ export const importRulesRoute = ( const siemResponse = buildSiemResponse(response); try { - const rulesClient = context.alerting.getRulesClient(); - const actionsClient = context.actions.getActionsClient(); - const esClient = context.core.elasticsearch.client; - const actionSOClient = context.core.savedObjects.getClient({ + const ctx = await context.resolve([ + 'core', + 'securitySolution', + 'alerting', + 'actions', + 'lists', + 'licensing', + ]); + + const rulesClient = ctx.alerting.getRulesClient(); + const actionsClient = ctx.actions.getActionsClient(); + const esClient = ctx.core.elasticsearch.client; + const actionSOClient = ctx.core.savedObjects.getClient({ includedHiddenTypes: ['action'], }); - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); - const exceptionsClient = context.lists?.getExceptionListClient(); + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); + const exceptionsClient = ctx.lists?.getExceptionListClient(); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, @@ -172,7 +181,7 @@ export const importRulesRoute = ( savedObjectsClient, exceptionsClient, isRuleRegistryEnabled, - spaceId: context.securitySolution.getSpaceId(), + spaceId: ctx.securitySolution.getSpaceId(), signalsIndex, existingLists: foundReferencedExceptionLists, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts index 728c5c479007bdb..6b6e65329c06fb8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts @@ -56,8 +56,8 @@ export const legacyCreateLegacyNotificationRoute = ( }, }, async (context, request, response) => { - const rulesClient = context.alerting.getRulesClient(); - const savedObjectsClient = context.core.savedObjects.client; + const rulesClient = (await context.alerting).getRulesClient(); + const savedObjectsClient = (await context.core).savedObjects.client; const { alert_id: ruleAlertId } = request.query; const { actions, interval, name } = request.body; try { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts index 8285c2dad45a8cd..f09763f8dec103a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts @@ -50,13 +50,19 @@ describe.each([ describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getPatchBulkRequest(), context); + const response = await server.inject( + getPatchBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns an error in the response when updating a single rule that does not exist', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getPatchBulkRequest(), context); + const response = await server.inject( + getPatchBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -79,7 +85,7 @@ describe.each([ }, ], }); - await server.inject(request, context); + await server.inject(request, requestContextMock.convertContext(context)); expect(clients.rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -104,7 +110,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_UPDATE, body: [typicalMlRulePayload()], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ @@ -130,7 +136,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_UPDATE, body: [payloadWithoutType], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ @@ -152,7 +158,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_UPDATE, body: [{ ...getCreateRulesSchemaMock(), rule_id: undefined }], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts index a0ed8abb8b9aafe..7e103d13635a981 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts @@ -54,12 +54,14 @@ export const patchRulesBulkRoute = ( const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts index 51bced3480f282d..f8f6e3917143063 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts @@ -53,13 +53,19 @@ describe.each([ describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getPatchRequest(), context); + const response = await server.inject( + getPatchRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 404 when updating a single rule that does not exist', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getPatchRequest(), context); + const response = await server.inject( + getPatchRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ message: 'rule_id: "rule-1" not found', @@ -69,7 +75,10 @@ describe.each([ test('returns error if requesting a non-rule', async () => { clients.rulesClient.find.mockResolvedValue(nonRuleFindResult(isRuleRegistryEnabled)); - const response = await server.inject(getPatchRequest(), context); + const response = await server.inject( + getPatchRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ message: expect.stringContaining('not found'), @@ -81,7 +90,10 @@ describe.each([ clients.rulesClient.update.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getPatchRequest(), context); + const response = await server.inject( + getPatchRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -100,7 +112,7 @@ describe.each([ machine_learning_job_id: 'some_job_id', }, }); - await server.inject(request, context); + await server.inject(request, requestContextMock.convertContext(context)); expect(clients.rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -125,7 +137,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, body: typicalMlRulePayload(), }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(403); expect(response.body).toEqual({ @@ -146,7 +158,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, body: payloadWithoutType, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(403); expect(response.body).toEqual({ @@ -163,7 +175,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, body: { ...getPatchRulesSchemaMock(), rule_id: undefined }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ message: ['either "id" or "rule_id" must be set'], status_code: 400, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts index a5bc76cc5ef2ef6..6516d612de3b78f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts @@ -106,12 +106,12 @@ export const patchRulesRoute = ( const actions: RuleAlertAction[] = actionsRest as RuleAlertAction[]; const filters: PartialFilter[] | undefined = filtersRest as PartialFilter[]; - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const rulesClient = (await context.alerting).getRulesClient(); + const ruleExecutionLog = (await context.securitySolution).getRuleExecutionLog(); + const savedObjectsClient = (await context.core).savedObjects.client; const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: (await context.licensing).license, ml, request, savedObjectsClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts index e7e960e83245893..b250af78968a8a2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts @@ -49,7 +49,10 @@ describe.each([ describe('status codes', () => { it('returns 200 when performing bulk action with all dependencies present', async () => { - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ success: true, @@ -67,7 +70,10 @@ describe.each([ it("returns 200 when provided filter query doesn't match any rules", async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ success: true, @@ -87,7 +93,10 @@ describe.each([ clients.rulesClient.find.mockResolvedValue( getFindResultWithMultiHits({ data: [], total: Infinity }) ); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: 'More than 10000 rules matched the filter query. Try to narrow it down.', @@ -105,7 +114,10 @@ describe.each([ }) ); - const response = await server.inject(getBulkActionEditRequest(), context); + const response = await server.inject( + getBulkActionEditRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -138,7 +150,10 @@ describe.each([ clients.rulesClient.disable.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Bulk edit failed', @@ -172,7 +187,10 @@ describe.each([ .fn() .mockResolvedValue({ valid: false, message: 'mocked validation message' }), }); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -222,7 +240,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -273,7 +291,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -325,7 +343,10 @@ describe.each([ .mockImplementationOnce(() => ({ valid: true })) .mockImplementationOnce(() => ({ valid: true })), }); - const response = await server.inject(getBulkActionEditRequest(), context); + const response = await server.inject( + getBulkActionEditRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -372,7 +393,10 @@ describe.each([ clients.rulesClient.disable.mockImplementation(async () => { throw new Error('a'.repeat(1_300)); }); - const response = await server.inject(getBulkActionRequest(), context); + const response = await server.inject( + getBulkActionRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body.attributes.errors[0].message.length).toEqual(1000); }); @@ -392,7 +416,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); expect(response.body).toEqual({ @@ -489,7 +513,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body.message).toEqual('More than 100 ids sent for bulk edit action.'); @@ -506,7 +530,7 @@ describe.each([ }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body.message).toEqual( @@ -524,7 +548,10 @@ describe.each([ }) ); - const response = await server.inject(getBulkActionEditRequest(), context); + const response = await server.inject( + getBulkActionEditRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts index e5b7dc2ef85ed36..b9009fd14a8ae93 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts @@ -270,13 +270,21 @@ export const performBulkActionRoute = ( request.events.completed$.subscribe(() => abortController.abort()); try { - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const exceptionsClient = context.lists?.getExceptionListClient(); - const savedObjectsClient = context.core.savedObjects.client; + const ctx = await context.resolve([ + 'core', + 'securitySolution', + 'alerting', + 'licensing', + 'lists', + ]); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const exceptionsClient = ctx.lists?.getExceptionListClient(); + const savedObjectsClient = ctx.core.savedObjects.client; const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts index c9cc0cad0a65ff3..587be0bfe9b08e4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts @@ -80,14 +80,15 @@ export const previewRulesRoute = async ( async (context, request, response) => { const siemResponse = buildSiemResponse(response); const validationErrors = createRuleValidateTypeDependents(request.body); + const coreContext = await context.core; if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); } try { const [, { data, security: securityService }] = await getStartServices(); const searchSourceClient = data.search.searchSource.asScoped(request); - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + const savedObjectsClient = coreContext.savedObjects.client; + const siemClient = (await context.securitySolution).getAppClient(); let invocationCount = request.body.invocationCount; if ( @@ -107,13 +108,15 @@ export const previewRulesRoute = async ( const previewRuleParams = internalRule.params; const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: (await context.licensing).license, ml, request, savedObjectsClient, }); throwAuthzError(await mlAuthz.validateRuleType(internalRule.params.type)); - await context.lists?.getExceptionListClient().createEndpointList(); + + const listsContext = await context.lists; + await listsContext?.getExceptionListClient().createEndpointList(); const spaceId = siemClient.getSpaceId(); const previewId = uuid.v4(); @@ -234,13 +237,13 @@ export const previewRulesRoute = async ( shouldWriteAlerts, shouldStopExecution: () => false, alertFactory, - savedObjectsClient: context.core.savedObjects.client, + savedObjectsClient: coreContext.savedObjects.client, scopedClusterClient: wrapScopedClusterClient({ abortController, - scopedClusterClient: context.core.elasticsearch.client, + scopedClusterClient: coreContext.elasticsearch.client, }), searchSourceClient, - uiSettingsClient: context.core.uiSettings.client, + uiSettingsClient: coreContext.uiSettings.client, }, spaceId, startedAt: startedAt.toDate(), @@ -339,7 +342,7 @@ export const previewRulesRoute = async ( } // Refreshes alias to ensure index is able to be read before returning - await context.core.elasticsearch.client.asInternalUser.indices.refresh( + await coreContext.elasticsearch.client.asInternalUser.indices.refresh( { index: previewRuleDataClient.indexNameWithNamespace(spaceId), }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts index c802f9857ce5057..dc5cbec2e26dfbd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts @@ -53,12 +53,18 @@ describe.each([ describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getReadRequest(), context); + const response = await server.inject( + getReadRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when reading a single rule outcome === exactMatch', async () => { - const response = await server.inject(getReadRequestWithId(myFakeId), context); + const response = await server.inject( + getReadRequestWithId(myFakeId), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -70,7 +76,10 @@ describe.each([ id: myFakeId, outcome: 'aliasMatch', }); - const response = await server.inject(getReadRequestWithId(myFakeId), context); + const response = await server.inject( + getReadRequestWithId(myFakeId), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -83,14 +92,20 @@ describe.each([ outcome: 'conflict', alias_target_id: 'myaliastargetid', }); - const response = await server.inject(getReadRequestWithId(myFakeId), context); + const response = await server.inject( + getReadRequestWithId(myFakeId), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body.alias_target_id).toEqual('myaliastargetid'); }); test('returns error if requesting a non-rule', async () => { clients.rulesClient.find.mockResolvedValue(nonRuleFindResult(isRuleRegistryEnabled)); - const response = await server.inject(getReadRequest(), context); + const response = await server.inject( + getReadRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ message: 'rule_id: "rule-1" not found', @@ -102,7 +117,10 @@ describe.each([ clients.rulesClient.find.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getReadRequest(), context); + const response = await server.inject( + getReadRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -119,7 +137,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_URL, query: { rule_id: 'DNE_RULE' }, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(404); expect(response.body).toEqual({ message: 'rule_id: "DNE_RULE" not found', status_code: 404 }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts index e1d24677ff4cfdf..0b3852c29832975 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts @@ -49,9 +49,9 @@ export const readRulesRoute = ( const { id, rule_id: ruleId } = request.query; try { - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; + const rulesClient = (await context.alerting).getRulesClient(); + const ruleExecutionLog = (await context.securitySolution).getRuleExecutionLog(); + const savedObjectsClient = (await context.core).savedObjects.client; const rule = await readRules({ id, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts index 21ac33e294008f7..a1342d86a328d70 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts @@ -50,7 +50,10 @@ describe.each([ describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getUpdateBulkRequest(), context); + const response = await server.inject( + getUpdateBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -62,7 +65,10 @@ describe.each([ rule_id: 'rule-1', }, ]; - const response = await server.inject(getUpdateBulkRequest(), context); + const response = await server.inject( + getUpdateBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(expected); @@ -79,7 +85,10 @@ describe.each([ rule_id: 'rule-1', }, ]; - const response = await server.inject(getUpdateBulkRequest(), context); + const response = await server.inject( + getUpdateBulkRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(expected); }); @@ -96,7 +105,7 @@ describe.each([ body: [typicalMlRulePayload()], }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); expect(response.body).toEqual([ { @@ -117,7 +126,7 @@ describe.each([ path: DETECTION_ENGINE_RULES_BULK_UPDATE, body: [{ ...getCreateRulesSchemaMock(), rule_id: undefined }], }); - const response = await server.inject(noIdRequest, context); + const response = await server.inject(noIdRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual([ { error: { message: 'either "id" or "rule_id" must be set', status_code: 400 }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts index 0f9bc3535dc5708..b476a4c8b350da8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts @@ -48,13 +48,15 @@ export const updateRulesBulkRoute = ( const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting.getRulesClient(); - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); + + const rulesClient = ctx.alerting.getRulesClient(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts index 8a7a09a80c7437a..a8e9924c91b7a33 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts @@ -54,13 +54,19 @@ describe.each([ describe('status codes', () => { test('returns 200', async () => { - const response = await server.inject(getUpdateRequest(), context); + const response = await server.inject( + getUpdateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 404 when updating a single rule that does not exist', async () => { clients.rulesClient.find.mockResolvedValue(getEmptyFindResult()); - const response = await server.inject(getUpdateRequest(), context); + const response = await server.inject( + getUpdateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ @@ -71,7 +77,10 @@ describe.each([ test('returns error when updating non-rule', async () => { clients.rulesClient.find.mockResolvedValue(nonRuleFindResult(isRuleRegistryEnabled)); - const response = await server.inject(getUpdateRequest(), context); + const response = await server.inject( + getUpdateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(404); expect(response.body).toEqual({ @@ -84,7 +93,10 @@ describe.each([ clients.rulesClient.find.mockImplementation(async () => { throw new Error('Test error'); }); - const response = await server.inject(getUpdateRequest(), context); + const response = await server.inject( + getUpdateRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -104,7 +116,7 @@ describe.each([ body: typicalMlRulePayload(), }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(403); expect(response.body).toEqual({ message: 'mocked validation message', @@ -123,7 +135,7 @@ describe.each([ id: undefined, }, }); - const response = await server.inject(noIdRequest, context); + const response = await server.inject(noIdRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ message: ['either "id" or "rule_id" must be set'], status_code: 400, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts index 8ac90748d92176a..817a6468a355c2b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts @@ -44,12 +44,14 @@ export const updateRulesRoute = ( return siemResponse.error({ statusCode: 400, body: validationErrors }); } try { - const rulesClient = context.alerting.getRulesClient(); - const savedObjectsClient = context.core.savedObjects.client; - const siemClient = context.securitySolution.getAppClient(); + const ctx = await context.resolve(['core', 'securitySolution', 'alerting', 'licensing']); + + const rulesClient = ctx.alerting.getRulesClient(); + const savedObjectsClient = ctx.core.savedObjects.client; + const siemClient = ctx.securitySolution.getAppClient(); const mlAuthz = buildMlAuthz({ - license: context.licensing.license, + license: ctx.licensing.license, ml, request, savedObjectsClient, @@ -76,7 +78,7 @@ export const updateRulesRoute = ( }); if (rule != null) { - const ruleExecutionLog = context.securitySolution.getRuleExecutionLog(); + const ruleExecutionLog = ctx.securitySolution.getRuleExecutionLog(); const ruleExecutionSummary = await ruleExecutionLog.getExecutionSummary(rule.id); const [validated, errors] = transformValidate( rule, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts index 8da147d64a6cf05..df4ff25e9c640b4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts @@ -39,9 +39,12 @@ export const createSignalsMigrationRoute = ( const { index: indices, ...reindexOptions } = request.body; try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; - const appClient = context.securitySolution?.getAppClient(); + const core = await context.core; + const securitySolution = await context.securitySolution; + + const esClient = core.elasticsearch.client.asCurrentUser; + const soClient = core.savedObjects.client; + const appClient = securitySolution?.getAppClient(); if (!appClient) { return siemResponse.error({ statusCode: 404 }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts index 65ed42a0a166e4d..f94aff365f496ef 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts @@ -35,9 +35,12 @@ export const deleteSignalsMigrationRoute = ( const { migration_ids: migrationIds } = request.body; try { - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; - const appClient = context.securitySolution?.getAppClient(); + const core = await context.core; + const securitySolution = await context.securitySolution; + + const esClient = core.elasticsearch.client.asCurrentUser; + const soClient = core.savedObjects.client; + const appClient = securitySolution?.getAppClient(); if (!appClient) { return siemResponse.error({ statusCode: 404 }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts index a6f5f28fce8e4d3..6029ad8e86bbc3e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts @@ -35,12 +35,16 @@ export const finalizeSignalsMigrationRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; + + const core = await context.core; + const securitySolution = await context.securitySolution; + + const esClient = core.elasticsearch.client.asCurrentUser; + const soClient = core.savedObjects.client; const { migration_ids: migrationIds } = request.body; try { - const appClient = context.securitySolution?.getAppClient(); + const appClient = securitySolution?.getAppClient(); if (!appClient) { return siemResponse.error({ statusCode: 404 }); } @@ -55,7 +59,7 @@ export const finalizeSignalsMigrationRoute = ( soClient, }); - const spaceId = context.securitySolution.getSpaceId(); + const spaceId = securitySolution.getSpaceId(); const signalsAlias = ruleDataService.getResourceName(`security.alerts-${spaceId}`); const finalizeResults = await Promise.all( migrations.map(async (migration) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/get_signals_migration_status_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/get_signals_migration_status_route.ts index d800cead20cdc7d..f23bf4ae4185ec5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/get_signals_migration_status_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/get_signals_migration_status_route.ts @@ -31,11 +31,15 @@ export const getSignalsMigrationStatusRoute = (router: SecuritySolutionPluginRou }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const esClient = context.core.elasticsearch.client.asCurrentUser; - const soClient = context.core.savedObjects.client; + + const core = await context.core; + const securitySolution = await context.securitySolution; + + const esClient = core.elasticsearch.client.asCurrentUser; + const soClient = core.savedObjects.client; try { - const appClient = context.securitySolution?.getAppClient(); + const appClient = securitySolution?.getAppClient(); if (!appClient) { return siemResponse.error({ statusCode: 404 }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts index 9cc93bc7f590570..5a46d7a9b55f6e2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts @@ -44,12 +44,18 @@ describe('set signal status', () => { describe('status on signal', () => { test('returns 200 when setting a status on a signal by ids', async () => { - const response = await server.inject(getSetSignalStatusByIdsRequest(), context); + const response = await server.inject( + getSetSignalStatusByIdsRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('returns 200 when setting a status on a signal by query', async () => { - const response = await server.inject(getSetSignalStatusByQueryRequest(), context); + const response = await server.inject( + getSetSignalStatusByQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); @@ -68,7 +74,10 @@ describe('set signal status', () => { context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockRejectedValue( new Error('Test error') ); - const response = await server.inject(getSetSignalStatusByQueryRequest(), context); + const response = await server.inject( + getSetSignalStatusByQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -106,7 +115,7 @@ describe('set signal status', () => { path: DETECTION_ENGINE_SIGNALS_STATUS_URL, body: setStatusSignalMissingIdsAndQueryPayload(), }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: ['either "signal_ids" or "query" must be set'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index 8482dd3b94e18bb..63b90ccc4cfc75d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -49,11 +49,13 @@ export const setSignalsStatusRoute = ( }, async (context, request, response) => { const { conflicts, signal_ids: signalIds, query, status } = request.body; - const esClient = context.core.elasticsearch.client.asCurrentUser; - const siemClient = context.securitySolution?.getAppClient(); + const core = await context.core; + const securitySolution = await context.securitySolution; + const esClient = core.elasticsearch.client.asCurrentUser; + const siemClient = securitySolution?.getAppClient(); const siemResponse = buildSiemResponse(response); const validationErrors = setSignalStatusValidateTypeDependents(request.body); - const spaceId = context.securitySolution?.getSpaceId() ?? 'default'; + const spaceId = securitySolution?.getSpaceId() ?? 'default'; if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.test.ts index b3de63e6d278c8e..8a8af78a9b86e31 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.test.ts @@ -35,7 +35,10 @@ describe('query for signal', () => { describe('query and agg on signals index', () => { test('returns 200 when using single query', async () => { - const response = await server.inject(getSignalsQueryRequest(), context); + const response = await server.inject( + getSignalsQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(ruleDataClient.getReader().search).toHaveBeenCalledWith( @@ -46,7 +49,10 @@ describe('query for signal', () => { }); test('returns 200 when using single agg', async () => { - const response = await server.inject(getSignalsAggsQueryRequest(), context); + const response = await server.inject( + getSignalsAggsQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(ruleDataClient.getReader().search).toHaveBeenCalledWith( @@ -55,7 +61,10 @@ describe('query for signal', () => { }); test('returns 200 when using aggs and query together', async () => { - const response = await server.inject(getSignalsAggsAndQueryRequest(), context); + const response = await server.inject( + getSignalsAggsAndQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(ruleDataClient.getReader().search).toHaveBeenCalledWith( @@ -70,7 +79,10 @@ describe('query for signal', () => { test('catches error if query throws error', async () => { ruleDataClient.getReader().search.mockRejectedValue(new Error('Test error')); - const response = await server.inject(getSignalsAggsQueryRequest(), context); + const response = await server.inject( + getSignalsAggsQueryRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', @@ -120,7 +132,7 @@ describe('query for signal', () => { path: DETECTION_ENGINE_QUERY_SIGNALS_URL, body: {}, }); - const response = await server.inject(request, context); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.status).toEqual(400); expect(response.body).toEqual({ message: '"value" must have at least 1 children', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts index 3740d187347b61a..7b8216084ac9d34 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts @@ -52,20 +52,19 @@ export const querySignalsRoute = ( } try { - const result = await ruleDataClient - ?.getReader({ namespace: context.securitySolution.getSpaceId() }) - .search({ - body: { - query, - // Note: I use a spread operator to please TypeScript with aggs: { ...aggs } - aggs: { ...aggs }, - _source, - track_total_hits, - size, - runtime_mappings: runtime_mappings as MappingRuntimeFields, - }, - ignore_unavailable: true, - }); + const spaceId = (await context.securitySolution).getSpaceId(); + const result = await ruleDataClient?.getReader({ namespace: spaceId }).search({ + body: { + query, + // Note: I use a spread operator to please TypeScript with aggs: { ...aggs } + aggs: { ...aggs }, + _source, + track_total_hits, + size, + runtime_mappings: runtime_mappings as MappingRuntimeFields, + }, + ignore_unavailable: true, + }); return response.ok({ body: result }); } catch (err) { // error while getting or updating signal with id: id in signal index .siem-signals diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts index 04464e5d6f5a72b..87bfa3fcbac9032 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts @@ -26,7 +26,7 @@ export const readTagsRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const rulesClient = context.alerting?.getRulesClient(); + const rulesClient = (await context.alerting)?.getRulesClient(); if (!rulesClient) { return siemResponse.error({ statusCode: 404 }); diff --git a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.test.ts b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.test.ts index 08523d2e0334064..232aba9d1ae3a3c 100644 --- a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.test.ts @@ -137,7 +137,10 @@ describe('sourcerer route', () => { }); test('returns sourcerer formatted Data Views when SIEM Data View does NOT exist', async () => { createSourcererDataViewRoute(server.router, getStartServicesNotSiem); - const response = await server.inject(getSourcererRequest(mockPatternList), context); + const response = await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(mockDataViewsTransformed); }); @@ -163,7 +166,10 @@ describe('sourcerer route', () => { }, ] as unknown) as StartServicesAccessor; createSourcererDataViewRoute(server.router, getStartServicesSpecial); - const response = await server.inject(getSourcererRequest(mockPatternList), context); + const response = await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(mockDataViewsTransformed); }); @@ -192,14 +198,20 @@ describe('sourcerer route', () => { }, ] as unknown) as StartServicesAccessor; createSourcererDataViewRoute(server.router, getStartServicesSpecial); - await server.inject(getSourcererRequest(mockPatternList), context); + await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(mockCreateAndSave).toHaveBeenCalled(); expect(mockCreateAndSave.mock.calls[0][1]).toEqual(true); }); test('returns sourcerer formatted Data Views when SIEM Data View exists', async () => { createSourcererDataViewRoute(server.router, getStartServices); - const response = await server.inject(getSourcererRequest(mockPatternList), context); + const response = await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual(mockDataViewsTransformed); }); @@ -207,7 +219,10 @@ describe('sourcerer route', () => { test('returns sourcerer formatted Data Views when SIEM Data View exists and patternList input is changed', async () => { createSourcererDataViewRoute(server.router, getStartServices); mockPatternList.shift(); - const response = await server.inject(getSourcererRequest(mockPatternList), context); + const response = await server.inject( + getSourcererRequest(mockPatternList), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); expect(response.body).toEqual({ defaultDataView: { diff --git a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.ts b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.ts index 4ce0f7be20956b3..bf69ed03fb79aff 100644 --- a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.ts +++ b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/index.ts @@ -34,7 +34,8 @@ export const createSourcererDataViewRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const siemClient = context.securitySolution?.getAppClient(); + const coreContext = await context.core; + const siemClient = (await context.securitySolution)?.getAppClient(); const dataViewId = siemClient.getSourcererDataViewId(); try { @@ -46,8 +47,8 @@ export const createSourcererDataViewRoute = ( ] = await getStartServices(); const dataViewService = await indexPatterns.dataViewsServiceFactory( - context.core.savedObjects.client, - context.core.elasticsearch.client.asCurrentUser, + coreContext.savedObjects.client, + coreContext.elasticsearch.client.asCurrentUser, request, true ); @@ -103,7 +104,7 @@ export const createSourcererDataViewRoute = ( const defaultDataView = await buildSourcererDataView( siemDataView, - context.core.elasticsearch.client.asCurrentUser + coreContext.elasticsearch.client.asCurrentUser ); return response.ok({ body: { @@ -143,6 +144,7 @@ export const getSourcererDataViewRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); + const coreContext = await context.core; const { dataViewId } = request.query; try { const [ @@ -153,8 +155,8 @@ export const getSourcererDataViewRoute = ( ] = await getStartServices(); const dataViewService = await indexPatterns.dataViewsServiceFactory( - context.core.savedObjects.client, - context.core.elasticsearch.client.asCurrentUser, + coreContext.savedObjects.client, + coreContext.elasticsearch.client.asCurrentUser, request, true ); @@ -163,7 +165,7 @@ export const getSourcererDataViewRoute = ( const kibanaDataView = siemDataView ? await buildSourcererDataView( siemDataView, - context.core.elasticsearch.client.asCurrentUser + coreContext.elasticsearch.client.asCurrentUser ) : {}; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/clean_draft_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/clean_draft_timelines/index.test.ts index 3d66a6507a67bc3..1a62b7604bfd7b6 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/clean_draft_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/clean_draft_timelines/index.test.ts @@ -82,7 +82,10 @@ describe('clean draft timelines', () => { timeline: [], }); - const response = await server.inject(cleanDraftTimelinesRequest(TimelineType.default), context); + const response = await server.inject( + cleanDraftTimelinesRequest(TimelineType.default), + requestContextMock.convertContext(context) + ); const req = cleanDraftTimelinesRequest(TimelineType.default); expect(mockPersistTimeline).toHaveBeenCalled(); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ @@ -106,7 +109,10 @@ describe('clean draft timelines', () => { mockResetTimeline.mockResolvedValue({}); mockGetTimeline.mockResolvedValue({ ...mockGetDraftTimelineValue }); - const response = await server.inject(cleanDraftTimelinesRequest(TimelineType.default), context); + const response = await server.inject( + cleanDraftTimelinesRequest(TimelineType.default), + requestContextMock.convertContext(context) + ); const req = cleanDraftTimelinesRequest(TimelineType.default); expect(mockPersistTimeline).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/get_draft_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/get_draft_timelines/index.test.ts index 1911f964af4b103..cb488ef7d84ac1b 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/get_draft_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/draft_timelines/get_draft_timelines/index.test.ts @@ -83,7 +83,7 @@ describe('get draft timelines', () => { timeline: [], }); const req = getDraftTimelinesRequest(TimelineType.default); - const response = await server.inject(req, context); + const response = await server.inject(req, requestContextMock.convertContext(context)); expect(mockPersistTimeline).toHaveBeenCalled(); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ ...draftTimelineDefaults, @@ -107,7 +107,7 @@ describe('get draft timelines', () => { const response = await server.inject( getDraftTimelinesRequest(TimelineType.default), - context + requestContextMock.convertContext(context) ); expect(mockPersistTimeline).not.toHaveBeenCalled(); expect(response.status).toEqual(200); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.test.ts index 63e8d9afea9d874..6e0921eae8b290f 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.test.ts @@ -57,7 +57,11 @@ describe.each([ }); const request = addPrepackagedRulesRequest(); - frameworkRequest = await buildFrameworkRequest(context, securitySetup, request); + frameworkRequest = await buildFrameworkRequest( + requestContextMock.convertContext(context), + securitySetup, + request + ); }); afterEach(() => { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/index.test.ts index 55f4a06326fe125..34a26b977e38ef3 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/index.test.ts @@ -64,7 +64,10 @@ describe('installPrepackagedTimelines', () => { mockCheckTimelinesStatusBeforeInstallResult ); - await server.inject(installPrepackedTimelinesRequest(), context); + await server.inject( + installPrepackedTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(installPrepackagedTimelines).toHaveBeenCalled(); }); @@ -81,7 +84,10 @@ describe('installPrepackagedTimelines', () => { timelines_updated: 0, }); - const result = await server.inject(installPrepackedTimelinesRequest(), context); + const result = await server.inject( + installPrepackedTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(result.body).toEqual({ errors: [], @@ -95,7 +101,10 @@ describe('installPrepackagedTimelines', () => { test('should not call installPrepackagedTimelines if it has nothing to install or update', async () => { (checkTimelinesStatus as jest.Mock).mockReturnValue(mockCheckTimelinesStatusAfterInstallResult); - await server.inject(installPrepackedTimelinesRequest(), context); + await server.inject( + installPrepackedTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(installPrepackagedTimelines).not.toHaveBeenCalled(); }); @@ -103,7 +112,10 @@ describe('installPrepackagedTimelines', () => { test('should return success if it has nothing to install or update', async () => { (checkTimelinesStatus as jest.Mock).mockReturnValue(mockCheckTimelinesStatusAfterInstallResult); - const result = await server.inject(installPrepackedTimelinesRequest(), context); + const result = await server.inject( + installPrepackedTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(result.body).toEqual({ errors: [], diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts index 0270d525ae77956..be97cbd01e428bb 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts @@ -69,7 +69,11 @@ describe('createTimelines', () => { const { context } = requestContextMock.createTools(); const mockRequest = getCreateTimelinesRequest(createTimelineWithoutTimelineId); - frameworkRequest = await buildFrameworkRequest(context, securitySetup, mockRequest); + frameworkRequest = await buildFrameworkRequest( + requestContextMock.convertContext(context), + securitySetup, + mockRequest + ); Date.now = jest.fn().mockReturnValue(new Date('2020-11-04T11:37:31.655Z')); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/index.test.ts index 5e066e419c4bbdb..9de715751ca7f2f 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/index.test.ts @@ -93,7 +93,7 @@ describe('create timelines', () => { createTimelinesRoute(server.router, createMockConfig(), securitySetup); const mockRequest = getCreateTimelinesRequest(createTimelineWithoutTimelineId); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); }); test('should Create a new timeline savedObject', async () => { @@ -123,7 +123,7 @@ describe('create timelines', () => { test('returns 200 when create timeline successfully', async () => { const response = await server.inject( getCreateTimelinesRequest(createTimelineWithoutTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -157,7 +157,7 @@ describe('create timelines', () => { test('returns error message', async () => { const response = await server.inject( getCreateTimelinesRequest(createTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.body).toEqual({ message: CREATE_TIMELINE_ERROR_MESSAGE, @@ -195,7 +195,7 @@ describe('create timelines', () => { createTimelinesRoute(server.router, createMockConfig(), securitySetup); const mockRequest = getCreateTimelinesRequest(createTemplateTimelineWithoutTimelineId); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); }); test('should Create a new timeline template savedObject', async () => { @@ -227,7 +227,7 @@ describe('create timelines', () => { test('returns 200 when create timeline successfully', async () => { const response = await server.inject( getCreateTimelinesRequest(createTimelineWithoutTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -264,7 +264,7 @@ describe('create timelines', () => { test('returns error message', async () => { const response = await server.inject( getCreateTimelinesRequest(updateTemplateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.body).toEqual({ message: CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/index.test.ts index d117d3d0c1b4716..cfd61beb4b17439 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/export_timelines/index.test.ts @@ -71,14 +71,20 @@ describe('export timelines', () => { describe('status codes', () => { test('returns 200 when finding selected timelines', async () => { - const response = await server.inject(getExportTimelinesRequest(), context); + const response = await server.inject( + getExportTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(200); }); test('catch error when status search throws error', async () => { clients.savedObjectsClient.bulkGet.mockReset(); clients.savedObjectsClient.bulkGet.mockRejectedValue(new Error('Test error')); - const response = await server.inject(getExportTimelinesRequest(), context); + const response = await server.inject( + getExportTimelinesRequest(), + requestContextMock.convertContext(context) + ); expect(response.status).toEqual(500); expect(response.body).toEqual({ message: 'Test error', diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timeline/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timeline/index.test.ts index 609b26f89be5c0a..c5c8ab6bfb7f22b 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timeline/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timeline/index.test.ts @@ -49,7 +49,10 @@ describe('get timeline', () => { test('should call getTimelineTemplateOrNull if templateTimelineId is given', async () => { const templateTimelineId = '123'; - await server.inject(getTimelineRequest({ template_timeline_id: templateTimelineId }), context); + await server.inject( + getTimelineRequest({ template_timeline_id: templateTimelineId }), + requestContextMock.convertContext(context) + ); expect((getTimelineTemplateOrNull as jest.Mock).mock.calls[0][1]).toEqual(templateTimelineId); }); @@ -57,13 +60,16 @@ describe('get timeline', () => { test('should call getTimelineOrNull if id is given', async () => { const id = '456'; - await server.inject(getTimelineRequest({ id }), context); + await server.inject(getTimelineRequest({ id }), requestContextMock.convertContext(context)); expect((getTimelineOrNull as jest.Mock).mock.calls[0][1]).toEqual(id); }); test('should throw error message if nither templateTimelineId nor id is given', async () => { - const res = await server.inject(getTimelineRequest(), context); + const res = await server.inject( + getTimelineRequest(), + requestContextMock.convertContext(context) + ); expect(res.body.message).toEqual('please provide id or template_timeline_id'); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timelines/index.test.ts index 0298a3f869bd4af..208b804f222dce4 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/get_timelines/index.test.ts @@ -46,13 +46,13 @@ describe('get all timelines', () => { }); test('should get the total count', async () => { - await server.inject(getTimelineRequest(), context); + await server.inject(getTimelineRequest(), requestContextMock.convertContext(context)); expect((getAllTimeline as jest.Mock).mock.calls[0][2]).toEqual({ pageSize: 1, pageIndex: 1 }); }); test('should get all timelines with total count', async () => { (getAllTimeline as jest.Mock).mockResolvedValue({ totalCount: 100 }); - await server.inject(getTimelineRequest(), context); + await server.inject(getTimelineRequest(), requestContextMock.convertContext(context)); expect((getAllTimeline as jest.Mock).mock.calls[1][2]).toEqual({ pageSize: 100, pageIndex: 1 }); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts index d92d82ea82fc2d3..9148c8f5441d1df 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts @@ -158,31 +158,31 @@ describe('import timelines', () => { test('should use given timelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTimeline.mock.calls[0][1]).toEqual(mockUniqueParsedObjects[0].savedObjectId); }); test('should Create a new timeline savedObject', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline).toHaveBeenCalled(); }); test('should Create a new timeline savedObject without timelineId', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][1]).toBeNull(); }); test('should Create a new timeline savedObject without timeline version', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][2]).toBeNull(); }); test('should Create a new timeline savedObject with given timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ ...mockParsedTimelineObject, status: TimelineStatus.active, @@ -202,7 +202,7 @@ describe('import timelines', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -222,13 +222,13 @@ describe('import timelines', () => { test('should Create new pinned events', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline).toHaveBeenCalled(); }); test('should Create a new pinned event with new timeline id', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline.mock.calls[0][1]).toEqual( mockCreatedTimeline.savedObjectId ); @@ -236,7 +236,7 @@ describe('import timelines', () => { test('should Create a new pinned event with pinnedEventId', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline.mock.calls[0][2]).toEqual( mockUniqueParsedObjects[0].pinnedEventIds ); @@ -244,7 +244,7 @@ describe('import timelines', () => { test('should Check if note exists', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetNote.mock.calls[0][1]).toEqual( mockUniqueParsedObjects[0].globalNotes[0].noteId ); @@ -252,19 +252,19 @@ describe('import timelines', () => { test('should Create notes', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote).toHaveBeenCalled(); }); test('should provide no noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should provide new notes with original author info when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: 'original note', @@ -299,7 +299,7 @@ describe('import timelines', () => { mockGetNote.mockRejectedValue(new Error()); const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].note).toEqual({ created: mockUniqueParsedObjects[0].globalNotes[0].created, createdBy: mockUniqueParsedObjects[0].globalNotes[0].createdBy, @@ -331,7 +331,7 @@ describe('import timelines', () => { test('returns 200 when import timeline successfully', async () => { const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); }); @@ -364,7 +364,7 @@ describe('import timelines', () => { test('returns error message', async () => { const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -393,7 +393,7 @@ describe('import timelines', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -422,7 +422,7 @@ describe('import timelines', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -582,7 +582,7 @@ describe('import timeline templates', () => { test('should use given timelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].savedObjectId ); @@ -590,7 +590,7 @@ describe('import timeline templates', () => { test('should use given templateTimelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTemplateTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].templateTimelineId ); @@ -598,25 +598,25 @@ describe('import timeline templates', () => { test('should Create a new timeline savedObject', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline).toHaveBeenCalled(); }); test('should Create a new timeline savedObject without timelineId', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][1]).toBeNull(); }); test('should Create a new timeline savedObject without timeline version', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][2]).toBeNull(); }); test('should Create a new timeline savedObject witn given timeline and skip the omitted fields', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][3]).toEqual({ ...mockParsedTemplateTimelineObject, status: TimelineStatus.active, @@ -625,19 +625,19 @@ describe('import timeline templates', () => { test('should NOT Create new pinned events', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline).not.toHaveBeenCalled(); }); test('should provide no noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should exclude event notes when creating notes', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: mockUniqueParsedTemplateTimelineObjects[0].globalNotes[0].note, @@ -651,7 +651,7 @@ describe('import timeline templates', () => { test('returns 200 when import timeline successfully', async () => { const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); @@ -666,7 +666,7 @@ describe('import timeline templates', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][3].templateTimelineId).toEqual( mockNewTemplateTimelineId ); @@ -684,7 +684,7 @@ describe('import timeline templates', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const result = await server.inject(mockRequest, context); + const result = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(result.body).toEqual({ errors: [], success: true, @@ -727,7 +727,7 @@ describe('import timeline templates', () => { test('should use given timelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].savedObjectId ); @@ -735,7 +735,7 @@ describe('import timeline templates', () => { test('should use given templateTimelineId to check if the timeline savedObject already exist', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockGetTemplateTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].templateTimelineId ); @@ -743,13 +743,13 @@ describe('import timeline templates', () => { test('should UPDATE timeline savedObject', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline).toHaveBeenCalled(); }); test('should UPDATE timeline savedObject with timelineId', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][1]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].savedObjectId ); @@ -757,7 +757,7 @@ describe('import timeline templates', () => { test('should UPDATE timeline savedObject without timeline version', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][2]).toEqual( mockUniqueParsedTemplateTimelineObjects[0].version ); @@ -765,25 +765,25 @@ describe('import timeline templates', () => { test('should UPDATE a new timeline savedObject witn given timeline and skip the omitted fields', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistTimeline.mock.calls[0][3]).toEqual(mockParsedTemplateTimelineObject); }); test('should NOT Create new pinned events', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistPinnedEventOnTimeline).not.toHaveBeenCalled(); }); test('should provide noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should exclude event notes when creating notes', async () => { const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: mockUniqueParsedTemplateTimelineObjects[0].globalNotes[0].note, @@ -797,7 +797,7 @@ describe('import timeline templates', () => { test('returns 200 when import timeline successfully', async () => { const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.status).toEqual(200); }); @@ -812,7 +812,7 @@ describe('import timeline templates', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, @@ -841,7 +841,7 @@ describe('import timeline templates', () => { ], ]); const mockRequest = await getImportTimelinesRequest(); - const response = await server.inject(mockRequest, context); + const response = await server.inject(mockRequest, requestContextMock.convertContext(context)); expect(response.body).toEqual({ success: false, success_count: 0, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.ts index c06d99adf04d05e..4336c9fd934189e 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.ts @@ -46,7 +46,7 @@ export const importTimelinesRoute = ( async (context, request, response) => { try { const siemResponse = buildSiemResponse(response); - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; if (!savedObjectsClient) { return siemResponse.error({ statusCode: 404 }); } diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/patch_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/patch_timelines/index.test.ts index ca3482591407a49..1c7ab73cc380967 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/patch_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/patch_timelines/index.test.ts @@ -90,7 +90,7 @@ describe('update timelines', () => { patchTimelinesRoute(server.router, createMockConfig(), securitySetup); const mockRequest = getUpdateTimelinesRequest(updateTimelineWithTimelineId); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); }); test('should Check if given timeline id exist', async () => { @@ -122,7 +122,7 @@ describe('update timelines', () => { test('returns 200 when create timeline successfully', async () => { const response = await server.inject( getUpdateTimelinesRequest(updateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -157,7 +157,7 @@ describe('update timelines', () => { test('returns error message', async () => { const response = await server.inject( getUpdateTimelinesRequest(updateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.body).toEqual({ message: UPDATE_TIMELINE_ERROR_MESSAGE, @@ -198,7 +198,7 @@ describe('update timelines', () => { patchTimelinesRoute(server.router, createMockConfig(), securitySetup); const mockRequest = getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId); - await server.inject(mockRequest, context); + await server.inject(mockRequest, requestContextMock.convertContext(context)); }); test('should Check if given timeline id exist', async () => { @@ -242,7 +242,7 @@ describe('update timelines', () => { test('returns 200 when create timeline template successfully', async () => { const response = await server.inject( getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.status).toEqual(200); }); @@ -277,7 +277,7 @@ describe('update timelines', () => { test('returns error message', async () => { const response = await server.inject( getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId), - context + requestContextMock.convertContext(context) ); expect(response.body).toEqual({ message: UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts index ecf7b04bc1b1b18..64820711d6685b9 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts @@ -34,7 +34,7 @@ import { timelineSavedObjectType } from '../../saved_object_mappings'; import { noteFieldsMigrator } from './field_migrator'; export const deleteNote = async (request: FrameworkRequest, noteIds: string[]) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; await Promise.all( noteIds.map((noteId) => savedObjectsClient.delete(noteSavedObjectType, noteId)) @@ -47,7 +47,7 @@ export const deleteNoteByTimelineId = async (request: FrameworkRequest, timeline hasReference: { type: timelineSavedObjectType, id: timelineId }, }; const notesToBeDeleted = await getAllSavedNote(request, options); - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; await Promise.all( notesToBeDeleted.notes.map((note) => @@ -159,7 +159,7 @@ const createNote = async ({ note: SavedNote; overrideOwner?: boolean; }) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const userInfo = request.user; const shallowCopyOfNote = { ...note }; @@ -217,7 +217,7 @@ const updateNote = async ({ note: SavedNote; overrideOwner?: boolean; }) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const userInfo = request.user; const existingNote = await savedObjectsClient.get( @@ -258,7 +258,7 @@ const updateNote = async ({ }; const getSavedNote = async (request: FrameworkRequest, NoteId: string) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObject = await savedObjectsClient.get( noteSavedObjectType, NoteId @@ -270,7 +270,7 @@ const getSavedNote = async (request: FrameworkRequest, NoteId: string) => { }; const getAllSavedNote = async (request: FrameworkRequest, options: SavedObjectsFindOptions) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObjects = await savedObjectsClient.find(options); return { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/pinned_events/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/pinned_events/index.ts index 3253deb0194c69d..59d83ee93e5a20f 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/pinned_events/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/pinned_events/index.ts @@ -70,7 +70,7 @@ export const deletePinnedEventOnTimeline = async ( request: FrameworkRequest, pinnedEventIds: string[] ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; await Promise.all( pinnedEventIds.map((pinnedEventId) => @@ -83,7 +83,7 @@ export const deleteAllPinnedEventsOnTimeline = async ( request: FrameworkRequest, timelineId: string ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const options: SavedObjectsFindOptions = { type: pinnedEventSavedObjectType, search: timelineId, @@ -186,7 +186,7 @@ const getValidTimelineIdAndVersion = async ( }; } - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; // create timeline because it didn't exist const { timeline: timelineResult } = await createTimeline({ @@ -224,7 +224,7 @@ const createPinnedEvent = async ({ timelineId: string; timelineVersion?: string; }) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedPinnedEvent: SavedPinnedEvent = { eventId, @@ -252,7 +252,7 @@ const createPinnedEvent = async ({ }; const getSavedPinnedEvent = async (request: FrameworkRequest, pinnedEventId: string) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObject = await savedObjectsClient.get( pinnedEventSavedObjectType, pinnedEventId @@ -267,7 +267,7 @@ const getAllSavedPinnedEvents = async ( request: FrameworkRequest, options: SavedObjectsFindOptions ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObjects = await savedObjectsClient.find(options); return savedObjects.saved_objects.map((savedObject) => { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts index 2c573d72dd6e4bf..de7c31fb47a98e9 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts @@ -380,7 +380,7 @@ export const persistTimeline = async ( timeline: SavedTimeline, isImmutable?: boolean ): Promise => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const userInfo = isImmutable ? ({ username: 'Elastic' } as AuthenticatedUser) : request.user; try { if (timelineId == null) { @@ -498,7 +498,7 @@ const updatePartialSavedTimeline = async ( timelineId: string, timeline: SavedTimeline ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const currentSavedTimeline = await savedObjectsClient.get( timelineSavedObjectType, timelineId @@ -563,7 +563,7 @@ export const resetTimeline = async ( }; export const deleteTimeline = async (request: FrameworkRequest, timelineIds: string[]) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; await Promise.all( timelineIds.map((timelineId) => @@ -577,7 +577,7 @@ export const deleteTimeline = async (request: FrameworkRequest, timelineIds: str }; const resolveBasicSavedTimeline = async (request: FrameworkRequest, timelineId: string) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const { saved_object: savedObject, ...resolveAttributes } = await savedObjectsClient.resolve( timelineSavedObjectType, @@ -615,7 +615,7 @@ const resolveSavedTimeline = async (request: FrameworkRequest, timelineId: strin }; const getBasicSavedTimeline = async (request: FrameworkRequest, timelineId: string) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObject = await savedObjectsClient.get( timelineSavedObjectType, timelineId @@ -644,7 +644,7 @@ const getSavedTimeline = async (request: FrameworkRequest, timelineId: string) = const getAllSavedTimeline = async (request: FrameworkRequest, options: SavedObjectsFindOptions) => { const userName = request.user?.username ?? UNAUTHENTICATED_USER; - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; const savedObjects = await savedObjectsClient.find(options); @@ -693,7 +693,7 @@ export const getSelectedTimelines = async ( request: FrameworkRequest, timelineIds?: string[] | null ) => { - const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjectsClient = (await request.context.core).savedObjects.client; let exportedIds = timelineIds; if (timelineIds == null || timelineIds.length === 0) { const { timeline: savedAllTimelines } = await getAllTimeline( diff --git a/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts b/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts index 958a5bf061711d4..f05366264ece6fc 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts @@ -23,7 +23,7 @@ export const buildFrameworkRequest = async ( security: StartPlugins['security'] | SetupPlugins['security'] | undefined, request: KibanaRequest ): Promise => { - const savedObjectsClient = context.core.savedObjects.client; + const savedObjectsClient = (await context.core).savedObjects.client; const user = await security?.authc.getCurrentUser(request); return set( diff --git a/x-pack/plugins/security_solution/server/request_context_factory.ts b/x-pack/plugins/security_solution/server/request_context_factory.ts index b0fe00485e2ad61..9f6b950c462020e 100644 --- a/x-pack/plugins/security_solution/server/request_context_factory.ts +++ b/x-pack/plugins/security_solution/server/request_context_factory.ts @@ -72,11 +72,14 @@ export class RequestContextFactory implements IRequestContextFactory { // If Fleet is enabled, then get its Authz if (startPlugins.fleet) { - fleetAuthz = context.fleet?.authz ?? (await startPlugins.fleet?.authz.fromRequest(request)); + fleetAuthz = + (await context.fleet)?.authz ?? (await startPlugins.fleet?.authz.fromRequest(request)); } + const coreContext = await context.core; + return { - core: context.core, + core: coreContext, get endpointAuthz(): Immutable { // Lazy getter of endpoint Authz. No point in defining it if it is never used. @@ -105,7 +108,7 @@ export class RequestContextFactory implements IRequestContextFactory { getRuleExecutionLog: memoize(() => ruleExecutionLogForRoutesFactory( - context.core.savedObjects.client, + coreContext.savedObjects.client, startPlugins.eventLog.getClient(request), logger ) @@ -117,7 +120,7 @@ export class RequestContextFactory implements IRequestContextFactory { } const username = security?.authc.getCurrentUser(request)?.username || 'elastic'; - return lists.getExceptionListClient(context.core.savedObjects.client, username); + return lists.getExceptionListClient(coreContext.savedObjects.client, username); }, }; } diff --git a/x-pack/plugins/security_solution/server/types.ts b/x-pack/plugins/security_solution/server/types.ts index c0e496ba4e64743..b1bf51439a3f63c 100644 --- a/x-pack/plugins/security_solution/server/types.ts +++ b/x-pack/plugins/security_solution/server/types.ts @@ -5,7 +5,11 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { + IRouter, + CustomRequestHandlerContext, + CoreRequestHandlerContext, +} from '@kbn/core/server'; import type { ActionsApiRequestHandlerContext } from '@kbn/actions-plugin/server'; import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server'; import type { FleetRequestHandlerContext } from '@kbn/fleet-plugin/server'; @@ -21,7 +25,8 @@ import { EndpointAuthz } from '../common/endpoint/types/authz'; export { AppClient }; -export interface SecuritySolutionApiRequestHandlerContext extends RequestHandlerContext { +export interface SecuritySolutionApiRequestHandlerContext { + core: CoreRequestHandlerContext; endpointAuthz: EndpointAuthz; getConfig: () => ConfigType; getFrameworkRequest: () => FrameworkRequest; @@ -32,13 +37,13 @@ export interface SecuritySolutionApiRequestHandlerContext extends RequestHandler getExceptionListClient: () => ExceptionListClient | null; } -export interface SecuritySolutionRequestHandlerContext extends RequestHandlerContext { +export type SecuritySolutionRequestHandlerContext = CustomRequestHandlerContext<{ securitySolution: SecuritySolutionApiRequestHandlerContext; actions: ActionsApiRequestHandlerContext; alerting: AlertingApiRequestHandlerContext; licensing: LicensingApiRequestHandlerContext; lists?: ListsApiRequestHandlerContext; fleet?: FleetRequestHandlerContext['fleet']; -} +}>; export type SecuritySolutionPluginRouter = IRouter; diff --git a/x-pack/plugins/session_view/server/routes/process_events_route.ts b/x-pack/plugins/session_view/server/routes/process_events_route.ts index c75bdc3fb6ed8f3..7341f8238f9af8d 100644 --- a/x-pack/plugins/session_view/server/routes/process_events_route.ts +++ b/x-pack/plugins/session_view/server/routes/process_events_route.ts @@ -27,7 +27,7 @@ export const registerProcessEventsRoute = (router: IRouter) => { }, }, async (context, request, response) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const { sessionEntityId, cursor, forward = true } = request.query; const body = await doSearch(client, sessionEntityId, cursor, forward); diff --git a/x-pack/plugins/session_view/server/routes/session_entry_leaders_route.ts b/x-pack/plugins/session_view/server/routes/session_entry_leaders_route.ts index 186195c342a48a6..c8fd28334f18ec5 100644 --- a/x-pack/plugins/session_view/server/routes/session_entry_leaders_route.ts +++ b/x-pack/plugins/session_view/server/routes/session_entry_leaders_route.ts @@ -19,7 +19,7 @@ export const sessionEntryLeadersRoute = (router: IRouter) => { }, }, async (context, request, response) => { - const client = context.core.elasticsearch.client.asCurrentUser; + const client = (await context.core).elasticsearch.client.asCurrentUser; const { id } = request.query; const result = await client.get({ diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/app.ts b/x-pack/plugins/snapshot_restore/server/routes/api/app.ts index 21938eaecf605d8..702a7633f7cc7ee 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/app.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/app.ts @@ -32,7 +32,7 @@ export function registerAppRoutes({ router.get( { path: addBasePath('privileges'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const privilegesResult: Privileges = { hasAllPrivileges: true, diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts b/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts index 57cb81ca13b9b23..8068c64ec77b649 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts @@ -23,7 +23,7 @@ export function registerPolicyRoutes({ router.get( { path: addBasePath('policies'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const managedPolicies = await getManagedPolicyNames(clusterClient.asCurrentUser); @@ -53,7 +53,7 @@ export function registerPolicyRoutes({ router.get( { path: addBasePath('policy/{name}'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; try { @@ -80,7 +80,7 @@ export function registerPolicyRoutes({ router.post( { path: addBasePath('policies'), validate: { body: policySchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const policy = req.body as TypeOf; const { name } = policy; @@ -120,7 +120,7 @@ export function registerPolicyRoutes({ validate: { params: nameParameterSchema, body: policySchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const policy = req.body as TypeOf; @@ -147,7 +147,7 @@ export function registerPolicyRoutes({ router.delete( { path: addBasePath('policies/{name}'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const policyNames = name.split(','); @@ -178,7 +178,7 @@ export function registerPolicyRoutes({ router.post( { path: addBasePath('policy/{name}/run'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; try { @@ -197,7 +197,7 @@ export function registerPolicyRoutes({ router.get( { path: addBasePath('policies/indices'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; try { const response = await clusterClient.asCurrentUser.indices.resolveIndex({ @@ -227,7 +227,7 @@ export function registerPolicyRoutes({ router.get( { path: addBasePath('policies/retention_settings'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { persistent, transient, defaults } = await clusterClient.asCurrentUser.cluster.getSettings({ filter_path: '**.slm.retention*', @@ -257,7 +257,7 @@ export function registerPolicyRoutes({ validate: { body: retentionSettingsSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { retentionSchedule } = req.body as TypeOf; try { @@ -282,7 +282,7 @@ export function registerPolicyRoutes({ router.post( { path: addBasePath('policies/retention'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const response = await clusterClient.asCurrentUser.slm.executeRetention(); return res.ok({ body: response }); }) diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts index 4666870133f1f51..4e86de4036d53ba 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts @@ -43,7 +43,7 @@ export function registerRepositoriesRoutes({ router.get( { path: addBasePath('repositories'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const managedRepositoryName = await getManagedRepositoryName(clusterClient.asCurrentUser); let repositoryNames: string[] | undefined; @@ -102,7 +102,7 @@ export function registerRepositoriesRoutes({ router.get( { path: addBasePath('repositories/{name}'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const managedRepository = await getManagedRepositoryName(clusterClient.asCurrentUser); @@ -157,7 +157,7 @@ export function registerRepositoriesRoutes({ router.get( { path: addBasePath('repository_types'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; // module repo types are available everywhere out of the box // on-prem repo types are not available on Cloud const types: RepositoryType[] = isCloudEnabled @@ -198,7 +198,7 @@ export function registerRepositoriesRoutes({ validate: { params: nameParameterSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; try { @@ -232,7 +232,7 @@ export function registerRepositoriesRoutes({ validate: { params: nameParameterSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; try { @@ -274,7 +274,7 @@ export function registerRepositoriesRoutes({ router.put( { path: addBasePath('repositories'), validate: { body: repositorySchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name = '', type = '', settings = {} } = req.body as TypeOf; // Check that repository with the same name doesn't already exist @@ -313,7 +313,7 @@ export function registerRepositoriesRoutes({ validate: { body: repositorySchema, params: nameParameterSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const { type = '', settings = {} } = req.body as TypeOf; @@ -345,7 +345,7 @@ export function registerRepositoriesRoutes({ router.delete( { path: addBasePath('repositories/{name}'), validate: { params: nameParameterSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { name } = req.params as TypeOf; const repositoryNames = name.split(','); diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts b/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts index ea688273781edd6..e97a64f26a123ad 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts @@ -24,7 +24,7 @@ export function registerRestoreRoutes({ router.get( { path: addBasePath('restores'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; try { const snapshotRestores: SnapshotRestore[] = []; @@ -99,7 +99,7 @@ export function registerRestoreRoutes({ validate: { body: restoreSettingsSchema, params: restoreParamsSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { repository, snapshot } = req.params as TypeOf; const restoreSettings = req.body as TypeOf; diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts b/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts index 7425ad0c272c639..c486180424da56b 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts @@ -47,7 +47,7 @@ export function registerSnapshotsRoutes({ router.get( { path: addBasePath('snapshots'), validate: { query: snapshotListSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const sortField = sortFieldToESParams[(req.query as TypeOf).sortField]; const sortDirection = (req.query as TypeOf).sortDirection; @@ -176,7 +176,7 @@ export function registerSnapshotsRoutes({ validate: { params: getOneParamsSchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const { repository, snapshot } = req.params as TypeOf; const managedRepository = await getManagedRepositoryName(clusterClient.asCurrentUser); @@ -232,7 +232,7 @@ export function registerSnapshotsRoutes({ router.post( { path: addBasePath('snapshots/bulk_delete'), validate: { body: deleteSchema } }, license.guardApiRoute(async (ctx, req, res) => { - const { client: clusterClient } = ctx.core.elasticsearch; + const { client: clusterClient } = (await ctx.core).elasticsearch; const response: { itemsDeleted: Array<{ snapshot: string; repository: string }>; diff --git a/x-pack/plugins/snapshot_restore/server/types.ts b/x-pack/plugins/snapshot_restore/server/types.ts index 9e7d97aed39eff6..d5710bb39d4c92f 100644 --- a/x-pack/plugins/snapshot_restore/server/types.ts +++ b/x-pack/plugins/snapshot_restore/server/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext, IScopedClusterClient } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext, IScopedClusterClient } from '@kbn/core/server'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { CloudSetup } from '@kbn/cloud-plugin/server'; @@ -63,6 +63,6 @@ export interface SnapshotRestoreContext { /** * @internal */ -export interface SnapshotRestoreRequestHandlerContext extends RequestHandlerContext { +export type SnapshotRestoreRequestHandlerContext = CustomRequestHandlerContext<{ snapshotRestore: SnapshotRestoreContext; -} +}>; diff --git a/x-pack/plugins/spaces/server/routes/lib/licensed_route_handler.ts b/x-pack/plugins/spaces/server/routes/lib/licensed_route_handler.ts index 19b163e31e31f62..254130cc1c51b33 100644 --- a/x-pack/plugins/spaces/server/routes/lib/licensed_route_handler.ts +++ b/x-pack/plugins/spaces/server/routes/lib/licensed_route_handler.ts @@ -5,23 +5,23 @@ * 2.0. */ -import type { RequestHandler, RequestHandlerContext } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, RequestHandler } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; export const createLicensedRouteHandler = < P, Q, B, - Context extends RequestHandlerContext & { licensing: LicensingApiRequestHandlerContext } + Context extends CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext }> >( handler: RequestHandler ) => { - const licensedRouteHandler: RequestHandler = ( + const licensedRouteHandler: RequestHandler = async ( context, request, responseToolkit ) => { - const { license } = context.licensing; + const { license } = await context.licensing; const licenseCheck = license.check('spaces', 'basic'); if (licenseCheck.state === 'unavailable' || licenseCheck.state === 'invalid') { return responseToolkit.forbidden({ body: { message: licenseCheck.message! } }); diff --git a/x-pack/plugins/spaces/server/routes/views/index.ts b/x-pack/plugins/spaces/server/routes/views/index.ts index de33027f5be45b1..d0cff27e85433eb 100644 --- a/x-pack/plugins/spaces/server/routes/views/index.ts +++ b/x-pack/plugins/spaces/server/routes/views/index.ts @@ -26,7 +26,8 @@ export function initSpacesViewsRoutes(deps: ViewRouteDeps) { { path: ENTER_SPACE_PATH, validate: false }, async (context, request, response) => { try { - const defaultRoute = await context.core.uiSettings.client.get('defaultRoute'); + const { uiSettings } = await context.core; + const defaultRoute = await uiSettings.client.get('defaultRoute'); const basePath = deps.basePath.get(request); const url = `${basePath}${defaultRoute}`; diff --git a/x-pack/plugins/spaces/server/types.ts b/x-pack/plugins/spaces/server/types.ts index 789f66fe2cbda86..267e7b51377a7a2 100644 --- a/x-pack/plugins/spaces/server/types.ts +++ b/x-pack/plugins/spaces/server/types.ts @@ -5,15 +5,15 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { CustomRequestHandlerContext, IRouter } from '@kbn/core/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; /** * @internal */ -export interface SpacesRequestHandlerContext extends RequestHandlerContext { +export type SpacesRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/synthetics/server/rest_api/create_route_with_auth.ts b/x-pack/plugins/synthetics/server/rest_api/create_route_with_auth.ts index c3d7c693ef00a56..20bb6043e624f9a 100644 --- a/x-pack/plugins/synthetics/server/rest_api/create_route_with_auth.ts +++ b/x-pack/plugins/synthetics/server/rest_api/create_route_with_auth.ts @@ -22,7 +22,7 @@ export const createRouteWithAuth = ( savedObjectsClient, server, }) => { - const { statusCode, message } = libs.license(context.licensing.license); + const { statusCode, message } = libs.license((await context.licensing).license); if (statusCode === 200) { return handler({ uptimeEsClient, diff --git a/x-pack/plugins/synthetics/server/rest_api/monitors/monitors_details.ts b/x-pack/plugins/synthetics/server/rest_api/monitors/monitors_details.ts index 64e9ed504e7cd7a..bed10c5cda9a75f 100644 --- a/x-pack/plugins/synthetics/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/plugins/synthetics/server/rest_api/monitors/monitors_details.ts @@ -23,7 +23,7 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteFactory = (libs: UMServ handler: async ({ uptimeEsClient, context, request }): Promise => { const { monitorId, dateStart, dateEnd } = request.query; - const rulesClient = context.alerting?.getRulesClient(); + const rulesClient = (await context.alerting)?.getRulesClient(); return await libs.requests.getMonitorDetails({ uptimeEsClient, diff --git a/x-pack/plugins/synthetics/server/rest_api/uptime_route_wrapper.ts b/x-pack/plugins/synthetics/server/rest_api/uptime_route_wrapper.ts index 6ad4e868a7fcbb8..03948589774ab7e 100644 --- a/x-pack/plugins/synthetics/server/rest_api/uptime_route_wrapper.ts +++ b/x-pack/plugins/synthetics/server/rest_api/uptime_route_wrapper.ts @@ -21,20 +21,21 @@ export const uptimeRouteWrapper: UMKibanaRouteWrapper = (uptimeRoute, server) => tags: ['access:uptime-read', ...(uptimeRoute?.writeAccess ? ['access:uptime-write'] : [])], }, handler: async (context, request, response) => { - const { client: esClient } = context.core.elasticsearch; + const coreContext = await context.core; + const { client: esClient } = coreContext.elasticsearch; let savedObjectsClient: SavedObjectsClientContract; if (server.config?.service) { - savedObjectsClient = context.core.savedObjects.getClient({ + savedObjectsClient = coreContext.savedObjects.getClient({ includedHiddenTypes: [syntheticsServiceApiKey.name], }); } else { - savedObjectsClient = context.core.savedObjects.client; + savedObjectsClient = coreContext.savedObjects.client; } // specifically needed for the synthetics service api key generation server.authSavedObjectsClient = savedObjectsClient; - const isInspectorEnabled = await context.core.uiSettings.client.get( + const isInspectorEnabled = await coreContext.uiSettings.client.get( enableInspectEsQueries ); diff --git a/x-pack/plugins/synthetics/server/types.ts b/x-pack/plugins/synthetics/server/types.ts index b05ac2ee38a798e..e66400ce55a0713 100644 --- a/x-pack/plugins/synthetics/server/types.ts +++ b/x-pack/plugins/synthetics/server/types.ts @@ -5,16 +5,17 @@ * 2.0. */ -import type { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { IRouter, CustomRequestHandlerContext } from '@kbn/core/server'; import type { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server'; import type { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; + /** * @internal */ -export interface UptimeRequestHandlerContext extends RequestHandlerContext { +export type UptimeRequestHandlerContext = CustomRequestHandlerContext<{ licensing: LicensingApiRequestHandlerContext; alerting: AlertingApiRequestHandlerContext; -} +}>; /** * @internal diff --git a/x-pack/plugins/transform/server/routes/api/field_histograms.ts b/x-pack/plugins/transform/server/routes/api/field_histograms.ts index 25991d7e865c372..c9623f262b5e097 100644 --- a/x-pack/plugins/transform/server/routes/api/field_histograms.ts +++ b/x-pack/plugins/transform/server/routes/api/field_histograms.ts @@ -32,8 +32,9 @@ export function registerFieldHistogramsRoutes({ router, license }: RouteDependen const { query, fields, runtimeMappings, samplerShardSize } = req.body; try { + const esClient = (await ctx.core).elasticsearch.client; const resp = await getHistogramsForFields( - ctx.core.elasticsearch.client, + esClient, dataViewTitle, query, fields, diff --git a/x-pack/plugins/transform/server/routes/api/privileges.ts b/x-pack/plugins/transform/server/routes/api/privileges.ts index d8bce73244c1598..bad077100c83a3e 100644 --- a/x-pack/plugins/transform/server/routes/api/privileges.ts +++ b/x-pack/plugins/transform/server/routes/api/privileges.ts @@ -28,9 +28,10 @@ export function registerPrivilegesRoute({ router, license }: RouteDependencies) return res.ok({ body: privilegesResult }); } + const esClient = (await ctx.core).elasticsearch.client; // Get cluster privileges const { has_all_requested: hasAllPrivileges, cluster } = - await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + await esClient.asCurrentUser.security.hasPrivileges({ body: { // @ts-expect-error SecurityClusterPrivilege doesn’t contain all the priviledges cluster: APP_CLUSTER_PRIVILEGES, @@ -42,8 +43,7 @@ export function registerPrivilegesRoute({ router, license }: RouteDependencies) privilegesResult.hasAllPrivileges = hasAllPrivileges; // Get all index privileges the user has - const { indices } = - await ctx.core.elasticsearch.client.asCurrentUser.security.getUserPrivileges(); + const { indices } = await esClient.asCurrentUser.security.getUserPrivileges(); // Check if they have all the required index privileges for at least one index const oneIndexWithAllPrivileges = indices.find(({ privileges }: { privileges: string[] }) => { diff --git a/x-pack/plugins/transform/server/routes/api/transforms.ts b/x-pack/plugins/transform/server/routes/api/transforms.ts index 252cc2eda5529ee..f1c5e74056a9452 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms.ts @@ -90,15 +90,17 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute( async (ctx, req, res) => { try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.getTransform({ size: 1000, ...req.params, }); - if (ctx.alerting) { + const alerting = await ctx.alerting; + if (alerting) { const transformHealthService = transformHealthServiceProvider( - ctx.core.elasticsearch.client.asCurrentUser, - ctx.alerting.getRulesClient() + esClient.asCurrentUser, + alerting.getRulesClient() ); // @ts-ignore @@ -130,7 +132,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute(async (ctx, req, res) => { const { transformId } = req.params; try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.getTransform({ transform_id: transformId, }); return res.ok({ body }); @@ -152,11 +155,11 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute( async (ctx, req, res) => { try { - const body = - await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransformStats({ - size: 1000, - transform_id: '_all', - }); + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.getTransformStats({ + size: 1000, + transform_id: '_all', + }); return res.ok({ body }); } catch (e) { return res.customError(wrapError(wrapEsError(e))); @@ -182,7 +185,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute(async (ctx, req, res) => { const { transformId } = req.params; try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransformStats({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.getTransformStats({ transform_id: transformId, }); return res.ok({ body }); @@ -219,7 +223,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { errors: [], }; - await ctx.core.elasticsearch.client.asCurrentUser.transform + const esClient = (await ctx.core).elasticsearch.client; + await esClient.asCurrentUser.transform .putTransform({ // @ts-expect-error @elastic/elasticsearch group_by is expected to be optional in TransformPivot body: req.body, @@ -263,7 +268,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { const { transformId } = req.params; try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.updateTransform({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.updateTransform({ // @ts-expect-error query doesn't satisfy QueryDslQueryContainer from @elastic/elasticsearch body: req.body, transform_id: transformId, @@ -437,7 +443,8 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { }, license.guardApiRoute(async (ctx, req, res) => { try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.search(req.body); + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.search(req.body); return res.ok({ body }); } catch (e) { return res.customError(wrapError(wrapEsError(e))); @@ -482,6 +489,10 @@ async function deleteTransforms( const results: DeleteTransformsResponseSchema = {}; + const coreContext = await ctx.core; + const esClient = coreContext.elasticsearch.client; + const soClient = coreContext.savedObjects.client; + for (const transformInfo of transformsInfo) { let destinationIndex: string | undefined; @@ -501,7 +512,7 @@ async function deleteTransforms( if (!shouldForceDelete) { // Grab destination index info to delete try { - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ + const body = await esClient.asCurrentUser.transform.getTransform({ transform_id: transformId, }); const transformConfig = body.transforms[0]; @@ -525,7 +536,7 @@ async function deleteTransforms( try { // If user does have privilege to delete the index, then delete the index // if no permission then return 403 forbidden - await ctx.core.elasticsearch.client.asCurrentUser.indices.delete({ + await esClient.asCurrentUser.indices.delete({ index: destinationIndex, }); destIndexDeleted.success = true; @@ -537,9 +548,9 @@ async function deleteTransforms( // Delete the data view if there's a data view that matches the name of dest index if (destinationIndex && deleteDestDataView) { try { - const dataViewId = await getDataViewId(destinationIndex, ctx.core.savedObjects.client); + const dataViewId = await getDataViewId(destinationIndex, soClient); if (dataViewId) { - await deleteDestDataViewById(dataViewId, ctx.core.savedObjects.client); + await deleteDestDataViewById(dataViewId, soClient); destDataViewDeleted.success = true; } } catch (deleteDestDataViewError) { @@ -548,7 +559,7 @@ async function deleteTransforms( } try { - await ctx.core.elasticsearch.client.asCurrentUser.transform.deleteTransform({ + await esClient.asCurrentUser.transform.deleteTransform({ transform_id: transformId, force: shouldForceDelete && needToForceDelete, }); @@ -589,6 +600,7 @@ async function resetTransforms( const { transformsInfo } = reqBody; const results: ResetTransformsResponseSchema = {}; + const esClient = (await ctx.core).elasticsearch.client; for (const transformInfo of transformsInfo) { const transformReset: ResponseStatus = { success: false }; @@ -596,7 +608,7 @@ async function resetTransforms( try { try { - await ctx.core.elasticsearch.client.asCurrentUser.transform.resetTransform({ + await esClient.asCurrentUser.transform.resetTransform({ transform_id: transformId, }); transformReset.success = true; @@ -632,12 +644,13 @@ const previewTransformHandler: RequestHandler< > = async (ctx, req, res) => { try { const reqBody = req.body; - const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.previewTransform({ + const esClient = (await ctx.core).elasticsearch.client; + const body = await esClient.asCurrentUser.transform.previewTransform({ body: reqBody, }); if (isLatestTransform(reqBody)) { // for the latest transform mappings properties have to be retrieved from the source - const fieldCapsResponse = await ctx.core.elasticsearch.client.asCurrentUser.fieldCaps({ + const fieldCapsResponse = await esClient.asCurrentUser.fieldCaps({ index: reqBody.source.index, fields: '*', include_unmapped: false, @@ -676,7 +689,8 @@ const startTransformsHandler: RequestHandler< const transformsInfo = req.body; try { - const body = await startTransforms(transformsInfo, ctx.core.elasticsearch.client.asCurrentUser); + const esClient = (await ctx.core).elasticsearch.client; + const body = await startTransforms(transformsInfo, esClient.asCurrentUser); return res.ok({ body, }); @@ -721,8 +735,9 @@ const stopTransformsHandler: RequestHandler< const transformsInfo = req.body; try { + const esClient = (await ctx.core).elasticsearch.client; return res.ok({ - body: await stopTransforms(transformsInfo, ctx.core.elasticsearch.client.asCurrentUser), + body: await stopTransforms(transformsInfo, esClient.asCurrentUser), }); } catch (e) { return res.customError(wrapError(wrapEsError(e))); diff --git a/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts b/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts index 3004a2bd42a71f3..bd3e7d101624ef6 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts @@ -78,7 +78,8 @@ export function registerTransformsAuditMessagesRoutes({ router, license }: Route } try { - const resp = await ctx.core.elasticsearch.client.asCurrentUser.search({ + const esClient = (await ctx.core).elasticsearch.client; + const resp = await esClient.asCurrentUser.search({ index: ML_DF_NOTIFICATION_INDEX_PATTERN, ignore_unavailable: true, size: SIZE, diff --git a/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts b/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts index 3950354f08d405e..426dc3d4fa34218 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts @@ -48,11 +48,12 @@ export function registerTransformNodesRoutes({ router, license }: RouteDependenc }, license.guardApiRoute(async (ctx, req, res) => { try { + const esClient = (await ctx.core).elasticsearch.client; // If security is enabled, check that the user has at least permission to // view transforms before calling the _nodes endpoint with the internal user. if (license.getStatus().isSecurityEnabled === true) { const { has_all_requested: hasAllPrivileges } = - await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + await esClient.asCurrentUser.security.hasPrivileges({ body: { // @ts-expect-error SecurityClusterPrivilege doesn’t contain all the priviledges cluster: NODES_INFO_PRIVILEGES, @@ -64,7 +65,7 @@ export function registerTransformNodesRoutes({ router, license }: RouteDependenc } } - const { nodes } = await ctx.core.elasticsearch.client.asInternalUser.nodes.info({ + const { nodes } = await esClient.asInternalUser.nodes.info({ filter_path: `nodes.*.${NODE_ROLES}`, }); diff --git a/x-pack/plugins/transform/server/services/license.ts b/x-pack/plugins/transform/server/services/license.ts index cd98e28d973a03d..7a54f45de707b75 100644 --- a/x-pack/plugins/transform/server/services/license.ts +++ b/x-pack/plugins/transform/server/services/license.ts @@ -11,7 +11,7 @@ import { KibanaRequest, KibanaResponseFactory, RequestHandler, - RequestHandlerContext, + CustomRequestHandlerContext, } from '@kbn/core/server'; import { LicensingPluginSetup, LicenseType } from '@kbn/licensing-plugin/server'; @@ -29,9 +29,9 @@ interface SetupSettings { defaultErrorMessage: string; } -type TransformRequestHandlerContext = RequestHandlerContext & { +type TransformRequestHandlerContext = CustomRequestHandlerContext<{ alerting?: AlertingApiRequestHandlerContext; -}; +}>; export class License { private licenseStatus: LicenseStatus = { @@ -75,7 +75,7 @@ export class License { const license = this; return function licenseCheck( - ctx: RequestHandlerContext, + ctx: TransformRequestHandlerContext, request: KibanaRequest, response: KibanaResponseFactory ): IKibanaResponse | Promise> { diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 7de054edb991df4..bd7126e25c44bbd 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -25464,17 +25464,11 @@ "xpack.securitySolution.endpoint.policyResponse.appliedOn": "Révision {rev} appliquée le {date}", "xpack.securitySolution.endpoint.policyResponse.backLinkTitle": "Détails de point de terminaison", "xpack.securitySolution.endpoint.policyResponse.title": "Réponse de politique", - "xpack.securitySolution.endpoint.resolver.compactBillions": "B", - "xpack.securitySolution.endpoint.resolver.compactMillions": "M", - "xpack.securitySolution.endpoint.resolver.compactOverflow": "+", - "xpack.securitySolution.endpoint.resolver.compactThousands": "k", - "xpack.securitySolution.endpoint.resolver.compactTrillions": "T", "xpack.securitySolution.endpoint.resolver.eitherLineageLimitExceeded": "Certains événements de processus dans la visualisation et la liste d'événements ci-dessous n'ont pas pu être affichés, car la limite de données a été atteinte.", "xpack.securitySolution.endpoint.resolver.elapsedTime": "{duration} {durationType}", "xpack.securitySolution.endpoint.resolver.errorProcess": "Processus d'erreur", "xpack.securitySolution.endpoint.resolver.loadingError": "Erreur lors du chargement des données.", "xpack.securitySolution.endpoint.resolver.loadingProcess": "Processus de chargement", - "xpack.securitySolution.endpoint.resolver.node.pillNumber": "{mantissa}{scale}{hasRemainder}", "xpack.securitySolution.endpoint.resolver.panel.error.error": "Erreur", "xpack.securitySolution.endpoint.resolver.panel.error.events": "Événements", "xpack.securitySolution.endpoint.resolver.panel.error.goBack": "Afficher tous les processus", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 01c890923fba8a6..1270d3e8a5f6a9b 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -25631,17 +25631,11 @@ "xpack.securitySolution.endpoint.policyResponse.appliedOn": "{date}に改訂{rev}が適用されました", "xpack.securitySolution.endpoint.policyResponse.backLinkTitle": "エンドポイント詳細", "xpack.securitySolution.endpoint.policyResponse.title": "ポリシー応答", - "xpack.securitySolution.endpoint.resolver.compactBillions": "B", - "xpack.securitySolution.endpoint.resolver.compactMillions": "M", - "xpack.securitySolution.endpoint.resolver.compactOverflow": "+", - "xpack.securitySolution.endpoint.resolver.compactThousands": "k", - "xpack.securitySolution.endpoint.resolver.compactTrillions": "T", "xpack.securitySolution.endpoint.resolver.eitherLineageLimitExceeded": "以下のビジュアライゼーションとイベントリストの一部のプロセスイベントを表示できませんでした。データの上限に達しました。", "xpack.securitySolution.endpoint.resolver.elapsedTime": "{duration} {durationType}", "xpack.securitySolution.endpoint.resolver.errorProcess": "エラープロセス", "xpack.securitySolution.endpoint.resolver.loadingError": "データの読み込み中にエラーが発生しました。", "xpack.securitySolution.endpoint.resolver.loadingProcess": "プロセスの読み込み中", - "xpack.securitySolution.endpoint.resolver.node.pillNumber": "{mantissa}{scale}{hasRemainder}", "xpack.securitySolution.endpoint.resolver.panel.error.error": "エラー", "xpack.securitySolution.endpoint.resolver.panel.error.events": "イベント", "xpack.securitySolution.endpoint.resolver.panel.error.goBack": "すべてのプロセスを表示", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index ada26cb30fd7fea..0bfadb5e9443773 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -25665,17 +25665,11 @@ "xpack.securitySolution.endpoint.policyResponse.appliedOn": "修订 {rev} 应用于 {date}", "xpack.securitySolution.endpoint.policyResponse.backLinkTitle": "终端详情", "xpack.securitySolution.endpoint.policyResponse.title": "策略响应", - "xpack.securitySolution.endpoint.resolver.compactBillions": "B", - "xpack.securitySolution.endpoint.resolver.compactMillions": "M", - "xpack.securitySolution.endpoint.resolver.compactOverflow": "+", - "xpack.securitySolution.endpoint.resolver.compactThousands": "k", - "xpack.securitySolution.endpoint.resolver.compactTrillions": "T", "xpack.securitySolution.endpoint.resolver.eitherLineageLimitExceeded": "下面可视化和事件列表中的一些进程事件无法显示,因为已达到数据限制。", "xpack.securitySolution.endpoint.resolver.elapsedTime": "{duration} {durationType}", "xpack.securitySolution.endpoint.resolver.errorProcess": "进程错误", "xpack.securitySolution.endpoint.resolver.loadingError": "加载数据时出错。", "xpack.securitySolution.endpoint.resolver.loadingProcess": "正在加载进程", - "xpack.securitySolution.endpoint.resolver.node.pillNumber": "{mantissa}{scale}{hasRemainder}", "xpack.securitySolution.endpoint.resolver.panel.error.error": "错误", "xpack.securitySolution.endpoint.resolver.panel.error.events": "事件", "xpack.securitySolution.endpoint.resolver.panel.error.goBack": "查看所有进程", diff --git a/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts index 3cd8d8e81e252c9..e2e9b5967305df2 100644 --- a/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts +++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts @@ -34,6 +34,7 @@ export function createFieldsRoute(logger: Logger, router: IRouter, baseRoute: st }, handler ); + async function handler( ctx: RequestHandlerContext, req: KibanaRequest, @@ -49,10 +50,8 @@ export function createFieldsRoute(logger: Logger, router: IRouter, baseRoute: st } try { - rawFields = await getRawFields( - ctx.core.elasticsearch.client.asCurrentUser, - req.body.indexPatterns - ); + const esClient = (await ctx.core).elasticsearch.client.asCurrentUser; + rawFields = await getRawFields(esClient, req.body.indexPatterns); } catch (err) { const indexPatterns = req.body.indexPatterns.join(','); logger.warn( diff --git a/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts index b32c80aa6f0b437..3fdee6f23b39b8b 100644 --- a/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts +++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/indices.ts @@ -45,6 +45,7 @@ export function createIndicesRoute(logger: Logger, router: IRouter, baseRoute: s res: KibanaResponseFactory ): Promise { const pattern = req.body.pattern; + const esClient = (await ctx.core).elasticsearch.client.asCurrentUser; logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`); if (pattern.trim() === '') { @@ -53,14 +54,14 @@ export function createIndicesRoute(logger: Logger, router: IRouter, baseRoute: s let aliases: string[] = []; try { - aliases = await getAliasesFromPattern(ctx.core.elasticsearch.client.asCurrentUser, pattern); + aliases = await getAliasesFromPattern(esClient, pattern); } catch (err) { logger.warn(`route ${path} error getting aliases from pattern "${pattern}": ${err.message}`); } let indices: string[] = []; try { - indices = await getIndicesFromPattern(ctx.core.elasticsearch.client.asCurrentUser, pattern); + indices = await getIndicesFromPattern(esClient, pattern); } catch (err) { logger.warn(`route ${path} error getting indices from pattern "${pattern}": ${err.message}`); } diff --git a/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts index 1273351795f876f..1fb7f2217d11b45 100644 --- a/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts +++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/time_series_query.ts @@ -41,9 +41,10 @@ export function createTimeSeriesQueryRoute( ): Promise { logger.debug(`route ${path} request: ${JSON.stringify(req.body)}`); + const esClient = (await ctx.core).elasticsearch.client.asCurrentUser; const result = await timeSeriesQuery({ logger, - esClient: ctx.core.elasticsearch.client.asCurrentUser, + esClient, query: req.body, }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts index 72c71a8a21c8e50..d1df5f8e3117095 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts @@ -104,7 +104,10 @@ describe('EsVersionPrecheck', () => { ctx.core.elasticsearch.client.asInternalUser.nodes.info.mockRejectedValue({ statusCode: 403 }); - const result = await esVersionCheck(ctx, kibanaResponseFactory); + const result = await esVersionCheck( + coreMock.createCustomRequestHandlerContext(ctx), + kibanaResponseFactory + ); expect(result).toHaveProperty('status', 403); }); @@ -120,7 +123,10 @@ describe('EsVersionPrecheck', () => { }, }); - const result = await esVersionCheck(ctx, kibanaResponseFactory); + const result = await esVersionCheck( + coreMock.createCustomRequestHandlerContext(ctx), + kibanaResponseFactory + ); expect(result).toHaveProperty('status', 426); expect(result).toHaveProperty('payload.attributes.allNodesUpgraded', false); }); @@ -137,7 +143,10 @@ describe('EsVersionPrecheck', () => { }, }); - const result = await esVersionCheck(ctx, kibanaResponseFactory); + const result = await esVersionCheck( + coreMock.createCustomRequestHandlerContext(ctx), + kibanaResponseFactory + ); expect(result).toHaveProperty('status', 426); expect(result).toHaveProperty('payload.attributes.allNodesUpgraded', true); }); @@ -154,6 +163,8 @@ describe('EsVersionPrecheck', () => { }, }); - await expect(esVersionCheck(ctx, kibanaResponseFactory)).resolves.toBe(undefined); + await expect( + esVersionCheck(coreMock.createCustomRequestHandlerContext(ctx), kibanaResponseFactory) + ).resolves.toBe(undefined); }); }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts index 699f40a65bae148..2e85cbaf73a9442 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts @@ -65,7 +65,7 @@ export const esVersionCheck = async ( ctx: RequestHandlerContext, response: KibanaResponseFactory ) => { - const { client } = ctx.core.elasticsearch; + const { client } = (await ctx.core).elasticsearch; let allNodeVersions: SemVer[]; try { diff --git a/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts index 9fb35b838d81de5..172b1d53474d446 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { AwaitedProperties } from '@kbn/utility-types'; import { RequestHandler, RequestHandlerContext } from '@kbn/core/server'; import { elasticsearchServiceMock, @@ -20,7 +21,7 @@ export const routeHandlerContextMock = { savedObjects: { client: savedObjectsClientMock.create() }, deprecations: { client: deprecationsServiceMock.createClient() }, }, -} as unknown as RequestHandlerContext; +} as unknown as AwaitedProperties; /** * Creates a very crude mock of the new platform router implementation. This enables use to test diff --git a/x-pack/plugins/upgrade_assistant/server/routes/app.ts b/x-pack/plugins/upgrade_assistant/server/routes/app.ts index b976811a87e5bc7..2193d69cca2558a 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/app.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/app.ts @@ -30,50 +30,43 @@ export function registerAppRoutes({ path: `${API_BASE_PATH}/privileges`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + elasticsearch: { client }, + } = await core; + const privilegesResult: Privileges = { + hasAllPrivileges: true, + missingPrivileges: { + index: [], }, - request, - response - ) => { - const privilegesResult: Privileges = { - hasAllPrivileges: true, - missingPrivileges: { - index: [], - }, - }; + }; - if (!isSecurityEnabled()) { - return response.ok({ body: privilegesResult }); - } - - try { - const { has_all_requested: hasAllPrivileges, index } = - await client.asCurrentUser.security.hasPrivileges({ - body: { - index: [ - { - names: [DEPRECATION_LOGS_INDEX], - privileges: ['read'], - }, - ], - }, - }); + if (!isSecurityEnabled()) { + return response.ok({ body: privilegesResult }); + } - if (!hasAllPrivileges) { - privilegesResult.missingPrivileges.index = extractMissingPrivileges(index); - } + try { + const { has_all_requested: hasAllPrivileges, index } = + await client.asCurrentUser.security.hasPrivileges({ + body: { + index: [ + { + names: [DEPRECATION_LOGS_INDEX], + privileges: ['read'], + }, + ], + }, + }); - privilegesResult.hasAllPrivileges = hasAllPrivileges; - return response.ok({ body: privilegesResult }); - } catch (error) { - return handleEsError({ error, response }); + if (!hasAllPrivileges) { + privilegesResult.missingPrivileges.index = extractMissingPrivileges(index); } + + privilegesResult.hasAllPrivileges = hasAllPrivileges; + return response.ok({ body: privilegesResult }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/cloud_backup_status.ts b/x-pack/plugins/upgrade_assistant/server/routes/cloud_backup_status.ts index 6dffead8ec91f66..17b80f6a685b3ac 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/cloud_backup_status.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/cloud_backup_status.ts @@ -17,7 +17,7 @@ export function registerCloudBackupStatusRoutes({ router.get( { path: `${API_BASE_PATH}/cloud_backup_status`, validate: false }, versionCheckHandlerWrapper(async (context, request, response) => { - const { client: clusterClient } = context.core.elasticsearch; + const { client: clusterClient } = (await context.core).elasticsearch; try { const { snapshots } = await clusterClient.asCurrentUser.snapshot.get({ diff --git a/x-pack/plugins/upgrade_assistant/server/routes/cluster_settings.ts b/x-pack/plugins/upgrade_assistant/server/routes/cluster_settings.ts index f64c3a383781f1e..d85123ab3e7d657 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/cluster_settings.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/cluster_settings.ts @@ -23,59 +23,52 @@ export function registerClusterSettingsRoute({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const { settings } = request.body; - - // We need to fetch the current cluster settings in order to determine - // if the settings to delete were set as transient or persistent settings - const currentClusterSettings = await client.asCurrentUser.cluster.getSettings({ - flat_settings: true, - }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const { settings } = request.body; - const settingsToDelete = settings.reduce( - (settingsBody, currentSetting) => { - if ( - Object.keys(currentClusterSettings.persistent).find((key) => key === currentSetting) - ) { - settingsBody.persistent[currentSetting] = null; - } + // We need to fetch the current cluster settings in order to determine + // if the settings to delete were set as transient or persistent settings + const currentClusterSettings = await client.asCurrentUser.cluster.getSettings({ + flat_settings: true, + }); - if ( - Object.keys(currentClusterSettings.transient).find((key) => key === currentSetting) - ) { - settingsBody.transient[currentSetting] = null; - } + const settingsToDelete = settings.reduce( + (settingsBody, currentSetting) => { + if ( + Object.keys(currentClusterSettings.persistent).find((key) => key === currentSetting) + ) { + settingsBody.persistent[currentSetting] = null; + } - return settingsBody; - }, - { persistent: {}, transient: {} } as { - persistent: { [key: string]: null }; - transient: { [key: string]: null }; + if ( + Object.keys(currentClusterSettings.transient).find((key) => key === currentSetting) + ) { + settingsBody.transient[currentSetting] = null; } - ); - const settingsResponse = await client.asCurrentUser.cluster.putSettings({ - body: settingsToDelete, - flat_settings: true, - }); + return settingsBody; + }, + { persistent: {}, transient: {} } as { + persistent: { [key: string]: null }; + transient: { [key: string]: null }; + } + ); + + const settingsResponse = await client.asCurrentUser.cluster.putSettings({ + body: settingsToDelete, + flat_settings: true, + }); - return response.ok({ - body: settingsResponse, - }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ + body: settingsResponse, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts index 70fd5d035ad528d..6770869233ab8ba 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts @@ -30,24 +30,17 @@ export function registerDeprecationLoggingRoutes({ path: `${API_BASE_PATH}/deprecation_logging`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const result = await getDeprecationLoggingStatus(client); - return response.ok({ body: result }); - } catch (error) { - return handleEsError({ error, response }); - } + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const result = await getDeprecationLoggingStatus(client); + return response.ok({ body: result }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); router.put( @@ -59,26 +52,19 @@ export function registerDeprecationLoggingRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const { isEnabled } = request.body as { isEnabled: boolean }; - return response.ok({ - body: await setDeprecationLogging(client, isEnabled), - }); - } catch (error) { - return handleEsError({ error, response }); - } + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const { isEnabled } = request.body as { isEnabled: boolean }; + return response.ok({ + body: await setDeprecationLogging(client, isEnabled), + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); router.get( @@ -90,56 +76,49 @@ export function registerDeprecationLoggingRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const indexExists = await client.asCurrentUser.indices.exists({ - index: DEPRECATION_LOGS_INDEX, - }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const indexExists = await client.asCurrentUser.indices.exists({ + index: DEPRECATION_LOGS_INDEX, + }); - if (!indexExists) { - return response.ok({ body: { count: 0 } }); - } + if (!indexExists) { + return response.ok({ body: { count: 0 } }); + } - const now = moment().toISOString(); + const now = moment().toISOString(); - const body = await client.asCurrentUser.count({ - index: DEPRECATION_LOGS_INDEX, - body: { - query: { - bool: { - must: { - range: { - '@timestamp': { - gte: request.query.from, - lte: now, - }, + const body = await client.asCurrentUser.count({ + index: DEPRECATION_LOGS_INDEX, + body: { + query: { + bool: { + must: { + range: { + '@timestamp': { + gte: request.query.from, + lte: now, }, }, - must_not: { - terms: { - [DEPRECATION_LOGS_ORIGIN_FIELD]: [...APPS_WITH_DEPRECATION_LOGS], - }, + }, + must_not: { + terms: { + [DEPRECATION_LOGS_ORIGIN_FIELD]: [...APPS_WITH_DEPRECATION_LOGS], }, }, }, }, - }); + }, + }); - return response.ok({ body: { count: body.count } }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ body: { count: body.count } }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); router.delete( @@ -147,27 +126,20 @@ export function registerDeprecationLoggingRoutes({ path: `${API_BASE_PATH}/deprecation_logging/cache`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - await client.asCurrentUser.transport.request({ - method: 'DELETE', - path: '/_logging/deprecation_cache', - }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + await client.asCurrentUser.transport.request({ + method: 'DELETE', + path: '/_logging/deprecation_cache', + }); - return response.ok({ body: 'ok' }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ body: 'ok' }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/es_deprecations.ts b/x-pack/plugins/upgrade_assistant/server/routes/es_deprecations.ts index 98089e34bdca192..ff04fd694335dfe 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/es_deprecations.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/es_deprecations.ts @@ -23,41 +23,29 @@ export function registerESDeprecationRoutes({ path: `${API_BASE_PATH}/es_deprecations`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const status = await getESUpgradeStatus(client); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client }, + } = await core; + const status = await getESUpgradeStatus(client); - const asCurrentUser = client.asCurrentUser; - const reindexActions = reindexActionsFactory(savedObjectsClient, asCurrentUser); - const reindexService = reindexServiceFactory( - asCurrentUser, - reindexActions, - log, - licensing - ); - const indexNames = status.deprecations - .filter(({ index }) => typeof index !== 'undefined') - .map(({ index }) => index as string); + const asCurrentUser = client.asCurrentUser; + const reindexActions = reindexActionsFactory(savedObjectsClient, asCurrentUser); + const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); + const indexNames = status.deprecations + .filter(({ index }) => typeof index !== 'undefined') + .map(({ index }) => index as string); - await reindexService.cleanupReindexOperations(indexNames); + await reindexService.cleanupReindexOperations(indexNames); - return response.ok({ - body: status, - }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ + body: status, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts b/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts index 45455eee01e1087..1698934e0d8a418 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts @@ -151,47 +151,40 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - try { - const { snapshotId, jobId } = request.body; - - const body = await esClient.asCurrentUser.ml.upgradeJobSnapshot({ - job_id: jobId, - snapshot_id: snapshotId, - }); - - const snapshotInfo: MlOperation = { - nodeId: body.node, - snapshotId, - jobId, - }; - - // Store snapshot in saved object if upgrade not complete - if (body.completed !== true) { - await createMlOperation(savedObjectsClient, snapshotInfo); - } - - return response.ok({ - body: { - ...snapshotInfo, - status: body.completed === true ? 'complete' : 'in_progress', - }, - }); - } catch (error) { - return handleEsError({ error, response }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client: esClient }, + } = await core; + const { snapshotId, jobId } = request.body; + + const body = await esClient.asCurrentUser.ml.upgradeJobSnapshot({ + job_id: jobId, + snapshot_id: snapshotId, + }); + + const snapshotInfo: MlOperation = { + nodeId: body.node, + snapshotId, + jobId, + }; + + // Store snapshot in saved object if upgrade not complete + if (body.completed !== true) { + await createMlOperation(savedObjectsClient, snapshotInfo); } + + return response.ok({ + body: { + ...snapshotInfo, + status: body.completed === true ? 'complete' : 'in_progress', + }, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); // Get the status of the upgrade snapshot task @@ -205,102 +198,67 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - try { - const { snapshotId, jobId } = request.params; - - // Verify snapshot exists - await esClient.asCurrentUser.ml.getModelSnapshots({ - job_id: jobId, - snapshot_id: snapshotId, + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client: esClient }, + } = await core; + const { snapshotId, jobId } = request.params; + + // Verify snapshot exists + await esClient.asCurrentUser.ml.getModelSnapshots({ + job_id: jobId, + snapshot_id: snapshotId, + }); + + const foundSnapshots = await findMlOperation(savedObjectsClient, snapshotId); + + // If snapshot is *not* found in SO, assume there has not been an upgrade operation started + if (typeof foundSnapshots === 'undefined' || foundSnapshots.total === 0) { + return response.ok({ + body: { + snapshotId, + jobId, + nodeId: undefined, + status: 'idle', + }, }); + } - const foundSnapshots = await findMlOperation(savedObjectsClient, snapshotId); - - // If snapshot is *not* found in SO, assume there has not been an upgrade operation started - if (typeof foundSnapshots === 'undefined' || foundSnapshots.total === 0) { + const upgradeStatus = await getModelSnapshotUpgradeStatus(esClient, jobId, snapshotId); + // Create snapshotInfo payload to send back in the response + const snapshotOp = foundSnapshots.saved_objects[0]; + const snapshotInfo: MlOperation = { + ...snapshotOp.attributes, + }; + + if (upgradeStatus) { + if ( + upgradeStatus.state === 'loading_old_state' || + upgradeStatus.state === 'saving_new_state' + ) { return response.ok({ body: { - snapshotId, - jobId, - nodeId: undefined, - status: 'idle', + ...snapshotInfo, + status: 'in_progress', + }, + }); + } else if (upgradeStatus.state === 'failed') { + return response.customError({ + statusCode: 500, + body: { + message: i18n.translate( + 'xpack.upgradeAssistant.ml_snapshots.modelSnapshotUpgradeFailed', + { + defaultMessage: + 'The upgrade process for this model snapshot failed. Check the Elasticsearch logs for more details.', + } + ), }, }); - } - - const upgradeStatus = await getModelSnapshotUpgradeStatus(esClient, jobId, snapshotId); - // Create snapshotInfo payload to send back in the response - const snapshotOp = foundSnapshots.saved_objects[0]; - const snapshotInfo: MlOperation = { - ...snapshotOp.attributes, - }; - - if (upgradeStatus) { - if ( - upgradeStatus.state === 'loading_old_state' || - upgradeStatus.state === 'saving_new_state' - ) { - return response.ok({ - body: { - ...snapshotInfo, - status: 'in_progress', - }, - }); - } else if (upgradeStatus.state === 'failed') { - return response.customError({ - statusCode: 500, - body: { - message: i18n.translate( - 'xpack.upgradeAssistant.ml_snapshots.modelSnapshotUpgradeFailed', - { - defaultMessage: - 'The upgrade process for this model snapshot failed. Check the Elasticsearch logs for more details.', - } - ), - }, - }); - } else { - // The task ID was not found; verify the deprecation was resolved - const { isSuccessful: isSnapshotDeprecationResolved, error: upgradeSnapshotError } = - await verifySnapshotUpgrade(esClient, { - snapshotId, - jobId, - }); - - // Delete the SO; if it's complete, no need to store it anymore. If there's an error, this will give the user a chance to retry - await deleteMlOperation(savedObjectsClient, snapshotOp.id); - - if (isSnapshotDeprecationResolved) { - return response.ok({ - body: { - ...snapshotInfo, - status: 'complete', - }, - }); - } - - return response.customError({ - statusCode: upgradeSnapshotError ? upgradeSnapshotError.statusCode! : 500, - body: { - message: - upgradeSnapshotError?.body?.error?.reason || - 'The upgrade process for this model snapshot stopped yet the snapshot is not upgraded. Check the Elasticsearch logs for more details.', - }, - }); - } } else { - // No tasks found; verify the deprecation was resolved + // The task ID was not found; verify the deprecation was resolved const { isSuccessful: isSnapshotDeprecationResolved, error: upgradeSnapshotError } = await verifySnapshotUpgrade(esClient, { snapshotId, @@ -319,23 +277,51 @@ export function registerMlSnapshotRoutes({ }); } - log.error( - `Failed to determine status of the ML model upgrade, upgradeStatus is not defined and snapshot upgrade is not completed. snapshotId=${snapshotId} and jobId=${jobId}` - ); return response.customError({ statusCode: upgradeSnapshotError ? upgradeSnapshotError.statusCode! : 500, body: { message: upgradeSnapshotError?.body?.error?.reason || - 'The upgrade process for this model snapshot completed yet the snapshot is not upgraded. Check the Elasticsearch logs for more details.', + 'The upgrade process for this model snapshot stopped yet the snapshot is not upgraded. Check the Elasticsearch logs for more details.', + }, + }); + } + } else { + // No tasks found; verify the deprecation was resolved + const { isSuccessful: isSnapshotDeprecationResolved, error: upgradeSnapshotError } = + await verifySnapshotUpgrade(esClient, { + snapshotId, + jobId, + }); + + // Delete the SO; if it's complete, no need to store it anymore. If there's an error, this will give the user a chance to retry + await deleteMlOperation(savedObjectsClient, snapshotOp.id); + + if (isSnapshotDeprecationResolved) { + return response.ok({ + body: { + ...snapshotInfo, + status: 'complete', }, }); } - } catch (e) { - return handleEsError({ error: e, response }); + + log.error( + `Failed to determine status of the ML model upgrade, upgradeStatus is not defined and snapshot upgrade is not completed. snapshotId=${snapshotId} and jobId=${jobId}` + ); + return response.customError({ + statusCode: upgradeSnapshotError ? upgradeSnapshotError.statusCode! : 500, + body: { + message: + upgradeSnapshotError?.body?.error?.reason || + 'The upgrade process for this model snapshot completed yet the snapshot is not upgraded. Check the Elasticsearch logs for more details.', + }, + }); } + } catch (e) { + return handleEsError({ error: e, response }); } - ) + }) ); // Get the ml upgrade mode @@ -344,29 +330,22 @@ export function registerMlSnapshotRoutes({ path: `${API_BASE_PATH}/ml_upgrade_mode`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client: esClient }, + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client: esClient }, + } = await core; + const mlInfo = await esClient.asCurrentUser.ml.info(); + + return response.ok({ + body: { + mlUpgradeModeEnabled: mlInfo.upgrade_mode, }, - }, - request, - response - ) => { - try { - const mlInfo = await esClient.asCurrentUser.ml.info(); - - return response.ok({ - body: { - mlUpgradeModeEnabled: mlInfo.upgrade_mode, - }, - }); - } catch (e) { - return handleEsError({ error: e, response }); - } + }); + } catch (e) { + return handleEsError({ error: e, response }); } - ) + }) ); // Delete ML model snapshot @@ -380,31 +359,24 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const { snapshotId, jobId } = request.params; - - const deleteSnapshotResponse = await client.asCurrentUser.ml.deleteModelSnapshot({ - job_id: jobId, - snapshot_id: snapshotId, - }); - - return response.ok({ - body: deleteSnapshotResponse, - }); - } catch (e) { - return handleEsError({ error: e, response }); - } + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const { snapshotId, jobId } = request.params; + + const deleteSnapshotResponse = await client.asCurrentUser.ml.deleteModelSnapshot({ + job_id: jobId, + snapshot_id: snapshotId, + }); + + return response.ok({ + body: deleteSnapshotResponse, + }); + } catch (e) { + return handleEsError({ error: e, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/node_disk_space.ts b/x-pack/plugins/upgrade_assistant/server/routes/node_disk_space.ts index 9bd6b39cd6f5e71..3707bee0f1395aa 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/node_disk_space.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/node_disk_space.ts @@ -49,91 +49,84 @@ export function registerNodeDiskSpaceRoute({ router, lib: { handleEsError } }: R path: `${API_BASE_PATH}/node_disk_space`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const clusterSettings = await client.asCurrentUser.cluster.getSettings({ - flat_settings: true, - include_defaults: true, + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const clusterSettings = await client.asCurrentUser.cluster.getSettings({ + flat_settings: true, + include_defaults: true, + }); + + const lowDiskWatermarkSetting = getLowDiskWatermarkSetting(clusterSettings); + + if (lowDiskWatermarkSetting) { + const nodeStats = await client.asCurrentUser.nodes.stats({ + metric: 'fs', }); - const lowDiskWatermarkSetting = getLowDiskWatermarkSetting(clusterSettings); + const nodeIds = Object.keys(nodeStats.nodes); - if (lowDiskWatermarkSetting) { - const nodeStats = await client.asCurrentUser.nodes.stats({ - metric: 'fs', - }); + const nodesWithLowDiskSpace: NodeWithLowDiskSpace[] = []; - const nodeIds = Object.keys(nodeStats.nodes); + nodeIds.forEach((nodeId) => { + const node = nodeStats.nodes[nodeId]; + const byteStats = node?.fs?.total; + // @ts-expect-error @elastic/elasticsearch not supported + const { total_in_bytes: totalInBytes, available_in_bytes: availableInBytes } = + byteStats; - const nodesWithLowDiskSpace: NodeWithLowDiskSpace[] = []; + // Regex to determine if the low disk watermark setting is configured as a percentage value + // Elasticsearch accepts a percentage or bytes value + const isLowDiskWatermarkPercentage = /^(\d+|(\.\d+))(\.\d+)?%$/.test( + lowDiskWatermarkSetting! + ); - nodeIds.forEach((nodeId) => { - const node = nodeStats.nodes[nodeId]; - const byteStats = node?.fs?.total; - // @ts-expect-error @elastic/elasticsearch not supported - const { total_in_bytes: totalInBytes, available_in_bytes: availableInBytes } = - byteStats; - - // Regex to determine if the low disk watermark setting is configured as a percentage value - // Elasticsearch accepts a percentage or bytes value - const isLowDiskWatermarkPercentage = /^(\d+|(\.\d+))(\.\d+)?%$/.test( - lowDiskWatermarkSetting! + if (isLowDiskWatermarkPercentage) { + const percentageAvailable = (availableInBytes / totalInBytes) * 100; + const rawLowDiskWatermarkPercentageValue = Number( + lowDiskWatermarkSetting!.replace('%', '') ); - if (isLowDiskWatermarkPercentage) { - const percentageAvailable = (availableInBytes / totalInBytes) * 100; - const rawLowDiskWatermarkPercentageValue = Number( - lowDiskWatermarkSetting!.replace('%', '') - ); - - // If the percentage available is < the low disk watermark setting, mark node as having low disk space - if (percentageAvailable < rawLowDiskWatermarkPercentageValue) { - nodesWithLowDiskSpace.push({ - nodeId, - nodeName: node.name || nodeId, - available: `${Math.round(percentageAvailable)}%`, - lowDiskWatermarkSetting: lowDiskWatermarkSetting!, - }); - } - } else { - // If not a percentage value, assume user configured low disk watermark setting in bytes - const rawLowDiskWatermarkBytesValue = ByteSizeValue.parse( - lowDiskWatermarkSetting! - ).getValueInBytes(); - - const percentageAvailable = (availableInBytes / totalInBytes) * 100; - - // If bytes available < the low disk watermarket setting, mark node as having low disk space - if (availableInBytes < rawLowDiskWatermarkBytesValue) { - nodesWithLowDiskSpace.push({ - nodeId, - nodeName: node.name || nodeId, - available: `${Math.round(percentageAvailable)}%`, - lowDiskWatermarkSetting: lowDiskWatermarkSetting!, - }); - } + // If the percentage available is < the low disk watermark setting, mark node as having low disk space + if (percentageAvailable < rawLowDiskWatermarkPercentageValue) { + nodesWithLowDiskSpace.push({ + nodeId, + nodeName: node.name || nodeId, + available: `${Math.round(percentageAvailable)}%`, + lowDiskWatermarkSetting: lowDiskWatermarkSetting!, + }); } - }); - - return response.ok({ body: nodesWithLowDiskSpace }); - } + } else { + // If not a percentage value, assume user configured low disk watermark setting in bytes + const rawLowDiskWatermarkBytesValue = ByteSizeValue.parse( + lowDiskWatermarkSetting! + ).getValueInBytes(); + + const percentageAvailable = (availableInBytes / totalInBytes) * 100; + + // If bytes available < the low disk watermarket setting, mark node as having low disk space + if (availableInBytes < rawLowDiskWatermarkBytesValue) { + nodesWithLowDiskSpace.push({ + nodeId, + nodeName: node.name || nodeId, + available: `${Math.round(percentageAvailable)}%`, + lowDiskWatermarkSetting: lowDiskWatermarkSetting!, + }); + } + } + }); - // If the low disk watermark setting is undefined, send empty array - // This could occur if the setting is configured in elasticsearch.yml - return response.ok({ body: [] }); - } catch (error) { - return handleEsError({ error, response }); + return response.ok({ body: nodesWithLowDiskSpace }); } + + // If the low disk watermark setting is undefined, send empty array + // This could occur if the setting is configured in elasticsearch.yml + return response.ok({ body: [] }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts index 62be9a1807aad7a..c6ea9b4a8fb9679 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts @@ -38,37 +38,30 @@ export function registerBatchReindexIndicesRoutes( path: `${BASE_PATH}/batch/queue`, validate: {}, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client: esClient }, - savedObjects, - }, - }, - request, - response - ) => { - const { client } = savedObjects; - const callAsCurrentUser = esClient.asCurrentUser; - const reindexActions = reindexActionsFactory(client, callAsCurrentUser); - try { - const inProgressOps = await reindexActions.findAllByStatus(ReindexStatus.inProgress); - const { queue } = sortAndOrderReindexOperations(inProgressOps); - const result: GetBatchQueueResponse = { - queue: queue.map((savedObject) => savedObject.attributes), - }; - return response.ok({ - body: result, - }); - } catch (error) { - if (error instanceof errors.ResponseError) { - return handleEsError({ error, response }); - } - return mapAnyErrorToKibanaHttpResponse(error); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + elasticsearch: { client: esClient }, + savedObjects, + } = await core; + const { client } = savedObjects; + const callAsCurrentUser = esClient.asCurrentUser; + const reindexActions = reindexActionsFactory(client, callAsCurrentUser); + try { + const inProgressOps = await reindexActions.findAllByStatus(ReindexStatus.inProgress); + const { queue } = sortAndOrderReindexOperations(inProgressOps); + const result: GetBatchQueueResponse = { + queue: queue.map((savedObject) => savedObject.attributes), + }; + return response.ok({ + body: result, + }); + } catch (error) { + if (error instanceof errors.ResponseError) { + return handleEsError({ error, response }); } + return mapAnyErrorToKibanaHttpResponse(error); } - ) + }) ); // Add indices for reindexing to the worker's batch @@ -81,53 +74,46 @@ export function registerBatchReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - const { indexNames } = request.body; - const results: PostBatchResponse = { - enqueued: [], - errors: [], - }; - for (const indexName of indexNames) { - try { - const result = await reindexHandler({ - savedObjects: savedObjectsClient, - dataClient: esClient, - indexName, - log, - licensing, - request, - credentialStore, - reindexOptions: { - enqueue: true, - }, - security: getSecurityPlugin(), - }); - results.enqueued.push(result); - } catch (e) { - results.errors.push({ - indexName, - message: e.message, - }); - } - } - - if (results.errors.length < indexNames.length) { - // Kick the worker on this node to immediately pickup the batch. - getWorker().forceRefresh(); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client: esClient }, + } = await core; + const { indexNames } = request.body; + const results: PostBatchResponse = { + enqueued: [], + errors: [], + }; + for (const indexName of indexNames) { + try { + const result = await reindexHandler({ + savedObjects: savedObjectsClient, + dataClient: esClient, + indexName, + log, + licensing, + request, + credentialStore, + reindexOptions: { + enqueue: true, + }, + security: getSecurityPlugin(), + }); + results.enqueued.push(result); + } catch (e) { + results.errors.push({ + indexName, + message: e.message, + }); } + } - return response.ok({ body: results }); + if (results.errors.length < indexNames.length) { + // Kick the worker on this node to immediately pickup the batch. + getWorker().forceRefresh(); } - ) + + return response.ok({ body: results }); + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts index d5776cb161b4d4e..11ebb6d5f4a987a 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts @@ -40,44 +40,37 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects: { client: savedObjectsClient }, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - const { indexName } = request.params; - try { - const result = await reindexHandler({ - savedObjects: savedObjectsClient, - dataClient: esClient, - indexName, - log, - licensing, - request, - credentialStore, - security: getSecurityPlugin(), - }); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + savedObjects: { client: savedObjectsClient }, + elasticsearch: { client: esClient }, + } = await core; + const { indexName } = request.params; + try { + const result = await reindexHandler({ + savedObjects: savedObjectsClient, + dataClient: esClient, + indexName, + log, + licensing, + request, + credentialStore, + security: getSecurityPlugin(), + }); - // Kick the worker on this node to immediately pickup the new reindex operation. - getWorker().forceRefresh(); + // Kick the worker on this node to immediately pickup the new reindex operation. + getWorker().forceRefresh(); - return response.ok({ - body: result, - }); - } catch (error) { - if (error instanceof errors.ResponseError) { - return handleEsError({ error, response }); - } - return mapAnyErrorToKibanaHttpResponse(error); + return response.ok({ + body: result, + }); + } catch (error) { + if (error instanceof errors.ResponseError) { + return handleEsError({ error, response }); } + return mapAnyErrorToKibanaHttpResponse(error); } - ) + }) ); // Get status @@ -90,55 +83,48 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - const { client } = savedObjects; - const { indexName } = request.params; - const asCurrentUser = esClient.asCurrentUser; - const reindexActions = reindexActionsFactory(client, asCurrentUser); - const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + savedObjects, + elasticsearch: { client: esClient }, + } = await core; + const { client } = savedObjects; + const { indexName } = request.params; + const asCurrentUser = esClient.asCurrentUser; + const reindexActions = reindexActionsFactory(client, asCurrentUser); + const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); - try { - const hasRequiredPrivileges = await reindexService.hasRequiredPrivileges(indexName); - const reindexOp = await reindexService.findReindexOperation(indexName); - // If the user doesn't have privileges than querying for warnings is going to fail. - const warnings = hasRequiredPrivileges - ? await reindexService.detectReindexWarnings(indexName) - : []; + try { + const hasRequiredPrivileges = await reindexService.hasRequiredPrivileges(indexName); + const reindexOp = await reindexService.findReindexOperation(indexName); + // If the user doesn't have privileges than querying for warnings is going to fail. + const warnings = hasRequiredPrivileges + ? await reindexService.detectReindexWarnings(indexName) + : []; - const indexAliases = await reindexService.getIndexAliases(indexName); + const indexAliases = await reindexService.getIndexAliases(indexName); - const body: ReindexStatusResponse = { - reindexOp: reindexOp ? reindexOp.attributes : undefined, - warnings, - hasRequiredPrivileges, - meta: { - indexName, - reindexName: generateNewIndexName(indexName), - aliases: Object.keys(indexAliases), - }, - }; + const body: ReindexStatusResponse = { + reindexOp: reindexOp ? reindexOp.attributes : undefined, + warnings, + hasRequiredPrivileges, + meta: { + indexName, + reindexName: generateNewIndexName(indexName), + aliases: Object.keys(indexAliases), + }, + }; - return response.ok({ - body, - }); - } catch (error) { - if (error instanceof errors.ResponseError) { - return handleEsError({ error, response }); - } - return mapAnyErrorToKibanaHttpResponse(error); + return response.ok({ + body, + }); + } catch (error) { + if (error instanceof errors.ResponseError) { + return handleEsError({ error, response }); } + return mapAnyErrorToKibanaHttpResponse(error); } - ) + }) ); // Cancel reindex @@ -151,40 +137,33 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - savedObjects, - elasticsearch: { client: esClient }, - }, - }, - request, - response - ) => { - const { indexName } = request.params; - const { client } = savedObjects; - const callAsCurrentUser = esClient.asCurrentUser; - const reindexActions = reindexActionsFactory(client, callAsCurrentUser); - const reindexService = reindexServiceFactory( - callAsCurrentUser, - reindexActions, - log, - licensing - ); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + const { + savedObjects, + elasticsearch: { client: esClient }, + } = await core; + const { indexName } = request.params; + const { client } = savedObjects; + const callAsCurrentUser = esClient.asCurrentUser; + const reindexActions = reindexActionsFactory(client, callAsCurrentUser); + const reindexService = reindexServiceFactory( + callAsCurrentUser, + reindexActions, + log, + licensing + ); - try { - await reindexService.cancelReindexing(indexName); + try { + await reindexService.cancelReindexing(indexName); - return response.ok({ body: { acknowledged: true } }); - } catch (error) { - if (error instanceof errors.ResponseError) { - return handleEsError({ error, response }); - } - - return mapAnyErrorToKibanaHttpResponse(error); + return response.ok({ body: { acknowledged: true } }); + } catch (error) { + if (error instanceof errors.ResponseError) { + return handleEsError({ error, response }); } + + return mapAnyErrorToKibanaHttpResponse(error); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts b/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts index 0d7268e1be5be17..6598051e3c7f6b6 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts @@ -15,26 +15,19 @@ export function registerRemoteClustersRoute({ router, lib: { handleEsError } }: path: `${API_BASE_PATH}/remote_clusters`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const clustersByName = await client.asCurrentUser.cluster.remoteInfo(); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const clustersByName = await client.asCurrentUser.cluster.remoteInfo(); - const remoteClusters = Object.keys(clustersByName); + const remoteClusters = Object.keys(clustersByName); - return response.ok({ body: remoteClusters }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ body: remoteClusters }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/status.ts b/x-pack/plugins/upgrade_assistant/server/routes/status.ts index 9e8d3f9b2734b77..691debfe776cd45 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/status.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/status.ts @@ -22,98 +22,89 @@ export function registerUpgradeStatusRoute({ router, lib: { handleEsError } }: R path: `${API_BASE_PATH}/status`, validate: false, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client: esClient }, - deprecations: { client: deprecationsClient }, - }, - }, - request, - response - ) => { - try { - // Fetch ES upgrade status - const { totalCriticalDeprecations: esTotalCriticalDeps } = await getESUpgradeStatus( - esClient - ); - // Fetch system indices migration status - const { migration_status: systemIndicesMigrationStatus, features } = - await getESSystemIndicesMigrationStatus(esClient.asCurrentUser); - const notMigratedSystemIndices = features.filter( - (feature) => feature.migration_status !== 'NO_MIGRATION_NEEDED' - ).length; - - // Fetch Kibana upgrade status - const { totalCriticalDeprecations: kibanaTotalCriticalDeps } = - await getKibanaUpgradeStatus(deprecationsClient); - const readyForUpgrade = - esTotalCriticalDeps === 0 && - kibanaTotalCriticalDeps === 0 && - systemIndicesMigrationStatus === 'NO_MIGRATION_NEEDED'; + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client: esClient }, + deprecations: { client: deprecationsClient }, + } = await core; + // Fetch ES upgrade status + const { totalCriticalDeprecations: esTotalCriticalDeps } = await getESUpgradeStatus( + esClient + ); + // Fetch system indices migration status + const { migration_status: systemIndicesMigrationStatus, features } = + await getESSystemIndicesMigrationStatus(esClient.asCurrentUser); + const notMigratedSystemIndices = features.filter( + (feature) => feature.migration_status !== 'NO_MIGRATION_NEEDED' + ).length; - const getStatusMessage = () => { - if (readyForUpgrade) { - return i18n.translate( - 'xpack.upgradeAssistant.status.allDeprecationsResolvedMessage', - { - defaultMessage: 'All deprecation warnings have been resolved.', - } - ); - } + // Fetch Kibana upgrade status + const { totalCriticalDeprecations: kibanaTotalCriticalDeps } = await getKibanaUpgradeStatus( + deprecationsClient + ); + const readyForUpgrade = + esTotalCriticalDeps === 0 && + kibanaTotalCriticalDeps === 0 && + systemIndicesMigrationStatus === 'NO_MIGRATION_NEEDED'; - const upgradeIssues: string[] = []; + const getStatusMessage = () => { + if (readyForUpgrade) { + return i18n.translate('xpack.upgradeAssistant.status.allDeprecationsResolvedMessage', { + defaultMessage: 'All deprecation warnings have been resolved.', + }); + } - if (notMigratedSystemIndices) { - upgradeIssues.push( - i18n.translate('xpack.upgradeAssistant.status.systemIndicesMessage', { - defaultMessage: - '{notMigratedSystemIndices} unmigrated system {notMigratedSystemIndices, plural, one {index} other {indices}}', - values: { notMigratedSystemIndices }, - }) - ); - } + const upgradeIssues: string[] = []; - if (esTotalCriticalDeps) { - upgradeIssues.push( - i18n.translate('xpack.upgradeAssistant.status.esTotalCriticalDepsMessage', { - defaultMessage: - '{esTotalCriticalDeps} Elasticsearch deprecation {esTotalCriticalDeps, plural, one {issue} other {issues}}', - values: { esTotalCriticalDeps }, - }) - ); - } + if (notMigratedSystemIndices) { + upgradeIssues.push( + i18n.translate('xpack.upgradeAssistant.status.systemIndicesMessage', { + defaultMessage: + '{notMigratedSystemIndices} unmigrated system {notMigratedSystemIndices, plural, one {index} other {indices}}', + values: { notMigratedSystemIndices }, + }) + ); + } - if (kibanaTotalCriticalDeps) { - upgradeIssues.push( - i18n.translate('xpack.upgradeAssistant.status.kibanaTotalCriticalDepsMessage', { - defaultMessage: - '{kibanaTotalCriticalDeps} Kibana deprecation {kibanaTotalCriticalDeps, plural, one {issue} other {issues}}', - values: { kibanaTotalCriticalDeps }, - }) - ); - } + if (esTotalCriticalDeps) { + upgradeIssues.push( + i18n.translate('xpack.upgradeAssistant.status.esTotalCriticalDepsMessage', { + defaultMessage: + '{esTotalCriticalDeps} Elasticsearch deprecation {esTotalCriticalDeps, plural, one {issue} other {issues}}', + values: { esTotalCriticalDeps }, + }) + ); + } - return i18n.translate('xpack.upgradeAssistant.status.deprecationsUnresolvedMessage', { - defaultMessage: - 'The following issues must be resolved before upgrading: {upgradeIssues}.', - values: { - upgradeIssues: upgradeIssues.join(', '), - }, - }); - }; + if (kibanaTotalCriticalDeps) { + upgradeIssues.push( + i18n.translate('xpack.upgradeAssistant.status.kibanaTotalCriticalDepsMessage', { + defaultMessage: + '{kibanaTotalCriticalDeps} Kibana deprecation {kibanaTotalCriticalDeps, plural, one {issue} other {issues}}', + values: { kibanaTotalCriticalDeps }, + }) + ); + } - return response.ok({ - body: { - readyForUpgrade, - details: getStatusMessage(), + return i18n.translate('xpack.upgradeAssistant.status.deprecationsUnresolvedMessage', { + defaultMessage: + 'The following issues must be resolved before upgrading: {upgradeIssues}.', + values: { + upgradeIssues: upgradeIssues.join(', '), }, }); - } catch (error) { - return handleEsError({ error, response }); - } + }; + + return response.ok({ + body: { + readyForUpgrade, + details: getStatusMessage(), + }, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.ts b/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.ts index 67f91aa08a07680..aae7df2f43f15c6 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.ts @@ -20,57 +20,43 @@ export function registerSystemIndicesMigrationRoutes({ // GET status of the system indices migration router.get( { path: `${API_BASE_PATH}/system_indices_migration`, validate: false }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const status = await getESSystemIndicesMigrationStatus(client.asCurrentUser); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const status = await getESSystemIndicesMigrationStatus(client.asCurrentUser); - return response.ok({ - body: { - ...status, - features: status.features.filter( - (feature) => feature.migration_status !== 'NO_MIGRATION_NEEDED' - ), - }, - }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ + body: { + ...status, + features: status.features.filter( + (feature) => feature.migration_status !== 'NO_MIGRATION_NEEDED' + ), + }, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); // POST starts the system indices migration router.post( { path: `${API_BASE_PATH}/system_indices_migration`, validate: false }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const status = await startESSystemIndicesMigration(client.asCurrentUser); + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const status = await startESSystemIndicesMigration(client.asCurrentUser); - return response.ok({ - body: status, - }); - } catch (error) { - return handleEsError({ error, response }); - } + return response.ok({ + body: status, + }); + } catch (error) { + return handleEsError({ error, response }); } - ) + }) ); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/update_index_settings.ts b/x-pack/plugins/upgrade_assistant/server/routes/update_index_settings.ts index c0d7134ffee5f1d..382ac77721616bd 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/update_index_settings.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/update_index_settings.ts @@ -23,42 +23,35 @@ export function registerUpdateSettingsRoute({ router }: RouteDependencies) { }), }, }, - versionCheckHandlerWrapper( - async ( - { - core: { - elasticsearch: { client }, - }, - }, - request, - response - ) => { - try { - const { indexName } = request.params; - const { settings } = request.body; + versionCheckHandlerWrapper(async ({ core }, request, response) => { + try { + const { + elasticsearch: { client }, + } = await core; + const { indexName } = request.params; + const { settings } = request.body; - const settingsToDelete = settings.reduce((settingsBody, currentSetting) => { - settingsBody[currentSetting] = null; - return settingsBody; - }, {} as { [key: string]: null }); + const settingsToDelete = settings.reduce((settingsBody, currentSetting) => { + settingsBody[currentSetting] = null; + return settingsBody; + }, {} as { [key: string]: null }); - const settingsResponse = await client.asCurrentUser.indices.putSettings({ - index: indexName, - body: settingsToDelete, - }); + const settingsResponse = await client.asCurrentUser.indices.putSettings({ + index: indexName, + body: settingsToDelete, + }); - return response.ok({ - body: settingsResponse, - }); - } catch (e) { - const status = e.status || e.statusCode; - if (status === 403) { - return response.forbidden({ body: e }); - } - - throw e; + return response.ok({ + body: settingsResponse, + }); + } catch (e) { + const status = e.status || e.statusCode; + if (status === 403) { + return response.forbidden({ body: e }); } + + throw e; } - ) + }) ); } diff --git a/x-pack/plugins/watcher/server/routes/api/indices/register_get_index_patterns_route.ts b/x-pack/plugins/watcher/server/routes/api/indices/register_get_index_patterns_route.ts index 26ecb5de4761e01..0c49e5ea894dd6f 100644 --- a/x-pack/plugins/watcher/server/routes/api/indices/register_get_index_patterns_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/indices/register_get_index_patterns_route.ts @@ -18,8 +18,9 @@ export function registerGetIndexPatternsRoute({ path: '/api/watcher/indices/index_patterns', validate: false, }, - license.guardApiRoute(async ({ core: { savedObjects } }, request, response) => { + license.guardApiRoute(async ({ core }, request, response) => { try { + const { savedObjects } = await core; const finder = savedObjects.client.createPointInTimeFinder({ type: 'index-pattern', fields: ['title'], diff --git a/x-pack/plugins/watcher/server/routes/api/indices/register_get_route.ts b/x-pack/plugins/watcher/server/routes/api/indices/register_get_route.ts index 8cf7d0a61d5d8f4..da78238ebd5cde8 100644 --- a/x-pack/plugins/watcher/server/routes/api/indices/register_get_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/indices/register_get_route.ts @@ -87,7 +87,8 @@ export function registerGetRoute({ router, license, lib: { handleEsError } }: Ro const { pattern } = request.body; try { - const indices = await getIndices(ctx.core.elasticsearch.client, pattern); + const esClient = (await ctx.core).elasticsearch.client; + const indices = await getIndices(esClient, pattern); return response.ok({ body: { indices } }); } catch (e) { return handleEsError({ error: e, response }); diff --git a/x-pack/plugins/watcher/server/routes/api/register_list_fields_route.ts b/x-pack/plugins/watcher/server/routes/api/register_list_fields_route.ts index 458fdb1d56fee0a..915695eaf50fa3a 100644 --- a/x-pack/plugins/watcher/server/routes/api/register_list_fields_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/register_list_fields_route.ts @@ -43,7 +43,8 @@ export function registerListFieldsRoute({ const { indexes } = request.body; try { - const fieldsResponse = await fetchFields(ctx.core.elasticsearch.client, indexes); + const esClient = (await ctx.core).elasticsearch.client; + const fieldsResponse = await fetchFields(esClient, indexes); const json = fieldsResponse.statusCode === 404 ? { fields: [] } : fieldsResponse.body; const fields = Fields.fromUpstreamJson(json); return response.ok({ body: fields.downstreamJson }); diff --git a/x-pack/plugins/watcher/server/routes/api/register_load_history_route.ts b/x-pack/plugins/watcher/server/routes/api/register_load_history_route.ts index c24ddc2d74655b1..d3a3f07e41b9adb 100644 --- a/x-pack/plugins/watcher/server/routes/api/register_load_history_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/register_load_history_route.ts @@ -46,7 +46,8 @@ export function registerLoadHistoryRoute({ const id = request.params.id; try { - const responseFromES = await fetchHistoryItem(ctx.core.elasticsearch.client, id); + const esClient = (await ctx.core).elasticsearch.client; + const responseFromES = await fetchHistoryItem(esClient, id); const hit = get(responseFromES, 'hits.hits[0]'); if (!hit) { return response.notFound({ body: `Watch History Item with id = ${id} not found` }); diff --git a/x-pack/plugins/watcher/server/routes/api/settings/register_load_route.ts b/x-pack/plugins/watcher/server/routes/api/settings/register_load_route.ts index 6733da355c86210..6fdbbe1de96ac9c 100644 --- a/x-pack/plugins/watcher/server/routes/api/settings/register_load_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/settings/register_load_route.ts @@ -25,7 +25,8 @@ export function registerLoadRoute({ router, license, lib: { handleEsError } }: R }, license.guardApiRoute(async (ctx, request, response) => { try { - const settings = await fetchClusterSettings(ctx.core.elasticsearch.client); + const esClient = (await ctx.core).elasticsearch.client; + const settings = await fetchClusterSettings(esClient); return response.ok({ body: Settings.fromUpstreamJson(settings).downstreamJson }); } catch (e) { return handleEsError({ error: e, response }); diff --git a/x-pack/plugins/watcher/server/routes/api/watch/action/register_acknowledge_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/action/register_acknowledge_route.ts index 9f0e17cfe4ef54f..31b6d9ec15995ca 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/action/register_acknowledge_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/action/register_acknowledge_route.ts @@ -40,7 +40,8 @@ export function registerAcknowledgeRoute({ const { watchId, actionId } = request.params; try { - const hit = await acknowledgeAction(ctx.core.elasticsearch.client, watchId, actionId); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await acknowledgeAction(esClient, watchId, actionId); const watchStatusJson = get(hit, 'status'); const json = { id: watchId, diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_activate_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_activate_route.ts index 5b59a35e8ffcdfb..213567aef26a3a3 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_activate_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_activate_route.ts @@ -38,7 +38,8 @@ export function registerActivateRoute({ const { watchId } = request.params; try { - const hit = await activateWatch(ctx.core.elasticsearch.client, watchId); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await activateWatch(esClient, watchId); const watchStatusJson = get(hit, 'status'); const json = { id: watchId, diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_deactivate_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_deactivate_route.ts index a22fcee62e58864..2d929965468b1a9 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_deactivate_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_deactivate_route.ts @@ -38,7 +38,8 @@ export function registerDeactivateRoute({ const { watchId } = request.params; try { - const hit = await deactivateWatch(ctx.core.elasticsearch.client, watchId); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await deactivateWatch(esClient, watchId); const watchStatusJson = get(hit, 'status'); const json = { id: watchId, diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_delete_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_delete_route.ts index 809500dad205e2f..c35efbd4bb3209a 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_delete_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_delete_route.ts @@ -35,8 +35,9 @@ export function registerDeleteRoute({ const { watchId } = request.params; try { + const esClient = (await ctx.core).elasticsearch.client; return response.ok({ - body: await deleteWatch(ctx.core.elasticsearch.client, watchId), + body: await deleteWatch(esClient, watchId), }); } catch (e) { if (e?.statusCode === 404 && e.meta?.body?.error) { diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_execute_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_execute_route.ts index 106447879198f02..c7a082f640c6aaa 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_execute_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_execute_route.ts @@ -50,11 +50,8 @@ export function registerExecuteRoute({ const watch = Watch.fromDownstreamJson(request.body.watch); try { - const hit = await executeWatch( - ctx.core.elasticsearch.client, - executeDetails.upstreamJson, - watch.watchJson - ); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await executeWatch(esClient, executeDetails.upstreamJson, watch.watchJson); const id = get(hit, '_id'); const watchHistoryItemJson = get(hit, 'watch_record'); const watchId = get(hit, 'watch_record.watch_id'); diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_history_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_history_route.ts index af820c20fc01a92..f3d810424d9a607 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_history_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_history_route.ts @@ -66,7 +66,8 @@ export function registerHistoryRoute({ const { startTime } = request.query; try { - const hits = await fetchHistoryItems(ctx.core.elasticsearch.client, watchId, startTime); + const esClient = (await ctx.core).elasticsearch.client; + const hits = await fetchHistoryItems(esClient, watchId, startTime); const watchHistoryItems = hits.map((hit: any) => { const id = get(hit, '_id'); const watchHistoryItemJson = get(hit, '_source'); diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_load_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_load_route.ts index 76dea16c9698194..a2fea1d5b73d491 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_load_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_load_route.ts @@ -34,7 +34,8 @@ export function registerLoadRoute({ router, license, lib: { handleEsError } }: R const id = request.params.id; try { - const hit = await fetchWatch(ctx.core.elasticsearch.client, id); + const esClient = (await ctx.core).elasticsearch.client; + const hit = await fetchWatch(esClient, id); const watchJson = get(hit, 'watch'); const watchStatusJson = get(hit, 'status'); const json = { diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_save_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_save_route.ts index 6aebd4968f066c5..86e3c2d1da1024d 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_save_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_save_route.ts @@ -37,7 +37,7 @@ export function registerSaveRoute({ router, license, lib: { handleEsError } }: R const { id } = request.params; const { type, isNew, isActive, ...watchConfig } = request.body; - const dataClient = ctx.core.elasticsearch.client; + const dataClient = (await ctx.core).elasticsearch.client; // For new watches, verify watch with the same ID doesn't already exist if (isNew) { diff --git a/x-pack/plugins/watcher/server/routes/api/watch/register_visualize_route.ts b/x-pack/plugins/watcher/server/routes/api/watch/register_visualize_route.ts index 40672b3d8f5a4b0..defc1b3451e6b75 100644 --- a/x-pack/plugins/watcher/server/routes/api/watch/register_visualize_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watch/register_visualize_route.ts @@ -52,7 +52,8 @@ export function registerVisualizeRoute({ const body = watch.getVisualizeQuery(options, kibanaVersion); try { - const hits = await fetchVisualizeData(ctx.core.elasticsearch.client, watch.index, body); + const esClient = (await ctx.core).elasticsearch.client; + const hits = await fetchVisualizeData(esClient, watch.index, body); const visualizeData = watch.formatVisualizeData(hits); return response.ok({ diff --git a/x-pack/plugins/watcher/server/routes/api/watches/register_delete_route.ts b/x-pack/plugins/watcher/server/routes/api/watches/register_delete_route.ts index 9f481fec3f4db7f..5458f850b33e627 100644 --- a/x-pack/plugins/watcher/server/routes/api/watches/register_delete_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watches/register_delete_route.ts @@ -56,7 +56,8 @@ export function registerDeleteRoute({ router, license }: RouteDependencies) { }, }, license.guardApiRoute(async (ctx, request, response) => { - const results = await deleteWatches(ctx.core.elasticsearch.client, request.body.watchIds); + const esClient = (await ctx.core).elasticsearch.client; + const results = await deleteWatches(esClient, request.body.watchIds); return response.ok({ body: { results } }); }) ); diff --git a/x-pack/plugins/watcher/server/routes/api/watches/register_list_route.ts b/x-pack/plugins/watcher/server/routes/api/watches/register_list_route.ts index 9ccfddbaf3923cf..9951da819e9e093 100644 --- a/x-pack/plugins/watcher/server/routes/api/watches/register_list_route.ts +++ b/x-pack/plugins/watcher/server/routes/api/watches/register_list_route.ts @@ -36,7 +36,8 @@ export function registerListRoute({ router, license, lib: { handleEsError } }: R }, license.guardApiRoute(async (ctx, request, response) => { try { - const hits = await fetchWatches(ctx.core.elasticsearch.client); + const esClient = (await ctx.core).elasticsearch.client; + const hits = await fetchWatches(esClient); const watches = hits.map((hit: any) => { const id = get(hit, '_id'); const watchJson = get(hit, '_source'); diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts index 10fedc3151270b2..6e4eba065ec70ef 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager_fixture/server/plugin.ts @@ -88,7 +88,8 @@ export class SampleTaskManagerFixturePlugin req: KibanaRequest, res: KibanaResponseFactory ): Promise> { - await context.core.elasticsearch.client.asInternalUser.indices.refresh({ + const coreCtx = await context.core; + await coreCtx.elasticsearch.client.asInternalUser.indices.refresh({ index: '.kibana_task_manager', }); return res.ok({ body: {} }); diff --git a/x-pack/test/functional_execution_context/fixtures/plugins/alerts/server/plugin.ts b/x-pack/test/functional_execution_context/fixtures/plugins/alerts/server/plugin.ts index 82e6253ab6d10bb..e6fc9c5aff6c44e 100644 --- a/x-pack/test/functional_execution_context/fixtures/plugins/alerts/server/plugin.ts +++ b/x-pack/test/functional_execution_context/fixtures/plugins/alerts/server/plugin.ts @@ -103,7 +103,8 @@ export class FixturePlugin implements Plugin { - const body = await context.core.elasticsearch.client.asCurrentUser.security.getUser(); + const coreContext = await context.core; + const body = await coreContext.elasticsearch.client.asCurrentUser.security.getUser(); return res.ok({ body }); } ); diff --git a/x-pack/test/plugin_api_integration/plugins/event_log/server/init_routes.ts b/x-pack/test/plugin_api_integration/plugins/event_log/server/init_routes.ts index 031f898c06fc9a8..f4cbc4ad31ffc97 100644 --- a/x-pack/test/plugin_api_integration/plugins/event_log/server/init_routes.ts +++ b/x-pack/test/plugin_api_integration/plugins/event_log/server/init_routes.ts @@ -35,13 +35,14 @@ export const logEventRoute = (router: IRouter, eventLogger: IEventLogger, logger ): Promise> { const { id } = req.params as { id: string }; const event: IValidatedEvent = req.body; + const soClient = (await context.core).savedObjects.client; logger.info(`test fixture: log event: ${id} ${JSON.stringify(event)}`); try { - await context.core.savedObjects.client.get('event_log_test', id); + await soClient.get('event_log_test', id); logger.info(`found existing saved object`); } catch (ex) { logger.info(`log event error: ${ex}`); - await context.core.savedObjects.client.create('event_log_test', {}, { id }); + await soClient.create('event_log_test', {}, { id }); logger.info(`created saved object ${id}`); } // mark now as start and end diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts index cea7432cbae0838..2d98a58d29d7c17 100644 --- a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts @@ -249,7 +249,7 @@ export function initRoutes( res: KibanaResponseFactory ): Promise> { try { - await ensureIndexIsRefreshed(context.core.elasticsearch.client); + await ensureIndexIsRefreshed((await context.core).elasticsearch.client); const taskManager = await taskManagerStart; return res.ok({ body: await taskManager.get(req.params.taskId) }); } catch ({ isBoom, output, message }) { @@ -268,7 +268,7 @@ export function initRoutes( req: KibanaRequest, res: KibanaResponseFactory ): Promise> { - await ensureIndexIsRefreshed(context.core.elasticsearch.client); + await ensureIndexIsRefreshed((await context.core).elasticsearch.client); return res.ok({ body: {} }); } ); @@ -284,7 +284,7 @@ export function initRoutes( res: KibanaResponseFactory ): Promise> { try { - await ensureIndexIsRefreshed(context.core.elasticsearch.client); + await ensureIndexIsRefreshed((await context.core).elasticsearch.client); let tasksFound = 0; const taskManager = await taskManagerStart; do { diff --git a/x-pack/test/security_api_integration/fixtures/audit/audit_log/server/plugin.ts b/x-pack/test/security_api_integration/fixtures/audit/audit_log/server/plugin.ts index 3fe195595d0ffd2..dcbe7a86bf35390 100644 --- a/x-pack/test/security_api_integration/fixtures/audit/audit_log/server/plugin.ts +++ b/x-pack/test/security_api_integration/fixtures/audit/audit_log/server/plugin.ts @@ -11,8 +11,9 @@ export class AuditTrailTestPlugin implements Plugin { public setup(core: CoreSetup) { const router = core.http.createRouter(); router.get({ path: '/audit_log', validate: false }, async (context, request, response) => { - await context.core.savedObjects.client.create('dashboard', {}); - await context.core.savedObjects.client.find({ type: 'dashboard' }); + const soClient = (await context.core).savedObjects.client; + await soClient.create('dashboard', {}); + await soClient.find({ type: 'dashboard' }); return response.noContent(); }); } diff --git a/x-pack/test/security_functional/fixtures/common/test_endpoints/server/init_routes.ts b/x-pack/test/security_functional/fixtures/common/test_endpoints/server/init_routes.ts index 951ca0b755758ed..16db5c82429314c 100644 --- a/x-pack/test/security_functional/fixtures/common/test_endpoints/server/init_routes.ts +++ b/x-pack/test/security_functional/fixtures/common/test_endpoints/server/init_routes.ts @@ -62,7 +62,7 @@ export function initRoutes(initializerContext: PluginInitializerContext, core: C if (request.body.client === 'start-contract') { scopedClient = (await core.getStartServices())[0].elasticsearch.client.asScoped(request); } else if (request.body.client === 'request-context') { - scopedClient = context.core.elasticsearch.client; + scopedClient = (await context.core).elasticsearch.client; } else { scopedClient = (await core.getStartServices())[0].elasticsearch .createClient('custom') diff --git a/yarn.lock b/yarn.lock index bfa0ddcc26a201b..9a4e679245f8ae7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1415,29 +1415,29 @@ dependencies: tslib "^2.0.0" -"@elastic/apm-rum-core@^5.14.1": - version "5.14.1" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.14.1.tgz#8f65060967c8d68498f2c520e4169ec07eb3b5bb" - integrity sha512-RFgTpXUIEIoy44TPnEN7cVcf2YIBOwaNdALrYVc4lOTMH3u0v4gaS0n9/Aee5nTGqWBLKWXXvMk/dAkjQW6qEg== +"@elastic/apm-rum-core@^5.15.0": + version "5.15.0" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.15.0.tgz#f1067078080be1b7167c72ae6d155b0ed5cdf6c6" + integrity sha512-T5/1hZPskmU6N3Xo2CRNi5tX2ht8R5nLmh5t0I1v8RxkwbQms47AR1f0ZVvXN7W2FCDPadyQXC3f9do3k5A6OA== dependencies: error-stack-parser "^1.3.5" opentracing "^0.14.3" promise-polyfill "^8.1.3" -"@elastic/apm-rum-react@^1.3.4": - version "1.3.4" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum-react/-/apm-rum-react-1.3.4.tgz#f60f1ba55696f4e04eba64edb323e43ef9d67acb" - integrity sha512-HPKU/tnTbiSQr6HYxHB9rP4TKBHZ9HKhBPzmCvZj8PNH5tkMFR4nj0PLN9eYL59A7omAmtH2Sg95T47OIG9ZtQ== +"@elastic/apm-rum-react@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum-react/-/apm-rum-react-1.4.0.tgz#f36453e54d2ebdedb0d6d0c4f6cc76e16304b118" + integrity sha512-YIBuEJN6fkiB1M/o84PF4lQheAjrd3PQCm6t8pP4dKuWN1cWZnSsojnuGacx2bJn1kWWZxVDQ7wTjPJutkIy2A== dependencies: - "@elastic/apm-rum" "^5.10.2" + "@elastic/apm-rum" "^5.11.0" hoist-non-react-statics "^3.3.0" -"@elastic/apm-rum@^5.10.2": - version "5.10.2" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum/-/apm-rum-5.10.2.tgz#06d3e9f08adc19e1227073dda7e5c4ab34be48c7" - integrity sha512-NrBQcgautAGwJOrJ20WUUXV1Ynux4dEEU/fgeqfdG7G3JGqMbuIlF8s/nqLgQ9oXz72Z5MirOf68P7m5Zh/5HA== +"@elastic/apm-rum@^5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@elastic/apm-rum/-/apm-rum-5.11.0.tgz#97dbc426d0ec27b46e78a649f73d9e4a198ae258" + integrity sha512-+98NLG4NDa7o1DCtkhXeGmKW5riDPHSpgy2UxzLK4j02ZPBOccOUjIw5F8yZAUsrPUpQmk39x13IJl0mFyzjyA== dependencies: - "@elastic/apm-rum-core" "^5.14.1" + "@elastic/apm-rum-core" "^5.15.0" "@elastic/apm-synthtrace@link:bazel-bin/packages/elastic-apm-synthtrace": version "0.0.0"