[KP] Expose new es client (#73651)

* mark legacy ES client types as deprecated

* expose es client to plugins and update mocks

* ElasticSearchClientMock --> ElasticsearchClientMock

* expose es client mocks

* expose es client via RequestHandlerContext

* convert test/plugin_functional/config into ts

* convert top_nav test into ts

* add an integration test for the es client

* update comments to refer to the new es client

* fix import paths. do not use extensions

temp

* update docs

* fix other refs

* add test for a custom client

* fix context

* add test for scoped client

* update docs
This commit is contained in:
Mikhail Shustov 2020-07-30 20:12:37 +03:00 committed by GitHub
parent e8cc2ff72f
commit 585d58c202
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
78 changed files with 695 additions and 146 deletions

View file

@ -4,6 +4,9 @@
## AssistanceAPIResponse interface
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -4,6 +4,9 @@
## AssistantAPIClientParams interface
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -4,6 +4,9 @@
## DeprecationAPIClientParams interface
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -4,6 +4,9 @@
## DeprecationAPIResponse interface
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -4,6 +4,9 @@
## DeprecationInfo interface
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -0,0 +1,18 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ElasticsearchClientConfig](./kibana-plugin-core-server.elasticsearchclientconfig.md)
## ElasticsearchClientConfig type
Configuration options to be used to create a [cluster client](./kibana-plugin-core-server.iclusterclient.md) using the [createClient API](./kibana-plugin-core-server.elasticsearchservicestart.createclient.md)
<b>Signature:</b>
```typescript
export declare type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'logQueries' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password'> & {
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout'];
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout'];
ssl?: Partial<ElasticsearchConfig['ssl']>;
keepAlive?: boolean;
};
```

View file

@ -0,0 +1,22 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ElasticsearchServiceStart](./kibana-plugin-core-server.elasticsearchservicestart.md) &gt; [client](./kibana-plugin-core-server.elasticsearchservicestart.client.md)
## ElasticsearchServiceStart.client property
A pre-configured [Elasticsearch client](./kibana-plugin-core-server.iclusterclient.md)
<b>Signature:</b>
```typescript
readonly client: IClusterClient;
```
## Example
```js
const client = core.elasticsearch.client;
```

View file

@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ElasticsearchServiceStart](./kibana-plugin-core-server.elasticsearchservicestart.md) &gt; [createClient](./kibana-plugin-core-server.elasticsearchservicestart.createclient.md)
## ElasticsearchServiceStart.createClient property
Create application specific Elasticsearch cluster API client with customized config. See [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)<!-- -->.
<b>Signature:</b>
```typescript
readonly createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ICustomClusterClient;
```
## Example
```js
const client = elasticsearch.createClient('my-app-name', config);
const data = await client.asInternalUser.search();
```

View file

@ -15,5 +15,7 @@ export interface ElasticsearchServiceStart
| Property | Type | Description |
| --- | --- | --- |
| [client](./kibana-plugin-core-server.elasticsearchservicestart.client.md) | <code>IClusterClient</code> | A pre-configured [Elasticsearch client](./kibana-plugin-core-server.iclusterclient.md) |
| [createClient](./kibana-plugin-core-server.elasticsearchservicestart.createclient.md) | <code>(type: string, clientConfig?: Partial&lt;ElasticsearchClientConfig&gt;) =&gt; ICustomClusterClient</code> | Create application specific Elasticsearch cluster API client with customized config. See [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)<!-- -->. |
| [legacy](./kibana-plugin-core-server.elasticsearchservicestart.legacy.md) | <code>{</code><br/><code> readonly createClient: (type: string, clientConfig?: Partial&lt;LegacyElasticsearchClientConfig&gt;) =&gt; ILegacyCustomClusterClient;</code><br/><code> readonly client: ILegacyClusterClient;</code><br/><code> }</code> | |

View file

@ -21,7 +21,7 @@ registerRouteHandlerContext: <T extends keyof RequestHandlerContext>(contextName
'myApp',
(context, req) => {
async function search (id: string) {
return await context.elasticsearch.legacy.client.callAsInternalUser('endpoint', id);
return await context.elasticsearch.client.asCurrentUser.find(id);
}
return { search };
}

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [IClusterClient](./kibana-plugin-core-server.iclusterclient.md) &gt; [asInternalUser](./kibana-plugin-core-server.iclusterclient.asinternaluser.md)
## IClusterClient.asInternalUser property
A [client](./kibana-plugin-core-server.elasticsearchclient.md) to be used to query the ES cluster on behalf of the Kibana internal user
<b>Signature:</b>
```typescript
readonly asInternalUser: ElasticsearchClient;
```

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [IClusterClient](./kibana-plugin-core-server.iclusterclient.md) &gt; [asScoped](./kibana-plugin-core-server.iclusterclient.asscoped.md)
## IClusterClient.asScoped property
Creates a [scoped cluster client](./kibana-plugin-core-server.iscopedclusterclient.md) bound to given [request](./kibana-plugin-core-server.scopeablerequest.md)
<b>Signature:</b>
```typescript
asScoped: (request: ScopeableRequest) => IScopedClusterClient;
```

View file

@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)
## IClusterClient interface
Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`<!-- -->).
<b>Signature:</b>
```typescript
export interface IClusterClient
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [asInternalUser](./kibana-plugin-core-server.iclusterclient.asinternaluser.md) | <code>ElasticsearchClient</code> | A [client](./kibana-plugin-core-server.elasticsearchclient.md) to be used to query the ES cluster on behalf of the Kibana internal user |
| [asScoped](./kibana-plugin-core-server.iclusterclient.asscoped.md) | <code>(request: ScopeableRequest) =&gt; IScopedClusterClient</code> | Creates a [scoped cluster client](./kibana-plugin-core-server.iscopedclusterclient.md) bound to given [request](./kibana-plugin-core-server.scopeablerequest.md) |

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ICustomClusterClient](./kibana-plugin-core-server.icustomclusterclient.md) &gt; [close](./kibana-plugin-core-server.icustomclusterclient.close.md)
## ICustomClusterClient.close property
Closes the cluster client. After that client cannot be used and one should create a new client instance to be able to interact with Elasticsearch API.
<b>Signature:</b>
```typescript
close: () => Promise<void>;
```

View file

@ -0,0 +1,20 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ICustomClusterClient](./kibana-plugin-core-server.icustomclusterclient.md)
## ICustomClusterClient interface
See [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)
<b>Signature:</b>
```typescript
export interface ICustomClusterClient extends IClusterClient
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [close](./kibana-plugin-core-server.icustomclusterclient.close.md) | <code>() =&gt; Promise&lt;void&gt;</code> | Closes the cluster client. After that client cannot be used and one should create a new client instance to be able to interact with Elasticsearch API. |

View file

@ -4,6 +4,11 @@
## ILegacyClusterClient type
> Warning: This API is now obsolete.
>
> Use [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)<!-- -->.
>
Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`<!-- -->).
See [LegacyClusterClient](./kibana-plugin-core-server.legacyclusterclient.md)<!-- -->.

View file

@ -4,6 +4,11 @@
## ILegacyCustomClusterClient type
> Warning: This API is now obsolete.
>
> Use [ICustomClusterClient](./kibana-plugin-core-server.icustomclusterclient.md)<!-- -->.
>
Represents an Elasticsearch cluster API client created by a plugin. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`<!-- -->).
See [LegacyClusterClient](./kibana-plugin-core-server.legacyclusterclient.md)<!-- -->.

View file

@ -4,6 +4,11 @@
## ILegacyScopedClusterClient type
> Warning: This API is now obsolete.
>
> Use [IScopedClusterClient](./kibana-plugin-core-server.iscopedclusterclient.md)<!-- -->.
>
Serves the same purpose as "normal" `ClusterClient` but exposes additional `callAsCurrentUser` method that doesn't use credentials of the Kibana internal user (as `callAsInternalUser` does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API.
See [LegacyScopedClusterClient](./kibana-plugin-core-server.legacyscopedclusterclient.md)<!-- -->.

View file

@ -4,6 +4,9 @@
## IndexSettingsDeprecationInfo interface
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [IScopedClusterClient](./kibana-plugin-core-server.iscopedclusterclient.md) &gt; [asCurrentUser](./kibana-plugin-core-server.iscopedclusterclient.ascurrentuser.md)
## IScopedClusterClient.asCurrentUser property
A [client](./kibana-plugin-core-server.elasticsearchclient.md) to be used to query the elasticsearch cluster on behalf of the user that initiated the request to the Kibana server.
<b>Signature:</b>
```typescript
readonly asCurrentUser: ElasticsearchClient;
```

View file

@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [IScopedClusterClient](./kibana-plugin-core-server.iscopedclusterclient.md) &gt; [asInternalUser](./kibana-plugin-core-server.iscopedclusterclient.asinternaluser.md)
## IScopedClusterClient.asInternalUser property
A [client](./kibana-plugin-core-server.elasticsearchclient.md) to be used to query the elasticsearch cluster on behalf of the internal Kibana user.
<b>Signature:</b>
```typescript
readonly asInternalUser: ElasticsearchClient;
```

View file

@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [IScopedClusterClient](./kibana-plugin-core-server.iscopedclusterclient.md)
## IScopedClusterClient interface
Serves the same purpose as the normal [cluster client](./kibana-plugin-core-server.iclusterclient.md) but exposes an additional `asCurrentUser` method that doesn't use credentials of the Kibana internal user (as `asInternalUser` does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API instead.
<b>Signature:</b>
```typescript
export interface IScopedClusterClient
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [asCurrentUser](./kibana-plugin-core-server.iscopedclusterclient.ascurrentuser.md) | <code>ElasticsearchClient</code> | A [client](./kibana-plugin-core-server.elasticsearchclient.md) to be used to query the elasticsearch cluster on behalf of the user that initiated the request to the Kibana server. |
| [asInternalUser](./kibana-plugin-core-server.iscopedclusterclient.asinternaluser.md) | <code>ElasticsearchClient</code> | A [client](./kibana-plugin-core-server.elasticsearchclient.md) to be used to query the elasticsearch cluster on behalf of the internal Kibana user. |

View file

@ -4,6 +4,9 @@
## LegacyAPICaller interface
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -4,6 +4,10 @@
## LegacyCallAPIOptions interface
> Warning: This API is now obsolete.
>
>
The set of options that defines how API call should be made and result be processed.
<b>Signature:</b>

View file

@ -4,6 +4,12 @@
## LegacyClusterClient class
> Warning: This API is now obsolete.
>
> Use [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)<!-- -->.
>
Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`<!-- -->).
<b>Signature:</b>

View file

@ -4,6 +4,9 @@
## LegacyElasticsearchClientConfig type
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -4,6 +4,7 @@
## LegacyElasticsearchError interface
@<!-- -->deprecated. The new elasticsearch client doesn't wrap errors anymore.
<b>Signature:</b>

View file

@ -4,6 +4,12 @@
## LegacyScopedClusterClient class
> Warning: This API is now obsolete.
>
> Use [scoped cluster client](./kibana-plugin-core-server.iscopedclusterclient.md)<!-- -->.
>
Serves the same purpose as the normal [cluster client](./kibana-plugin-core-server.iclusterclient.md) but exposes an additional `asCurrentUser` method that doesn't use credentials of the Kibana internal user (as `asInternalUser` does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API instead.
<b>Signature:</b>

View file

@ -20,9 +20,9 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [CspConfig](./kibana-plugin-core-server.cspconfig.md) | CSP configuration for use in Kibana. |
| [ElasticsearchConfig](./kibana-plugin-core-server.elasticsearchconfig.md) | Wrapper of config schema. |
| [KibanaRequest](./kibana-plugin-core-server.kibanarequest.md) | Kibana specific abstraction for an incoming request. |
| [LegacyClusterClient](./kibana-plugin-core-server.legacyclusterclient.md) | |
| [LegacyClusterClient](./kibana-plugin-core-server.legacyclusterclient.md) | Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via <code>asScoped(...)</code>). |
| [LegacyElasticsearchErrorHelpers](./kibana-plugin-core-server.legacyelasticsearcherrorhelpers.md) | Helpers for working with errors returned from the Elasticsearch service.Since the internal data of errors are subject to change, consumers of the Elasticsearch service should always use these helpers to classify errors instead of checking error internals such as <code>body.error.header[WWW-Authenticate]</code> |
| [LegacyScopedClusterClient](./kibana-plugin-core-server.legacyscopedclusterclient.md) | |
| [LegacyScopedClusterClient](./kibana-plugin-core-server.legacyscopedclusterclient.md) | Serves the same purpose as the normal [cluster client](./kibana-plugin-core-server.iclusterclient.md) but exposes an additional <code>asCurrentUser</code> method that doesn't use credentials of the Kibana internal user (as <code>asInternalUser</code> does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API instead. |
| [RouteValidationError](./kibana-plugin-core-server.routevalidationerror.md) | Error to return when the validation is not successful. |
| [SavedObjectsClient](./kibana-plugin-core-server.savedobjectsclient.md) | |
| [SavedObjectsErrorHelpers](./kibana-plugin-core-server.savedobjectserrorhelpers.md) | |
@ -98,20 +98,23 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [HttpServerInfo](./kibana-plugin-core-server.httpserverinfo.md) | |
| [HttpServiceSetup](./kibana-plugin-core-server.httpservicesetup.md) | Kibana HTTP Service provides own abstraction for work with HTTP stack. Plugins don't have direct access to <code>hapi</code> server and its primitives anymore. Moreover, plugins shouldn't rely on the fact that HTTP Service uses one or another library under the hood. This gives the platform flexibility to upgrade or changing our internal HTTP stack without breaking plugins. If the HTTP Service lacks functionality you need, we are happy to discuss and support your needs. |
| [HttpServiceStart](./kibana-plugin-core-server.httpservicestart.md) | |
| [IClusterClient](./kibana-plugin-core-server.iclusterclient.md) | Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via <code>asScoped(...)</code>). |
| [IContextContainer](./kibana-plugin-core-server.icontextcontainer.md) | An object that handles registration of context providers and configuring handlers with context. |
| [ICspConfig](./kibana-plugin-core-server.icspconfig.md) | CSP configuration for use in Kibana. |
| [ICustomClusterClient](./kibana-plugin-core-server.icustomclusterclient.md) | See [IClusterClient](./kibana-plugin-core-server.iclusterclient.md) |
| [IKibanaResponse](./kibana-plugin-core-server.ikibanaresponse.md) | A response data object, expected to returned as a result of [RequestHandler](./kibana-plugin-core-server.requesthandler.md) execution |
| [IKibanaSocket](./kibana-plugin-core-server.ikibanasocket.md) | A tiny abstraction for TCP socket. |
| [ImageValidation](./kibana-plugin-core-server.imagevalidation.md) | |
| [IndexSettingsDeprecationInfo](./kibana-plugin-core-server.indexsettingsdeprecationinfo.md) | |
| [IRenderOptions](./kibana-plugin-core-server.irenderoptions.md) | |
| [IRouter](./kibana-plugin-core-server.irouter.md) | Registers route handlers for specified resource path and method. See [RouteConfig](./kibana-plugin-core-server.routeconfig.md) and [RequestHandler](./kibana-plugin-core-server.requesthandler.md) for more information about arguments to route registrations. |
| [IScopedClusterClient](./kibana-plugin-core-server.iscopedclusterclient.md) | Serves the same purpose as the normal [cluster client](./kibana-plugin-core-server.iclusterclient.md) but exposes an additional <code>asCurrentUser</code> method that doesn't use credentials of the Kibana internal user (as <code>asInternalUser</code> does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API instead. |
| [IUiSettingsClient](./kibana-plugin-core-server.iuisettingsclient.md) | Server-side client that provides access to the advanced settings stored in elasticsearch. The settings provide control over the behavior of the Kibana application. For example, a user can specify how to display numeric or date fields. Users can adjust the settings via Management UI. |
| [KibanaRequestEvents](./kibana-plugin-core-server.kibanarequestevents.md) | Request events. |
| [KibanaRequestRoute](./kibana-plugin-core-server.kibanarequestroute.md) | Request specific route information exposed to a handler. |
| [LegacyAPICaller](./kibana-plugin-core-server.legacyapicaller.md) | |
| [LegacyCallAPIOptions](./kibana-plugin-core-server.legacycallapioptions.md) | The set of options that defines how API call should be made and result be processed. |
| [LegacyElasticsearchError](./kibana-plugin-core-server.legacyelasticsearcherror.md) | |
| [LegacyElasticsearchError](./kibana-plugin-core-server.legacyelasticsearcherror.md) | @<!-- -->deprecated. The new elasticsearch client doesn't wrap errors anymore. |
| [LegacyRequest](./kibana-plugin-core-server.legacyrequest.md) | |
| [LegacyServiceSetupDeps](./kibana-plugin-core-server.legacyservicesetupdeps.md) | |
| [LegacyServiceStartDeps](./kibana-plugin-core-server.legacyservicestartdeps.md) | |
@ -137,7 +140,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [PluginConfigDescriptor](./kibana-plugin-core-server.pluginconfigdescriptor.md) | Describes a plugin configuration properties. |
| [PluginInitializerContext](./kibana-plugin-core-server.plugininitializercontext.md) | Context that's available to plugins during initialization stage. |
| [PluginManifest](./kibana-plugin-core-server.pluginmanifest.md) | Describes the set of required and optional properties plugin can define in its mandatory JSON manifest file. |
| [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.legacy.client](./kibana-plugin-core-server.legacyscopedclusterclient.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) | 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 - [elasticsearch.legacy.client](./kibana-plugin-core-server.legacyscopedclusterclient.md) - The legacy 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 - [uiSettings.auditor](./kibana-plugin-core-server.auditor.md) - AuditTrail client scoped to the incoming request |
| [RouteConfig](./kibana-plugin-core-server.routeconfig.md) | Route specific configuration. |
| [RouteConfigOptions](./kibana-plugin-core-server.routeconfigoptions.md) | Additional route options. |
| [RouteConfigOptionsBody](./kibana-plugin-core-server.routeconfigoptionsbody.md) | Additional body options for a route |
@ -236,6 +239,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [ConfigPath](./kibana-plugin-core-server.configpath.md) | |
| [DestructiveRouteMethod](./kibana-plugin-core-server.destructiveroutemethod.md) | Set of HTTP methods changing the state of the server. |
| [ElasticsearchClient](./kibana-plugin-core-server.elasticsearchclient.md) | Client used to query the elasticsearch cluster. |
| [ElasticsearchClientConfig](./kibana-plugin-core-server.elasticsearchclientconfig.md) | Configuration options to be used to create a [cluster client](./kibana-plugin-core-server.iclusterclient.md) using the [createClient API](./kibana-plugin-core-server.elasticsearchservicestart.createclient.md) |
| [Freezable](./kibana-plugin-core-server.freezable.md) | |
| [GetAuthHeaders](./kibana-plugin-core-server.getauthheaders.md) | Get headers to authenticate a user against Elasticsearch. |
| [GetAuthState](./kibana-plugin-core-server.getauthstate.md) | Gets authentication state for a request. Returned by <code>auth</code> interceptor. |

View file

@ -4,6 +4,9 @@
## MIGRATION\_ASSISTANCE\_INDEX\_ACTION type
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -4,6 +4,9 @@
## MIGRATION\_DEPRECATION\_LEVEL type
> Warning: This API is now obsolete.
>
>
<b>Signature:</b>

View file

@ -13,6 +13,7 @@ core: {
typeRegistry: ISavedObjectTypeRegistry;
};
elasticsearch: {
client: IScopedClusterClient;
legacy: {
client: ILegacyScopedClusterClient;
};

View file

@ -6,7 +6,7 @@
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.legacy.client](./kibana-plugin-core-server.legacyscopedclusterclient.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
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 - [elasticsearch.legacy.client](./kibana-plugin-core-server.legacyscopedclusterclient.md) - The legacy 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 - [uiSettings.auditor](./kibana-plugin-core-server.auditor.md) - AuditTrail client scoped to the incoming request
<b>Signature:</b>
@ -18,5 +18,5 @@ export interface RequestHandlerContext
| Property | Type | Description |
| --- | --- | --- |
| [core](./kibana-plugin-core-server.requesthandlercontext.core.md) | <code>{</code><br/><code> savedObjects: {</code><br/><code> client: SavedObjectsClientContract;</code><br/><code> typeRegistry: ISavedObjectTypeRegistry;</code><br/><code> };</code><br/><code> elasticsearch: {</code><br/><code> legacy: {</code><br/><code> client: ILegacyScopedClusterClient;</code><br/><code> };</code><br/><code> };</code><br/><code> uiSettings: {</code><br/><code> client: IUiSettingsClient;</code><br/><code> };</code><br/><code> auditor: Auditor;</code><br/><code> }</code> | |
| [core](./kibana-plugin-core-server.requesthandlercontext.core.md) | <code>{</code><br/><code> savedObjects: {</code><br/><code> client: SavedObjectsClientContract;</code><br/><code> typeRegistry: ISavedObjectTypeRegistry;</code><br/><code> };</code><br/><code> elasticsearch: {</code><br/><code> client: IScopedClusterClient;</code><br/><code> legacy: {</code><br/><code> client: ILegacyScopedClusterClient;</code><br/><code> };</code><br/><code> };</code><br/><code> uiSettings: {</code><br/><code> client: IUiSettingsClient;</code><br/><code> };</code><br/><code> auditor: Auditor;</code><br/><code> }</code> | |

View file

@ -20,7 +20,7 @@
// eslint-disable-next-line no-restricted-syntax
const alwaysImportedTests = [
require.resolve('../test/functional/config.js'),
require.resolve('../test/plugin_functional/config.js'),
require.resolve('../test/plugin_functional/config.ts'),
require.resolve('../test/ui_capabilities/newsfeed_err/config.ts'),
require.resolve('../test/new_visualize_flow/config.js'),
];

View file

@ -70,15 +70,14 @@ const createInternalClientMock = (): DeeplyMockedKeys<Client> => {
return (mock as unknown) as DeeplyMockedKeys<Client>;
};
// TODO fix naming ElasticsearchClientMock
export type ElasticSearchClientMock = DeeplyMockedKeys<ElasticsearchClient>;
export type ElasticsearchClientMock = DeeplyMockedKeys<ElasticsearchClient>;
const createClientMock = (): ElasticSearchClientMock =>
(createInternalClientMock() as unknown) as ElasticSearchClientMock;
const createClientMock = (): ElasticsearchClientMock =>
(createInternalClientMock() as unknown) as ElasticsearchClientMock;
interface ScopedClusterClientMock {
asInternalUser: ElasticSearchClientMock;
asCurrentUser: ElasticSearchClientMock;
asInternalUser: ElasticsearchClientMock;
asCurrentUser: ElasticsearchClientMock;
}
const createScopedClusterClientMock = () => {
@ -91,7 +90,7 @@ const createScopedClusterClientMock = () => {
};
export interface ClusterClientMock {
asInternalUser: ElasticSearchClientMock;
asInternalUser: ElasticsearchClientMock;
asScoped: jest.MockedFunction<() => ScopedClusterClientMock>;
}
@ -157,7 +156,7 @@ export const elasticsearchClientMock = {
createClusterClient: createClusterClientMock,
createCustomClusterClient: createCustomClusterClientMock,
createScopedClusterClient: createScopedClusterClientMock,
createElasticSearchClient: createClientMock,
createElasticsearchClient: createClientMock,
createInternalClient: createInternalClientMock,
createSuccessTransportRequestPromise,
createErrorTransportRequestPromise,

View file

@ -27,10 +27,10 @@ const createErrorReturn = (err: any) =>
elasticsearchClientMock.createErrorTransportRequestPromise(err);
describe('retryCallCluster', () => {
let client: ReturnType<typeof elasticsearchClientMock.createElasticSearchClient>;
let client: ReturnType<typeof elasticsearchClientMock.createElasticsearchClient>;
beforeEach(() => {
client = elasticsearchClientMock.createElasticSearchClient();
client = elasticsearchClientMock.createElasticsearchClient();
});
it('returns response from ES API call in case of success', async () => {
@ -91,11 +91,11 @@ describe('retryCallCluster', () => {
});
describe('migrationRetryCallCluster', () => {
let client: ReturnType<typeof elasticsearchClientMock.createElasticSearchClient>;
let client: ReturnType<typeof elasticsearchClientMock.createElasticsearchClient>;
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
beforeEach(() => {
client = elasticsearchClientMock.createElasticSearchClient();
client = elasticsearchClientMock.createElasticsearchClient();
logger = loggingSystemMock.createLogger();
});

View file

@ -22,8 +22,8 @@ import { ScopedClusterClient } from './scoped_cluster_client';
describe('ScopedClusterClient', () => {
it('uses the internal client passed in the constructor', () => {
const internalClient = elasticsearchClientMock.createElasticSearchClient();
const scopedClient = elasticsearchClientMock.createElasticSearchClient();
const internalClient = elasticsearchClientMock.createElasticsearchClient();
const scopedClient = elasticsearchClientMock.createElasticsearchClient();
const scopedClusterClient = new ScopedClusterClient(internalClient, scopedClient);
@ -31,8 +31,8 @@ describe('ScopedClusterClient', () => {
});
it('uses the scoped client passed in the constructor', () => {
const internalClient = elasticsearchClientMock.createElasticSearchClient();
const scopedClient = elasticsearchClientMock.createElasticSearchClient();
const internalClient = elasticsearchClientMock.createElasticsearchClient();
const scopedClient = elasticsearchClientMock.createElasticsearchClient();
const scopedClusterClient = new ScopedClusterClient(internalClient, scopedClient);

View file

@ -20,7 +20,7 @@
import { ElasticsearchClient } from './types';
/**
* Serves the same purpose as the normal {@link ClusterClient | cluster client} but exposes
* Serves the same purpose as the normal {@link IClusterClient | cluster client} but exposes
* an additional `asCurrentUser` method that doesn't use credentials of the Kibana internal
* user (as `asInternalUser` does) to request Elasticsearch API, but rather passes HTTP headers
* extracted from the current user request to the API instead.

View file

@ -24,6 +24,7 @@ import {
ClusterClientMock,
CustomClusterClientMock,
} from './client/mocks';
import { ElasticsearchClientConfig } from './client';
import { legacyClientMock } from './legacy/mocks';
import { ElasticsearchConfig } from './elasticsearch_config';
import { ElasticsearchService } from './elasticsearch_service';
@ -38,12 +39,12 @@ interface MockedElasticSearchServiceSetup {
};
}
type MockedElasticSearchServiceStart = MockedElasticSearchServiceSetup;
interface MockedInternalElasticSearchServiceStart extends MockedElasticSearchServiceStart {
type MockedElasticSearchServiceStart = MockedElasticSearchServiceSetup & {
client: ClusterClientMock;
createClient: jest.MockedFunction<() => CustomClusterClientMock>;
}
createClient: jest.MockedFunction<
(name: string, config?: Partial<ElasticsearchClientConfig>) => CustomClusterClientMock
>;
};
const createSetupContractMock = () => {
const setupContract: MockedElasticSearchServiceSetup = {
@ -61,6 +62,8 @@ const createSetupContractMock = () => {
const createStartContractMock = () => {
const startContract: MockedElasticSearchServiceStart = {
client: elasticsearchClientMock.createClusterClient(),
createClient: jest.fn(),
legacy: {
createClient: jest.fn(),
client: legacyClientMock.createClusterClient(),
@ -70,20 +73,13 @@ const createStartContractMock = () => {
startContract.legacy.client.asScoped.mockReturnValue(
legacyClientMock.createScopedClusterClient()
);
startContract.createClient.mockImplementation(() =>
elasticsearchClientMock.createCustomClusterClient()
);
return startContract;
};
const createInternalStartContractMock = () => {
const startContract: MockedInternalElasticSearchServiceStart = {
...createStartContractMock(),
client: elasticsearchClientMock.createClusterClient(),
createClient: jest.fn(),
};
startContract.createClient.mockReturnValue(elasticsearchClientMock.createCustomClusterClient());
return startContract;
};
const createInternalStartContractMock = createStartContractMock;
type MockedInternalElasticSearchServiceSetup = jest.Mocked<
InternalElasticsearchServiceSetup & {
@ -136,4 +132,6 @@ export const elasticsearchServiceMock = {
createLegacyCustomClusterClient: legacyClientMock.createCustomClusterClient,
createLegacyScopedClusterClient: legacyClientMock.createScopedClusterClient,
createLegacyElasticsearchClient: legacyClientMock.createElasticsearchClient,
...elasticsearchClientMock,
};

View file

@ -150,6 +150,7 @@ import {
* processed.
*
* @public
* @deprecated
*/
export interface LegacyCallAPIOptions {
/**
@ -165,7 +166,10 @@ export interface LegacyCallAPIOptions {
signal?: AbortSignal;
}
/** @public */
/**
* @deprecated
* @public
* */
export interface LegacyAPICaller {
/* eslint-disable */
(endpoint: 'bulk', params: BulkIndexDocumentsParams, options?: LegacyCallAPIOptions): ReturnType<Client['bulk']>;
@ -317,18 +321,30 @@ export interface LegacyAPICaller {
/* eslint-enable */
}
/** @public */
/**
* @deprecated
* @public
* */
export interface AssistantAPIClientParams extends GenericParams {
path: '/_migration/assistance';
method: 'GET';
}
/** @public */
/**
* @deprecated
* @public
* */
export type MIGRATION_ASSISTANCE_INDEX_ACTION = 'upgrade' | 'reindex';
/** @public */
/**
* @deprecated
* @public
* */
export type MIGRATION_DEPRECATION_LEVEL = 'none' | 'info' | 'warning' | 'critical';
/** @public */
/**
* @deprecated
* @public
* */
export interface AssistanceAPIResponse {
indices: {
[indexName: string]: {
@ -337,13 +353,19 @@ export interface AssistanceAPIResponse {
};
}
/** @public */
/**
* @deprecated
* @public
* */
export interface DeprecationAPIClientParams extends GenericParams {
path: '/_migration/deprecations';
method: 'GET';
}
/** @public */
/**
* @deprecated
* @public
* */
export interface DeprecationInfo {
level: MIGRATION_DEPRECATION_LEVEL;
message: string;
@ -351,12 +373,18 @@ export interface DeprecationInfo {
details?: string;
}
/** @public */
/**
* @deprecated
* @public
* */
export interface IndexSettingsDeprecationInfo {
[indexName: string]: DeprecationInfo[];
}
/** @public */
/**
* @deprecated
* @public
* */
export interface DeprecationAPIResponse {
cluster_settings: DeprecationInfo[];
ml_settings: DeprecationInfo[];

View file

@ -88,6 +88,7 @@ const callAPI = async (
*
* See {@link LegacyClusterClient}.
*
* @deprecated Use {@link IClusterClient}.
* @public
*/
export type ILegacyClusterClient = Pick<LegacyClusterClient, 'callAsInternalUser' | 'asScoped'>;
@ -98,7 +99,7 @@ export type ILegacyClusterClient = Pick<LegacyClusterClient, 'callAsInternalUser
* the actual user that is derived from the request headers (via `asScoped(...)`).
*
* See {@link LegacyClusterClient}.
*
* @deprecated Use {@link ICustomClusterClient}.
* @public
*/
export type ILegacyCustomClusterClient = Pick<
@ -108,6 +109,7 @@ export type ILegacyCustomClusterClient = Pick<
/**
* {@inheritDoc IClusterClient}
* @deprecated Use {@link IClusterClient}.
* @public
*/
export class LegacyClusterClient implements ILegacyClusterClient {

View file

@ -31,6 +31,7 @@ import { ElasticsearchConfig } from '../elasticsearch_config';
* not only entries from standard `elasticsearch.*` yaml config, but also some Elasticsearch JS
* client specific options like `keepAlive` or `plugins` (that eventually will be deprecated).
*
* @deprecated
* @public
*/
export type LegacyElasticsearchClientConfig = Pick<ConfigOptions, 'keepAlive' | 'log' | 'plugins'> &

View file

@ -26,7 +26,10 @@ enum ErrorCode {
NOT_AUTHORIZED = 'Elasticsearch/notAuthorized',
}
/** @public */
/**
* @deprecated. The new elasticsearch client doesn't wrap errors anymore.
* @public
* */
export interface LegacyElasticsearchError extends Boom {
[code]?: string;
}

View file

@ -30,6 +30,7 @@ import { LegacyAPICaller, LegacyCallAPIOptions } from './api_types';
*
* See {@link LegacyScopedClusterClient}.
*
* @deprecated Use {@link IScopedClusterClient}.
* @public
*/
export type ILegacyScopedClusterClient = Pick<
@ -39,6 +40,7 @@ export type ILegacyScopedClusterClient = Pick<
/**
* {@inheritDoc IScopedClusterClient}
* @deprecated Use {@link IScopedClusterClient | scoped cluster client}.
* @public
*/
export class LegacyScopedClusterClient implements ILegacyScopedClusterClient {

View file

@ -95,6 +95,37 @@ export interface InternalElasticsearchServiceSetup {
* @public
*/
export interface ElasticsearchServiceStart {
/**
* A pre-configured {@link IClusterClient | Elasticsearch client}
*
* @example
* ```js
* const client = core.elasticsearch.client;
* ```
*/
readonly client: IClusterClient;
/**
* Create application specific Elasticsearch cluster API client with customized config. See {@link IClusterClient}.
*
* @param type Unique identifier of the client
* @param clientConfig A config consists of Elasticsearch JS client options and
* valid sub-set of Elasticsearch service config.
* We fill all the missing properties in the `clientConfig` using the default
* Elasticsearch config so that we don't depend on default values set and
* controlled by underlying Elasticsearch JS client.
* We don't run validation against the passed config and expect it to be valid.
*
* @example
* ```js
* const client = elasticsearch.createClient('my-app-name', config);
* const data = await client.asInternalUser.search();
* ```
*/
readonly createClient: (
type: string,
clientConfig?: Partial<ElasticsearchClientConfig>
) => ICustomClusterClient;
/**
* @deprecated
* Provided for the backward compatibility.
@ -138,38 +169,7 @@ export interface ElasticsearchServiceStart {
/**
* @internal
*/
export interface InternalElasticsearchServiceStart extends ElasticsearchServiceStart {
/**
* A pre-configured {@link IClusterClient | Elasticsearch client}
*
* @example
* ```js
* const client = core.elasticsearch.client;
* ```
*/
readonly client: IClusterClient;
/**
* Create application specific Elasticsearch cluster API client with customized config. See {@link IClusterClient}.
*
* @param type Unique identifier of the client
* @param clientConfig A config consists of Elasticsearch JS client options and
* valid sub-set of Elasticsearch service config.
* We fill all the missing properties in the `clientConfig` using the default
* Elasticsearch config so that we don't depend on default values set and
* controlled by underlying Elasticsearch JS client.
* We don't run validation against the passed config and expect it to be valid.
*
* @example
* ```js
* const client = elasticsearch.createClient('my-app-name', config);
* const data = await client.asInternalUser().search();
* ```
*/
readonly createClient: (
type: string,
clientConfig?: Partial<ElasticsearchClientConfig>
) => ICustomClusterClient;
}
export type InternalElasticsearchServiceStart = ElasticsearchServiceStart;
/** @public */
export interface ElasticsearchStatusMeta {

View file

@ -250,7 +250,7 @@ export interface HttpServiceSetup {
* 'myApp',
* (context, req) => {
* async function search (id: string) {
* return await context.elasticsearch.legacy.client.callAsInternalUser('endpoint', id);
* return await context.elasticsearch.client.asCurrentUser.find(id);
* }
* return { search };
* }

View file

@ -44,6 +44,7 @@ import {
ILegacyScopedClusterClient,
configSchema as elasticsearchConfigSchema,
ElasticsearchServiceStart,
IScopedClusterClient,
} from './elasticsearch';
import { HttpServiceSetup, HttpServiceStart } from './http';
@ -110,6 +111,10 @@ export {
FakeRequest,
ScopeableRequest,
ElasticsearchClient,
IClusterClient,
ICustomClusterClient,
ElasticsearchClientConfig,
IScopedClusterClient,
SearchResponse,
CountResponse,
ShardsInfo,
@ -367,10 +372,13 @@ export {
* which uses the credentials of the incoming request
* - {@link ISavedObjectTypeRegistry | savedObjects.typeRegistry} - Type registry containing
* all the registered types.
* - {@link LegacyScopedClusterClient | elasticsearch.legacy.client} - Elasticsearch
* - {@link IScopedClusterClient | elasticsearch.client} - Elasticsearch
* data client which uses the credentials of the incoming request
* - {@link LegacyScopedClusterClient | elasticsearch.legacy.client} - The legacy Elasticsearch
* data client which uses the credentials of the incoming request
* - {@link IUiSettingsClient | uiSettings.client} - uiSettings client
* which uses the credentials of the incoming request
* - {@link Auditor | uiSettings.auditor} - AuditTrail client scoped to the incoming request
*
* @public
*/
@ -381,6 +389,7 @@ export interface RequestHandlerContext {
typeRegistry: ISavedObjectTypeRegistry;
};
elasticsearch: {
client: IScopedClusterClient;
legacy: {
client: ILegacyScopedClusterClient;
};

View file

@ -193,6 +193,7 @@ function createCoreRequestHandlerContextMock() {
typeRegistry: savedObjectsTypeRegistryMock.create(),
},
elasticsearch: {
client: elasticsearchServiceMock.createScopedClusterClient(),
legacy: {
client: elasticsearchServiceMock.createLegacyScopedClusterClient(),
},

View file

@ -212,6 +212,8 @@ export function createPluginStartContext<TPlugin, TPluginDependencies>(
resolveCapabilities: deps.capabilities.resolveCapabilities,
},
elasticsearch: {
client: deps.elasticsearch.client,
createClient: deps.elasticsearch.createClient,
legacy: deps.elasticsearch.legacy,
},
http: {

View file

@ -22,10 +22,10 @@ import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks';
import * as Index from './elastic_index';
describe('ElasticIndex', () => {
let client: ReturnType<typeof elasticsearchClientMock.createElasticSearchClient>;
let client: ReturnType<typeof elasticsearchClientMock.createElasticsearchClient>;
beforeEach(() => {
client = elasticsearchClientMock.createElasticSearchClient();
client = elasticsearchClientMock.createElasticsearchClient();
});
describe('fetchInfo', () => {
test('it handles 404', async () => {

View file

@ -27,13 +27,13 @@ import { loggingSystemMock } from '../../../logging/logging_system.mock';
describe('IndexMigrator', () => {
let testOpts: jest.Mocked<MigrationOpts> & {
client: ReturnType<typeof elasticsearchClientMock.createElasticSearchClient>;
client: ReturnType<typeof elasticsearchClientMock.createElasticsearchClient>;
};
beforeEach(() => {
testOpts = {
batchSize: 10,
client: elasticsearchClientMock.createElasticSearchClient(),
client: elasticsearchClientMock.createElasticsearchClient(),
index: '.kibana',
log: loggingSystemMock.create().get(),
mappingProperties: {},
@ -366,7 +366,7 @@ describe('IndexMigrator', () => {
});
function withIndex(
client: ReturnType<typeof elasticsearchClientMock.createElasticSearchClient>,
client: ReturnType<typeof elasticsearchClientMock.createElasticsearchClient>,
opts: any = {}
) {
const defaultIndex = {

View file

@ -24,11 +24,11 @@ import { loggerMock } from '../../../logging/logger.mock';
import { SavedObjectsErrorHelpers } from '../../service/lib/errors';
describe('MigrationEsClient', () => {
let client: ReturnType<typeof elasticsearchClientMock.createElasticSearchClient>;
let client: ReturnType<typeof elasticsearchClientMock.createElasticsearchClient>;
let migrationEsClient: MigrationEsClient;
beforeEach(() => {
client = elasticsearchClientMock.createElasticSearchClient();
client = elasticsearchClientMock.createElasticsearchClient();
migrationEsClient = createMigrationEsClient(client, loggerMock.create());
migrationRetryCallClusterMock.mockClear();
});

View file

@ -127,7 +127,7 @@ describe('KibanaMigrator', () => {
});
type MockedOptions = KibanaMigratorOptions & {
client: ReturnType<typeof elasticsearchClientMock.createElasticSearchClient>;
client: ReturnType<typeof elasticsearchClientMock.createElasticsearchClient>;
};
const mockOptions = () => {
@ -170,7 +170,7 @@ const mockOptions = () => {
scrollDuration: '10m',
skip: false,
},
client: elasticsearchClientMock.createElasticSearchClient(),
client: elasticsearchClientMock.createElasticsearchClient(),
};
return options;
};

View file

@ -201,7 +201,7 @@ describe('SavedObjectsRepository', () => {
};
beforeEach(() => {
client = elasticsearchClientMock.createElasticSearchClient();
client = elasticsearchClientMock.createElasticsearchClient();
migrator = {
migrateDocument: jest.fn().mockImplementation(documentMigrator.migrate),
runMigrations: async () => ({ status: 'skipped' }),

View file

@ -23,11 +23,11 @@ import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks';
import { SavedObjectsErrorHelpers } from './errors';
describe('RepositoryEsClient', () => {
let client: ReturnType<typeof elasticsearchClientMock.createElasticSearchClient>;
let client: ReturnType<typeof elasticsearchClientMock.createElasticsearchClient>;
let repositoryClient: RepositoryEsClient;
beforeEach(() => {
client = elasticsearchClientMock.createElasticSearchClient();
client = elasticsearchClientMock.createElasticsearchClient();
repositoryClient = createRepositoryEsClient(client);
retryCallClusterMock.mockClear();
});

View file

@ -158,7 +158,7 @@ export type AppenderConfigType = TypeOf<typeof appendersSchema>;
// @public
export function assertNever(x: never): never;
// @public (undocumented)
// @public @deprecated (undocumented)
export interface AssistanceAPIResponse {
// (undocumented)
indices: {
@ -168,7 +168,7 @@ export interface AssistanceAPIResponse {
};
}
// @public (undocumented)
// @public @deprecated (undocumented)
export interface AssistantAPIClientParams extends GenericParams {
// (undocumented)
method: 'GET';
@ -622,7 +622,7 @@ export interface DeleteDocumentResponse {
_version: number;
}
// @public (undocumented)
// @public @deprecated (undocumented)
export interface DeprecationAPIClientParams extends GenericParams {
// (undocumented)
method: 'GET';
@ -630,7 +630,7 @@ export interface DeprecationAPIClientParams extends GenericParams {
path: '/_migration/deprecations';
}
// @public (undocumented)
// @public @deprecated (undocumented)
export interface DeprecationAPIResponse {
// (undocumented)
cluster_settings: DeprecationInfo[];
@ -642,7 +642,7 @@ export interface DeprecationAPIResponse {
node_settings: DeprecationInfo[];
}
// @public (undocumented)
// @public @deprecated (undocumented)
export interface DeprecationInfo {
// (undocumented)
details?: string;
@ -679,6 +679,14 @@ export type ElasticsearchClient = Omit<KibanaClient, 'connectionPool' | 'transpo
};
};
// @public
export type ElasticsearchClientConfig = Pick<ElasticsearchConfig, 'customHeaders' | 'logQueries' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'requestHeadersWhitelist' | 'sniffInterval' | 'hosts' | 'username' | 'password'> & {
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ClientOptions['pingTimeout'];
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ClientOptions['requestTimeout'];
ssl?: Partial<ElasticsearchConfig['ssl']>;
keepAlive?: boolean;
};
// @public
export class ElasticsearchConfig {
constructor(rawConfig: ElasticsearchConfigType);
@ -715,6 +723,8 @@ export interface ElasticsearchServiceSetup {
// @public (undocumented)
export interface ElasticsearchServiceStart {
readonly client: IClusterClient;
readonly createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ICustomClusterClient;
// @deprecated (undocumented)
legacy: {
readonly createClient: (type: string, clientConfig?: Partial<LegacyElasticsearchClientConfig>) => ILegacyCustomClusterClient;
@ -895,6 +905,12 @@ export interface HttpServiceStart {
// @public
export type IBasePath = Pick<BasePath, keyof BasePath>;
// @public
export interface IClusterClient {
readonly asInternalUser: ElasticsearchClient;
asScoped: (request: ScopeableRequest) => IScopedClusterClient;
}
// @public
export interface IContextContainer<THandler extends HandlerFunction<any>> {
createHandler(pluginOpaqueId: PluginOpaqueId, handler: THandler): (...rest: HandlerParameters<THandler>) => ShallowPromise<ReturnType<THandler>>;
@ -914,6 +930,11 @@ export interface ICspConfig {
readonly warnLegacyBrowsers: boolean;
}
// @public
export interface ICustomClusterClient extends IClusterClient {
close: () => Promise<void>;
}
// @public
export interface IKibanaResponse<T extends HttpResponsePayload | ResponseError = any> {
// (undocumented)
@ -935,13 +956,13 @@ export interface IKibanaSocket {
getPeerCertificate(detailed?: boolean): PeerCertificate | DetailedPeerCertificate | null;
}
// @public
// @public @deprecated
export type ILegacyClusterClient = Pick<LegacyClusterClient, 'callAsInternalUser' | 'asScoped'>;
// @public
// @public @deprecated
export type ILegacyCustomClusterClient = Pick<LegacyClusterClient, 'callAsInternalUser' | 'close' | 'asScoped'>;
// @public
// @public @deprecated
export type ILegacyScopedClusterClient = Pick<LegacyScopedClusterClient, 'callAsCurrentUser' | 'callAsInternalUser'>;
// @public (undocumented)
@ -956,7 +977,7 @@ export interface ImageValidation {
// @public
export function importSavedObjectsFromStream({ readStream, objectLimit, overwrite, savedObjectsClient, supportedTypes, namespace, }: SavedObjectsImportOptions): Promise<SavedObjectsImportResponse>;
// @public (undocumented)
// @public @deprecated (undocumented)
export interface IndexSettingsDeprecationInfo {
// (undocumented)
[indexName: string]: DeprecationInfo[];
@ -997,6 +1018,12 @@ export type ISavedObjectsRepository = Pick<SavedObjectsRepository, keyof SavedOb
// @public
export type ISavedObjectTypeRegistry = Omit<SavedObjectTypeRegistry, 'registerType'>;
// @public
export interface IScopedClusterClient {
readonly asCurrentUser: ElasticsearchClient;
readonly asInternalUser: ElasticsearchClient;
}
// @public
export function isRelativeUrl(candidatePath: string): boolean;
@ -1086,7 +1113,7 @@ export const kibanaResponseFactory: {
// @public
export type KnownHeaders = KnownKeys<IncomingHttpHeaders>;
// @public (undocumented)
// @public @deprecated (undocumented)
export interface LegacyAPICaller {
// (undocumented)
(endpoint: 'bulk', params: BulkIndexDocumentsParams, options?: LegacyCallAPIOptions): ReturnType<Client['bulk']>;
@ -1330,15 +1357,13 @@ export interface LegacyAPICaller {
<T = any>(endpoint: string, clientParams?: Record<string, any>, options?: LegacyCallAPIOptions): Promise<T>;
}
// @public
// @public @deprecated
export interface LegacyCallAPIOptions {
signal?: AbortSignal;
wrap401Errors?: boolean;
}
// Warning: (ae-unresolved-inheritdoc-reference) The @inheritDoc reference could not be resolved: The package "kibana" does not have an export "IClusterClient"
//
// @public (undocumented)
// @public @deprecated
export class LegacyClusterClient implements ILegacyClusterClient {
constructor(config: LegacyElasticsearchClientConfig, log: Logger, getAuditorFactory: () => AuditorFactory, getAuthHeaders?: GetAuthHeaders);
asScoped(request?: ScopeableRequest): ILegacyScopedClusterClient;
@ -1360,7 +1385,7 @@ export interface LegacyConfig {
set(config: LegacyVars): void;
}
// @public (undocumented)
// @public @deprecated (undocumented)
export type LegacyElasticsearchClientConfig = Pick<ConfigOptions, 'keepAlive' | 'log' | 'plugins'> & Pick<ElasticsearchConfig, 'apiVersion' | 'customHeaders' | 'logQueries' | 'requestHeadersWhitelist' | 'sniffOnStart' | 'sniffOnConnectionFault' | 'hosts' | 'username' | 'password'> & {
pingTimeout?: ElasticsearchConfig['pingTimeout'] | ConfigOptions['pingTimeout'];
requestTimeout?: ElasticsearchConfig['requestTimeout'] | ConfigOptions['requestTimeout'];
@ -1368,7 +1393,7 @@ export type LegacyElasticsearchClientConfig = Pick<ConfigOptions, 'keepAlive' |
ssl?: Partial<ElasticsearchConfig['ssl']>;
};
// @public (undocumented)
// @public
export interface LegacyElasticsearchError extends Boom {
// (undocumented)
[code]?: string;
@ -1401,9 +1426,7 @@ export class LegacyInternals implements ILegacyInternals {
export interface LegacyRequest extends Request {
}
// Warning: (ae-unresolved-inheritdoc-reference) The @inheritDoc reference could not be resolved: The package "kibana" does not have an export "IScopedClusterClient"
//
// @public (undocumented)
// @public @deprecated
export class LegacyScopedClusterClient implements ILegacyScopedClusterClient {
constructor(internalAPICaller: LegacyAPICaller, scopedAPICaller: LegacyAPICaller, headers?: Headers | undefined, auditor?: Auditor | undefined);
callAsCurrentUser(endpoint: string, clientParams?: Record<string, any>, options?: LegacyCallAPIOptions): Promise<any>;
@ -1559,10 +1582,10 @@ export interface LogRecord {
export interface MetricsServiceSetup {
}
// @public (undocumented)
// @public @deprecated (undocumented)
export type MIGRATION_ASSISTANCE_INDEX_ACTION = 'upgrade' | 'reindex';
// @public (undocumented)
// @public @deprecated (undocumented)
export type MIGRATION_DEPRECATION_LEVEL = 'none' | 'info' | 'warning' | 'critical';
// @public
@ -1812,6 +1835,7 @@ export interface RequestHandlerContext {
typeRegistry: ISavedObjectTypeRegistry;
};
elasticsearch: {
client: IScopedClusterClient;
legacy: {
client: ILegacyScopedClusterClient;
};

View file

@ -275,6 +275,7 @@ export class Server {
typeRegistry: coreStart.savedObjects.getTypeRegistry(),
},
elasticsearch: {
client: coreStart.elasticsearch.client.asScoped(req),
legacy: {
client: coreStart.elasticsearch.legacy.client.asScoped(req),
},

View file

@ -22,6 +22,7 @@ import { CatTasksParams } from 'elasticsearch';
import { CatThreadPoolParams } from 'elasticsearch';
import { ClearScrollParams } from 'elasticsearch';
import { Client } from 'elasticsearch';
import { ClientOptions } from '@elastic/elasticsearch';
import { ClusterAllocationExplainParams } from 'elasticsearch';
import { ClusterGetSettingsParams } from 'elasticsearch';
import { ClusterHealthParams } from 'elasticsearch';

View file

@ -210,7 +210,7 @@ module.exports = function () {
args: [
'scripts/functional_tests',
'--config',
'test/plugin_functional/config.js',
'test/plugin_functional/config.ts',
'--bail',
'--debug',
],

View file

@ -19,7 +19,6 @@
import { services as commonServices } from '../../common/services';
// @ts-ignore not TS yet
import { KibanaSupertestProvider, ElasticsearchSupertestProvider } from './supertest';
export const services = {

View file

@ -17,9 +17,9 @@ To run these tests during development you can use the following commands:
```
# Start the test server (can continue running)
node scripts/functional_tests_server.js --config test/plugin_functional/config.js
node scripts/functional_tests_server.js --config test/plugin_functional/config.ts
# Start a test run
node scripts/functional_test_runner.js --config test/plugin_functional/config.js
node scripts/functional_test_runner.js --config test/plugin_functional/config.ts
```
## Run Kibana with a test plugin
@ -42,7 +42,7 @@ If you wish to load up specific es archived data for your test, you can do so vi
Another option, which will automatically use any specific settings the test environment may rely on, is to boot up the functional test server pointing to the plugin configuration file.
```
node scripts/functional_tests_server --config test/plugin_functional/config.js
node scripts/functional_tests_server --config test/plugin_functional/config.ts
```
*Note:* you may still need to use the es_archiver script to boot up any required data.

View file

@ -16,12 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
import path from 'path';
import fs from 'fs';
import { services } from './services';
export default async function ({ readConfigFile }) {
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const functionalConfig = await readConfigFile(require.resolve('../functional/config'));
// Find all folders in ./plugins since we treat all them as plugin folder
@ -42,7 +41,6 @@ export default async function ({ readConfigFile }) {
],
services: {
...functionalConfig.get('services'),
...services,
},
pageObjects: functionalConfig.get('pageObjects'),
servers: functionalConfig.get('servers'),

View file

@ -0,0 +1,7 @@
{
"id": "elasticsearch_client_plugin",
"version": "0.0.1",
"kibanaVersion": "kibana",
"server": true,
"ui": false
}

View file

@ -0,0 +1,15 @@
{
"name": "elasticsearch_client_plugin",
"version": "1.0.0",
"kibana": {
"version": "kibana"
},
"license": "Apache-2.0",
"scripts": {
"kbn": "node ../../../../scripts/kbn.js",
"build": "rm -rf './target' && tsc"
},
"devDependencies": {
"typescript": "3.9.5"
}
}

View file

@ -16,13 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { format as formatUrl } from 'url';
import { FtrProviderContext } from 'test/functional/ftr_provider_context';
import supertestAsPromised from 'supertest-as-promised';
import { ElasticsearchClientPlugin } from './plugin';
export function KibanaSupertestProvider({ getService }: FtrProviderContext) {
const config = getService('config');
const kibanaServerUrl = formatUrl(config.get('servers.kibana'));
return supertestAsPromised(kibanaServerUrl);
}
export const plugin = () => new ElasticsearchClientPlugin();

View file

@ -0,0 +1,53 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Plugin, CoreSetup, CoreStart, ICustomClusterClient } from 'src/core/server';
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();
return res.ok({ body });
}
);
router.get(
{ path: '/api/elasticsearch_client_plugin/contract/ping', validate: false },
async (context, req, res) => {
const [coreStart] = await core.getStartServices();
const { body } = await coreStart.elasticsearch.client.asInternalUser.ping();
return res.ok({ body });
}
);
router.get(
{ path: '/api/elasticsearch_client_plugin/custom_client/ping', validate: false },
async (context, req, res) => {
const { body } = await this.client!.asInternalUser.ping();
return res.ok({ body });
}
);
}
public start(core: CoreStart) {
this.client = core.elasticsearch.createClient('my-custom-client-test');
}
public stop() {}
}

View file

@ -0,0 +1,12 @@
{
"extends": "../../../../tsconfig.json",
"compilerOptions": {
"outDir": "./target",
"skipLibCheck": true
},
"include": [
"server/**/*.ts",
"../../../../typings/**/*"
],
"exclude": []
}

View file

@ -16,14 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { GenericFtrProviderContext } from '@kbn/test/types/ftr';
import { FtrProviderContext } from 'test/functional/ftr_provider_context';
import { KibanaSupertestProvider } from './supertest';
import { FtrProviderContext } from '../../functional/ftr_provider_context';
export const services = {
supertest: KibanaSupertestProvider,
};
export type PluginFunctionalProviderContext = FtrProviderContext &
GenericFtrProviderContext<typeof services, {}>;
export type PluginFunctionalProviderContext = FtrProviderContext;

View file

@ -0,0 +1,38 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { PluginFunctionalProviderContext } from '../../services';
import '../../plugins/core_provider_plugin/types';
// eslint-disable-next-line import/no-default-export
export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) {
const supertest = getService('supertest');
describe('elasticsearch client', () => {
it('server plugins have access to elasticsearch client via request context', async () => {
await supertest.get('/api/elasticsearch_client_plugin/context/ping').expect(200, 'true');
});
it('server plugins have access to elasticsearch client via core contract', async () => {
await supertest.get('/api/elasticsearch_client_plugin/contract/ping').expect(200, 'true');
});
it('server plugins can create a custom elasticsearch client', async () => {
await supertest
.get('/api/elasticsearch_client_plugin/custom_client/ping')
.expect(200, 'true');
});
});
}

View file

@ -22,6 +22,7 @@ import { PluginFunctionalProviderContext } from '../../services';
export default function ({ loadTestFile }: PluginFunctionalProviderContext) {
describe('core plugins', () => {
loadTestFile(require.resolve('./applications'));
loadTestFile(require.resolve('./elasticsearch_client'));
loadTestFile(require.resolve('./legacy_plugins'));
loadTestFile(require.resolve('./server_plugins'));
loadTestFile(require.resolve('./ui_plugins'));

View file

@ -17,8 +17,10 @@
* under the License.
*/
import expect from '@kbn/expect';
import { PluginFunctionalProviderContext } from '../../services';
export default function ({ getService, getPageObjects }) {
// eslint-disable-next-line import/no-default-export
export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) {
const PageObjects = getPageObjects(['common']);
const browser = getService('browser');

View file

@ -20,6 +20,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
return {
testFiles: [
require.resolve('./test_suites/platform'),
require.resolve('./test_suites/task_manager'),
require.resolve('./test_suites/event_log'),
require.resolve('./test_suites/licensed_feature_usage'),

View file

@ -0,0 +1,7 @@
{
"id": "elasticsearch_client_xpack",
"version": "1.0.0",
"kibanaVersion": "kibana",
"server": true,
"ui": false
}

View file

@ -0,0 +1,14 @@
{
"name": "elasticsearch_client_xpack",
"version": "1.0.0",
"kibana": {
"version": "kibana"
},
"scripts": {
"kbn": "node ../../../../../scripts/kbn.js",
"build": "rm -rf './target' && tsc"
},
"devDependencies": {
"typescript": "3.9.5"
}
}

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { ElasticsearchClientXPack } from './plugin';
export const plugin = () => new ElasticsearchClientXPack();

View file

@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { Plugin, CoreSetup } from 'kibana/server';
export class ElasticsearchClientXPack implements Plugin {
constructor() {}
public setup(core: CoreSetup) {
const router = core.http.createRouter();
router.get(
{ path: '/api/elasticsearch_client_xpack/context/user', validate: false },
async (context, req, res) => {
const { body } = await context.core.elasticsearch.client.asCurrentUser.security.getUser();
return res.ok({ body });
}
);
router.get(
{ path: '/api/elasticsearch_client_xpack/contract/user', validate: false },
async (context, req, res) => {
const [coreStart] = await core.getStartServices();
const { body } = await coreStart.elasticsearch.client
.asScoped(req)
.asCurrentUser.security.getUser();
return res.ok({ body });
}
);
}
public start() {}
public stop() {}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
describe('elasticsearch client', () => {
it('scopes the elasticsearch client provided via request context to user credentials', async () => {
const { body } = await supertest
.get('/api/elasticsearch_client_xpack/context/user')
.expect(200);
expect(body).not.to.be.empty();
});
it('scopes the elasticsearch client provided via request context to user credentials', async () => {
const { body } = await supertest
.get('/api/elasticsearch_client_xpack/contract/user')
.expect(200);
expect(body).not.to.be.empty();
});
});
}

View file

@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ loadTestFile }: FtrProviderContext) {
describe('platform', function taskManagerSuite() {
this.tags('ciGroup2');
loadTestFile(require.resolve('./elasticsearch_client'));
});
}