diff --git a/docs/development/core/server/kibana-plugin-core-server.elasticsearchclient.md b/docs/development/core/server/kibana-plugin-core-server.elasticsearchclient.md index f6190fb3bc055..9a04a1d581765 100644 --- a/docs/development/core/server/kibana-plugin-core-server.elasticsearchclient.md +++ b/docs/development/core/server/kibana-plugin-core-server.elasticsearchclient.md @@ -9,9 +9,5 @@ Client used to query the elasticsearch cluster. Signature: ```typescript -export declare type ElasticsearchClient = Omit & { - transport: { - request(params: TransportRequestParams, options?: TransportRequestOptions): Promise>; - }; -}; +export declare type ElasticsearchClient = Omit; ``` diff --git a/examples/preboot_example/server/plugin.ts b/examples/preboot_example/server/plugin.ts index a3c1e9d199143..288b5245c82b1 100644 --- a/examples/preboot_example/server/plugin.ts +++ b/examples/preboot_example/server/plugin.ts @@ -114,7 +114,7 @@ export class PrebootExamplePlugin implements PrebootPlugin { try { return response.ok({ - body: (await scopedClient.asCurrentUser.security.authenticate()).body, + body: await scopedClient.asCurrentUser.security.authenticate(), }); } catch (err) { return response.customError({ statusCode: 500, body: getDetailedErrorMessage(err) }); diff --git a/packages/kbn-securitysolution-es-utils/src/elasticsearch_client/index.ts b/packages/kbn-securitysolution-es-utils/src/elasticsearch_client/index.ts index 95fa040142c15..90ca50aa17c22 100644 --- a/packages/kbn-securitysolution-es-utils/src/elasticsearch_client/index.ts +++ b/packages/kbn-securitysolution-es-utils/src/elasticsearch_client/index.ts @@ -9,7 +9,7 @@ // Copied from src/core/server/elasticsearch/client/types.ts // as these types aren't part of any package yet. Once they are, remove this completely -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; +import type { Client } from '@elastic/elasticsearch'; /** * Client used to query the elasticsearch cluster. @@ -17,6 +17,6 @@ import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; * @public */ export type ElasticsearchClient = Omit< - KibanaClient, - 'connectionPool' | 'transport' | 'serializer' | 'extend' | 'child' | 'close' | 'diagnostic' + Client, + 'connectionPool' | 'serializer' | 'extend' | 'child' | 'close' | 'diagnostic' >; diff --git a/packages/kbn-securitysolution-es-utils/src/get_bootstrap_index_exists/index.ts b/packages/kbn-securitysolution-es-utils/src/get_bootstrap_index_exists/index.ts index 959e38b3f7ee4..a743a9b66af54 100644 --- a/packages/kbn-securitysolution-es-utils/src/get_bootstrap_index_exists/index.ts +++ b/packages/kbn-securitysolution-es-utils/src/get_bootstrap_index_exists/index.ts @@ -22,7 +22,7 @@ export const getBootstrapIndexExists = async ( index: string ): Promise => { try { - const { body } = await esClient.indices.getAlias({ + const body = await esClient.indices.getAlias({ index: `${index}-*`, name: index, }); diff --git a/packages/kbn-securitysolution-es-utils/src/get_index_aliases/index.ts b/packages/kbn-securitysolution-es-utils/src/get_index_aliases/index.ts index 9a0d0fed1b63e..0df165a6b8b73 100644 --- a/packages/kbn-securitysolution-es-utils/src/get_index_aliases/index.ts +++ b/packages/kbn-securitysolution-es-utils/src/get_index_aliases/index.ts @@ -8,16 +8,6 @@ import type { ElasticsearchClient } from '../elasticsearch_client'; -interface AliasesResponse { - [indexName: string]: { - aliases: { - [aliasName: string]: { - is_write_index: boolean; - }; - }; - }; -} - interface IndexAlias { alias: string; index: string; @@ -39,7 +29,7 @@ export const getIndexAliases = async ({ esClient: ElasticsearchClient; alias: string; }): Promise => { - const response = await esClient.indices.getAlias( + const response = await esClient.indices.getAlias( { name: alias, }, diff --git a/packages/kbn-securitysolution-es-utils/src/get_index_count/index.ts b/packages/kbn-securitysolution-es-utils/src/get_index_count/index.ts index 59cae505bfded..6d7b35a00ae75 100644 --- a/packages/kbn-securitysolution-es-utils/src/get_index_count/index.ts +++ b/packages/kbn-securitysolution-es-utils/src/get_index_count/index.ts @@ -23,7 +23,7 @@ export const getIndexCount = async ({ esClient: ElasticsearchClient; index: string; }): Promise => { - const response = await esClient.count<{ count: number }>( + const response = await esClient.count( { index, }, diff --git a/packages/kbn-test/src/es/client_to_kibana_client.ts b/packages/kbn-test/src/es/client_to_kibana_client.ts deleted file mode 100644 index 778ee0a7705b3..0000000000000 --- a/packages/kbn-test/src/es/client_to_kibana_client.ts +++ /dev/null @@ -1,35 +0,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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; -import type { - Client, - TransportRequestParams, - TransportRequestOptions, - TransportResult, -} from '@elastic/elasticsearch'; -import { Transport } from '@elastic/elasticsearch'; - -// remove once https://github.com/elastic/kibana/issues/116095 is addressed -class KibanaTransport extends Transport { - request(params: TransportRequestParams, options?: TransportRequestOptions) { - const opts: TransportRequestOptions = options || {}; - // Enforce the client to return TransportResult. - // It's required for bwc with responses in 7.x version. - if (opts?.meta === undefined) { - opts.meta = true; - } - return super.request(params, opts) as Promise>; - } -} - -export function convertToKibanaClient(esClient: Client): KibanaClient { - // @ts-expect-error @elastic/elasticsearch fix discrepancy between clients - return esClient.child({ - Transport: KibanaTransport, - }); -} diff --git a/packages/kbn-test/src/es/index.ts b/packages/kbn-test/src/es/index.ts index c823adaab101f..641253acc3647 100644 --- a/packages/kbn-test/src/es/index.ts +++ b/packages/kbn-test/src/es/index.ts @@ -9,6 +9,5 @@ export { createTestEsCluster } from './test_es_cluster'; export type { CreateTestEsClusterOptions, EsTestCluster, ICluster } from './test_es_cluster'; export { esTestConfig } from './es_test_config'; -export { convertToKibanaClient } from './client_to_kibana_client'; export { createEsClientForTesting, createEsClientForFtrConfig } from './es_client_for_testing'; export type { EsClientForTestingOptions } from './es_client_for_testing'; diff --git a/packages/kbn-test/src/es/test_es_cluster.ts b/packages/kbn-test/src/es/test_es_cluster.ts index 575fc965962eb..388d578c9af57 100644 --- a/packages/kbn-test/src/es/test_es_cluster.ts +++ b/packages/kbn-test/src/es/test_es_cluster.ts @@ -12,11 +12,9 @@ import del from 'del'; // @ts-expect-error in js import { Cluster } from '@kbn/es'; import { Client, HttpConnection } from '@elastic/elasticsearch'; -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; import type { ToolingLog } from '@kbn/dev-utils'; import { CI_PARALLEL_PROCESS_PREFIX } from '../ci_parallel_process_prefix'; import { esTestConfig } from './es_test_config'; -import { convertToKibanaClient } from './client_to_kibana_client'; import { KIBANA_ROOT } from '../'; @@ -53,7 +51,6 @@ export interface ICluster { stop: () => Promise; cleanup: () => Promise; getClient: () => Client; - getKibanaEsClient: () => KibanaClient; getHostUrls: () => string[]; } @@ -289,13 +286,6 @@ export function createTestEsCluster< }); } - /** - * Returns an ES Client to the configured cluster - */ - getKibanaEsClient(): KibanaClient { - return convertToKibanaClient(this.getClient()); - } - getUrl() { if (this.nodes.length > 1) { throw new Error( diff --git a/packages/kbn-test/src/index.ts b/packages/kbn-test/src/index.ts index 5efd1c1f26852..26d40f70edb78 100644 --- a/packages/kbn-test/src/index.ts +++ b/packages/kbn-test/src/index.ts @@ -34,7 +34,6 @@ export type { export { esTestConfig, createTestEsCluster, - convertToKibanaClient, createEsClientForTesting, createEsClientForFtrConfig, } from './es'; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index d8cf4706ceb16..6d2ee9a5dd4e1 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -9,6 +9,7 @@ import { Action } from 'history'; import Boom from '@hapi/boom'; import { ByteSizeValue } from '@kbn/config-schema'; +import type { Client } from '@elastic/elasticsearch'; import { ConfigPath } from '@kbn/config'; import { DetailedPeerCertificate } from 'tls'; import type { DocLinks } from '@kbn/doc-links'; @@ -24,7 +25,6 @@ import { History as History_2 } from 'history'; import { Href } from 'history'; import { IconType } from '@elastic/eui'; import { IncomingHttpHeaders } from 'http'; -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; import { Location as Location_2 } from 'history'; import { LocationDescriptorObject } from 'history'; import { Logger } from '@kbn/logging'; @@ -44,9 +44,6 @@ import * as Rx from 'rxjs'; import { SchemaTypeError } from '@kbn/config-schema'; import type { ThemeVersion } from '@kbn/ui-shared-deps-npm'; import { TransitionPromptHook } from 'history'; -import type { TransportRequestOptions } from '@elastic/elasticsearch'; -import type { TransportRequestParams } from '@elastic/elasticsearch'; -import type { TransportResult } from '@elastic/elasticsearch'; import { Type } from '@kbn/config-schema'; import { TypeOf } from '@kbn/config-schema'; import { UiCounterMetricType } from '@kbn/analytics'; diff --git a/src/core/server/core_usage_data/core_usage_data_service.test.ts b/src/core/server/core_usage_data/core_usage_data_service.test.ts index e6e890b1a7dab..b2315a7cde281 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.test.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.test.ts @@ -207,47 +207,37 @@ describe('CoreUsageDataService', () => { }); service.setup({ http, metrics, savedObjectsStartPromise, changedDeprecatedConfigPath$ }); const elasticsearch = elasticsearchServiceMock.createStart(); - elasticsearch.client.asInternalUser.cat.indices.mockResolvedValueOnce({ - body: [ - { - name: '.kibana_task_manager_1', - 'docs.count': '10', - 'docs.deleted': '10', - 'store.size': '1000', - 'pri.store.size': '2000', - }, - ], - } as any); - elasticsearch.client.asInternalUser.count.mockResolvedValueOnce({ - body: { - count: '15', + elasticsearch.client.asInternalUser.cat.indices.mockResponseOnce([ + { + name: '.kibana_task_manager_1', + 'docs.count': '10', + 'docs.deleted': '10', + 'store.size': '1000', + 'pri.store.size': '2000', }, + ] as any); + elasticsearch.client.asInternalUser.count.mockResponseOnce({ + count: '15', } as any); - elasticsearch.client.asInternalUser.cat.indices.mockResolvedValueOnce({ - body: [ - { - name: '.kibana_1', - 'docs.count': '20', - 'docs.deleted': '20', - 'store.size': '2000', - 'pri.store.size': '4000', - }, - ], - } as any); - elasticsearch.client.asInternalUser.count.mockResolvedValueOnce({ - body: { - count: '10', + elasticsearch.client.asInternalUser.cat.indices.mockResponseOnce([ + { + name: '.kibana_1', + 'docs.count': '20', + 'docs.deleted': '20', + 'store.size': '2000', + 'pri.store.size': '4000', }, + ] as any); + elasticsearch.client.asInternalUser.count.mockResponseOnce({ + count: '10', } as any); - elasticsearch.client.asInternalUser.search.mockResolvedValueOnce({ - body: { - hits: { total: { value: 6 } }, - aggregations: { - aliases: { - buckets: { - active: { doc_count: 1 }, - disabled: { doc_count: 2 }, - }, + elasticsearch.client.asInternalUser.search.mockResponseOnce({ + hits: { total: { value: 6 } }, + aggregations: { + aliases: { + buckets: { + active: { doc_count: 1 }, + disabled: { doc_count: 2 }, }, }, }, diff --git a/src/core/server/core_usage_data/core_usage_data_service.ts b/src/core/server/core_usage_data/core_usage_data_service.ts index 824bfdffdceec..bdd46932fd9a9 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.ts @@ -136,12 +136,12 @@ export class CoreUsageDataService // to map back from the index to the alias. So we have to make an API // call for every alias. The document count is the lucene document count. const catIndicesResults = await elasticsearch.client.asInternalUser.cat - .indices({ + .indices({ index, format: 'JSON', bytes: 'b', }) - .then(({ body }) => { + .then((body) => { const stats = body[0]; return { @@ -160,7 +160,7 @@ export class CoreUsageDataService .count({ index, }) - .then(({ body }) => { + .then((body) => { return { savedObjectsDocsCount: body.count ? body.count : 0, }; @@ -182,7 +182,7 @@ export class CoreUsageDataService private async getSavedObjectAliasUsageData(elasticsearch: ElasticsearchServiceStart) { // Note: this agg can be changed to use `savedObjectsRepository.find` in the future after `filters` is supported. // See src/core/server/saved_objects/service/lib/aggregations/aggs_types/bucket_aggs.ts for supported aggregations. - const { body: resp } = await elasticsearch.client.asInternalUser.search< + const resp = await elasticsearch.client.asInternalUser.search< unknown, { aliases: UsageDataAggs } >({ diff --git a/src/core/server/elasticsearch/client/cluster_client.ts b/src/core/server/elasticsearch/client/cluster_client.ts index 6bf74294ab6c1..038fe109b3988 100644 --- a/src/core/server/elasticsearch/client/cluster_client.ts +++ b/src/core/server/elasticsearch/client/cluster_client.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; +import type { Client } from '@elastic/elasticsearch'; import { Logger } from '../../logging'; import { IAuthHeadersStorage, Headers, isKibanaRequest, isRealRequest } from '../../http'; import { ensureRawRequest, filterHeaders } from '../../http/router'; @@ -60,12 +60,12 @@ export interface ICustomClusterClient extends IClusterClient { export class ClusterClient implements ICustomClusterClient { private readonly config: ElasticsearchClientConfig; private readonly authHeaders?: IAuthHeadersStorage; - private readonly rootScopedClient: KibanaClient; + private readonly rootScopedClient: Client; private readonly getUnauthorizedErrorHandler: () => UnauthorizedErrorHandler | undefined; private readonly getExecutionContext: () => string | undefined; private isClosed = false; - public readonly asInternalUser: KibanaClient; + public readonly asInternalUser: Client; constructor({ config, diff --git a/src/core/server/elasticsearch/client/configure_client.ts b/src/core/server/elasticsearch/client/configure_client.ts index 58d1e228b98a0..e1e4a1846852b 100644 --- a/src/core/server/elasticsearch/client/configure_client.ts +++ b/src/core/server/elasticsearch/client/configure_client.ts @@ -7,7 +7,6 @@ */ import { Client, HttpConnection } from '@elastic/elasticsearch'; -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; import { Logger } from '../../logging'; import { parseClientOptions, ElasticsearchClientConfig } from './client_config'; import { instrumentEsQueryAndDeprecationLogger } from './log_query_and_deprecation'; @@ -28,7 +27,7 @@ export const configureClient = ( scoped?: boolean; getExecutionContext?: () => string | undefined; } -): KibanaClient => { +): Client => { const clientOptions = parseClientOptions(config, scoped); const KibanaTransport = createTransport({ getExecutionContext }); @@ -40,5 +39,5 @@ export const configureClient = ( instrumentEsQueryAndDeprecationLogger({ logger, client, type }); - return client as KibanaClient; + return client; }; diff --git a/src/core/server/elasticsearch/client/create_transport.test.ts b/src/core/server/elasticsearch/client/create_transport.test.ts index df2717e7ce9e6..ce54d8356f38b 100644 --- a/src/core/server/elasticsearch/client/create_transport.test.ts +++ b/src/core/server/elasticsearch/client/create_transport.test.ts @@ -116,7 +116,7 @@ describe('createTransport', () => { }); describe('`meta` option', () => { - it('adds `meta: true` to the options when not provided', async () => { + it('does not adds `meta: true` to the options when not provided', async () => { const transportClass = createTransportClass(); const transport = new transportClass(baseConstructorParams); const requestOptions = { method: 'GET', path: '/' }; @@ -126,7 +126,7 @@ describe('createTransport', () => { expect(transportRequestMock).toHaveBeenCalledTimes(1); expect(transportRequestMock).toHaveBeenCalledWith( expect.any(Object), - expect.objectContaining({ + expect.not.objectContaining({ meta: true, }) ); diff --git a/src/core/server/elasticsearch/client/create_transport.ts b/src/core/server/elasticsearch/client/create_transport.ts index d72fae58c88cf..7ebe61afabdd0 100644 --- a/src/core/server/elasticsearch/client/create_transport.ts +++ b/src/core/server/elasticsearch/client/create_transport.ts @@ -46,11 +46,6 @@ export const createTransport = ({ // rewrites headers['x-opaque-id'] if it presents opts.opaqueId = opaqueId; } - // Enforce the client to return TransportResult. - // It's required for bwc with responses in 7.x version. - if (opts.meta === undefined) { - opts.meta = true; - } // add stored headers to the options opts.headers = { diff --git a/src/core/server/elasticsearch/client/mocks.test.ts b/src/core/server/elasticsearch/client/mocks.test.ts index 30b50e19f6c7e..6c7f34112117c 100644 --- a/src/core/server/elasticsearch/client/mocks.test.ts +++ b/src/core/server/elasticsearch/client/mocks.test.ts @@ -47,9 +47,156 @@ describe('Mocked client', () => { it('`child` should be mocked and return a mocked Client', () => { expectMocked(client.child); - const child = client.child(); + const child = client.child({}); expect(child).not.toBe(client); expectMocked(child.search); }); + + describe('mockResponse', () => { + beforeEach(() => { + client.ping.mockReset(); + client.ping.mockResponse(true, { statusCode: 217, headers: { foo: 'bar' } }); + }); + + it('returns the body when `meta` is false', async () => { + const response = await client.ping({}, { meta: false }); + expect(response).toBe(true); + }); + it('returns the response when `meta` is true', async () => { + const response = await client.ping({}, { meta: true }); + expect(response).toEqual({ + body: true, + statusCode: 217, + headers: { foo: 'bar' }, + warnings: [], + meta: {}, + }); + }); + it('returns the body when `meta` is not provided', async () => { + const response = await client.ping({}, {}); + expect(response).toBe(true); + }); + it('mocks the response multiple times', async () => { + expect(await client.ping({}, {})).toBe(true); + expect(await client.ping({}, {})).toBe(true); + expect(await client.ping({}, {})).toBe(true); + }); + }); + describe('mockResponseOnce', () => { + beforeEach(() => { + client.ping.mockReset(); + client.ping.mockResponseOnce(true, { statusCode: 217, headers: { foo: 'bar' } }); + }); + + it('returns the body when `meta` is false', async () => { + const response = await client.ping({}, { meta: false }); + expect(response).toBe(true); + }); + it('returns the response when `meta` is true', async () => { + const response = await client.ping({}, { meta: true }); + expect(response).toEqual({ + body: true, + statusCode: 217, + headers: { foo: 'bar' }, + warnings: [], + meta: {}, + }); + }); + it('returns the body when `meta` is not provided', async () => { + const response = await client.ping({}, {}); + expect(response).toBe(true); + }); + it('mocks the response only once', async () => { + expect(await client.ping({}, {})).toBe(true); + expect(await client.ping({}, {})).toBe(undefined); + }); + it('can be chained', async () => { + client.ping.mockReset(); + client.ping.mockResponseOnce(true); + client.ping.mockResponseOnce(false); + client.ping.mockResponseOnce(true); + + expect(await client.ping({}, {})).toBe(true); + expect(await client.ping({}, {})).toBe(false); + expect(await client.ping({}, {})).toBe(true); + }); + }); + describe('mockResponseImplementation', () => { + beforeEach(() => { + client.ping.mockReset(); + client.ping.mockResponseImplementation(() => ({ + body: true, + statusCode: 217, + headers: { foo: 'bar' }, + })); + }); + + it('returns the body when `meta` is false', async () => { + const response = await client.ping({}, { meta: false }); + expect(response).toBe(true); + }); + it('returns the response when `meta` is true', async () => { + const response = await client.ping({}, { meta: true }); + expect(response).toEqual({ + body: true, + statusCode: 217, + headers: { foo: 'bar' }, + warnings: [], + meta: {}, + }); + }); + it('returns the body when `meta` is not provided', async () => { + const response = await client.ping({}, {}); + expect(response).toBe(true); + }); + it('mocks the response multiple times', async () => { + expect(await client.ping({}, {})).toBe(true); + expect(await client.ping({}, {})).toBe(true); + expect(await client.ping({}, {})).toBe(true); + }); + }); + describe('mockResponseImplementationOnce', () => { + beforeEach(() => { + client.ping.mockReset(); + client.ping.mockResponseImplementationOnce(() => ({ + body: true, + statusCode: 217, + headers: { foo: 'bar' }, + })); + }); + + it('returns the body when `meta` is false', async () => { + const response = await client.ping({}, { meta: false }); + expect(response).toBe(true); + }); + it('returns the response when `meta` is true', async () => { + const response = await client.ping({}, { meta: true }); + expect(response).toEqual({ + body: true, + statusCode: 217, + headers: { foo: 'bar' }, + warnings: [], + meta: {}, + }); + }); + it('returns the body when `meta` is not provided', async () => { + const response = await client.ping({}, {}); + expect(response).toBe(true); + }); + it('mocks the response only once', async () => { + expect(await client.ping({}, {})).toBe(true); + expect(await client.ping({}, {})).toBe(undefined); + }); + it('can be chained', async () => { + client.ping.mockReset(); + client.ping.mockResponseImplementationOnce(() => ({ body: true })); + client.ping.mockResponseImplementationOnce(() => ({ body: false })); + client.ping.mockResponseImplementationOnce(() => ({ body: true })); + + expect(await client.ping({}, {})).toBe(true); + expect(await client.ping({}, {})).toBe(false); + expect(await client.ping({}, {})).toBe(true); + }); + }); }); diff --git a/src/core/server/elasticsearch/client/mocks.ts b/src/core/server/elasticsearch/client/mocks.ts index 4cb31438791e0..2c34629f2fd57 100644 --- a/src/core/server/elasticsearch/client/mocks.ts +++ b/src/core/server/elasticsearch/client/mocks.ts @@ -6,9 +6,8 @@ * Side Public License, v 1. */ -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; -import type { TransportResult } from '@elastic/elasticsearch'; -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; +import type { Client } from '@elastic/elasticsearch'; +import type { TransportResult, TransportRequestOptions } from '@elastic/elasticsearch'; import type { PublicKeys } from '@kbn/utility-types'; import { ElasticsearchClient } from './types'; import { ICustomClusterClient } from './cluster_client'; @@ -21,11 +20,110 @@ const omittedProps = [ 'transport', 'serializer', 'helpers', -] as Array>; +] as Array>; + +export type DeeplyMockedApi = { + [P in keyof T]: T[P] extends (...args: any[]) => any + ? ClientApiMockInstance, Parameters> + : DeeplyMockedApi; +} & T; + +export interface ClientApiMockInstance extends jest.MockInstance { + /** + * Helper API around `mockReturnValue` returning either the body or the whole TransportResult + * depending on the `meta` parameter used during the call + */ + mockResponse(value: Awaited, opts?: Partial, 'body'>>): this; + + /** + * Helper API around `mockReturnValueOnce` returning either the body or the whole TransportResult + * depending on the `meta` parameter used during the call + */ + mockResponseOnce(value: Awaited, opts?: Partial, 'body'>>): this; + + /** + * Helper API around `mockImplementation` returning either the body or the whole TransportResult + * depending on the `meta` parameter used during the call + */ + mockResponseImplementation(handler: (...args: Y) => Partial>>): this; + + /** + * Helper API around `mockImplementationOnce` returning either the body or the whole TransportResult + * depending on the `meta` parameter used during the call + */ + mockResponseImplementationOnce( + handler: (...args: Y) => Partial>> + ): this; +} + +const createMockedApi = < + T = unknown, + Y extends [any, TransportRequestOptions] = [any, TransportRequestOptions] +>(): ClientApiMockInstance => { + const mock: ClientApiMockInstance = jest.fn() as any; + + mock.mockResponse = (value: T, opts?: Partial, 'body'>>) => { + mock.mockImplementation((args: unknown, options?: TransportRequestOptions) => { + const meta = options?.meta ?? false; + if (meta) { + return Promise.resolve(createApiResponse({ ...opts, body: value })) as any; + } else { + return Promise.resolve(value) as Promise; + } + }); + return mock; + }; + + mock.mockResponseOnce = (value: T, opts?: Partial, 'body'>>) => { + mock.mockImplementationOnce((args: unknown, options?: TransportRequestOptions) => { + const meta = options?.meta ?? false; + if (meta) { + return Promise.resolve(createApiResponse({ ...opts, body: value })) as any; + } else { + return Promise.resolve(value) as Promise; + } + }); + return mock; + }; + + mock.mockResponseImplementation = ( + handler: (...args: Y) => Partial>> + ) => { + mock.mockImplementation((args: unknown, options?: TransportRequestOptions) => { + const meta = options?.meta ?? false; + // @ts-expect-error couldn't do better while keeping compatibility this jest.MockInstance + const response = handler(args, options); + if (meta) { + return Promise.resolve(createApiResponse(response)) as any; + } else { + return Promise.resolve(response.body ?? {}) as Promise; + } + }); + return mock; + }; + + mock.mockResponseImplementationOnce = ( + handler: (...args: Y) => Partial>> + ) => { + mock.mockImplementationOnce((args: unknown, options?: TransportRequestOptions) => { + const meta = options?.meta ?? false; + // @ts-expect-error couldn't do better while keeping compatibility this jest.MockInstance + const response = handler(args, options); + if (meta) { + return Promise.resolve(createApiResponse(response)) as any; + } else { + return Promise.resolve(response.body ?? {}) as Promise; + } + }); + return mock; + }; + + return mock; +}; // use jest.requireActual() to prevent weird errors when people mock @elastic/elasticsearch const { Client: UnmockedClient } = jest.requireActual('@elastic/elasticsearch'); -const createInternalClientMock = (res?: Promise): DeeplyMockedKeys => { +const createInternalClientMock = (res?: Promise): DeeplyMockedApi => { // we mimic 'reflection' on a concrete instance of the client to generate the mocked functions. const client = new UnmockedClient({ node: 'http://127.0.0.1', @@ -50,14 +148,16 @@ const createInternalClientMock = (res?: Promise): DeeplyMockedKeys !omitted.includes(key)) .forEach(([key, descriptor]) => { if (typeof descriptor.value === 'function') { - obj[key] = jest.fn(() => res ?? createSuccessTransportRequestPromise({})); + const mock = createMockedApi(); + mock.mockImplementation(() => res ?? createSuccessTransportRequestPromise({})); + obj[key] = mock; } else if (typeof obj[key] === 'object' && obj[key] != null) { mockify(obj[key], omitted); } }); }; - mockify(client, omittedProps); + mockify(client, omittedProps as string[]); client.close = jest.fn().mockReturnValue(Promise.resolve()); client.child = jest.fn().mockImplementation(() => createInternalClientMock()); @@ -81,10 +181,10 @@ const createInternalClientMock = (res?: Promise): DeeplyMockedKeys; + return client as DeeplyMockedApi; }; -export type ElasticsearchClientMock = DeeplyMockedKeys; +export type ElasticsearchClientMock = DeeplyMockedApi; const createClientMock = (res?: Promise): ElasticsearchClientMock => createInternalClientMock(res) as unknown as ElasticsearchClientMock; @@ -138,13 +238,12 @@ const createSuccessTransportRequestPromise = ( body: T, { statusCode = 200 }: { statusCode?: number } = {}, headers: Record = { [PRODUCT_RESPONSE_HEADER]: 'Elasticsearch' } -): Promise> => { +): Promise & T> => { const response = createApiResponse({ body, statusCode, headers }); - - return Promise.resolve(response) as Promise>; + return Promise.resolve(response) as Promise & T>; }; -const createErrorTransportRequestPromise = (err: any): Promise> => { +const createErrorTransportRequestPromise = (err: any): Promise => { return Promise.reject(err); }; diff --git a/src/core/server/elasticsearch/client/retry_call_cluster.test.ts b/src/core/server/elasticsearch/client/retry_call_cluster.test.ts index 636841316941b..c2a9dd6ab91c8 100644 --- a/src/core/server/elasticsearch/client/retry_call_cluster.test.ts +++ b/src/core/server/elasticsearch/client/retry_call_cluster.test.ts @@ -23,37 +23,27 @@ describe('retryCallCluster', () => { }); it('returns response from ES API call in case of success', async () => { - const successReturn = elasticsearchClientMock.createSuccessTransportRequestPromise({ - ...dummyBody, - }); - - client.asyncSearch.get.mockReturnValue(successReturn); + client.asyncSearch.get.mockResponseOnce(dummyBody); const result = await retryCallCluster(() => client.asyncSearch.get({} as any)); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects with `NoLivingConnectionsError`', async () => { - const successReturn = elasticsearchClientMock.createSuccessTransportRequestPromise({ - ...dummyBody, - }); - client.asyncSearch.get .mockImplementationOnce(() => createErrorReturn(new errors.NoLivingConnectionsError('no living connections', {} as any)) ) - .mockImplementationOnce(() => successReturn); + .mockResponseOnce(dummyBody); const result = await retryCallCluster(() => client.asyncSearch.get({} as any)); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('rejects when ES API calls reject with other errors', async () => { client.ping .mockImplementationOnce(() => createErrorReturn(new Error('unknown error'))) - .mockImplementationOnce(() => - elasticsearchClientMock.createSuccessTransportRequestPromise({ ...dummyBody }) - ); + .mockResponseOnce(dummyBody); await expect(retryCallCluster(() => client.ping())).rejects.toMatchInlineSnapshot( `[Error: unknown error]` @@ -69,9 +59,7 @@ describe('retryCallCluster', () => { createErrorReturn(new errors.NoLivingConnectionsError('no living connections', {} as any)) ) .mockImplementationOnce(() => createErrorReturn(new Error('unknown error'))) - .mockImplementationOnce(() => - elasticsearchClientMock.createSuccessTransportRequestPromise({ ...dummyBody }) - ); + .mockResponseOnce(dummyBody); await expect(retryCallCluster(() => client.ping())).rejects.toMatchInlineSnapshot( `[Error: unknown error]` @@ -92,9 +80,7 @@ describe('migrationRetryCallCluster', () => { client.ping .mockImplementationOnce(() => createErrorReturn(error)) .mockImplementationOnce(() => createErrorReturn(error)) - .mockImplementationOnce(() => - elasticsearchClientMock.createSuccessTransportRequestPromise({ ...dummyBody }) - ); + .mockResponseOnce(dummyBody); }; it('retries ES API calls that rejects with `NoLivingConnectionsError`', async () => { @@ -103,21 +89,21 @@ describe('migrationRetryCallCluster', () => { ); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects with `ConnectionError`', async () => { mockClientPingWithErrorBeforeSuccess(new errors.ConnectionError('connection error', {} as any)); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects with `TimeoutError`', async () => { mockClientPingWithErrorBeforeSuccess(new errors.TimeoutError('timeout error', {} as any)); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects with 503 `ResponseError`', async () => { @@ -128,7 +114,7 @@ describe('migrationRetryCallCluster', () => { ); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects 401 `ResponseError`', async () => { @@ -139,7 +125,7 @@ describe('migrationRetryCallCluster', () => { ); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects with 403 `ResponseError`', async () => { @@ -150,7 +136,7 @@ describe('migrationRetryCallCluster', () => { ); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects with 408 `ResponseError`', async () => { @@ -161,7 +147,7 @@ describe('migrationRetryCallCluster', () => { ); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects with 410 `ResponseError`', async () => { @@ -172,7 +158,7 @@ describe('migrationRetryCallCluster', () => { ); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('retries ES API calls that rejects with `snapshot_in_progress_exception` `ResponseError`', async () => { @@ -188,7 +174,7 @@ describe('migrationRetryCallCluster', () => { ); const result = await migrationRetryCallCluster(() => client.ping(), logger, 1); - expect(result.body).toEqual(dummyBody); + expect(result).toEqual(dummyBody); }); it('logs only once for each unique error message', async () => { diff --git a/src/core/server/elasticsearch/client/types.ts b/src/core/server/elasticsearch/client/types.ts index e168a4a4a9c21..68fbc87193074 100644 --- a/src/core/server/elasticsearch/client/types.ts +++ b/src/core/server/elasticsearch/client/types.ts @@ -6,12 +6,7 @@ * Side Public License, v 1. */ -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; -import type { - TransportResult, - TransportRequestOptions, - TransportRequestParams, -} from '@elastic/elasticsearch'; +import type { Client } from '@elastic/elasticsearch'; /** * Client used to query the elasticsearch cluster. @@ -19,16 +14,9 @@ import type { * @public */ export type ElasticsearchClient = Omit< - KibanaClient, - 'connectionPool' | 'transport' | 'serializer' | 'extend' | 'child' | 'close' | 'diagnostic' -> & { - transport: { - request( - params: TransportRequestParams, - options?: TransportRequestOptions - ): Promise>; - }; -}; + Client, + 'connectionPool' | 'serializer' | 'extend' | 'child' | 'close' | 'diagnostic' +>; /** * All response typings are maintained until elasticsearch-js provides them out of the box diff --git a/src/core/server/elasticsearch/integration_tests/client.test.ts b/src/core/server/elasticsearch/integration_tests/client.test.ts index 05100564dac03..96a9d70d1b651 100644 --- a/src/core/server/elasticsearch/integration_tests/client.test.ts +++ b/src/core/server/elasticsearch/integration_tests/client.test.ts @@ -39,16 +39,19 @@ describe('elasticsearch clients', () => { it('does not return deprecation warning when x-elastic-product-origin header is set', async () => { // Header should be automatically set by Core const resp1 = - await kibanaServer.coreStart.elasticsearch.client.asInternalUser.indices.getSettings({ - index: '.kibana', - }); + await kibanaServer.coreStart.elasticsearch.client.asInternalUser.indices.getSettings( + { + index: '.kibana', + }, + { meta: true } + ); expect(resp1.headers).not.toHaveProperty('warning'); // Also test setting it explicitly const resp2 = await kibanaServer.coreStart.elasticsearch.client.asInternalUser.indices.getSettings( { index: '.kibana' }, - { headers: { 'x-elastic-product-origin': 'kibana' } } + { headers: { 'x-elastic-product-origin': 'kibana' }, meta: true } ); expect(resp2.headers).not.toHaveProperty('warning'); }); diff --git a/src/core/server/elasticsearch/is_scripting_enabled.test.ts b/src/core/server/elasticsearch/is_scripting_enabled.test.ts index dd84c29818556..797ff8972b7be 100644 --- a/src/core/server/elasticsearch/is_scripting_enabled.test.ts +++ b/src/core/server/elasticsearch/is_scripting_enabled.test.ts @@ -18,9 +18,7 @@ describe('isInlineScriptingEnabled', () => { }); const mockSettingsValue = (settings: estypes.ClusterGetSettingsResponse) => { - client.cluster.getSettings.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise(settings) - ); + client.cluster.getSettings.mockResolvedValue(settings); }; it('returns `true` if all settings are empty', async () => { diff --git a/src/core/server/elasticsearch/is_scripting_enabled.ts b/src/core/server/elasticsearch/is_scripting_enabled.ts index 31276a8c72aef..13685362c11ca 100644 --- a/src/core/server/elasticsearch/is_scripting_enabled.ts +++ b/src/core/server/elasticsearch/is_scripting_enabled.ts @@ -15,7 +15,7 @@ export const isInlineScriptingEnabled = async ({ }: { client: ElasticsearchClient; }): Promise => { - const { body: settings } = await client.cluster.getSettings({ + const settings = await client.cluster.getSettings({ include_defaults: true, flat_settings: true, }); diff --git a/src/core/server/elasticsearch/version_check/ensure_es_version.test.ts b/src/core/server/elasticsearch/version_check/ensure_es_version.test.ts index c9bb82d5da65c..9dfb2463f0893 100644 --- a/src/core/server/elasticsearch/version_check/ensure_es_version.test.ts +++ b/src/core/server/elasticsearch/version_check/ensure_es_version.test.ts @@ -18,10 +18,6 @@ const mockLogger = mockLoggerFactory.get('mock logger'); const KIBANA_VERSION = '5.1.0'; -const createEsSuccess = elasticsearchClientMock.createSuccessTransportRequestPromise; -const createEsErrorReturn = (err: any) => - elasticsearchClientMock.createErrorTransportRequestPromise(err); - function createNodes(...versions: string[]): NodesInfo { const nodes = {} as any; versions @@ -140,10 +136,10 @@ describe('pollEsNodesVersion', () => { const nodeInfosSuccessOnce = (infos: NodesInfo) => { // @ts-expect-error not full interface - internalClient.nodes.info.mockImplementationOnce(() => createEsSuccess(infos)); + internalClient.nodes.info.mockResponseOnce(infos); }; const nodeInfosErrorOnce = (error: any) => { - internalClient.nodes.info.mockImplementationOnce(() => createEsErrorReturn(new Error(error))); + internalClient.nodes.info.mockImplementationOnce(() => Promise.reject(new Error(error))); }; it('returns isCompatible=false and keeps polling when a poll request throws', (done) => { @@ -317,13 +313,9 @@ describe('pollEsNodesVersion', () => { expect.assertions(1); // @ts-expect-error we need to return an incompatible type to use the testScheduler here - internalClient.nodes.info.mockReturnValueOnce([ - { body: createNodes('5.1.0', '5.2.0', '5.0.0') }, - ]); + internalClient.nodes.info.mockReturnValueOnce([createNodes('5.1.0', '5.2.0', '5.0.0')]); // @ts-expect-error we need to return an incompatible type to use the testScheduler here - internalClient.nodes.info.mockReturnValueOnce([ - { body: createNodes('5.1.1', '5.2.0', '5.0.0') }, - ]); + internalClient.nodes.info.mockReturnValueOnce([createNodes('5.1.1', '5.2.0', '5.0.0')]); getTestScheduler().run(({ expectObservable }) => { const expected = 'a 99ms (b|)'; @@ -359,11 +351,11 @@ describe('pollEsNodesVersion', () => { internalClient.nodes.info.mockReturnValueOnce( // @ts-expect-error we need to return an incompatible type to use the testScheduler here - of({ body: createNodes('5.1.0', '5.2.0', '5.0.0') }).pipe(delay(100)) + of(createNodes('5.1.0', '5.2.0', '5.0.0')).pipe(delay(100)) ); internalClient.nodes.info.mockReturnValueOnce( // @ts-expect-error we need to return an incompatible type to use the testScheduler here - of({ body: createNodes('5.1.1', '5.2.0', '5.0.0') }).pipe(delay(100)) + of(createNodes('5.1.1', '5.2.0', '5.0.0')).pipe(delay(100)) ); const esNodesCompatibility$ = pollEsNodesVersion({ diff --git a/src/core/server/elasticsearch/version_check/ensure_es_version.ts b/src/core/server/elasticsearch/version_check/ensure_es_version.ts index b21c3544afa9a..5a1856b35acd6 100644 --- a/src/core/server/elasticsearch/version_check/ensure_es_version.ts +++ b/src/core/server/elasticsearch/version_check/ensure_es_version.ts @@ -120,6 +120,7 @@ export function mapNodesVersionCompatibility( kibanaVersion, }; } + // Returns true if NodesVersionCompatibility nodesInfoRequestError is the same function compareNodesInfoErrorMessages( prev: NodesVersionCompatibility, @@ -127,6 +128,7 @@ function compareNodesInfoErrorMessages( ): boolean { return prev.nodesInfoRequestError?.message === curr.nodesInfoRequestError?.message; } + // Returns true if two NodesVersionCompatibility entries match function compareNodes(prev: NodesVersionCompatibility, curr: NodesVersionCompatibility) { const nodesEqual = (n: NodeInfo, m: NodeInfo) => n.ip === m.ip && n.version === m.version; @@ -152,11 +154,10 @@ export const pollEsNodesVersion = ({ return timer(0, healthCheckInterval).pipe( exhaustMap(() => { return from( - internalClient.nodes.info({ + internalClient.nodes.info({ filter_path: ['nodes.*.version', 'nodes.*.http.publish_address', 'nodes.*.ip'], }) ).pipe( - map(({ body }) => body), catchError((nodesInfoRequestError) => { return of({ nodes: {}, nodesInfoRequestError }); }) 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 7a54315204a6b..4aef2e815fa30 100644 --- a/src/core/server/execution_context/integration_tests/tracing.test.ts +++ b/src/core/server/execution_context/integration_tests/tracing.test.ts @@ -58,7 +58,10 @@ 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 { headers } = await context.core.elasticsearch.client.asInternalUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -80,7 +83,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -102,7 +108,10 @@ 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 { headers } = await context.core.elasticsearch.client.asInternalUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -120,7 +129,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -142,6 +154,7 @@ describe('trace', () => { {}, { opaqueId: 'new-opaque-id', + meta: true, } ); return res.ok({ body: headers || {} }); @@ -183,7 +196,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -206,7 +222,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: { context: executionContext.get()?.toJSON(), @@ -319,7 +338,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -429,7 +451,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -450,7 +475,10 @@ 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 { headers } = await context.core.elasticsearch.client.asInternalUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -471,7 +499,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -494,7 +525,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -523,7 +557,10 @@ 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(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return res.ok({ body: headers || {} }); }); @@ -591,7 +628,7 @@ describe('trace', () => { }; router.get({ path: '/execution-context', validate: false }, async (context, req, res) => { const { headers } = await executionContext.withContext(newContext, () => - context.core.elasticsearch.client.asCurrentUser.ping() + context.core.elasticsearch.client.asCurrentUser.ping({}, { meta: true }) ); return res.ok({ body: headers || {} }); }); diff --git a/src/core/server/http/integration_tests/core_services.test.ts b/src/core/server/http/integration_tests/core_services.test.ts index 4bf64a96cf773..8bf0908ae4dc7 100644 --- a/src/core/server/http/integration_tests/core_services.test.ts +++ b/src/core/server/http/integration_tests/core_services.test.ts @@ -297,7 +297,9 @@ describe('http service', () => { const router = createRouter('/new-platform'); router.get({ path: '/', validate: false }, async (context, req, res) => { try { - const result = await elasticsearch.client.asScoped(req).asInternalUser.ping(); + const result = await elasticsearch.client + .asScoped(req) + .asInternalUser.ping({}, { meta: true }); return res.ok({ body: result, }); diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 515f5bdb28586..32c0729dcae34 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -63,6 +63,8 @@ export { deprecationsServiceMock } from './deprecations/deprecations_service.moc export { executionContextServiceMock } from './execution_context/execution_context_service.mock'; export { docLinksServiceMock } from './doc_links/doc_links_service.mock'; +export type { ElasticsearchClientMock } from './elasticsearch/client/mocks'; + type MockedPluginInitializerConfig = jest.Mocked['config']>; export function pluginInitializerContextConfigMock(config: T) { diff --git a/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts b/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts index 5b2687262ab36..749ec58bcbfed 100644 --- a/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts +++ b/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts @@ -48,9 +48,7 @@ describe('unknown saved object types deprecation', () => { describe('getUnknownTypesDeprecations', () => { beforeEach(() => { - esClient.asInternalUser.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(createSearchResponse(0)) - ); + esClient.asInternalUser.search.mockResponse(createSearchResponse(0)); }); it('calls `esClient.asInternalUser.search` with the correct parameters', async () => { @@ -76,9 +74,7 @@ describe('unknown saved object types deprecation', () => { }); it('returns no deprecation if no unknown type docs are found', async () => { - esClient.asInternalUser.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(createSearchResponse(0)) - ); + esClient.asInternalUser.search.mockResponse(createSearchResponse(0)); const deprecations = await getUnknownTypesDeprecations({ esClient, @@ -91,9 +87,7 @@ describe('unknown saved object types deprecation', () => { }); it('returns a deprecation if any unknown type docs are found', async () => { - esClient.asInternalUser.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(createSearchResponse(1)) - ); + esClient.asInternalUser.search.mockResponse(createSearchResponse(1)); const deprecations = await getUnknownTypesDeprecations({ esClient, diff --git a/src/core/server/saved_objects/deprecations/unknown_object_types.ts b/src/core/server/saved_objects/deprecations/unknown_object_types.ts index 8815065984a27..28dbc4dcd41fa 100644 --- a/src/core/server/saved_objects/deprecations/unknown_object_types.ts +++ b/src/core/server/saved_objects/deprecations/unknown_object_types.ts @@ -74,7 +74,7 @@ const getUnknownSavedObjects = async ({ }); const query = getUnknownTypesQuery(knownTypes); - const { body } = await esClient.asInternalUser.search({ + const body = await esClient.asInternalUser.search({ index: targetIndices, body: { size: 10000, diff --git a/src/core/server/saved_objects/migrations/actions/bulk_overwrite_transformed_documents.test.ts b/src/core/server/saved_objects/migrations/actions/bulk_overwrite_transformed_documents.test.ts index 57a1f54925d47..7f2cfa01ec42f 100644 --- a/src/core/server/saved_objects/migrations/actions/bulk_overwrite_transformed_documents.test.ts +++ b/src/core/server/saved_objects/migrations/actions/bulk_overwrite_transformed_documents.test.ts @@ -21,7 +21,7 @@ describe('bulkOverwriteTransformedDocuments', () => { it('resolves with `right:bulk_index_succeeded` if no error is encountered', async () => { const client = elasticsearchClientMock.createInternalClient( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + Promise.resolve({ items: [ { index: { @@ -52,7 +52,7 @@ describe('bulkOverwriteTransformedDocuments', () => { it('resolves with `right:bulk_index_succeeded` if version conflict errors are encountered', async () => { const client = elasticsearchClientMock.createInternalClient( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + Promise.resolve({ items: [ { index: { @@ -113,7 +113,7 @@ describe('bulkOverwriteTransformedDocuments', () => { it('resolves with `left:target_index_had_write_block` if all errors are write block exceptions', async () => { const client = elasticsearchClientMock.createInternalClient( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + Promise.resolve({ items: [ { index: { @@ -158,7 +158,7 @@ describe('bulkOverwriteTransformedDocuments', () => { }); const client = elasticsearchClientMock.createInternalClient( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + Promise.resolve({ items: [ { index: { diff --git a/src/core/server/saved_objects/migrations/actions/bulk_overwrite_transformed_documents.ts b/src/core/server/saved_objects/migrations/actions/bulk_overwrite_transformed_documents.ts index f3ddc0c308970..5f3e95bbcfc72 100644 --- a/src/core/server/saved_objects/migrations/actions/bulk_overwrite_transformed_documents.ts +++ b/src/core/server/saved_objects/migrations/actions/bulk_overwrite_transformed_documents.ts @@ -93,7 +93,7 @@ export const bulkOverwriteTransformedDocuments = .then((res) => { // Filter out version_conflict_engine_exception since these just mean // that another instance already updated these documents - const errors: estypes.ErrorCause[] = (res.body.items ?? []) + const errors: estypes.ErrorCause[] = (res.items ?? []) .filter((item) => item.index?.error) .map((item) => item.index!.error!) .filter(({ type }) => type !== 'version_conflict_engine_exception'); diff --git a/src/core/server/saved_objects/migrations/actions/calculate_exclude_filters.ts b/src/core/server/saved_objects/migrations/actions/calculate_exclude_filters.ts index 2b35e3b59e988..27ce7bd4c404b 100644 --- a/src/core/server/saved_objects/migrations/actions/calculate_exclude_filters.ts +++ b/src/core/server/saved_objects/migrations/actions/calculate_exclude_filters.ts @@ -45,7 +45,11 @@ export const calculateExcludeFilters = Object.entries(excludeFromUpgradeFilterHooks).map(([soType, hook]) => withTimeout({ promise: Promise.resolve( - hook({ readonlyEsClient: { search: client.search.bind(client) } }) + hook({ + readonlyEsClient: { + search: client.search.bind(client) as ElasticsearchClient['search'], + }, + }) ), timeoutMs: hookTimeoutMs, }) diff --git a/src/core/server/saved_objects/migrations/actions/check_for_unknown_docs.test.ts b/src/core/server/saved_objects/migrations/actions/check_for_unknown_docs.test.ts index 0ddb858f91bc0..4254c152a1fa8 100644 --- a/src/core/server/saved_objects/migrations/actions/check_for_unknown_docs.test.ts +++ b/src/core/server/saved_objects/migrations/actions/check_for_unknown_docs.test.ts @@ -53,7 +53,7 @@ describe('checkForUnknownDocs', () => { it('calls `client.search` with the correct parameters', async () => { const client = elasticsearchClientMock.createInternalClient( - elasticsearchClientMock.createSuccessTransportRequestPromise({ hits: { hits: [] } }) + Promise.resolve({ hits: { hits: [] } }) ); const task = checkForUnknownDocs({ @@ -85,7 +85,7 @@ describe('checkForUnknownDocs', () => { it('resolves with `Either.right` when no unknown docs are found', async () => { const client = elasticsearchClientMock.createInternalClient( - elasticsearchClientMock.createSuccessTransportRequestPromise({ hits: { hits: [] } }) + Promise.resolve({ hits: { hits: [] } }) ); const task = checkForUnknownDocs({ @@ -103,7 +103,7 @@ describe('checkForUnknownDocs', () => { it('resolves with `Either.left` when unknown docs are found', async () => { const client = elasticsearchClientMock.createInternalClient( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { _id: '12', _source: { type: 'foo' } }, @@ -134,7 +134,7 @@ describe('checkForUnknownDocs', () => { it('uses `unknown` as the type when the document does not contain a type field', async () => { const client = elasticsearchClientMock.createInternalClient( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [{ _id: '12', _source: {} }], }, diff --git a/src/core/server/saved_objects/migrations/actions/check_for_unknown_docs.ts b/src/core/server/saved_objects/migrations/actions/check_for_unknown_docs.ts index 6dd8fbda73c95..f9e3df9a0443a 100644 --- a/src/core/server/saved_objects/migrations/actions/check_for_unknown_docs.ts +++ b/src/core/server/saved_objects/migrations/actions/check_for_unknown_docs.ts @@ -56,8 +56,8 @@ export const checkForUnknownDocs = query, }, }) - .then((response) => { - const { hits } = response.body.hits; + .then((body) => { + const { hits } = body.hits; if (hits.length) { return Either.left({ type: 'unknown_docs_found' as const, diff --git a/src/core/server/saved_objects/migrations/actions/clone_index.ts b/src/core/server/saved_objects/migrations/actions/clone_index.ts index d7994f5a465d2..e77ce8c47156f 100644 --- a/src/core/server/saved_objects/migrations/actions/clone_index.ts +++ b/src/core/server/saved_objects/migrations/actions/clone_index.ts @@ -83,7 +83,7 @@ export const cloneIndex = ({ }, { maxRetries: 0 /** handle retry ourselves for now */ } ) - .then((res) => { + .then((response) => { /** * - acknowledged=false, we timed out before the cluster state was * updated with the newly created index, but it probably will be @@ -93,8 +93,8 @@ export const cloneIndex = ({ * - acknowledged=true, shards_acknowledged=true, cloning complete */ return Either.right({ - acknowledged: res.body.acknowledged, - shardsAcknowledged: res.body.shards_acknowledged, + acknowledged: response.acknowledged, + shardsAcknowledged: response.shards_acknowledged, }); }) .catch((error: EsErrors.ResponseError) => { diff --git a/src/core/server/saved_objects/migrations/actions/close_pit.ts b/src/core/server/saved_objects/migrations/actions/close_pit.ts index 9dd7f1d22386f..cb340068560d4 100644 --- a/src/core/server/saved_objects/migrations/actions/close_pit.ts +++ b/src/core/server/saved_objects/migrations/actions/close_pit.ts @@ -31,7 +31,7 @@ export const closePit = body: { id: pitId }, }) .then((response) => { - if (!response.body.succeeded) { + if (!response.succeeded) { throw new Error(`Failed to close PointInTime with id: ${pitId}`); } return Either.right({}); diff --git a/src/core/server/saved_objects/migrations/actions/create_index.ts b/src/core/server/saved_objects/migrations/actions/create_index.ts index b687a4ad93b36..e037de1712373 100644 --- a/src/core/server/saved_objects/migrations/actions/create_index.ts +++ b/src/core/server/saved_objects/migrations/actions/create_index.ts @@ -102,8 +102,8 @@ export const createIndex = ({ * - acknowledged=true, shards_acknowledged=true, index creation complete */ return Either.right({ - acknowledged: Boolean(res.body.acknowledged), - shardsAcknowledged: res.body.shards_acknowledged, + acknowledged: Boolean(res.acknowledged), + shardsAcknowledged: res.shards_acknowledged, }); }) .catch((error) => { diff --git a/src/core/server/saved_objects/migrations/actions/fetch_indices.ts b/src/core/server/saved_objects/migrations/actions/fetch_indices.ts index 1256b2d858906..faed825400c1f 100644 --- a/src/core/server/saved_objects/migrations/actions/fetch_indices.ts +++ b/src/core/server/saved_objects/migrations/actions/fetch_indices.ts @@ -43,7 +43,7 @@ export const fetchIndices = }, { ignore: [404], maxRetries: 0 } ) - .then(({ body }) => { + .then((body) => { return Either.right(body); }) .catch(catchRetryableEsClientErrors); diff --git a/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts b/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts index 008bc3d301d9f..ef84f0cb49231 100644 --- a/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts +++ b/src/core/server/saved_objects/migrations/actions/integration_tests/actions.test.ts @@ -63,7 +63,7 @@ describe('migration actions', () => { beforeAll(async () => { esServer = await startES(); - client = esServer.es.getKibanaEsClient(); + client = esServer.es.getClient(); // Create test fixture data: await createIndex({ @@ -277,7 +277,7 @@ describe('migration actions', () => { })(); const redStatusResponse = await client.cluster.health({ index: 'red_then_yellow_index' }); - expect(redStatusResponse.body.status).toBe('red'); + expect(redStatusResponse.status).toBe('red'); client.indices.putSettings({ index: 'red_then_yellow_index', @@ -291,7 +291,7 @@ describe('migration actions', () => { // Assert that the promise didn't resolve before the index became yellow const yellowStatusResponse = await client.cluster.health({ index: 'red_then_yellow_index' }); - expect(yellowStatusResponse.body.status).toBe('yellow'); + expect(yellowStatusResponse.status).toBe('yellow'); }); }); @@ -924,7 +924,7 @@ describe('migration actions', () => { }, }); - await expect(searchResponse.body.hits.hits.length).toBeGreaterThan(0); + await expect(searchResponse.hits.hits.length).toBeGreaterThan(0); }); it('rejects if index does not exist', async () => { const openPitTask = openPit({ client, index: 'no_such_index' }); diff --git a/src/core/server/saved_objects/migrations/actions/integration_tests/es_errors.test.ts b/src/core/server/saved_objects/migrations/actions/integration_tests/es_errors.test.ts index 2473d8d3ae410..7f998938e92c0 100644 --- a/src/core/server/saved_objects/migrations/actions/integration_tests/es_errors.test.ts +++ b/src/core/server/saved_objects/migrations/actions/integration_tests/es_errors.test.ts @@ -65,7 +65,7 @@ describe('Elasticsearch Errors', () => { ); // @ts-expect-error @elastic/elasticsearch doesn't declare error on IndexResponse - expect(isWriteBlockException(res.body.error!)).toEqual(true); + expect(isWriteBlockException(res.error!)).toEqual(true); }); it('correctly identify errors from create operations', async () => { @@ -81,7 +81,7 @@ describe('Elasticsearch Errors', () => { ); // @ts-expect-error @elastic/elasticsearch doesn't declare error on IndexResponse - expect(isWriteBlockException(res.body.error!)).toEqual(true); + expect(isWriteBlockException(res.error!)).toEqual(true); }); it('correctly identify errors from bulk index operations', async () => { @@ -100,7 +100,7 @@ describe('Elasticsearch Errors', () => { ], }); - const cause = res.body.items[0].index!.error! as estypes.ErrorCause; + const cause = res.items[0].index!.error! as estypes.ErrorCause; expect(isWriteBlockException(cause)).toEqual(true); }); @@ -122,7 +122,7 @@ describe('Elasticsearch Errors', () => { ], }); - const cause = res.body.items[0].create!.error! as estypes.ErrorCause; + const cause = res.items[0].create!.error! as estypes.ErrorCause; expect(isWriteBlockException(cause)).toEqual(true); }); diff --git a/src/core/server/saved_objects/migrations/actions/open_pit.ts b/src/core/server/saved_objects/migrations/actions/open_pit.ts index 43c84a2b26613..7e1f3a77f2d1e 100644 --- a/src/core/server/saved_objects/migrations/actions/open_pit.ts +++ b/src/core/server/saved_objects/migrations/actions/open_pit.ts @@ -40,6 +40,6 @@ export const openPit = index, keep_alive: pitKeepAlive, }) - .then((response) => Either.right({ pitId: response.body.id })) + .then((response) => Either.right({ pitId: response.id })) .catch(catchRetryableEsClientErrors); }; diff --git a/src/core/server/saved_objects/migrations/actions/pickup_updated_mappings.ts b/src/core/server/saved_objects/migrations/actions/pickup_updated_mappings.ts index 2db6b1833c6dd..c1e1111a4afe3 100644 --- a/src/core/server/saved_objects/migrations/actions/pickup_updated_mappings.ts +++ b/src/core/server/saved_objects/migrations/actions/pickup_updated_mappings.ts @@ -14,6 +14,7 @@ import { RetryableEsClientError, } from './catch_retryable_es_client_errors'; import { BATCH_SIZE } from './constants'; + export interface UpdateByQueryResponse { taskId: string; } @@ -52,7 +53,7 @@ export const pickupUpdatedMappings = // Create a task and return task id instead of blocking until complete wait_for_completion: false, }) - .then(({ body: { task: taskId } }) => { + .then(({ task: taskId }) => { return Either.right({ taskId: String(taskId!) }); }) .catch(catchRetryableEsClientErrors); diff --git a/src/core/server/saved_objects/migrations/actions/read_with_pit.ts b/src/core/server/saved_objects/migrations/actions/read_with_pit.ts index 0902e206147d3..013cd59271ee1 100644 --- a/src/core/server/saved_objects/migrations/actions/read_with_pit.ts +++ b/src/core/server/saved_objects/migrations/actions/read_with_pit.ts @@ -68,12 +68,12 @@ export const readWithPit = query, }, }) - .then((response) => { + .then((body) => { const totalHits = - typeof response.body.hits.total === 'number' - ? response.body.hits.total // This format is to be removed in 8.0 - : response.body.hits.total?.value; - const hits = response.body.hits.hits; + typeof body.hits.total === 'number' + ? body.hits.total // This format is to be removed in 8.0 + : body.hits.total?.value; + const hits = body.hits.hits; if (hits.length > 0) { return Either.right({ diff --git a/src/core/server/saved_objects/migrations/actions/reindex.ts b/src/core/server/saved_objects/migrations/actions/reindex.ts index e8e054c7a1780..cfd7449971b7f 100644 --- a/src/core/server/saved_objects/migrations/actions/reindex.ts +++ b/src/core/server/saved_objects/migrations/actions/reindex.ts @@ -21,6 +21,7 @@ import { BATCH_SIZE } from './constants'; export interface ReindexResponse { taskId: string; } + /** @internal */ export interface ReindexParams { client: ElasticsearchClient; @@ -34,6 +35,7 @@ export interface ReindexParams { */ unusedTypesQuery: estypes.QueryDslQueryContainer; } + /** * Reindex documents from the `sourceIndex` into the `targetIndex`. Returns a * task ID which can be tracked for progress. @@ -85,7 +87,7 @@ export const reindex = // Create a task and return task id instead of blocking until complete wait_for_completion: false, }) - .then(({ body: { task: taskId } }) => { + .then(({ task: taskId }) => { return Either.right({ taskId: String(taskId) }); }) .catch(catchRetryableEsClientErrors); diff --git a/src/core/server/saved_objects/migrations/actions/remove_write_block.ts b/src/core/server/saved_objects/migrations/actions/remove_write_block.ts index cca9ea5e7598e..47a3ecf7a4404 100644 --- a/src/core/server/saved_objects/migrations/actions/remove_write_block.ts +++ b/src/core/server/saved_objects/migrations/actions/remove_write_block.ts @@ -19,6 +19,7 @@ export interface RemoveWriteBlockParams { client: ElasticsearchClient; index: string; } + /** * Removes a write block from an index */ @@ -32,10 +33,7 @@ export const removeWriteBlock = > => () => { return client.indices - .putSettings<{ - acknowledged: boolean; - shards_acknowledged: boolean; - }>( + .putSettings( { index, // Don't change any existing settings @@ -49,7 +47,7 @@ export const removeWriteBlock = { maxRetries: 0 /** handle retry ourselves for now */ } ) .then((res) => { - return res.body.acknowledged === true + return res.acknowledged === true ? Either.right('remove_write_block_succeeded' as const) : Either.left({ type: 'retryable_es_client_error' as const, diff --git a/src/core/server/saved_objects/migrations/actions/search_for_outdated_documents.ts b/src/core/server/saved_objects/migrations/actions/search_for_outdated_documents.ts index 5a92a7c6cc286..bc6b6e5c29d46 100644 --- a/src/core/server/saved_objects/migrations/actions/search_for_outdated_documents.ts +++ b/src/core/server/saved_objects/migrations/actions/search_for_outdated_documents.ts @@ -73,7 +73,7 @@ export const searchForOutdatedDocuments = ], }) .then((res) => - Either.right({ outdatedDocuments: (res.body.hits?.hits as SavedObjectsRawDoc[]) ?? [] }) + Either.right({ outdatedDocuments: (res.hits?.hits as SavedObjectsRawDoc[]) ?? [] }) ) .catch(catchRetryableEsClientErrors); }; diff --git a/src/core/server/saved_objects/migrations/actions/set_write_block.ts b/src/core/server/saved_objects/migrations/actions/set_write_block.ts index 9c40e1b64fae0..eaca12ab7e315 100644 --- a/src/core/server/saved_objects/migrations/actions/set_write_block.ts +++ b/src/core/server/saved_objects/migrations/actions/set_write_block.ts @@ -21,6 +21,7 @@ export interface SetWriteBlockParams { client: ElasticsearchClient; index: string; } + /** * Sets a write block in place for the given index. If the response includes * `acknowledged: true` all in-progress writes have drained and no further @@ -41,10 +42,7 @@ export const setWriteBlock = () => { return ( client.indices - .addBlock<{ - acknowledged: boolean; - shards_acknowledged: boolean; - }>( + .addBlock( { index, block: 'write', @@ -52,8 +50,8 @@ export const setWriteBlock = { maxRetries: 0 /** handle retry ourselves for now */ } ) // not typed yet - .then((res: any) => { - return res.body.acknowledged === true + .then((res) => { + return res.acknowledged === true ? Either.right('set_write_block_succeeded' as const) : Either.left({ type: 'retryable_es_client_error' as const, diff --git a/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts b/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts index 8c742005a01ce..06b3e9051ffa3 100644 --- a/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts +++ b/src/core/server/saved_objects/migrations/actions/update_and_pickup_mappings.ts @@ -51,7 +51,7 @@ export const updateAndPickupMappings = ({ timeout: DEFAULT_TIMEOUT, body: mappings, }) - .then((res) => { + .then(() => { // Ignore `acknowledged: false`. When the coordinating node accepts // the new cluster state update but not all nodes have applied the // update within the timeout `acknowledged` will be false. However, diff --git a/src/core/server/saved_objects/migrations/actions/verify_reindex.ts b/src/core/server/saved_objects/migrations/actions/verify_reindex.ts index a344bf5a97ff3..481daf459251d 100644 --- a/src/core/server/saved_objects/migrations/actions/verify_reindex.ts +++ b/src/core/server/saved_objects/migrations/actions/verify_reindex.ts @@ -33,13 +33,13 @@ export const verifyReindex = () => { const count = (index: string) => client - .count<{ count: number }>({ + .count({ index, // Return an error when targeting missing or closed indices allow_no_indices: false, }) .then((res) => { - return res.body.count; + return res.count; }); return Promise.all([count(sourceIndex), count(targetIndex)]) diff --git a/src/core/server/saved_objects/migrations/actions/wait_for_index_status_yellow.ts b/src/core/server/saved_objects/migrations/actions/wait_for_index_status_yellow.ts index 676471d99b7d2..dbff85ff59c23 100644 --- a/src/core/server/saved_objects/migrations/actions/wait_for_index_status_yellow.ts +++ b/src/core/server/saved_objects/migrations/actions/wait_for_index_status_yellow.ts @@ -51,7 +51,7 @@ export const waitForIndexStatusYellow = { ignore: [408] } ) .then((res) => { - if (res.body.timed_out === true) { + if (res.timed_out === true) { return Either.left({ type: 'retryable_es_client_error' as const, message: `Timeout waiting for the status of the [${index}] index to become 'yellow'`, diff --git a/src/core/server/saved_objects/migrations/actions/wait_for_task.ts b/src/core/server/saved_objects/migrations/actions/wait_for_task.ts index 1a319d17dbce9..f3f1e116ab3c0 100644 --- a/src/core/server/saved_objects/migrations/actions/wait_for_task.ts +++ b/src/core/server/saved_objects/migrations/actions/wait_for_task.ts @@ -82,8 +82,7 @@ export const waitForTask = wait_for_completion: true, timeout, }) - .then((res) => { - const body = res.body; + .then((body) => { const failures = body.response?.failures ?? []; return Either.right({ completed: body.completed, diff --git a/src/core/server/saved_objects/migrations/integration_tests/7.7.2_xpack_100k.test.ts b/src/core/server/saved_objects/migrations/integration_tests/7.7.2_xpack_100k.test.ts index 79a49b2518092..1b96baf210531 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/7.7.2_xpack_100k.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/7.7.2_xpack_100k.test.ts @@ -122,6 +122,6 @@ describe('migration from 7.7.2-xpack with 100k objects', () => { // Use a >= comparison since once Kibana has started it might create new // documents like telemetry tasks - expect(migratedIndexResponse.body.count).toBeGreaterThanOrEqual(oldIndexResponse.body.count); + expect(migratedIndexResponse.count).toBeGreaterThanOrEqual(oldIndexResponse.count); }); }); diff --git a/src/core/server/saved_objects/migrations/integration_tests/7_13_0_failed_action_tasks.test.ts b/src/core/server/saved_objects/migrations/integration_tests/7_13_0_failed_action_tasks.test.ts index 48bcdd6e5eaca..d2bf71f023de7 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/7_13_0_failed_action_tasks.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/7_13_0_failed_action_tasks.test.ts @@ -55,7 +55,7 @@ describe('migration from 7.13 to 7.14+ with many failed action_tasks', () => { kibanaIndexName = '.kibana', taskManagerIndexName = '.kibana_task_manager' ): Promise<{ tasksCount: number; actionTaskParamsCount: number }> => { - const esClient: ElasticsearchClient = esServer.es.getKibanaEsClient(); + const esClient: ElasticsearchClient = esServer.es.getClient(); const actionTaskParamsResponse = await esClient.count({ index: kibanaIndexName, @@ -75,8 +75,8 @@ describe('migration from 7.13 to 7.14+ with many failed action_tasks', () => { }); return { - actionTaskParamsCount: actionTaskParamsResponse.body.count, - tasksCount: tasksResponse.body.count, + actionTaskParamsCount: actionTaskParamsResponse.count, + tasksCount: tasksResponse.count, }; }; diff --git a/src/core/server/saved_objects/migrations/integration_tests/batch_size_bytes.test.ts b/src/core/server/saved_objects/migrations/integration_tests/batch_size_bytes.test.ts index a86177b59ee3b..e9915b9fc9759 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/batch_size_bytes.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/batch_size_bytes.test.ts @@ -31,7 +31,7 @@ function sortByTypeAndId(a: { type: string; id: string }, b: { type: string; id: } async function fetchDocuments(esClient: ElasticsearchClient, index: string) { - const { body } = await esClient.search({ + const body = await esClient.search({ index, body: { query: { @@ -95,7 +95,7 @@ describe('migration v2', () => { // wait a bit for the count to settle. await new Promise((resolve) => setTimeout(resolve, 5000)); - const esClient: ElasticsearchClient = esServer.es.getKibanaEsClient(); + const esClient: ElasticsearchClient = esServer.es.getClient(); // assert that the docs from the original index have been migrated rather than comparing a doc count after startup const originalDocs = await fetchDocuments(esClient, '.kibana_7.14.0_001'); diff --git a/src/core/server/saved_objects/migrations/integration_tests/cleanup.test.ts b/src/core/server/saved_objects/migrations/integration_tests/cleanup.test.ts index 4f3026c619d3c..c84f72b184261 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/cleanup.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/cleanup.test.ts @@ -133,7 +133,7 @@ describe('migration v2', () => { const pitId = logRecordWithPit.right.pitId; expect(pitId).toBeTruthy(); - const client = esServer.es.getKibanaEsClient(); + const client = esServer.es.getClient(); await expect( client.search({ body: { diff --git a/src/core/server/saved_objects/migrations/integration_tests/migration_from_older_v1.test.ts b/src/core/server/saved_objects/migrations/integration_tests/migration_from_older_v1.test.ts index 8c71cf3a29ef5..e0c8aa340bd2a 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/migration_from_older_v1.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/migration_from_older_v1.test.ts @@ -35,7 +35,7 @@ function sortByTypeAndId(a: { type: string; id: string }, b: { type: string; id: } async function fetchDocuments(esClient: ElasticsearchClient, index: string) { - const { body } = await esClient.search({ + const body = await esClient.search({ index, body: { query: { @@ -175,7 +175,7 @@ describe('migrating from 7.3.0-xpack which used v1 migrations', () => { }); it('creates the new index and the correct aliases', async () => { - const { body } = await esClient.indices.get( + const body = await esClient.indices.get( { index: migratedIndex, }, @@ -203,7 +203,7 @@ describe('migrating from 7.3.0-xpack which used v1 migrations', () => { }, size: 10000, }); - const allDocuments = res.body.hits.hits as SavedObjectsRawDoc[]; + const allDocuments = res.hits.hits as SavedObjectsRawDoc[]; allDocuments.forEach((doc) => { assertMigrationVersion(doc, expectedVersions); }); diff --git a/src/core/server/saved_objects/migrations/integration_tests/migration_from_same_v1.test.ts b/src/core/server/saved_objects/migrations/integration_tests/migration_from_same_v1.test.ts index 1fa739768e412..eb54683e3a457 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/migration_from_same_v1.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/migration_from_same_v1.test.ts @@ -35,7 +35,7 @@ function sortByTypeAndId(a: { type: string; id: string }, b: { type: string; id: } async function fetchDocuments(esClient: ElasticsearchClient, index: string) { - const { body } = await esClient.search({ + const body = await esClient.search({ index, body: { query: { @@ -179,7 +179,7 @@ describe('migrating from the same Kibana version that used v1 migrations', () => }); it('creates the new index and the correct aliases', async () => { - const { body } = await esClient.indices.get( + const body = await esClient.indices.get( { index: migratedIndex, }, @@ -206,7 +206,7 @@ describe('migrating from the same Kibana version that used v1 migrations', () => }, size: 10000, }); - const allDocuments = res.body.hits.hits as SavedObjectsRawDoc[]; + const allDocuments = res.hits.hits as SavedObjectsRawDoc[]; allDocuments.forEach((doc) => { assertMigrationVersion(doc, expectedVersions); }); diff --git a/src/core/server/saved_objects/migrations/integration_tests/multiple_es_nodes.test.ts b/src/core/server/saved_objects/migrations/integration_tests/multiple_es_nodes.test.ts index ae8ae6bcc3084..f88f97a677616 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/multiple_es_nodes.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/multiple_es_nodes.test.ts @@ -29,7 +29,7 @@ function extractSortNumberFromId(id: string): number { } async function fetchDocs(esClient: ElasticsearchClient, index: string, type: string) { - const { body } = await esClient.search({ + const body = await esClient.search({ index, size: 10000, body: { @@ -180,7 +180,7 @@ describe('migration v2', () => { }); await root.start(); - const esClient = esServer.es.getKibanaEsClient(); + const esClient = esServer.es.getClient(); const migratedFooDocs = await fetchDocs(esClient, migratedIndex, 'foo'); expect(migratedFooDocs.length).toBe(2500); diff --git a/src/core/server/saved_objects/migrations/integration_tests/multiple_kibana_nodes.test.ts b/src/core/server/saved_objects/migrations/integration_tests/multiple_kibana_nodes.test.ts index 9830d3bf954cc..bc8c138e9ef20 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/multiple_kibana_nodes.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/multiple_kibana_nodes.test.ts @@ -30,7 +30,7 @@ function extractSortNumberFromId(id: string): number { } async function fetchDocs(esClient: ElasticsearchClient, index: string) { - const { body } = await esClient.search({ + const body = await esClient.search({ index, size: 10000, body: { @@ -183,7 +183,7 @@ describe('migration v2', () => { await startWithDelay([rootA, rootB, rootC], 0); - const esClient = esServer.es.getKibanaEsClient(); + const esClient = esServer.es.getClient(); const migratedDocs = await fetchDocs(esClient, migratedIndex); expect(migratedDocs.length).toBe(5000); @@ -202,7 +202,7 @@ describe('migration v2', () => { await startWithDelay([rootA, rootB, rootC], 1); - const esClient = esServer.es.getKibanaEsClient(); + const esClient = esServer.es.getClient(); const migratedDocs = await fetchDocs(esClient, migratedIndex); expect(migratedDocs.length).toBe(5000); @@ -221,7 +221,7 @@ describe('migration v2', () => { await startWithDelay([rootA, rootB, rootC], 5); - const esClient = esServer.es.getKibanaEsClient(); + const esClient = esServer.es.getClient(); const migratedDocs = await fetchDocs(esClient, migratedIndex); expect(migratedDocs.length).toBe(5000); @@ -240,7 +240,7 @@ describe('migration v2', () => { await startWithDelay([rootA, rootB, rootC], 20); - const esClient = esServer.es.getKibanaEsClient(); + const esClient = esServer.es.getClient(); const migratedDocs = await fetchDocs(esClient, migratedIndex); expect(migratedDocs.length).toBe(5000); diff --git a/src/core/server/saved_objects/migrations/integration_tests/outdated_docs.test.ts b/src/core/server/saved_objects/migrations/integration_tests/outdated_docs.test.ts index b40fcda246c3f..c62a764aea653 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/outdated_docs.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/outdated_docs.test.ts @@ -122,7 +122,7 @@ function createRoot() { } async function fetchDocs(esClient: ElasticsearchClient, index: string) { - const { body } = await esClient.search({ + const body = await esClient.search({ index, body: { query: { diff --git a/src/core/server/saved_objects/migrations/integration_tests/rewriting_id.test.ts b/src/core/server/saved_objects/migrations/integration_tests/rewriting_id.test.ts index 79e55ef5beeed..82f7bc5de978e 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/rewriting_id.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/rewriting_id.test.ts @@ -28,7 +28,7 @@ function sortByTypeAndId(a: { type: string; id: string }, b: { type: string; id: } async function fetchDocs(esClient: ElasticsearchClient, index: string) { - const { body } = await esClient.search({ + const body = await esClient.search({ index, body: { query: { diff --git a/src/core/server/saved_objects/migrations/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana_migrator.test.ts index eb7b72f144031..4bb24a3f8240d 100644 --- a/src/core/server/saved_objects/migrations/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/kibana_migrator.test.ts @@ -97,15 +97,9 @@ describe('KibanaMigrator', () => { it('throws if prepareMigrations is not called first', async () => { const options = mockOptions(); - options.client.cat.templates.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise([], { statusCode: 404 }) - ); - options.client.indices.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) - ); - options.client.indices.getAlias.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) - ); + options.client.cat.templates.mockResponse([], { statusCode: 404 }); + options.client.indices.get.mockResponse({}, { statusCode: 404 }); + options.client.indices.getAlias.mockResponse({}, { statusCode: 404 }); const migrator = new KibanaMigrator(options); @@ -117,12 +111,8 @@ describe('KibanaMigrator', () => { it('only runs migrations once if called multiple times', async () => { const options = mockOptions(); - options.client.indices.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) - ); - options.client.indices.getAlias.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) - ); + options.client.indices.get.mockResponse({}, { statusCode: 404 }); + options.client.indices.getAlias.mockResponse({}, { statusCode: 404 }); const migrator = new KibanaMigrator(options); @@ -158,20 +148,18 @@ describe('KibanaMigrator', () => { }); it('rejects when the migration state machine terminates in a FATAL state', () => { const options = mockV2MigrationOptions(); - options.client.indices.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( - { - '.my-index_8.2.4_001': { - aliases: { - '.my-index': {}, - '.my-index_8.2.4': {}, - }, - mappings: { properties: {}, _meta: { migrationMappingPropertyHashes: {} } }, - settings: {}, + options.client.indices.get.mockResponse( + { + '.my-index_8.2.4_001': { + aliases: { + '.my-index': {}, + '.my-index_8.2.4': {}, }, + mappings: { properties: {}, _meta: { migrationMappingPropertyHashes: {} } }, + settings: {}, }, - { statusCode: 200 } - ) + }, + { statusCode: 200 } ); const migrator = new KibanaMigrator(options); @@ -183,14 +171,11 @@ describe('KibanaMigrator', () => { it('rejects when an unexpected exception occurs in an action', async () => { const options = mockV2MigrationOptions(); - options.client.tasks.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - completed: true, - error: { type: 'elasticsearch_exception', reason: 'task failed with an error' }, - failures: [], - task: { description: 'task description' } as any, - }) - ); + options.client.tasks.get.mockResponse({ + completed: true, + error: { type: 'elasticsearch_exception', reason: 'task failed with an error' }, + task: { description: 'task description' } as any, + }); const migrator = new KibanaMigrator(options); migrator.prepareMigrations(); @@ -213,56 +198,38 @@ type MockedOptions = KibanaMigratorOptions & { const mockV2MigrationOptions = () => { const options = mockOptions(); - options.client.indices.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( - { - '.my-index': { - aliases: { '.kibana': {} }, - mappings: { properties: {} }, - settings: {}, - }, + options.client.indices.get.mockResponse( + { + '.my-index': { + aliases: { '.kibana': {} }, + mappings: { properties: {} }, + settings: {}, }, - { statusCode: 200 } - ) - ); - options.client.indices.addBlock.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - acknowledged: true, - shards_acknowledged: true, - indices: [], - }) - ); - options.client.reindex.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - taskId: 'reindex_task_id', - } as estypes.ReindexResponse) - ); - options.client.tasks.get.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - completed: true, - error: undefined, - failures: [], - task: { description: 'task description' } as any, - } as estypes.TasksGetResponse) + }, + { statusCode: 200 } ); + options.client.indices.addBlock.mockResponse({ + acknowledged: true, + shards_acknowledged: true, + indices: [], + }); + options.client.reindex.mockResponse({ + taskId: 'reindex_task_id', + } as estypes.ReindexResponse); + options.client.tasks.get.mockResponse({ + completed: true, + error: undefined, + failures: [], + task: { description: 'task description' } as any, + } as estypes.TasksGetResponse); - options.client.search = jest - .fn() - .mockImplementation(() => - elasticsearchClientMock.createSuccessTransportRequestPromise({ hits: { hits: [] } }) - ); + options.client.search.mockResponse({ hits: { hits: [] } } as any); - options.client.openPointInTime = jest - .fn() - .mockImplementation(() => - elasticsearchClientMock.createSuccessTransportRequestPromise({ id: 'pit_id' }) - ); + options.client.openPointInTime.mockResponse({ id: 'pit_id' }); - options.client.closePointInTime = jest - .fn() - .mockImplementation(() => - elasticsearchClientMock.createSuccessTransportRequestPromise({ succeeded: true }) - ); + options.client.closePointInTime.mockResponse({ + succeeded: true, + } as estypes.ClosePointInTimeResponse); return options; }; diff --git a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts index 052096adcc853..202b5ca4386c9 100644 --- a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts +++ b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.test.ts @@ -11,9 +11,6 @@ import { mockRawDocExistsInNamespace, } from './collect_multi_namespace_references.test.mock'; -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; - -import type { ElasticsearchClient } from '../../../elasticsearch'; import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; import { SavedObjectsSerializer } from '../../serialization'; @@ -43,7 +40,7 @@ beforeEach(() => { }); describe('collectMultiNamespaceReferences', () => { - let client: DeeplyMockedKeys; + let client: ReturnType; /** Sets up the type registry, saved objects client, etc. and return the full parameters object to be passed to `collectMultiNamespaceReferences` */ function setup( @@ -88,30 +85,28 @@ describe('collectMultiNamespaceReferences', () => { references?: Array<{ type: string; id: string }>; }> ) { - client.mget.mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - docs: results.map((x) => { - const references = - x.references?.map(({ type, id }) => ({ type, id, name: 'ref-name' })) ?? []; - return x.found - ? { - _id: 'doesnt-matter', - _index: 'doesnt-matter', - _source: { - namespaces: SPACES, - references, - }, - ...VERSION_PROPS, - found: true, - } - : { - _id: 'doesnt-matter', - _index: 'doesnt-matter', - found: false, - }; - }), - }) - ); + client.mget.mockResponseOnce({ + docs: results.map((x) => { + const references = + x.references?.map(({ type, id }) => ({ type, id, name: 'ref-name' })) ?? []; + return x.found + ? { + _id: 'doesnt-matter', + _index: 'doesnt-matter', + _source: { + namespaces: SPACES, + references, + }, + ...VERSION_PROPS, + found: true, + } + : { + _id: 'doesnt-matter', + _index: 'doesnt-matter', + found: false, + }; + }), + }); } /** Asserts that mget is called for the given objects */ diff --git a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts index e82755e44aa78..a404f2e9475b7 100644 --- a/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts +++ b/src/core/server/saved_objects/service/lib/collect_multi_namespace_references.ts @@ -207,7 +207,7 @@ async function getObjectsAndReferences({ } const bulkGetResponse = await client.mget( { body: { docs: makeBulkGetDocs(bulkGetObjects) } }, - { ignore: [404] } + { ignore: [404], meta: true } ); // exit early if we can't verify a 404 response is from Elasticsearch if ( diff --git a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts index 5403e146509ae..883d7fa241944 100644 --- a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts +++ b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.test.ts @@ -12,10 +12,7 @@ import { mockIsNotFoundFromUnsupportedServer, } from './internal_bulk_resolve.test.mock'; -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import type { ElasticsearchClient } from 'src/core/server/elasticsearch'; import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; - import { LEGACY_URL_ALIAS_TYPE } from '../../object_types'; import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; import { SavedObjectsSerializer } from '../../serialization'; @@ -40,7 +37,7 @@ beforeEach(() => { }); describe('internalBulkResolve', () => { - let client: DeeplyMockedKeys; + let client: ReturnType; let serializer: SavedObjectsSerializer; let incrementCounterInternal: jest.Mock; @@ -69,52 +66,48 @@ describe('internalBulkResolve', () => { function mockBulkResults( ...results: Array<{ found: boolean; targetId?: string; disabled?: boolean }> ) { - client.bulk.mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - items: results.map(({ found, targetId, disabled }) => ({ - update: { - _index: 'doesnt-matter', - status: 0, - get: { - found, - _source: { - ...((targetId || disabled) && { - [LEGACY_URL_ALIAS_TYPE]: { targetId, disabled }, - }), - }, - ...VERSION_PROPS, + client.bulk.mockResponseOnce({ + items: results.map(({ found, targetId, disabled }) => ({ + update: { + _index: 'doesnt-matter', + status: 0, + get: { + found, + _source: { + ...((targetId || disabled) && { + [LEGACY_URL_ALIAS_TYPE]: { targetId, disabled }, + }), }, + ...VERSION_PROPS, }, - })), - errors: false, - took: 0, - }) - ); + }, + })), + errors: false, + took: 0, + }); } /** Mocks the elasticsearch client so it returns the expected results for an mget operation*/ function mockMgetResults(...results: Array<{ found: boolean }>) { - client.mget.mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - docs: results.map((x) => { - return x.found - ? { - _id: 'doesnt-matter', - _index: 'doesnt-matter', - _source: { - foo: 'bar', - }, - ...VERSION_PROPS, - found: true, - } - : { - _id: 'doesnt-matter', - _index: 'doesnt-matter', - found: false, - }; - }), - }) - ); + client.mget.mockResponseOnce({ + docs: results.map((x) => { + return x.found + ? { + _id: 'doesnt-matter', + _index: 'doesnt-matter', + _source: { + foo: 'bar', + }, + ...VERSION_PROPS, + found: true, + } + : { + _id: 'doesnt-matter', + _index: 'doesnt-matter', + found: false, + }; + }), + }); } /** Asserts that bulk is called for the given aliases */ @@ -158,16 +151,20 @@ describe('internalBulkResolve', () => { const error = SavedObjectsErrorHelpers.createUnsupportedTypeError(UNSUPPORTED_TYPE); return { type: UNSUPPORTED_TYPE, id, error }; } + function expectNotFoundError(id: string) { const error = SavedObjectsErrorHelpers.createGenericNotFoundError(OBJ_TYPE, id); return { type: OBJ_TYPE, id, error }; } + function expectExactMatchResult(id: string) { return { saved_object: `mock-obj-for-${id}`, outcome: 'exactMatch' }; } + function expectAliasMatchResult(id: string) { return { saved_object: `mock-obj-for-${id}`, outcome: 'aliasMatch', alias_target_id: id }; } + // eslint-disable-next-line @typescript-eslint/naming-convention function expectConflictResult(id: string, alias_target_id: string) { return { saved_object: `mock-obj-for-${id}`, outcome: 'conflict', alias_target_id }; diff --git a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts index 6c11fa1f245c7..e032e769b0220 100644 --- a/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts +++ b/src/core/server/saved_objects/service/lib/internal_bulk_resolve.ts @@ -138,7 +138,7 @@ export async function internalBulkResolve( const bulkGetResponse = docsToBulkGet.length ? await client.mget( { body: { docs: docsToBulkGet } }, - { ignore: [404] } + { ignore: [404], meta: true } ) : undefined; // exit early if a 404 isn't from elasticsearch @@ -293,7 +293,7 @@ async function fetchAndUpdateAliases( require_alias: true, body: bulkUpdateDocs, }); - return bulkUpdateResponse.body.items.map((item) => { + return bulkUpdateResponse.items.map((item) => { // Map the bulk update response to the `_source` fields that were returned for each document return item.update?.get; }); diff --git a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts index 22c57fe3f280f..4e7ce652bf4bf 100644 --- a/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts +++ b/src/core/server/saved_objects/service/lib/legacy_url_aliases/delete_legacy_url_aliases.test.ts @@ -54,9 +54,7 @@ describe('deleteLegacyUrlAliases', () => { body: { error: { type: 'es_type', reason: 'es_reason' } }, }) ); - params.client.updateByQuery.mockResolvedValueOnce( - elasticsearchClientMock.createErrorTransportRequestPromise(esError) - ); + params.client.updateByQuery.mockResolvedValueOnce(Promise.reject(esError)); mockGetEsErrorMessage.mockClear(); mockGetEsErrorMessage.mockReturnValue('Oh no!'); diff --git a/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts b/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts index 6a7e1294744ac..036a0e417386b 100644 --- a/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts +++ b/src/core/server/saved_objects/service/lib/preflight_check_for_create.ts @@ -273,7 +273,7 @@ async function bulkGetObjectsAndAliases( const bulkGetResponse = docsToBulkGet.length ? await client.mget( { body: { docs: docsToBulkGet } }, - { ignore: [404] } + { ignore: [404], meta: true } ) : undefined; diff --git a/src/core/server/saved_objects/service/lib/repository.test.ts b/src/core/server/saved_objects/service/lib/repository.test.ts index 41a284764b0ea..1df3ef351c6ae 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.ts +++ b/src/core/server/saved_objects/service/lib/repository.test.ts @@ -473,9 +473,7 @@ describe('SavedObjectsRepository', () => { options?: SavedObjectsCreateOptions ) => { const response = getMockBulkCreateResponse(objects, options?.namespace); - client.bulk.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.bulk.mockResponse(response); return await savedObjectsRepository.bulkCreate(objects, options); }; @@ -838,9 +836,7 @@ describe('SavedObjectsRepository', () => { } else { response = getMockBulkCreateResponse([obj1, obj2]); } - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.bulk.mockResponseOnce(response); const objects = [obj1, obj, obj2]; const result = await savedObjectsRepository.bulkCreate(objects); @@ -941,9 +937,7 @@ describe('SavedObjectsRepository', () => { }, ]); const bulkResponse = getMockBulkCreateResponse([o1, o5]); - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(bulkResponse) - ); + client.bulk.mockResponseOnce(bulkResponse); const options = { overwrite: true }; const result = await savedObjectsRepository.bulkCreate(objects, options); @@ -984,9 +978,7 @@ describe('SavedObjectsRepository', () => { it(`returns errors for any bulk objects with invalid schemas`, async () => { const response = getMockBulkCreateResponse([obj3]); - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.bulk.mockResponseOnce(response); const result = await savedObjectsRepository.bulkCreate([ obj3, @@ -1089,9 +1081,7 @@ describe('SavedObjectsRepository', () => { }; const objects = [obj1, obj, obj2]; const response = getMockBulkCreateResponse([obj1, obj2]); - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.bulk.mockResponseOnce(response); const result = await savedObjectsRepository.bulkCreate(objects); expect(client.bulk).toHaveBeenCalledTimes(1); expect(result).toEqual({ @@ -1107,9 +1097,7 @@ describe('SavedObjectsRepository', () => { // of the document when it actually does not, forcing to cast to any as BulkResponse // does not contains _source const response = getMockBulkCreateResponse([obj1, obj2], namespace) as any; - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.bulk.mockResponseOnce(response); // Bulk create one object with id unspecified, and one with id specified const result = await savedObjectsRepository.bulkCreate([{ ...obj1, id: undefined }, obj2], { @@ -1182,9 +1170,7 @@ describe('SavedObjectsRepository', () => { ); const bulkGetSuccess = async (objects: SavedObject[], options?: SavedObjectsBaseOptions) => { const response = getMockMgetResponse(objects, options?.namespace); - client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.mget.mockResponseOnce(response); const result = await bulkGet(objects, options); expect(client.mget).toHaveBeenCalledTimes(1); return result; @@ -1551,14 +1537,10 @@ describe('SavedObjectsRepository', () => { const multiNamespaceObjects = objects.filter(({ type }) => registry.isMultiNamespace(type)); if (multiNamespaceObjects?.length) { const response = getMockMgetResponse(multiNamespaceObjects, options?.namespace); - client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.mget.mockResponseOnce(response); } const response = getMockBulkUpdateResponse(objects, options, includeOriginId); - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.bulk.mockResponseOnce(response); const result = await savedObjectsRepository.bulkUpdate(objects, options); expect(client.mget).toHaveBeenCalledTimes(multiNamespaceObjects?.length ? 1 : 0); return result; @@ -1825,9 +1807,7 @@ describe('SavedObjectsRepository', () => { mockGetBulkOperationError.mockReturnValueOnce(undefined); mockGetBulkOperationError.mockReturnValueOnce(expectedErrorResult.error as Payload); } - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockResponse) - ); + client.bulk.mockResponseOnce(mockResponse); const result = await savedObjectsRepository.bulkUpdate(objects); expect(client.bulk).toHaveBeenCalled(); @@ -1848,16 +1828,10 @@ describe('SavedObjectsRepository', () => { mgetResponse: estypes.MgetResponse, mgetOptions?: { statusCode?: number } ) => { - client.mget.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mgetResponse, { - statusCode: mgetOptions?.statusCode, - }) - ); + client.mget.mockResponseOnce(mgetResponse, { statusCode: mgetOptions?.statusCode }); const bulkResponse = getMockBulkUpdateResponse([obj1, obj2], { namespace }); - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(bulkResponse) - ); + client.bulk.mockResponseOnce(bulkResponse); const result = await savedObjectsRepository.bulkUpdate([obj1, _obj, obj2], options); expect(client.bulk).toHaveBeenCalled(); @@ -1966,9 +1940,7 @@ describe('SavedObjectsRepository', () => { }; const objects = [obj1, obj, obj2]; const mockResponse = getMockBulkUpdateResponse(objects); - client.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockResponse) - ); + client.bulk.mockResponseOnce(mockResponse); const result = await savedObjectsRepository.bulkUpdate(objects); expect(client.bulk).toHaveBeenCalledTimes(1); @@ -2150,12 +2122,14 @@ describe('SavedObjectsRepository', () => { mockPreflightCheckForCreate.mockImplementation(({ objects }) => { return Promise.resolve(objects.map(({ type, id }) => ({ type, id }))); // respond with no errors by default }); - client.create.mockImplementation((params) => - elasticsearchClientMock.createSuccessTransportRequestPromise({ - _id: params.id, - ...mockVersionProps, - } as estypes.CreateResponse) - ); + client.create.mockResponseImplementation((params) => { + return { + body: { + _id: params.id, + ...mockVersionProps, + } as estypes.CreateResponse, + }; + }); }); const type = 'index-pattern'; @@ -2721,15 +2695,11 @@ describe('SavedObjectsRepository', () => { if (registry.isMultiNamespace(type)) { const mockGetResponse = mockGetResponseValue ?? getMockGetResponse({ type, id }, options?.namespace); - client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockGetResponse) - ); + client.get.mockResponseOnce(mockGetResponse); } - client.delete.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - result: 'deleted', - } as estypes.DeleteResponse) - ); + client.delete.mockResponseOnce({ + result: 'deleted', + } as estypes.DeleteResponse); const result = await savedObjectsRepository.delete(type, id, options); expect(client.get).toHaveBeenCalledTimes(registry.isMultiNamespace(type) ? 1 : 0); return result; @@ -3023,9 +2993,7 @@ describe('SavedObjectsRepository', () => { namespace: string, options?: SavedObjectsDeleteByNamespaceOptions ) => { - client.updateByQuery.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockUpdateResults) - ); + client.updateByQuery.mockResponseOnce(mockUpdateResults); const result = await savedObjectsRepository.deleteByNamespace(namespace, options); expect(mockGetSearchDsl).toHaveBeenCalledTimes(1); expect(client.updateByQuery).toHaveBeenCalledTimes(1); @@ -3097,11 +3065,9 @@ describe('SavedObjectsRepository', () => { const updatedCount = 42; const removeReferencesToSuccess = async (options = defaultOptions) => { - client.updateByQuery.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - updated: updatedCount, - }) - ); + client.updateByQuery.mockResponseOnce({ + updated: updatedCount, + }); return await savedObjectsRepository.removeReferencesTo(type, id, options); }; @@ -3226,15 +3192,13 @@ describe('SavedObjectsRepository', () => { describe('errors', () => { it(`throws when ES returns failures`, async () => { - client.updateByQuery.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - updated: 7, - failures: [ - { id: 'failure' } as estypes.BulkIndexByScrollFailure, - { id: 'another-failure' } as estypes.BulkIndexByScrollFailure, - ], - }) - ); + client.updateByQuery.mockResponseOnce({ + updated: 7, + failures: [ + { id: 'failure' } as estypes.BulkIndexByScrollFailure, + { id: 'another-failure' } as estypes.BulkIndexByScrollFailure, + ], + }); await expect( savedObjectsRepository.removeReferencesTo(type, id, defaultOptions) @@ -3322,11 +3286,7 @@ describe('SavedObjectsRepository', () => { const namespace = 'foo-namespace'; const findSuccess = async (options: SavedObjectsFindOptions, namespace?: string) => { - client.search.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise( - generateSearchResults(namespace) - ) - ); + client.search.mockResponseOnce(generateSearchResults(namespace)); const result = await savedObjectsRepository.find(options); expect(mockGetSearchDsl).toHaveBeenCalledTimes(1); expect(client.search).toHaveBeenCalledTimes(1); @@ -3818,9 +3778,7 @@ describe('SavedObjectsRepository', () => { }, options?.namespace ); - client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.get.mockResponseOnce(response); const result = await savedObjectsRepository.get(type, id, options); expect(client.get).toHaveBeenCalledTimes(1); return result; @@ -4034,31 +3992,32 @@ describe('SavedObjectsRepository', () => { if (isMultiNamespace) { const response = mockGetResponseValue ?? getMockGetResponse({ type, id }, options?.namespace); - client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + client.get.mockResponseOnce(response); } - client.update.mockImplementation((params) => - elasticsearchClientMock.createSuccessTransportRequestPromise({ - _id: params.id, - ...mockVersionProps, - _index: '.kibana', - get: { - found: true, - _source: { - type, - ...mockTimestampFields, - [type]: { - ...fields.reduce((acc, field) => { - acc[typeof field === 'string' ? field : field.fieldName] = 8468; - return acc; - }, {} as Record), - defaultIndex: 'logstash-*', + + client.update.mockResponseImplementation((params) => { + return { + body: { + _id: params.id, + ...mockVersionProps, + _index: '.kibana', + get: { + found: true, + _source: { + type, + ...mockTimestampFields, + [type]: { + ...fields.reduce((acc, field) => { + acc[typeof field === 'string' ? field : field.fieldName] = 8468; + return acc; + }, {} as Record), + defaultIndex: 'logstash-*', + }, }, }, - }, - } as estypes.UpdateResponse) - ); + } as estypes.UpdateResponse, + }; + }); const result = await savedObjectsRepository.incrementCounter(type, id, fields, options); expect(client.get).toHaveBeenCalledTimes(isMultiNamespace ? 1 : 0); @@ -4347,26 +4306,28 @@ describe('SavedObjectsRepository', () => { describe('returns', () => { it(`formats the ES response`, async () => { - client.update.mockImplementation((params) => - elasticsearchClientMock.createSuccessTransportRequestPromise({ - _id: params.id, - ...mockVersionProps, - _index: '.kibana', - get: { - found: true, - _source: { - type: 'config', - ...mockTimestampFields, - config: { - buildNum: 8468, - apiCallsCount: 100, - defaultIndex: 'logstash-*', + client.update.mockResponseImplementation((params) => { + return { + body: { + _id: params.id, + ...mockVersionProps, + _index: '.kibana', + get: { + found: true, + _source: { + type: 'config', + ...mockTimestampFields, + config: { + buildNum: 8468, + apiCallsCount: 100, + defaultIndex: 'logstash-*', + }, + originId, }, - originId, }, - }, - } as estypes.UpdateResponse) - ); + } as estypes.UpdateResponse, + }; + }); const response = await savedObjectsRepository.incrementCounter( 'config', @@ -4452,26 +4413,24 @@ describe('SavedObjectsRepository', () => { options?: SavedObjectsUpdateOptions, includeOriginId?: boolean ) => { - client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise( - { - _id: `${type}:${id}`, - ...mockVersionProps, - result: 'updated', - // don't need the rest of the source for test purposes, just the namespace and namespaces attributes - get: { - _source: { - namespaces: [options?.namespace ?? 'default'], - namespace: options?.namespace, + client.update.mockResponseOnce( + { + _id: `${type}:${id}`, + ...mockVersionProps, + result: 'updated', + // don't need the rest of the source for test purposes, just the namespace and namespaces attributes + get: { + _source: { + namespaces: [options?.namespace ?? 'default'], + namespace: options?.namespace, - // "includeOriginId" is not an option for the operation; however, if the existing saved object contains an originId attribute, the - // operation will return it in the result. This flag is just used for test purposes to modify the mock cluster call response. - ...(includeOriginId && { originId }), - }, + // "includeOriginId" is not an option for the operation; however, if the existing saved object contains an originId attribute, the + // operation will return it in the result. This flag is just used for test purposes to modify the mock cluster call response. + ...(includeOriginId && { originId }), }, - } as estypes.UpdateResponse, - { statusCode: 200 } - ) + }, + } as estypes.UpdateResponse, + { statusCode: 200 } ); }; @@ -4489,12 +4448,7 @@ describe('SavedObjectsRepository', () => { if (registry.isMultiNamespace(type)) { const mockGetResponse = mockGetResponseValue ?? getMockGetResponse({ type, id }, options?.namespace); - client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise( - { ...mockGetResponse }, - { statusCode: 200 } - ) - ); + client.get.mockResponseOnce(mockGetResponse, { statusCode: 200 }); } mockUpdateResponse(type, id, options, includeOriginId); const result = await savedObjectsRepository.update(type, id, attributes, options); @@ -4896,9 +4850,7 @@ describe('SavedObjectsRepository', () => { const generateResults = (id?: string) => ({ id: id || 'id' }); const successResponse = async (type: string, options?: SavedObjectsOpenPointInTimeOptions) => { - client.openPointInTime.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(generateResults()) - ); + client.openPointInTime.mockResponseOnce(generateResults()); const result = await savedObjectsRepository.openPointInTimeForType(type, options); expect(client.openPointInTime).toHaveBeenCalledTimes(1); return result; @@ -4987,9 +4939,7 @@ describe('SavedObjectsRepository', () => { describe('#closePointInTime', () => { const generateResults = () => ({ succeeded: true, num_freed: 3 }); const successResponse = async (id: string) => { - client.closePointInTime.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(generateResults()) - ); + client.closePointInTime.mockResponseOnce(generateResults()); const result = await savedObjectsRepository.closePointInTime(id); expect(client.closePointInTime).toHaveBeenCalledTimes(1); return result; @@ -5017,9 +4967,7 @@ describe('SavedObjectsRepository', () => { describe('returns', () => { it(`returns response body from ES`, async () => { const results = generateResults(); - client.closePointInTime.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(results) - ); + client.closePointInTime.mockResponseOnce(results); const response = await savedObjectsRepository.closePointInTime('abc123'); expect(response).toEqual(results); }); diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index a8ad0f68dba8b..abfea6e7ebafc 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -392,8 +392,8 @@ export class SavedObjectsRepository { const { body, statusCode, headers } = id && overwrite - ? await this.client.index(requestParams) - : await this.client.create(requestParams); + ? await this.client.index(requestParams, { meta: true }) + : await this.client.create(requestParams, { meta: true }); // throw if we can't verify a 404 response is from Elasticsearch if (isNotFoundFromUnsupportedServer({ statusCode, headers })) { @@ -602,7 +602,7 @@ export class SavedObjectsRepository { } const { requestedId, rawMigratedDoc, esRequestIndex } = expectedResult.value; - const rawResponse = Object.values(bulkResponse?.body.items[esRequestIndex] ?? {})[0] as any; + const rawResponse = Object.values(bulkResponse?.items[esRequestIndex] ?? {})[0] as any; const error = getBulkOperationError(rawMigratedDoc._source.type, requestedId, rawResponse); if (error) { @@ -672,7 +672,7 @@ export class SavedObjectsRepository { docs: bulkGetDocs, }, }, - { ignore: [404] } + { ignore: [404], meta: true } ) : undefined; // throw if we can't verify a 404 response is from Elasticsearch @@ -764,7 +764,7 @@ export class SavedObjectsRepository { ...getExpectedVersionProperties(undefined, preflightResult?.rawDocSource), refresh, }, - { ignore: [404] } + { ignore: [404], meta: true } ); if (isNotFoundFromUnsupportedServer({ statusCode, headers })) { @@ -865,7 +865,7 @@ export class SavedObjectsRepository { }), }, }, - { ignore: [404] } + { ignore: [404], meta: true } ); // throw if we can't verify a 404 response is from Elasticsearch if (isNotFoundFromUnsupportedServer({ statusCode, headers })) { @@ -1019,6 +1019,7 @@ export class SavedObjectsRepository { esOptions, { ignore: [404], + meta: true, } ); if (statusCode === 404) { @@ -1128,7 +1129,7 @@ export class SavedObjectsRepository { docs: bulkGetDocs, }, }, - { ignore: [404] } + { ignore: [404], meta: true } ) : undefined; // fail fast if we can't verify a 404 is from Elasticsearch @@ -1237,7 +1238,7 @@ export class SavedObjectsRepository { id: this._serializer.generateRawId(namespace, type, id), index: this.getIndexForType(type), }, - { ignore: [404] } + { ignore: [404], meta: true } ); const indexNotFound = statusCode === 404; // check if we have the elasticsearch header when index is not found and, if we do, ensure it is from Elasticsearch @@ -1368,8 +1369,8 @@ export class SavedObjectsRepository { ...(Array.isArray(references) && { references }), }; - const { body } = await this.client - .update({ + const body = await this.client + .update({ id: this._serializer.generateRawId(namespace, type, id), index: this.getIndexForType(type), ...getExpectedVersionProperties(version, preflightResult?.rawDocSource), @@ -1556,6 +1557,7 @@ export class SavedObjectsRepository { }, { ignore: [404], + meta: true, } ) : undefined; @@ -1655,7 +1657,7 @@ export class SavedObjectsRepository { } const { type, id, namespaces, documentToSave, esRequestIndex } = expectedResult.value; - const response = bulkUpdateResponse?.body.items[esRequestIndex] ?? {}; + const response = bulkUpdateResponse?.items[esRequestIndex] ?? {}; const rawResponse = Object.values(response)[0] as any; const error = getBulkOperationError(type, id, rawResponse); @@ -1734,7 +1736,7 @@ export class SavedObjectsRepository { }), }, }, - { ignore: [404] } + { ignore: [404], meta: true } ); // fail fast if we can't verify a 404 is from Elasticsearch if (isNotFoundFromUnsupportedServer({ statusCode, headers })) { @@ -1923,7 +1925,7 @@ export class SavedObjectsRepository { const raw = this._serializer.savedObjectToRaw(migrated as SavedObjectSanitizedDoc); - const { body } = await this.client.update({ + const body = await this.client.update({ id: raw._id, index: this.getIndexForType(type), refresh, @@ -2028,6 +2030,7 @@ export class SavedObjectsRepository { const { body, statusCode, headers } = await this.client.openPointInTime(esOptions, { ignore: [404], + meta: true, }); if (statusCode === 404) { @@ -2088,11 +2091,9 @@ export class SavedObjectsRepository { id: string, options?: SavedObjectsClosePointInTimeOptions ): Promise { - const { body } = await this.client.closePointInTime({ + return await this.client.closePointInTime({ body: { id }, }); - - return body; } /** @@ -2213,6 +2214,7 @@ export class SavedObjectsRepository { }, { ignore: [404], + meta: true, } ); diff --git a/src/core/server/saved_objects/service/lib/repository_es_client.test.ts b/src/core/server/saved_objects/service/lib/repository_es_client.test.ts index 97cafec68b905..d06172fc6a673 100644 --- a/src/core/server/saved_objects/service/lib/repository_es_client.test.ts +++ b/src/core/server/saved_objects/service/lib/repository_es_client.test.ts @@ -44,7 +44,7 @@ describe('RepositoryEsClient', () => { it('transform elasticsearch errors into saved objects errors', async () => { expect.assertions(1); - client.bulk = jest.fn().mockRejectedValue(new Error('reason')); + client.bulk.mockRejectedValue(new Error('reason')); try { await repositoryClient.bulk({ body: [] }); } catch (e) { diff --git a/src/core/server/saved_objects/service/lib/repository_es_client.ts b/src/core/server/saved_objects/service/lib/repository_es_client.ts index 4c1ae294cc7db..e9893d4b2d570 100644 --- a/src/core/server/saved_objects/service/lib/repository_es_client.ts +++ b/src/core/server/saved_objects/service/lib/repository_es_client.ts @@ -28,7 +28,7 @@ const methods = [ type MethodName = typeof methods[number]; -export type RepositoryEsClient = Pick; +export type RepositoryEsClient = Pick; export function createRepositoryEsClient(client: ElasticsearchClient): RepositoryEsClient { return methods.reduce((acc: RepositoryEsClient, key: MethodName) => { diff --git a/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts b/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts index 5163c4a4990ad..38bdba0208b8d 100644 --- a/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts +++ b/src/core/server/saved_objects/service/lib/update_objects_spaces.test.ts @@ -13,8 +13,6 @@ import { mockDeleteLegacyUrlAliases, } from './update_objects_spaces.test.mock'; -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import type { ElasticsearchClient } from 'src/core/server/elasticsearch'; import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { loggerMock } from '../../../logging/logger.mock'; @@ -66,7 +64,7 @@ afterAll(() => { }); describe('#updateObjectsSpaces', () => { - let client: DeeplyMockedKeys; + let client: ReturnType; /** Sets up the type registry, saved objects client, etc. and return the full parameters object to be passed to `updateObjectsSpaces` */ function setup({ objects = [], spacesToAdd = [], spacesToRemove = [], options }: SetupParams) { @@ -93,8 +91,29 @@ describe('#updateObjectsSpaces', () => { /** Mocks the saved objects client so it returns the expected results */ function mockMgetResults(...results: Array<{ found: boolean }>) { - client.mget.mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ + client.mget.mockResponseOnce({ + docs: results.map((x) => + x.found + ? { + _id: 'doesnt-matter', + _index: 'doesnt-matter', + _source: { namespaces: [EXISTING_SPACE] }, + ...VERSION_PROPS, + found: true, + } + : { + _id: 'doesnt-matter', + _index: 'doesnt-matter', + found: false, + } + ), + }); + } + + /** Mocks the saved objects client so as to test unsupported server responding with 404 */ + function mockMgetResultsNotFound(...results: Array<{ found: boolean }>) { + client.mget.mockResponseOnce( + { docs: results.map((x) => x.found ? { @@ -110,33 +129,8 @@ describe('#updateObjectsSpaces', () => { found: false, } ), - }) - ); - } - /** Mocks the saved objects client so as to test unsupported server responding with 404 */ - function mockMgetResultsNotFound(...results: Array<{ found: boolean }>) { - client.mget.mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise( - { - docs: results.map((x) => - x.found - ? { - _id: 'doesnt-matter', - _index: 'doesnt-matter', - _source: { namespaces: [EXISTING_SPACE] }, - ...VERSION_PROPS, - found: true, - } - : { - _id: 'doesnt-matter', - _index: 'doesnt-matter', - found: false, - } - ), - }, - { statusCode: 404 }, - {} - ) + }, + { statusCode: 404, headers: {} } ); } @@ -155,13 +149,11 @@ describe('#updateObjectsSpaces', () => { mockGetBulkOperationError.mockReturnValueOnce(undefined); } }); - client.bulk.mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - items: results.map(() => ({})), // as long as the result does not contain an error field, it is treated as a success - errors: false, - took: 0, - }) - ); + client.bulk.mockResponseOnce({ + items: results.map(() => ({})), // as long as the result does not contain an error field, it is treated as a success + errors: false, + took: 0, + }); } /** Asserts that mget is called for the given objects */ diff --git a/src/core/server/saved_objects/service/lib/update_objects_spaces.ts b/src/core/server/saved_objects/service/lib/update_objects_spaces.ts index f3c97382c3747..26da4909df247 100644 --- a/src/core/server/saved_objects/service/lib/update_objects_spaces.ts +++ b/src/core/server/saved_objects/service/lib/update_objects_spaces.ts @@ -124,6 +124,7 @@ const MAX_CONCURRENT_ALIAS_DELETIONS = 10; function isMgetError(doc?: estypes.MgetResponseItem): doc is estypes.MgetMultiGetError { return Boolean(doc && 'error' in doc); } + /** * Gets all references and transitive references of the given objects. Ignores any object and/or reference that is not a multi-namespace * type. @@ -204,7 +205,7 @@ export async function updateObjectsSpaces({ const bulkGetResponse = bulkGetDocs.length ? await client.mget( { body: { docs: bulkGetDocs } }, - { ignore: [404] } + { ignore: [404], meta: true } ) : undefined; // fail fast if we can't verify a 404 response is from Elasticsearch @@ -338,7 +339,7 @@ export async function updateObjectsSpaces({ const { type, id, updatedSpaces, esRequestIndex } = expectedResult.value; if (esRequestIndex !== undefined) { - const response = bulkOperationResponse?.body.items[esRequestIndex] ?? {}; + const response = bulkOperationResponse?.items[esRequestIndex] ?? {}; const rawResponse = Object.values(response)[0] as any; const error = getBulkOperationError(type, id, rawResponse); if (error) { diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index a722e6eb98b02..111f2ed0001fc 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -10,6 +10,7 @@ import { AddConfigDeprecation } from '@kbn/config'; import Boom from '@hapi/boom'; import { ByteSizeValue } from '@kbn/config-schema'; import { CliArgs } from '@kbn/config'; +import type { Client } from '@elastic/elasticsearch'; import type { ClientOptions } from '@elastic/elasticsearch/lib/client'; import { ConditionalType } from '@kbn/config-schema'; import { ConfigDeprecation } from '@kbn/config'; @@ -31,7 +32,6 @@ import { EnvironmentMode } from '@kbn/config'; import { errors } from '@elastic/elasticsearch'; import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { IncomingHttpHeaders } from 'http'; -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; import { Logger } from '@kbn/logging'; import { LoggerFactory } from '@kbn/logging'; import { LogLevel as LogLevel_2 } from '@kbn/logging'; @@ -53,9 +53,6 @@ import { ResponseToolkit } from '@hapi/hapi'; import { SchemaTypeError } from '@kbn/config-schema'; import { ShallowPromise } from '@kbn/utility-types'; import { Stream } from 'stream'; -import type { TransportRequestOptions } from '@elastic/elasticsearch'; -import type { TransportRequestParams } from '@elastic/elasticsearch'; -import type { TransportResult } from '@elastic/elasticsearch'; import { Type } from '@kbn/config-schema'; import { TypeOf } from '@kbn/config-schema'; import { UiCounterMetricType } from '@kbn/analytics'; @@ -888,11 +885,7 @@ export { EcsEventOutcome } export { EcsEventType } // @public -export type ElasticsearchClient = Omit & { - transport: { - request(params: TransportRequestParams, options?: TransportRequestOptions): Promise>; - }; -}; +export type ElasticsearchClient = Omit; // @public export type ElasticsearchClientConfig = Pick & { @@ -3167,7 +3160,7 @@ export const validBodyOutput: readonly ["data", "stream"]; // Warnings were encountered during analysis: // -// src/core/server/elasticsearch/client/types.ts:93:7 - (ae-forgotten-export) The symbol "Explanation" needs to be exported by the entry point index.d.ts +// src/core/server/elasticsearch/client/types.ts:81:7 - (ae-forgotten-export) The symbol "Explanation" needs to be exported by the entry point index.d.ts // src/core/server/http/router/response.ts:302:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:375:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts diff --git a/src/core/server/ui_settings/integration_tests/lib/servers.ts b/src/core/server/ui_settings/integration_tests/lib/servers.ts index d94ab98060a27..2591e4050341c 100644 --- a/src/core/server/ui_settings/integration_tests/lib/servers.ts +++ b/src/core/server/ui_settings/integration_tests/lib/servers.ts @@ -8,7 +8,7 @@ import type supertest from 'supertest'; import type { SavedObjectsClientContract, IUiSettingsClient } from 'src/core/server'; -import type { KibanaClient } from '@elastic/elasticsearch/lib/api/kibana'; +import type { Client } from '@elastic/elasticsearch'; import { createTestServers, @@ -26,7 +26,7 @@ let kbn: TestKibanaUtils; interface AllServices { savedObjectsClient: SavedObjectsClientContract; - esClient: KibanaClient; + esClient: Client; uiSettings: IUiSettingsClient; supertest: (method: HttpMethod, path: string) => supertest.Test; } @@ -55,7 +55,7 @@ export function getServices() { return services; } - const esClient = esServer.es.getKibanaEsClient(); + const esClient = esServer.es.getClient(); const savedObjectsClient = kbn.coreStart.savedObjects.getScopedClient( httpServerMock.createKibanaRequest() diff --git a/src/plugins/data/server/autocomplete/terms_agg.test.ts b/src/plugins/data/server/autocomplete/terms_agg.test.ts index eb24b71cae274..f9d45475d9e2f 100644 --- a/src/plugins/data/server/autocomplete/terms_agg.test.ts +++ b/src/plugins/data/server/autocomplete/terms_agg.test.ts @@ -10,7 +10,6 @@ import { coreMock } from '../../../../core/server/mocks'; import { ElasticsearchClient, SavedObjectsClientContract } from 'kibana/server'; import { ConfigSchema } from '../../config'; import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import type { TransportResult } from '@elastic/elasticsearch'; import { termsAggSuggestions } from './terms_agg'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { duration } from 'moment'; @@ -25,14 +24,12 @@ const configMock = { // @ts-expect-error not full interface const mockResponse = { - body: { - aggregations: { - suggestions: { - buckets: [{ key: 'whoa' }, { key: 'amazing' }], - }, + aggregations: { + suggestions: { + buckets: [{ key: 'whoa' }, { key: 'amazing' }], }, }, -} as TransportResult>; +} as estypes.SearchResponse; jest.mock('../data_views'); diff --git a/src/plugins/data/server/autocomplete/terms_agg.ts b/src/plugins/data/server/autocomplete/terms_agg.ts index 20a8a5c212f26..742812adafbb9 100644 --- a/src/plugins/data/server/autocomplete/terms_agg.ts +++ b/src/plugins/data/server/autocomplete/terms_agg.ts @@ -45,8 +45,8 @@ export async function termsAggSuggestions( ); const buckets = - get(result.body, 'aggregations.suggestions.buckets') || - get(result.body, 'aggregations.nestedSuggestions.suggestions.buckets'); + get(result, 'aggregations.suggestions.buckets') || + get(result, 'aggregations.nestedSuggestions.suggestions.buckets'); return map(buckets ?? [], 'key'); } diff --git a/src/plugins/data/server/autocomplete/terms_enum.test.ts b/src/plugins/data/server/autocomplete/terms_enum.test.ts index c0750ead5cc0a..ce2741f612ba8 100644 --- a/src/plugins/data/server/autocomplete/terms_enum.test.ts +++ b/src/plugins/data/server/autocomplete/terms_enum.test.ts @@ -11,7 +11,6 @@ import { coreMock } from '../../../../core/server/mocks'; import { ElasticsearchClient, SavedObjectsClientContract } from 'kibana/server'; import { ConfigSchema } from '../../config'; import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import type { TransportResult } from '@elastic/elasticsearch'; import { TermsEnumResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; let savedObjectsClientMock: jest.Mocked; @@ -19,9 +18,7 @@ let esClientMock: DeeplyMockedKeys; const configMock = { autocomplete: { valueSuggestions: { tiers: ['data_hot', 'data_warm', 'data_content'] } }, } as ConfigSchema; -const mockResponse = { - body: { terms: ['whoa', 'amazing'] }, -}; +const mockResponse = { terms: ['whoa', 'amazing'] }; jest.mock('../data_views'); @@ -30,9 +27,7 @@ describe('_terms_enum suggestions', () => { const requestHandlerContext = coreMock.createRequestHandlerContext(); savedObjectsClientMock = requestHandlerContext.savedObjects.client; esClientMock = requestHandlerContext.elasticsearch.client.asCurrentUser; - esClientMock.termsEnum.mockResolvedValue( - mockResponse as unknown as TransportResult - ); + esClientMock.termsEnum.mockResolvedValue(mockResponse as unknown as TermsEnumResponse); }); it('calls the _terms_enum API with the field, query, filters, and config tiers', async () => { @@ -73,7 +68,7 @@ describe('_terms_enum suggestions', () => { "index": "index", } `); - expect(result).toEqual(mockResponse.body.terms); + expect(result).toEqual(mockResponse.terms); }); it('calls the _terms_enum API and fallback to fieldName when field is null', async () => { @@ -113,6 +108,6 @@ describe('_terms_enum suggestions', () => { "index": "index", } `); - expect(result).toEqual(mockResponse.body.terms); + expect(result).toEqual(mockResponse.terms); }); }); diff --git a/src/plugins/data/server/autocomplete/terms_enum.ts b/src/plugins/data/server/autocomplete/terms_enum.ts index 201ff32c056ce..e4dca0a739087 100644 --- a/src/plugins/data/server/autocomplete/terms_enum.ts +++ b/src/plugins/data/server/autocomplete/terms_enum.ts @@ -54,5 +54,5 @@ export async function termsEnumSuggestions( } ); - return result.body.terms; + return result.terms; } diff --git a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts index 912526b22151f..fb874e4a41c20 100644 --- a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts +++ b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts @@ -30,45 +30,41 @@ function setupMockCallCluster( function mockedEsGetMethod() { if (optCount === null) { return Promise.resolve({ - body: { - _index: '.kibana_1', - _id: 'kql-telemetry:kql-telemetry', - found: false, - }, + _index: '.kibana_1', + _id: 'kql-telemetry:kql-telemetry', + found: false, }); } else { return Promise.resolve({ - body: { - _source: { - 'kql-telemetry': { ...optCount }, - type: 'kql-telemetry', - updated_at: '2018-10-05T20:20:56.258Z', - }, + _source: { + 'kql-telemetry': { ...optCount }, + type: 'kql-telemetry', + updated_at: '2018-10-05T20:20:56.258Z', }, }); } } + function mockedEsSearchMethod() { if (language === 'missingConfigDoc') { - return Promise.resolve({ body: { hits: { hits: [] } } }); + return Promise.resolve({ hits: { hits: [] } }); } else { return Promise.resolve({ - body: { - hits: { - hits: [ - { - _source: { - config: { - 'search:queryLanguage': language, - }, + hits: { + hits: [ + { + _source: { + config: { + 'search:queryLanguage': language, }, }, - ], - }, + }, + ], }, }); } } + const esClientMock = { get: jest.fn().mockImplementation(mockedEsGetMethod), search: jest.fn().mockImplementation(mockedEsSearchMethod), diff --git a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts index c04d8a89486af..bad26c1cf8f80 100644 --- a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts +++ b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts @@ -20,7 +20,7 @@ export interface Usage { export function fetchProvider(index: string) { return async ({ esClient }: CollectorFetchContext): Promise => { - const [{ body: response }, { body: config }] = await Promise.all([ + const [response, config] = await Promise.all([ esClient.get( { index, diff --git a/src/plugins/data/server/search/collectors/fetch.ts b/src/plugins/data/server/search/collectors/fetch.ts index a2d1917fc4770..054d04d6fbcae 100644 --- a/src/plugins/data/server/search/collectors/fetch.ts +++ b/src/plugins/data/server/search/collectors/fetch.ts @@ -15,7 +15,7 @@ interface SearchTelemetry { export function fetchProvider(kibanaIndex: string) { return async ({ esClient }: CollectorFetchContext): Promise => { - const { body: esResponse } = await esClient.search( + const esResponse = await esClient.search( { index: kibanaIndex, body: { diff --git a/src/plugins/data/server/search/strategies/eql_search/eql_search_strategy.ts b/src/plugins/data/server/search/strategies/eql_search/eql_search_strategy.ts index 3d9294765cc15..ebb07cff6e05d 100644 --- a/src/plugins/data/server/search/strategies/eql_search/eql_search_strategy.ts +++ b/src/plugins/data/server/search/strategies/eql_search/eql_search_strategy.ts @@ -53,11 +53,15 @@ export const eqlSearchStrategyProvider = ( ...request.params, }; const response = id - ? await client.get({ ...params, id }, { ...request.options, signal: options.abortSignal }) + ? await client.get( + { ...params, id }, + { ...request.options, signal: options.abortSignal, meta: true } + ) : // @ts-expect-error optional key cannot be used since search doesn't expect undefined await client.search(params as EqlSearchStrategyRequest['params'], { ...request.options, abortController: { signal: options.abortSignal }, + meta: true, }); return toEqlKibanaSearchResponse(response as TransportResult); diff --git a/src/plugins/data/server/search/strategies/es_search/es_search_strategy.test.ts b/src/plugins/data/server/search/strategies/es_search/es_search_strategy.test.ts index c06a75f3148a8..de5962763aed4 100644 --- a/src/plugins/data/server/search/strategies/es_search/es_search_strategy.test.ts +++ b/src/plugins/data/server/search/strategies/es_search/es_search_strategy.test.ts @@ -5,7 +5,8 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { TransportResult } from '@elastic/elasticsearch'; + +import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { elasticsearchServiceMock } from '../../../../../../core/server/mocks'; import { pluginInitializerContextConfigMock } from '../../../../../../core/server/mocks'; import { esSearchStrategyProvider } from './es_search_strategy'; @@ -23,31 +24,28 @@ describe('ES search strategy', () => { skipped: 2, successful: 7, }, - } as const; - let mockedApiCaller: Promise>; - let mockApiCaller: jest.Mock<() => TransportResult>; + } as estypes.SearchResponse; + const mockLogger: any = { debug: () => {}, }; + let esClient: ReturnType; + function getMockedDeps(err?: Record) { - mockApiCaller = jest.fn().mockImplementation(() => { - if (err) { - mockedApiCaller = elasticsearchServiceMock.createErrorTransportRequestPromise(err); - } else { - mockedApiCaller = elasticsearchServiceMock.createSuccessTransportRequestPromise( - successBody, - { statusCode: 200 } - ); - } - return mockedApiCaller; - }); + esClient = elasticsearchServiceMock.createElasticsearchClient(); + + if (err) { + esClient.search.mockImplementation(() => Promise.reject(err)); + } else { + esClient.search.mockResponse(successBody, { statusCode: 200 }); + } return { uiSettingsClient: { get: () => {}, }, - esClient: { asCurrentUser: { search: mockApiCaller } }, + esClient: { asCurrentUser: esClient }, } as unknown as SearchStrategyDependencies; } @@ -65,8 +63,8 @@ describe('ES search strategy', () => { await esSearchStrategyProvider(mockConfig$, mockLogger) .search({ params }, {}, getMockedDeps()) .subscribe(() => { - expect(mockApiCaller).toBeCalled(); - expect(mockApiCaller.mock.calls[0][0]).toEqual({ + expect(esClient.search).toBeCalled(); + expect(esClient.search.mock.calls[0][0]).toEqual({ ...params, ignore_unavailable: true, track_total_hits: true, @@ -81,8 +79,8 @@ describe('ES search strategy', () => { await esSearchStrategyProvider(mockConfig$, mockLogger) .search({ params }, {}, getMockedDeps()) .subscribe(() => { - expect(mockApiCaller).toBeCalled(); - expect(mockApiCaller.mock.calls[0][0]).toEqual({ + expect(esClient.search).toBeCalled(); + expect(esClient.search.mock.calls[0][0]).toEqual({ ...params, track_total_hits: true, }); @@ -117,8 +115,8 @@ describe('ES search strategy', () => { .search({ params }, { abortSignal: abortController.signal }, getMockedDeps()) .toPromise(); - expect(mockApiCaller).toBeCalled(); - expect(mockApiCaller.mock.calls[0][0]).toEqual({ + expect(esClient.search).toBeCalled(); + expect(esClient.search.mock.calls[0][0]).toEqual({ ...params, track_total_hits: true, }); @@ -139,7 +137,7 @@ describe('ES search strategy', () => { .search({ params }, {}, getMockedDeps(errResponse)) .toPromise(); } catch (e) { - expect(mockApiCaller).toBeCalled(); + expect(esClient.search).toBeCalled(); expect(e).toBeInstanceOf(KbnServerError); expect(e.statusCode).toBe(404); expect(e.message).toBe(errResponse.message); @@ -157,7 +155,7 @@ describe('ES search strategy', () => { .search({ params }, {}, getMockedDeps(errResponse)) .toPromise(); } catch (e) { - expect(mockApiCaller).toBeCalled(); + expect(esClient.search).toBeCalled(); expect(e).toBeInstanceOf(KbnServerError); expect(e.statusCode).toBe(500); expect(e.message).toBe(errResponse.message); @@ -175,7 +173,7 @@ describe('ES search strategy', () => { .search({ params }, {}, getMockedDeps(errResponse)) .toPromise(); } catch (e) { - expect(mockApiCaller).toBeCalled(); + expect(esClient.search).toBeCalled(); expect(e).toBeInstanceOf(KbnServerError); expect(e.statusCode).toBe(500); expect(e.message).toBe(errResponse.message); @@ -192,7 +190,7 @@ describe('ES search strategy', () => { .search({ indexType: 'banana', params }, {}, getMockedDeps()) .toPromise(); } catch (e) { - expect(mockApiCaller).not.toBeCalled(); + expect(esClient.search).not.toBeCalled(); expect(e).toBeInstanceOf(KbnServerError); expect(e.message).toBe('Unsupported index pattern type banana'); expect(e.statusCode).toBe(400); diff --git a/src/plugins/data/server/search/strategies/es_search/es_search_strategy.ts b/src/plugins/data/server/search/strategies/es_search/es_search_strategy.ts index 097e099bf2997..5fd734138824d 100644 --- a/src/plugins/data/server/search/strategies/es_search/es_search_strategy.ts +++ b/src/plugins/data/server/search/strategies/es_search/es_search_strategy.ts @@ -46,7 +46,7 @@ export const esSearchStrategyProvider = ( ...(terminateAfter ? { terminate_after: terminateAfter } : {}), ...requestParams, }; - const { body } = await esClient.asCurrentUser.search(params, { + const body = await esClient.asCurrentUser.search(params, { signal: abortSignal, }); const response = shimHitsTotal(body, options); diff --git a/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts b/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts index e94f1aa44d351..7a9caa4998f9a 100644 --- a/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts +++ b/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts @@ -68,9 +68,13 @@ export const enhancedEsSearchStrategyProvider = ( ...request.params, }; const { body, headers } = id - ? await client.asyncSearch.get({ ...params, id }, { signal: options.abortSignal }) + ? await client.asyncSearch.get( + { ...params, id }, + { signal: options.abortSignal, meta: true } + ) : await client.asyncSearch.submit(params, { signal: options.abortSignal, + meta: true, }); const response = shimHitsTotal(body.response, options); @@ -124,6 +128,7 @@ export const enhancedEsSearchStrategyProvider = ( }, { signal: options?.abortSignal, + meta: true, } ); 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 e95c12469ffb9..022cd92a4bb1e 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 @@ -70,7 +70,7 @@ export const registerFieldPreviewRoute = ({ router }: RouteDependencies): void = body, }); - const fieldValue = response.body.hits.hits[0]?.fields?.my_runtime_field ?? ''; + const fieldValue = response.hits.hits[0]?.fields?.my_runtime_field ?? ''; return res.ok({ body: { values: fieldValue } }); } catch (error: any) { 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 cc161859f4189..6756761fe9653 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 @@ -28,23 +28,27 @@ export function registerPreviewScriptedFieldRoute(router: IRouter): void { const { index, name, script, query, additionalFields } = request.body; try { - const response = await client.search({ - index, - body: { - _source: additionalFields && additionalFields.length > 0 ? additionalFields : undefined, - size: 10, - timeout: '30s', - query: query ?? { match_all: {} }, - script_fields: { - [name]: { - script: { - lang: 'painless', - source: script, + const response = await client.search( + { + index, + body: { + _source: + additionalFields && additionalFields.length > 0 ? additionalFields : undefined, + size: 10, + timeout: '30s', + query: query ?? { match_all: {} }, + script_fields: { + [name]: { + script: { + lang: 'painless', + source: script, + }, }, }, }, }, - }); + { meta: true } + ); return res.ok({ body: response }); } catch (err) { 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 22c214f2adee2..f668fb1f1b8de 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,7 @@ export function registerResolveIndexRoute(router: IRouter): void { }, }, async (context, req, res) => { - const { body } = await context.core.elasticsearch.client.asCurrentUser.indices.resolveIndex({ + const body = await context.core.elasticsearch.client.asCurrentUser.indices.resolveIndex({ name: req.params.query, expand_wildcards: req.query.expand_wildcards || 'open', }); diff --git a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.test.ts b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.test.ts index f55609d75a066..8f1749a4b61fa 100644 --- a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.test.ts +++ b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.test.ts @@ -5,46 +5,46 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + +import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { IndexPatternsFetcher } from '.'; -import { ElasticsearchClient } from 'kibana/server'; +import { elasticsearchServiceMock } from '../../../../core/server/mocks'; import * as indexNotFoundException from './index_not_found_exception.json'; describe('Index Pattern Fetcher - server', () => { let indexPatterns: IndexPatternsFetcher; - let esClient: ElasticsearchClient; + let esClient: ReturnType; const emptyResponse = { - body: { - indices: [], - }, + indices: [], }; const response = { - body: { - indices: ['b'], - fields: [{ name: 'foo' }, { name: 'bar' }, { name: 'baz' }], - }, + indices: ['b'], + fields: [{ name: 'foo' }, { name: 'bar' }, { name: 'baz' }], }; const patternList = ['a', 'b', 'c']; beforeEach(() => { jest.clearAllMocks(); - esClient = { - fieldCaps: jest.fn().mockResolvedValueOnce(emptyResponse).mockResolvedValue(response), - } as unknown as ElasticsearchClient; + esClient = elasticsearchServiceMock.createElasticsearchClient(); indexPatterns = new IndexPatternsFetcher(esClient); }); it('Removes pattern without matching indices', async () => { + esClient.fieldCaps + .mockResponseOnce(emptyResponse as unknown as estypes.FieldCapsResponse) + .mockResponse(response as unknown as estypes.FieldCapsResponse); // first field caps request returns empty const result = await indexPatterns.validatePatternListActive(patternList); expect(result).toEqual(['b', 'c']); }); it('Keeps matching and negating patterns', async () => { + esClient.fieldCaps + .mockResponseOnce(emptyResponse as unknown as estypes.FieldCapsResponse) + .mockResponse(response as unknown as estypes.FieldCapsResponse); // first field caps request returns empty const result = await indexPatterns.validatePatternListActive(['-a', 'b', 'c']); expect(result).toEqual(['-a', 'c']); }); it('Returns all patterns when all match indices', async () => { - esClient = { - fieldCaps: jest.fn().mockResolvedValue(response), - } as unknown as ElasticsearchClient; + esClient.fieldCaps.mockResponse(response as unknown as estypes.FieldCapsResponse); indexPatterns = new IndexPatternsFetcher(esClient); const result = await indexPatterns.validatePatternListActive(patternList); expect(result).toEqual(patternList); @@ -52,6 +52,7 @@ describe('Index Pattern Fetcher - server', () => { it('Removes pattern when error is thrown', async () => { class ServerError extends Error { public body?: Record; + constructor( message: string, public readonly statusCode: number, @@ -61,34 +62,29 @@ describe('Index Pattern Fetcher - server', () => { this.body = errBody; } } - esClient = { - fieldCaps: jest - .fn() - .mockResolvedValueOnce(response) - .mockRejectedValue( + + esClient.fieldCaps + .mockResponseOnce(response as unknown as estypes.FieldCapsResponse) + .mockImplementationOnce(() => { + return Promise.reject( new ServerError('index_not_found_exception', 404, indexNotFoundException) - ), - } as unknown as ElasticsearchClient; + ); + }); + indexPatterns = new IndexPatternsFetcher(esClient); const result = await indexPatterns.validatePatternListActive(patternList); expect(result).toEqual([patternList[0]]); }); it('When allowNoIndices is false, run validatePatternListActive', async () => { - const fieldCapsMock = jest.fn(); - esClient = { - fieldCaps: fieldCapsMock.mockResolvedValue(response), - } as unknown as ElasticsearchClient; + esClient.fieldCaps.mockResponse(response as unknown as estypes.FieldCapsResponse); indexPatterns = new IndexPatternsFetcher(esClient); await indexPatterns.getFieldsForWildcard({ pattern: patternList }); - expect(fieldCapsMock.mock.calls).toHaveLength(4); + expect(esClient.fieldCaps).toHaveBeenCalledTimes(4); }); it('When allowNoIndices is true, do not run validatePatternListActive', async () => { - const fieldCapsMock = jest.fn(); - esClient = { - fieldCaps: fieldCapsMock.mockResolvedValue(response), - } as unknown as ElasticsearchClient; + esClient.fieldCaps.mockResponse(response as unknown as estypes.FieldCapsResponse); indexPatterns = new IndexPatternsFetcher(esClient, true); await indexPatterns.getFieldsForWildcard({ pattern: patternList }); - expect(fieldCapsMock.mock.calls).toHaveLength(1); + expect(esClient.fieldCaps).toHaveBeenCalledTimes(1); }); }); diff --git a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts index 148e497d7ef02..dce48a6d96208 100644 --- a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts +++ b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts @@ -37,10 +37,12 @@ interface FieldSubType { export class IndexPatternsFetcher { private elasticsearchClient: ElasticsearchClient; private allowNoIndices: boolean; + constructor(elasticsearchClient: ElasticsearchClient, allowNoIndices: boolean = false) { this.elasticsearchClient = elasticsearchClient; this.allowNoIndices = allowNoIndices; } + /** * Get a list of field objects for an index pattern that may contain wildcards * @@ -80,11 +82,9 @@ export class IndexPatternsFetcher { if (type === 'rollup' && rollupIndex) { const rollupFields: FieldDescriptor[] = []; const rollupIndexCapabilities = getCapabilitiesForRollupIndices( - ( - await this.elasticsearchClient.rollup.getRollupIndexCaps({ - index: rollupIndex, - }) - ).body + await this.elasticsearchClient.rollup.getRollupIndexCaps({ + index: rollupIndex, + }) )[rollupIndex].aggs; const fieldCapsResponseObj = keyBy(fieldCapsResponse, 'name'); // Keep meta fields @@ -150,7 +150,7 @@ export class IndexPatternsFetcher { ignore_unavailable: true, allow_no_indices: false, }); - return searchResponse.body.indices.length > 0; + return searchResponse.indices.length > 0; }) .map((p) => p.catch(() => false)) ); diff --git a/src/plugins/data_views/server/fetcher/lib/es_api.ts b/src/plugins/data_views/server/fetcher/lib/es_api.ts index d01bf58048f66..fe0a8fb126aec 100644 --- a/src/plugins/data_views/server/fetcher/lib/es_api.ts +++ b/src/plugins/data_views/server/fetcher/lib/es_api.ts @@ -68,13 +68,16 @@ export async function callFieldCapsApi(params: FieldCapsApiParams) { }, } = params; try { - return await callCluster.fieldCaps({ - index: indices, - fields: '*', - ignore_unavailable: true, - index_filter: filter, - ...fieldCapsOptions, - }); + return await callCluster.fieldCaps( + { + index: indices, + fields: '*', + ignore_unavailable: true, + index_filter: filter, + ...fieldCapsOptions, + }, + { meta: true } + ); } catch (error) { throw convertEsError(indices, error); } diff --git a/src/plugins/data_views/server/fetcher/lib/resolve_time_pattern.test.js b/src/plugins/data_views/server/fetcher/lib/resolve_time_pattern.test.js index 597770dff0a90..e71022bfe6b26 100644 --- a/src/plugins/data_views/server/fetcher/lib/resolve_time_pattern.test.js +++ b/src/plugins/data_views/server/fetcher/lib/resolve_time_pattern.test.js @@ -64,15 +64,13 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => { describe('read response', () => { it('returns all aliases names in result.all, ordered by time desc', async () => { sandbox.stub(callIndexAliasApiNS, 'callIndexAliasApi').returns({ - body: { - 'logs-2016.2': {}, - 'logs-Saturday-2017.1': {}, - 'logs-2016.1': {}, - 'logs-Sunday-2017.1': {}, - 'logs-2015': {}, - 'logs-2016.3': {}, - 'logs-Friday-2017.1': {}, - }, + 'logs-2016.2': {}, + 'logs-Saturday-2017.1': {}, + 'logs-2016.1': {}, + 'logs-Sunday-2017.1': {}, + 'logs-2015': {}, + 'logs-2016.3': {}, + 'logs-Friday-2017.1': {}, }); const resp = await resolveTimePattern(noop, TIME_PATTERN); @@ -90,15 +88,13 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => { it('returns all indices matching the time pattern in matches, ordered by time desc', async () => { sandbox.stub(callIndexAliasApiNS, 'callIndexAliasApi').returns({ - body: { - 'logs-2016.2': {}, - 'logs-Saturday-2017.1': {}, - 'logs-2016.1': {}, - 'logs-Sunday-2017.1': {}, - 'logs-2015': {}, - 'logs-2016.3': {}, - 'logs-Friday-2017.1': {}, - }, + 'logs-2016.2': {}, + 'logs-Saturday-2017.1': {}, + 'logs-2016.1': {}, + 'logs-Sunday-2017.1': {}, + 'logs-2015': {}, + 'logs-2016.3': {}, + 'logs-Friday-2017.1': {}, }); const resp = await resolveTimePattern(noop, TIME_PATTERN); diff --git a/src/plugins/data_views/server/fetcher/lib/resolve_time_pattern.ts b/src/plugins/data_views/server/fetcher/lib/resolve_time_pattern.ts index 32b9d8c7f893f..0d487cae4ef41 100644 --- a/src/plugins/data_views/server/fetcher/lib/resolve_time_pattern.ts +++ b/src/plugins/data_views/server/fetcher/lib/resolve_time_pattern.ts @@ -28,7 +28,7 @@ import { callIndexAliasApi } from './es_api'; export async function resolveTimePattern(callCluster: ElasticsearchClient, timePattern: string) { const aliases = await callIndexAliasApi(callCluster, timePatternToWildcard(timePattern)); - const allIndexDetails = chain(aliases.body) + const allIndexDetails = chain(aliases) .reduce( (acc: string[], index: any, indexName: string) => acc.concat(indexName, Object.keys(index.aliases || {})), diff --git a/src/plugins/data_views/server/has_user_index_pattern.test.ts b/src/plugins/data_views/server/has_user_index_pattern.test.ts index aeaa64b949dbc..886fa8c618e90 100644 --- a/src/plugins/data_views/server/has_user_index_pattern.test.ts +++ b/src/plugins/data_views/server/has_user_index_pattern.test.ts @@ -69,13 +69,11 @@ describe('hasUserIndexPattern', () => { }); it('calls indices.resolveIndex for the index patterns', async () => { - esClient.indices.resolveIndex.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - indices: [], - data_streams: [], - aliases: [], - }) - ); + esClient.indices.resolveIndex.mockResponse({ + indices: [], + data_streams: [], + aliases: [], + }); await hasUserIndexPattern({ esClient, soClient }); expect(esClient.indices.resolveIndex).toHaveBeenCalledWith({ name: 'logs-*,metrics-*', @@ -83,91 +81,79 @@ describe('hasUserIndexPattern', () => { }); it('returns false if no logs or metrics data_streams exist', async () => { - esClient.indices.resolveIndex.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - indices: [], - data_streams: [], - aliases: [], - }) - ); + esClient.indices.resolveIndex.mockResponse({ + indices: [], + data_streams: [], + aliases: [], + }); expect(await hasUserIndexPattern({ esClient, soClient })).toEqual(false); }); it('returns true if any index exists', async () => { - esClient.indices.resolveIndex.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - indices: [{ name: 'logs', attributes: [] }], - data_streams: [], - aliases: [], - }) - ); + esClient.indices.resolveIndex.mockResponse({ + indices: [{ name: 'logs', attributes: [] }], + data_streams: [], + aliases: [], + }); expect(await hasUserIndexPattern({ esClient, soClient })).toEqual(true); }); it('returns false if only metrics-elastic_agent data stream exists', async () => { - esClient.indices.resolveIndex.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - indices: [], - data_streams: [ - { - name: 'metrics-elastic_agent', - timestamp_field: '@timestamp', - backing_indices: ['.ds-metrics-elastic_agent'], - }, - ], - aliases: [], - }) - ); + esClient.indices.resolveIndex.mockResponse({ + indices: [], + data_streams: [ + { + name: 'metrics-elastic_agent', + timestamp_field: '@timestamp', + backing_indices: ['.ds-metrics-elastic_agent'], + }, + ], + aliases: [], + }); expect(await hasUserIndexPattern({ esClient, soClient })).toEqual(false); }); it('returns false if only logs-elastic_agent data stream exists', async () => { - esClient.indices.resolveIndex.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - indices: [], - data_streams: [ - { - name: 'logs-elastic_agent', - timestamp_field: '@timestamp', - backing_indices: ['.ds-logs-elastic_agent'], - }, - ], - aliases: [], - }) - ); + esClient.indices.resolveIndex.mockResponse({ + indices: [], + data_streams: [ + { + name: 'logs-elastic_agent', + timestamp_field: '@timestamp', + backing_indices: ['.ds-logs-elastic_agent'], + }, + ], + aliases: [], + }); expect(await hasUserIndexPattern({ esClient, soClient })).toEqual(false); }); it('returns false if only metrics-endpoint.metadata_current_default index exists', async () => { - esClient.indices.resolveIndex.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - indices: [ - { - name: 'metrics-endpoint.metadata_current_default', - attributes: ['open'], - }, - ], - aliases: [], - data_streams: [], - }) - ); + esClient.indices.resolveIndex.mockResponse({ + indices: [ + { + name: 'metrics-endpoint.metadata_current_default', + attributes: ['open'], + }, + ], + aliases: [], + data_streams: [], + }); expect(await hasUserIndexPattern({ esClient, soClient })).toEqual(false); }); it('returns true if any other data stream exists', async () => { - esClient.indices.resolveIndex.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - indices: [], - data_streams: [ - { - name: 'other', - timestamp_field: '@timestamp', - backing_indices: ['.ds-other'], - }, - ], - aliases: [], - }) - ); + esClient.indices.resolveIndex.mockResponse({ + indices: [], + data_streams: [ + { + name: 'other', + timestamp_field: '@timestamp', + backing_indices: ['.ds-other'], + }, + ], + aliases: [], + }); expect(await hasUserIndexPattern({ esClient, soClient })).toEqual(true); }); }); diff --git a/src/plugins/data_views/server/has_user_index_pattern.ts b/src/plugins/data_views/server/has_user_index_pattern.ts index 6566f75ebc52e..cf64a2c2013da 100644 --- a/src/plugins/data_views/server/has_user_index_pattern.ts +++ b/src/plugins/data_views/server/has_user_index_pattern.ts @@ -44,13 +44,13 @@ export const hasUserIndexPattern = async ({ esClient, soClient }: Deps): Promise name: `${FLEET_ASSETS_TO_IGNORE.LOGS_INDEX_PATTERN},${FLEET_ASSETS_TO_IGNORE.METRICS_INDEX_PATTERN}`, }); - const hasAnyNonDefaultFleetIndices = resolveResponse.body.indices.some( + const hasAnyNonDefaultFleetIndices = resolveResponse.indices.some( (ds) => ds.name !== FLEET_ASSETS_TO_IGNORE.METRICS_ENDPOINT_INDEX_TO_IGNORE ); if (hasAnyNonDefaultFleetIndices) return true; - const hasAnyNonDefaultFleetDataStreams = resolveResponse.body.data_streams.some( + const hasAnyNonDefaultFleetDataStreams = resolveResponse.data_streams.some( (ds) => ds.name !== FLEET_ASSETS_TO_IGNORE.METRICS_DATA_STREAM_TO_IGNORE && ds.name !== FLEET_ASSETS_TO_IGNORE.LOGS_DATA_STREAM_TO_IGNORE 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 2939fc08712ea..b3cfef51920f1 100644 --- a/src/plugins/home/server/routes/fetch_es_hits_status.ts +++ b/src/plugins/home/server/routes/fetch_es_hits_status.ts @@ -25,7 +25,7 @@ export const registerHitsStatusRoute = (router: IRouter) => { const client = context.core.elasticsearch.client; try { - const { body } = await client.asCurrentUser.search({ + const body = await client.asCurrentUser.search({ index, size: 1, body: { diff --git a/src/plugins/home/server/services/sample_data/lib/insert_data_into_index.ts b/src/plugins/home/server/services/sample_data/lib/insert_data_into_index.ts index 4a7d7e9813dcc..e22a552b7d7bd 100644 --- a/src/plugins/home/server/services/sample_data/lib/insert_data_into_index.ts +++ b/src/plugins/home/server/services/sample_data/lib/insert_data_into_index.ts @@ -54,7 +54,7 @@ export const insertDataIntoIndex = ({ bulk.push(updateTimestamps(doc)); }); - const { body: resp } = await esClient.asCurrentUser.bulk({ + const resp = await esClient.asCurrentUser.bulk({ body: bulk, }); 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 a7ca32341f1f5..6bcc40c0c93e3 100644 --- a/src/plugins/home/server/services/sample_data/routes/list.ts +++ b/src/plugins/home/server/services/sample_data/routes/list.ts @@ -68,6 +68,7 @@ export const createListRoute = ( }; type ExistingSampleObjects = Map; + async function findExistingSampleObjects( context: RequestHandlerContext, logger: Logger, @@ -104,15 +105,14 @@ async function getSampleDatasetStatus( const dataIndexConfig = sampleDataset.dataIndices[i]; const index = createIndexName(sampleDataset.id, dataIndexConfig.id); try { - const { body: indexExists } = - await context.core.elasticsearch.client.asCurrentUser.indices.exists({ - index, - }); + const indexExists = await context.core.elasticsearch.client.asCurrentUser.indices.exists({ + index, + }); if (!indexExists) { return { status: NOT_INSTALLED }; } - const { body: count } = await context.core.elasticsearch.client.asCurrentUser.count({ + const count = await context.core.elasticsearch.client.asCurrentUser.count({ index, }); if (count.count === 0) { diff --git a/src/plugins/home/server/services/sample_data/sample_data_installer.test.ts b/src/plugins/home/server/services/sample_data/sample_data_installer.test.ts index 22079cbcafdb3..205b00e3df94f 100644 --- a/src/plugins/home/server/services/sample_data/sample_data_installer.test.ts +++ b/src/plugins/home/server/services/sample_data/sample_data_installer.test.ts @@ -206,17 +206,13 @@ describe('SampleDataInstaller', () => { it('deletes the alias and the index', async () => { const indexName = 'target_index'; - esClient.asCurrentUser.indices.getAlias.mockResolvedValue( - elasticsearchServiceMock.createApiResponse({ - body: { - [indexName]: { - aliases: { - kibana_sample_data_test_single_data_index: {}, - }, - }, + esClient.asCurrentUser.indices.getAlias.mockResponse({ + [indexName]: { + aliases: { + kibana_sample_data_test_single_data_index: {}, }, - }) - ); + }, + }); await installer.install('test_single_data_index'); @@ -301,17 +297,13 @@ describe('SampleDataInstaller', () => { it('deletes the alias and the index', async () => { const indexName = 'target_index'; - esClient.asCurrentUser.indices.getAlias.mockResolvedValue( - elasticsearchServiceMock.createApiResponse({ - body: { - [indexName]: { - aliases: { - kibana_sample_data_test_single_data_index: {}, - }, - }, + esClient.asCurrentUser.indices.getAlias.mockResponse({ + [indexName]: { + aliases: { + kibana_sample_data_test_single_data_index: {}, }, - }) - ); + }, + }); await installer.uninstall('test_single_data_index'); diff --git a/src/plugins/home/server/services/sample_data/sample_data_installer.ts b/src/plugins/home/server/services/sample_data/sample_data_installer.ts index 8e9315719bc16..5aec4a6b2d516 100644 --- a/src/plugins/home/server/services/sample_data/sample_data_installer.ts +++ b/src/plugins/home/server/services/sample_data/sample_data_installer.ts @@ -118,7 +118,7 @@ export class SampleDataInstaller { try { // if the sample data was reindexed using UA, the index name is actually an alias pointing to the reindexed // index. In that case, we need to get rid of the alias and to delete the underlying index - const { body: response } = await this.esClient.asCurrentUser.indices.getAlias({ + const response = await this.esClient.asCurrentUser.indices.getAlias({ name: index, }); const aliasName = index; diff --git a/src/plugins/home/server/services/sample_data/usage/collector_fetch.test.ts b/src/plugins/home/server/services/sample_data/usage/collector_fetch.test.ts index d2d06433634fa..c37c55bf02535 100644 --- a/src/plugins/home/server/services/sample_data/usage/collector_fetch.test.ts +++ b/src/plugins/home/server/services/sample_data/usage/collector_fetch.test.ts @@ -12,7 +12,7 @@ import { fetchProvider } from './collector_fetch'; const getMockFetchClients = (hits?: unknown[]) => { const fetchParamsMock = createCollectorFetchContextMock(); - fetchParamsMock.esClient.search = jest.fn().mockResolvedValue({ body: { hits: { hits } } }); + fetchParamsMock.esClient.search = jest.fn().mockResolvedValue({ hits: { hits } }); return fetchParamsMock; }; diff --git a/src/plugins/home/server/services/sample_data/usage/collector_fetch.ts b/src/plugins/home/server/services/sample_data/usage/collector_fetch.ts index d8da9b4654152..3342912919a62 100644 --- a/src/plugins/home/server/services/sample_data/usage/collector_fetch.ts +++ b/src/plugins/home/server/services/sample_data/usage/collector_fetch.ts @@ -35,7 +35,7 @@ type ESResponse = SearchResponse; export function fetchProvider(index: string) { return async ({ esClient }: CollectorFetchContext) => { - const { body: response } = await esClient.search( + const response = await esClient.search( { index, body: { diff --git a/src/plugins/interactive_setup/server/elasticsearch_service.test.ts b/src/plugins/interactive_setup/server/elasticsearch_service.test.ts index e7b326a1d019d..63d95673cacb4 100644 --- a/src/plugins/interactive_setup/server/elasticsearch_service.test.ts +++ b/src/plugins/interactive_setup/server/elasticsearch_service.test.ts @@ -197,9 +197,7 @@ describe('ElasticsearchService', () => { }); it('checks connection status only once if connection is known to be configured right from start', async () => { - mockConnectionStatusClient.asInternalUser.ping.mockResolvedValue( - interactiveSetupMock.createApiResponse({ body: true }) - ); + mockConnectionStatusClient.asInternalUser.ping.mockResponse(true); const mockHandler = jest.fn(); setupContract.connectionStatus$.subscribe(mockHandler); @@ -410,9 +408,9 @@ describe('ElasticsearchService', () => { ); mockEnrollClient.asScoped.mockReturnValue(mockEnrollScopedClusterClient); - mockAuthenticateClient.asInternalUser.security.authenticate.mockResolvedValue( - interactiveSetupMock.createApiResponse({ statusCode: 200, body: {} as any }) - ); + mockAuthenticateClient.asInternalUser.security.authenticate.mockResponse({} as any, { + statusCode: 200, + }); mockCompatibility(false, 'Oh no!'); @@ -457,9 +455,9 @@ describe('ElasticsearchService', () => { .mockReturnValueOnce(mockHostOneEnrollScopedClusterClient) .mockReturnValueOnce(mockHostTwoEnrollScopedClusterClient); - mockAuthenticateClient.asInternalUser.security.authenticate.mockResolvedValue( - interactiveSetupMock.createApiResponse({ statusCode: 200, body: {} as any }) - ); + mockAuthenticateClient.asInternalUser.security.authenticate.mockResponse({} as any, { + statusCode: 200, + }); const expectedCa = `-----BEGIN CERTIFICATE----- @@ -521,19 +519,25 @@ some weird+ca/with ).toHaveBeenCalledTimes(1); expect( mockHostOneEnrollScopedClusterClient.asCurrentUser.transport.request - ).toHaveBeenCalledWith({ - method: 'GET', - path: '/_security/enroll/kibana', - }); + ).toHaveBeenCalledWith( + { + method: 'GET', + path: '/_security/enroll/kibana', + }, + { meta: true } + ); expect( mockHostTwoEnrollScopedClusterClient.asCurrentUser.transport.request ).toHaveBeenCalledTimes(1); expect( mockHostTwoEnrollScopedClusterClient.asCurrentUser.transport.request - ).toHaveBeenCalledWith({ - method: 'GET', - path: '/_security/enroll/kibana', - }); + ).toHaveBeenCalledWith( + { + method: 'GET', + path: '/_security/enroll/kibana', + }, + { meta: true } + ); expect(mockAuthenticateClient.asInternalUser.security.authenticate).toHaveBeenCalledTimes( 1 ); @@ -560,9 +564,7 @@ some weird+ca/with }); it('fails if version is incompatible', async () => { - mockAuthenticateClient.asInternalUser.ping.mockResolvedValue( - interactiveSetupMock.createApiResponse({ statusCode: 200, body: true }) - ); + mockAuthenticateClient.asInternalUser.ping.mockResponse(true); mockCompatibility(false, 'Oh no!'); @@ -573,9 +575,7 @@ some weird+ca/with }); it('succeeds if ping call succeeds', async () => { - mockAuthenticateClient.asInternalUser.ping.mockResolvedValue( - interactiveSetupMock.createApiResponse({ statusCode: 200, body: true }) - ); + mockAuthenticateClient.asInternalUser.ping.mockResponse(true); await expect( setupContract.authenticate({ host: 'http://localhost:9200' }) @@ -612,9 +612,8 @@ some weird+ca/with }); it('fails if host is not Elasticsearch', async () => { - mockPingClient.asInternalUser.ping.mockResolvedValue( - interactiveSetupMock.createApiResponse({ statusCode: 200, body: true }) - ); + mockAuthenticateClient.asInternalUser.ping.mockResponse(true); + mockPingClient.asInternalUser.transport.request.mockResolvedValue( interactiveSetupMock.createApiResponse({ statusCode: 200, body: {}, headers: {} }) ); @@ -626,9 +625,7 @@ some weird+ca/with }); it('succeeds if host does not require authentication', async () => { - mockPingClient.asInternalUser.ping.mockResolvedValue( - interactiveSetupMock.createApiResponse({ statusCode: 200, body: true }) - ); + mockAuthenticateClient.asInternalUser.ping.mockResponse(true); await expect(setupContract.ping('http://localhost:9200')).resolves.toEqual({ authRequired: false, diff --git a/src/plugins/interactive_setup/server/elasticsearch_service.ts b/src/plugins/interactive_setup/server/elasticsearch_service.ts index 3b5f1532e0b1f..f9bcbd60d02d3 100644 --- a/src/plugins/interactive_setup/server/elasticsearch_service.ts +++ b/src/plugins/interactive_setup/server/elasticsearch_service.ts @@ -122,6 +122,7 @@ export class ElasticsearchService { * Elasticsearch client used to check Elasticsearch connection status. */ private connectionStatusClient?: ICustomClusterClient; + constructor(private readonly logger: Logger, private kibanaVersion: string) {} public setup({ @@ -199,10 +200,13 @@ export class ElasticsearchService { try { enrollmentResponse = await enrollClient .asScoped(scopeableRequest) - .asCurrentUser.transport.request({ - method: 'GET', - path: '/_security/enroll/kibana', - }); + .asCurrentUser.transport.request( + { + method: 'GET', + path: '/_security/enroll/kibana', + }, + { meta: true } + ); } catch (err) { // We expect that all hosts belong to exactly same node and any non-connection error for one host would mean // that enrollment will fail for any other host and we should bail out. @@ -357,10 +361,13 @@ export class ElasticsearchService { this.logger.debug(`Verifying that host "${host}" responds with Elastic product header`); try { - const response = await client.asInternalUser.transport.request({ - method: 'OPTIONS', - path: '/', - }); + const response = await client.asInternalUser.transport.request( + { + method: 'OPTIONS', + path: '/', + }, + { meta: true } + ); if (response.headers?.['x-elastic-product'] !== 'Elasticsearch') { throw new Error('Host did not respond with valid Elastic product header.'); } diff --git a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/get_saved_object_counts.test.ts b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/get_saved_object_counts.test.ts index 4b3421efed96e..8fb75d1ae08e3 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/get_saved_object_counts.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/get_saved_object_counts.test.ts @@ -11,10 +11,8 @@ import { getSavedObjectsCounts } from './get_saved_object_counts'; function mockGetSavedObjectsCounts(params: TBody) { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - esClient.search.mockResolvedValue( - // @ts-expect-error we only care about the response body - { body: { ...params } } - ); + // @ts-expect-error arbitrary type + esClient.search.mockResponse(params); return esClient; } diff --git a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/get_saved_object_counts.ts b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/get_saved_object_counts.ts index f82a803b763c5..cb3c09efa0e3b 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/get_saved_object_counts.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/get_saved_object_counts.ts @@ -25,7 +25,7 @@ export async function getSavedObjectsCounts( aggs: { types: { terms: { field: 'type' } } }, }, }; - const { body } = await esClient.search(savedObjectCountSearchParams); + const body = await esClient.search(savedObjectCountSearchParams); // @ts-expect-error declare type for aggregations explicitly return body.aggregations?.types?.buckets || []; } diff --git a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.test.ts b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.test.ts index d61b8ca2c7779..0f5152daa31a7 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.test.ts @@ -31,7 +31,7 @@ describe('kibana_usage', () => { const fetchParamsMock = createCollectorFetchContextMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; // @ts-expect-error for the sake of the tests, we only require `hits` - esClient.search.mockResolvedValue({ body: { hits: { hits } } }); + esClient.search.mockResponse({ hits: { hits } }); fetchParamsMock.esClient = esClient; return fetchParamsMock; }; @@ -58,9 +58,9 @@ describe('kibana_usage', () => { function mockGetSavedObjectsCounts(params: TBody) { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - esClient.search.mockResolvedValue( + esClient.search.mockResponse( // @ts-expect-error we only care about the response body - { body: { ...params } } + { ...params } ); return esClient; } diff --git a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.test.ts b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.test.ts index 1f507dcc44666..a5bda0c0b3713 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.test.ts @@ -38,16 +38,14 @@ describe('saved_objects_count_collector', () => { test('should return some values when the aggregations return something', async () => { const fetchContextMock = createCollectorFetchContextMock(); fetchContextMock.esClient.search = jest.fn().mockImplementation(() => ({ - body: { - aggregations: { - types: { - buckets: [ - { key: 'type_one', doc_count: 20 }, - { key: 'type_two', doc_count: 45 }, - { key: 'type-three', doc_count: 66 }, - { key: 'type-four', doc_count: 0 }, - ], - }, + aggregations: { + types: { + buckets: [ + { key: 'type_one', doc_count: 20 }, + { key: 'type_two', doc_count: 45 }, + { key: 'type-three', doc_count: 66 }, + { key: 'type-four', doc_count: 0 }, + ], }, }, })); diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.test.ts index cd414beb42182..3c96b45ed3262 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.test.ts @@ -12,7 +12,7 @@ import { getClusterInfo } from './get_cluster_info'; export function mockGetClusterInfo(clusterInfo: ClusterInfo) { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; // @ts-expect-error we only care about the response body - esClient.info.mockResolvedValue({ body: { ...clusterInfo } }); + esClient.info.mockResponse({ ...clusterInfo }); return esClient; } diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts index 3f93bde1e7e62..667b8564e4d33 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts @@ -16,6 +16,5 @@ import { ElasticsearchClient } from 'src/core/server'; * @param {function} esClient The asInternalUser handler (exposed for testing) */ export async function getClusterInfo(esClient: ElasticsearchClient) { - const { body } = await esClient.info(); - return body; + return await esClient.info(); } diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.test.ts index 06d3ebeb7ea0e..84a0fdaacb5b1 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.test.ts @@ -12,7 +12,7 @@ import { TIMEOUT } from './constants'; describe('get_cluster_stats', () => { it('uses the esClient to get the response from the `cluster.stats` API', async () => { - const response = { body: { cluster_uuid: '1234' } }; + const response = { cluster_uuid: '1234' }; const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; esClient.cluster.stats.mockImplementationOnce( // @ts-expect-error the method only cares about the response body @@ -22,6 +22,6 @@ describe('get_cluster_stats', () => { ); const result = await getClusterStats(esClient); expect(esClient.cluster.stats).toHaveBeenCalledWith({ timeout: TIMEOUT }); - expect(result).toStrictEqual(response.body); + expect(result).toStrictEqual(response); }); }); diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts index dd5f4f97c6b02..f420291d1c131 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts @@ -9,14 +9,14 @@ import { ClusterDetailsGetter } from 'src/plugins/telemetry_collection_manager/server'; import { ElasticsearchClient } from 'src/core/server'; import { TIMEOUT } from './constants'; + /** * Get the cluster stats from the connected cluster. * * This is the equivalent to GET /_cluster/stats?timeout=30s. */ export async function getClusterStats(esClient: ElasticsearchClient) { - const { body } = await esClient.cluster.stats({ timeout: TIMEOUT }); - return body; + return await esClient.cluster.stats({ timeout: TIMEOUT }); } /** @@ -25,7 +25,6 @@ export async function getClusterStats(esClient: ElasticsearchClient) { * @param esClient Scoped Elasticsearch client */ export const getClusterUuids: ClusterDetailsGetter = async ({ esClient }) => { - const { body } = await esClient.cluster.stats({ timeout: TIMEOUT }); - + const body = await esClient.cluster.stats({ timeout: TIMEOUT }); return [{ clusterUuid: body.cluster_uuid }]; }; diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts index b3a25da0a7abf..310ba6a3ee41d 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts @@ -309,11 +309,11 @@ function mockEsClient( }, ]) ); - return { body }; + return body; }); // @ts-expect-error esClient.indices.stats.mockImplementationOnce(async () => { - return { body: indexStats }; + return indexStats; }); return esClient; } diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts index 8a0b86cf3b0f0..3f98ead25ff4e 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts @@ -181,59 +181,6 @@ export function buildDataTelemetryPayload(indices: DataTelemetryIndex[]): DataTe return [...acc.values()]; } -interface IndexStats { - indices: { - [indexName: string]: { - total: { - docs: { - count: number; - deleted: number; - }; - store: { - size_in_bytes: number; - }; - }; - }; - }; -} - -interface IndexMappings { - [indexName: string]: { - mappings: { - _meta?: { - beat?: string; - - // Ingest Manager provided metadata - package?: { - name?: string; - }; - managed_by?: string; // Typically "ingest-manager" - }; - properties: { - data_stream?: { - properties: { - dataset?: { - type: string; - value?: string; - }; - type?: { - type: string; - value?: string; - }; - }; - }; - ecs?: { - properties: { - version?: { - type: string; - }; - }; - }; - }; - }; - }; -} - export async function getDataTelemetry(esClient: ElasticsearchClient) { try { const index = [ @@ -271,9 +218,9 @@ export async function getDataTelemetry(esClient: ElasticsearchClient) { metric: ['docs', 'store'], filter_path: ['indices.*.total'], }; - const [{ body: indexMappings }, { body: indexStats }] = await Promise.all([ - esClient.indices.getMapping(indexMappingsParams), - esClient.indices.stats(indicesStatsParams), + const [indexMappings, indexStats] = await Promise.all([ + esClient.indices.getMapping(indexMappingsParams), + esClient.indices.stats(indicesStatsParams), ]); const indexNames = Object.keys({ ...indexMappings, ...indexStats?.indices }); diff --git a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts index bcff58c3304c7..2392ac570ecbc 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts @@ -23,50 +23,45 @@ function mockUsageCollection(kibanaUsage = {}) { usageCollection.toObject = jest.fn().mockImplementation((data) => data); return usageCollection; } + // set up successful call mocks for info, cluster stats, nodes usage and data telemetry function mockGetLocalStats( clusterInfo: ClusterInfo, clusterStats: ClusterStats ) { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - esClient.info.mockResolvedValue( - // @ts-expect-error we only care about the response body - { body: { ...clusterInfo } } - ); - esClient.cluster.stats - // @ts-expect-error we only care about the response body - .mockResolvedValue({ body: { ...clusterStats } }); // @ts-expect-error we only care about the response body - esClient.nodes.usage.mockResolvedValue({ - body: { - cluster_name: 'testCluster', - nodes: { - some_node_id: { - timestamp: 1588617023177, - since: 1588616945163, - rest_actions: { - nodes_usage_action: 1, - create_index_action: 1, - document_get_action: 1, - search_action: 19, - nodes_info_action: 36, + esClient.info.mockResponse({ ...clusterInfo }); + // @ts-expect-error we only care about the response body + esClient.cluster.stats.mockResponse({ ...clusterStats }); + esClient.nodes.usage.mockResponse({ + cluster_name: 'testCluster', + nodes: { + some_node_id: { + timestamp: 1588617023177, + since: 1588616945163, + rest_actions: { + nodes_usage_action: 1, + create_index_action: 1, + document_get_action: 1, + search_action: 19, + nodes_info_action: 36, + }, + aggregations: { + scripted_metric: { + other: 7, }, - aggregations: { - scripted_metric: { - other: 7, - }, - terms: { - bytes: 2, - }, + terms: { + bytes: 2, }, }, }, }, }); // @ts-expect-error we only care about the response body - esClient.indices.getMapping.mockResolvedValue({ body: { mappings: {} } }); + esClient.indices.getMapping.mockResponse({ mappings: {} }); // @ts-expect-error we only care about the response body - esClient.indices.stats.mockResolvedValue({ body: { indices: {} } }); + esClient.indices.stats.mockResponse({ indices: {} }); return esClient; } diff --git a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.test.ts index 9192afd3376d5..65bb6eed344aa 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.test.ts @@ -37,14 +37,11 @@ const mockedNodesFetchResponse = { describe('get_nodes_usage', () => { it('returns a modified array of nodes usage data', async () => { - const response = Promise.resolve({ body: mockedNodesFetchResponse }); + const response = Promise.resolve(mockedNodesFetchResponse); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - esClient.nodes.usage.mockImplementationOnce( - // @ts-expect-error - async (_params = { timeout: TIMEOUT }) => { - return response; - } - ); + esClient.nodes.usage.mockImplementationOnce(async (_params = { timeout: TIMEOUT }) => { + return response; + }); const item = await getNodesUsage(esClient); expect(esClient.nodes.usage).toHaveBeenCalledWith({ timeout: TIMEOUT }); expect(item).toStrictEqual({ diff --git a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts index a5d4f32b3a62f..b701a696f210d 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts @@ -32,10 +32,9 @@ export type NodesUsageGetter = (esClient: ElasticsearchClient) => Promise<{ node export async function fetchNodesUsage( esClient: ElasticsearchClient ): Promise { - const { body } = await esClient.nodes.usage({ + return await esClient.nodes.usage({ timeout: TIMEOUT, }); - return body; } /** diff --git a/src/plugins/usage_collection/server/routes/stats/stats.ts b/src/plugins/usage_collection/server/routes/stats/stats.ts index d78f9ab69b66d..8e5382d163172 100644 --- a/src/plugins/usage_collection/server/routes/stats/stats.ts +++ b/src/plugins/usage_collection/server/routes/stats/stats.ts @@ -63,7 +63,7 @@ export function registerStatsRoute({ }; const getClusterUuid = async (asCurrentUser: ElasticsearchClient): Promise => { - const { body } = await asCurrentUser.info({ filter_path: 'cluster_uuid' }); + const body = await asCurrentUser.info({ filter_path: 'cluster_uuid' }); const { cluster_uuid: uuid } = body; return uuid; }; diff --git a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/rollup_search_strategy.test.ts b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/rollup_search_strategy.test.ts index 4d2608e3519ed..b74bb97c3d649 100644 --- a/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/rollup_search_strategy.test.ts +++ b/src/plugins/vis_types/timeseries/server/lib/search_strategies/strategies/rollup_search_strategy.test.ts @@ -118,7 +118,7 @@ describe('Rollup Search Strategy', () => { }); test('should return rollup data', async () => { - rollupResolvedData = Promise.resolve({ body: 'data' }); + rollupResolvedData = Promise.resolve('data'); const rollupData = await rollupSearchStrategy.getRollupData(requestContext, indexPattern); 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 2508c68066017..4d6d9d832a2e0 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 @@ -40,7 +40,7 @@ export class RollupSearchStrategy extends AbstractSearchStrategy { indexPattern: string ) { try { - const { body } = + const body = await requestContext.core.elasticsearch.client.asCurrentUser.rollup.getRollupIndexCaps({ index: indexPattern, }); 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 6701ff97cca80..c65690e8532fd 100644 --- a/test/plugin_functional/plugins/core_plugin_a/server/plugin.ts +++ b/test/plugin_functional/plugins/core_plugin_a/server/plugin.ts @@ -23,7 +23,7 @@ export class CorePluginAPlugin implements Plugin { (context) => { return { ping: async () => { - const { body } = await context.core.elasticsearch.client.asInternalUser.ping(); + const body = await context.core.elasticsearch.client.asInternalUser.ping(); return String(body); }, }; 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 48889c6d4a455..530b90eb5e6d0 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,12 +20,16 @@ export class CorePluginExecutionContext implements Plugin { }, }, async (context, request, response) => { - const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping(); + const { headers } = await context.core.elasticsearch.client.asCurrentUser.ping( + {}, + { meta: true } + ); return response.ok({ body: headers || {} }); } ); } public start() {} + public stop() {} } 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 70b4d3590c8db..ab046ab6a0131 100644 --- a/test/plugin_functional/plugins/elasticsearch_client_plugin/server/plugin.ts +++ b/test/plugin_functional/plugins/elasticsearch_client_plugin/server/plugin.ts @@ -15,7 +15,7 @@ export class ElasticsearchClientPlugin implements Plugin { 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 body = await context.core.elasticsearch.client.asInternalUser.ping(); return res.ok({ body: JSON.stringify(body) }); } ); @@ -23,14 +23,14 @@ export class ElasticsearchClientPlugin implements Plugin { { 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(); + const body = await coreStart.elasticsearch.client.asInternalUser.ping(); return res.ok({ body: JSON.stringify(body) }); } ); router.get( { path: '/api/elasticsearch_client_plugin/custom_client/ping', validate: false }, async (context, req, res) => { - const { body } = await this.client!.asInternalUser.ping(); + const body = await this.client!.asInternalUser.ping(); return res.ok({ body: JSON.stringify(body) }); } ); diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 18e405f70c859..c73809cc33773 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -35,8 +35,6 @@ import { } from './authorization/get_authorization_mode_by_source'; import { actionsAuthorizationMock } from './authorization/actions_authorization.mock'; import { trackLegacyRBACExemption } from './lib/track_legacy_rbac_exemption'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from '../../../../src/core/server/elasticsearch/client/mocks'; import { ConnectorTokenClient } from './builtin_action_types/lib/connector_token_client'; import { encryptedSavedObjectsMock } from '../../encrypted_saved_objects/server/mocks'; import { Logger } from 'kibana/server'; @@ -847,14 +845,14 @@ describe('getAll()', () => { ], }; unsecuredSavedObjectsClient.find.mockResolvedValueOnce(expectedResult); - scopedClusterClient.asInternalUser.search.mockResolvedValueOnce( + scopedClusterClient.asInternalUser.search.mockResponse( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { '1': { doc_count: 6 }, testPreconfigured: { doc_count: 2 }, }, - }) + } ); actionsClient = new ActionsClient({ @@ -924,14 +922,14 @@ describe('getAll()', () => { }, ], }); - scopedClusterClient.asInternalUser.search.mockResolvedValueOnce( + scopedClusterClient.asInternalUser.search.mockResponse( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { '1': { doc_count: 6 }, testPreconfigured: { doc_count: 2 }, }, - }) + } ); await actionsClient.getAll(); @@ -986,14 +984,14 @@ describe('getAll()', () => { ], }; unsecuredSavedObjectsClient.find.mockResolvedValueOnce(expectedResult); - scopedClusterClient.asInternalUser.search.mockResolvedValueOnce( + scopedClusterClient.asInternalUser.search.mockResponse( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { '1': { doc_count: 6 }, testPreconfigured: { doc_count: 2 }, }, - }) + } ); actionsClient = new ActionsClient({ @@ -1063,14 +1061,14 @@ describe('getBulk()', () => { }, ], }); - scopedClusterClient.asInternalUser.search.mockResolvedValueOnce( + scopedClusterClient.asInternalUser.search.mockResponse( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { '1': { doc_count: 6 }, testPreconfigured: { doc_count: 2 }, }, - }) + } ); actionsClient = new ActionsClient({ @@ -1137,14 +1135,14 @@ describe('getBulk()', () => { }, ], }); - scopedClusterClient.asInternalUser.search.mockResolvedValueOnce( + scopedClusterClient.asInternalUser.search.mockResponse( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { '1': { doc_count: 6 }, testPreconfigured: { doc_count: 2 }, }, - }) + } ); await actionsClient.getBulk(['1']); @@ -1196,14 +1194,14 @@ describe('getBulk()', () => { }, ], }); - scopedClusterClient.asInternalUser.search.mockResolvedValueOnce( + scopedClusterClient.asInternalUser.search.mockResponse( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { '1': { doc_count: 6 }, testPreconfigured: { doc_count: 2 }, }, - }) + } ); actionsClient = new ActionsClient({ diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 7d753a9106a1d..18e67c5ca8076 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -606,7 +606,7 @@ async function injectExtraFindData( }, }; } - const { body: aggregationResult } = await scopedClusterClient.asInternalUser.search({ + const aggregationResult = await scopedClusterClient.asInternalUser.search({ index: defaultKibanaIndex, body: { aggs, diff --git a/x-pack/plugins/actions/server/builtin_action_types/es_index.test.ts b/x-pack/plugins/actions/server/builtin_action_types/es_index.test.ts index 50a1deba5af20..7f9aa2298fc14 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/es_index.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/es_index.test.ts @@ -559,36 +559,34 @@ describe('execute()', () => { const scopedClusterClient = elasticsearchClientMock .createClusterClient() .asScoped().asCurrentUser; - scopedClusterClient.bulk.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 0, - errors: true, - items: [ - { - index: { - _index: 'indexme', - _id: '7buTjHQB0SuNSiS9Hayt', - status: 400, - error: { - type: 'mapper_parsing_exception', - reason: 'failed to parse', - caused_by: { - type: 'illegal_argument_exception', - reason: 'field name cannot be an empty string', - }, + scopedClusterClient.bulk.mockResponse({ + took: 0, + errors: true, + items: [ + { + index: { + _index: 'indexme', + _id: '7buTjHQB0SuNSiS9Hayt', + status: 400, + error: { + type: 'mapper_parsing_exception', + reason: 'failed to parse', + caused_by: { + type: 'illegal_argument_exception', + reason: 'field name cannot be an empty string', }, }, }, - ], - }) - ); + }, + ], + }); expect(await actionType.executor({ actionId, config, secrets, params, services })) .toMatchInlineSnapshot(` Object { "actionId": "some-id", "message": "error indexing documents", - "serviceMessage": "Cannot destructure property 'body' of '(intermediate value)' as it is undefined.", + "serviceMessage": "Cannot read properties of undefined (reading 'items')", "status": "error", } `); diff --git a/x-pack/plugins/actions/server/builtin_action_types/es_index.ts b/x-pack/plugins/actions/server/builtin_action_types/es_index.ts index 3662fea00e31d..6ab24293d18ad 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/es_index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/es_index.ts @@ -100,7 +100,7 @@ async function executor( }; try { - const { body: result } = await services.scopedClusterClient.bulk(bulkParams); + const result = await services.scopedClusterClient.bulk(bulkParams); const err = find(result.items, 'index.error.reason'); if (err) { diff --git a/x-pack/plugins/actions/server/cleanup_failed_executions/cleanup_tasks.test.ts b/x-pack/plugins/actions/server/cleanup_failed_executions/cleanup_tasks.test.ts index b80a8d092118a..6d3647be4b65d 100644 --- a/x-pack/plugins/actions/server/cleanup_failed_executions/cleanup_tasks.test.ts +++ b/x-pack/plugins/actions/server/cleanup_failed_executions/cleanup_tasks.test.ts @@ -11,7 +11,6 @@ import { spacesMock } from '../../../spaces/server/mocks'; import { CleanupTasksOpts, cleanupTasks } from './cleanup_tasks'; import { TaskInstance } from '../../../task_manager/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { TransportResult } from '@elastic/elasticsearch'; describe('cleanupTasks', () => { const logger = loggingSystemMock.create().get(); @@ -70,19 +69,27 @@ describe('cleanupTasks', () => { }); it('should delete action_task_params and task objects', async () => { - esClient.bulk.mockResolvedValue({ - body: { items: [], errors: false, took: 1 }, - } as unknown as TransportResult); + esClient.bulk.mockResponse({ + items: [], + errors: false, + took: 1, + } as unknown as estypes.BulkResponse); const result = await cleanupTasks({ ...cleanupTasksOpts, tasks: [taskSO], }); - expect(esClient.bulk).toHaveBeenCalledWith({ - body: [{ delete: { _index: cleanupTasksOpts.kibanaIndex, _id: 'action_task_params:123' } }], - }); - expect(esClient.bulk).toHaveBeenCalledWith({ - body: [{ delete: { _index: cleanupTasksOpts.taskManagerIndex, _id: 'task:123' } }], - }); + expect(esClient.bulk).toHaveBeenCalledWith( + { + body: [{ delete: { _index: cleanupTasksOpts.kibanaIndex, _id: 'action_task_params:123' } }], + }, + { meta: true } + ); + expect(esClient.bulk).toHaveBeenCalledWith( + { + body: [{ delete: { _index: cleanupTasksOpts.taskManagerIndex, _id: 'task:123' } }], + }, + { meta: true } + ); expect(result).toEqual({ success: true, successCount: 1, @@ -91,33 +98,37 @@ describe('cleanupTasks', () => { }); it('should not delete the task if the action_task_params failed to delete', async () => { - esClient.bulk.mockResolvedValue({ - body: { - items: [ - { - delete: { - _index: cleanupTasksOpts.kibanaIndex, - _id: 'action_task_params:123', - status: 500, - result: 'Failure', - error: true, - }, + esClient.bulk.mockResponse({ + items: [ + { + delete: { + _index: cleanupTasksOpts.kibanaIndex, + _id: 'action_task_params:123', + status: 500, + result: 'Failure', + error: true, }, - ], - errors: true, - took: 1, - }, - } as unknown as TransportResult); + }, + ], + errors: true, + took: 1, + } as unknown as estypes.BulkResponse); const result = await cleanupTasks({ ...cleanupTasksOpts, tasks: [taskSO], }); - expect(esClient.bulk).toHaveBeenCalledWith({ - body: [{ delete: { _index: cleanupTasksOpts.kibanaIndex, _id: 'action_task_params:123' } }], - }); - expect(esClient.bulk).not.toHaveBeenCalledWith({ - body: [{ delete: { _index: cleanupTasksOpts.taskManagerIndex, _id: 'task:123' } }], - }); + expect(esClient.bulk).toHaveBeenCalledWith( + { + body: [{ delete: { _index: cleanupTasksOpts.kibanaIndex, _id: 'action_task_params:123' } }], + }, + { meta: true } + ); + expect(esClient.bulk).not.toHaveBeenCalledWith( + { + body: [{ delete: { _index: cleanupTasksOpts.taskManagerIndex, _id: 'task:123' } }], + }, + { meta: true } + ); expect(result).toEqual({ success: false, successCount: 0, diff --git a/x-pack/plugins/actions/server/cleanup_failed_executions/lib/bulk_delete.ts b/x-pack/plugins/actions/server/cleanup_failed_executions/lib/bulk_delete.ts index 5bbb48a3d520d..c93cc12b49731 100644 --- a/x-pack/plugins/actions/server/cleanup_failed_executions/lib/bulk_delete.ts +++ b/x-pack/plugins/actions/server/cleanup_failed_executions/lib/bulk_delete.ts @@ -18,9 +18,12 @@ export async function bulkDelete( return; } - return await esClient.bulk({ - body: ids.map((id) => ({ - delete: { _index: index, _id: id }, - })), - }); + return await esClient.bulk( + { + body: ids.map((id) => ({ + delete: { _index: index, _id: id }, + })), + }, + { meta: true } + ); } diff --git a/x-pack/plugins/actions/server/preconfigured_connectors/alert_history_es_index/create_alert_history_index_template.test.ts b/x-pack/plugins/actions/server/preconfigured_connectors/alert_history_es_index/create_alert_history_index_template.test.ts index a7038d8dc62eb..4a7c5908963f6 100644 --- a/x-pack/plugins/actions/server/preconfigured_connectors/alert_history_es_index/create_alert_history_index_template.test.ts +++ b/x-pack/plugins/actions/server/preconfigured_connectors/alert_history_es_index/create_alert_history_index_template.test.ts @@ -5,9 +5,7 @@ * 2.0. */ -import { ElasticsearchClient } from 'src/core/server'; import { elasticsearchServiceMock, loggingSystemMock } from 'src/core/server/mocks'; -import { DeeplyMockedKeys } from '@kbn/utility-types/jest'; import { createAlertHistoryIndexTemplate, getAlertHistoryIndexTemplate, @@ -17,19 +15,15 @@ type MockedLogger = ReturnType; describe('createAlertHistoryIndexTemplate', () => { let logger: MockedLogger; - let clusterClient: DeeplyMockedKeys; + let clusterClient: ReturnType; beforeEach(() => { logger = loggingSystemMock.createLogger(); - clusterClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + clusterClient = elasticsearchServiceMock.createElasticsearchClient(); }); test(`should create index template if it doesn't exist`, async () => { - // Response type for existsIndexTemplate is still TODO - clusterClient.indices.existsIndexTemplate.mockResolvedValue({ - body: false, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any); + clusterClient.indices.existsIndexTemplate.mockResponse(false); await createAlertHistoryIndexTemplate({ client: clusterClient, logger }); expect(clusterClient.indices.putIndexTemplate).toHaveBeenCalledWith({ @@ -40,11 +34,7 @@ describe('createAlertHistoryIndexTemplate', () => { }); test(`shouldn't create index template if it already exists`, async () => { - // Response type for existsIndexTemplate is still TODO - clusterClient.indices.existsIndexTemplate.mockResolvedValue({ - body: true, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any); + clusterClient.indices.existsIndexTemplate.mockResponse(true); await createAlertHistoryIndexTemplate({ client: clusterClient, logger }); expect(clusterClient.indices.putIndexTemplate).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/actions/server/preconfigured_connectors/alert_history_es_index/create_alert_history_index_template.ts b/x-pack/plugins/actions/server/preconfigured_connectors/alert_history_es_index/create_alert_history_index_template.ts index 28b904361e677..bf3c4ff18e570 100644 --- a/x-pack/plugins/actions/server/preconfigured_connectors/alert_history_es_index/create_alert_history_index_template.ts +++ b/x-pack/plugins/actions/server/preconfigured_connectors/alert_history_es_index/create_alert_history_index_template.ts @@ -33,14 +33,11 @@ async function doesIndexTemplateExist({ client: ElasticsearchClient; templateName: string; }) { - let result; try { - result = (await client.indices.existsIndexTemplate({ name: templateName })).body; + return await client.indices.existsIndexTemplate({ name: templateName }); } catch (err) { throw new Error(`error checking existence of index template: ${err.message}`); } - - return result; } async function createIndexTemplate({ diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts index 07f7f83333844..c389529aa7e82 100644 --- a/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts +++ b/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts @@ -12,9 +12,9 @@ import { getExecutionsPerDayCount, getInUseTotalCount, getTotalCount } from './a describe('actions telemetry', () => { test('getTotalCount should replace first symbol . to __ for action types names', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockResponse( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { byActionTypeId: { value: { @@ -95,7 +95,7 @@ describe('actions telemetry', () => { }, ], }, - }) + } ); const telemetry = await getTotalCount(mockEsClient, 'test'); @@ -116,9 +116,9 @@ Object { test('getInUseTotalCount', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValueOnce( + mockEsClient.search.mockResponseOnce( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { refs: { actionRefIds: { @@ -132,36 +132,35 @@ Object { hits: [], }, }, - }) + } ); - mockEsClient.search.mockReturnValueOnce( - // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _source: { - action: { - id: '1', - actionTypeId: '.server-log', - }, - namespaces: ['default'], + mockEsClient.search.mockResponse({ + hits: { + hits: [ + // @ts-expect-error not full search response + { + _source: { + action: { + id: '1', + actionTypeId: '.server-log', }, + namespaces: ['default'], }, - { - _source: { - action: { - id: '2', - actionTypeId: '.slack', - }, - namespaces: ['default'], + }, + // @ts-expect-error not full search response + { + _source: { + action: { + id: '2', + actionTypeId: '.slack', }, + namespaces: ['default'], }, - ], - }, - }) - ); + }, + ], + }, + }); const telemetry = await getInUseTotalCount(mockEsClient, 'test'); expect(mockEsClient.search).toHaveBeenCalledTimes(2); @@ -181,9 +180,9 @@ Object { test('getInUseTotalCount should count preconfigured alert history connector usage', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValueOnce( + mockEsClient.search.mockResponseOnce( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { refs: { actionRefIds: { @@ -211,35 +210,34 @@ Object { }, }, }, - }) + } ); - mockEsClient.search.mockReturnValueOnce( - // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _source: { - action: { - id: '1', - actionTypeId: '.server-log', - }, - namespaces: ['default'], + mockEsClient.search.mockResponseOnce({ + hits: { + hits: [ + // @ts-expect-error not full search response + { + _source: { + action: { + id: '1', + actionTypeId: '.server-log', }, + namespaces: ['default'], }, - { - _source: { - action: { - id: '2', - actionTypeId: '.slack', - }, - namespaces: ['default'], + }, + // @ts-expect-error not full search response + { + _source: { + action: { + id: '2', + actionTypeId: '.slack', }, + namespaces: ['default'], }, - ], - }, - }) - ); + }, + ], + }, + }); const telemetry = await getInUseTotalCount(mockEsClient, 'test', undefined, [ { id: 'test', @@ -281,9 +279,9 @@ Object { test('getTotalCount accounts for preconfigured connectors', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockResponse( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { byActionTypeId: { value: { @@ -364,7 +362,7 @@ Object { }, ], }, - }) + } ); const telemetry = await getTotalCount(mockEsClient, 'test', [ { @@ -401,9 +399,9 @@ Object { test('getInUseTotalCount() accounts for preconfigured connectors', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValueOnce( + mockEsClient.search.mockResponseOnce( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { refs: { actionRefIds: { @@ -439,44 +437,44 @@ Object { }, }, }, - }) + } ); - mockEsClient.search.mockReturnValueOnce( - // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _source: { - action: { - id: '1', - actionTypeId: '.server-log', - }, - namespaces: ['default'], + mockEsClient.search.mockResponseOnce({ + hits: { + hits: [ + // @ts-expect-error not full search response + { + _source: { + action: { + id: '1', + actionTypeId: '.server-log', }, + namespaces: ['default'], }, - { - _source: { - action: { - id: '2', - actionTypeId: '.slack', - }, - namespaces: ['default'], + }, + // @ts-expect-error not full search response + { + _source: { + action: { + id: '2', + actionTypeId: '.slack', }, + namespaces: ['default'], }, - { - _source: { - action: { - id: '3', - actionTypeId: '.email', - }, - namespaces: ['default'], + }, + // @ts-expect-error not full search response + { + _source: { + action: { + id: '3', + actionTypeId: '.email', }, + namespaces: ['default'], }, - ], - }, - }) - ); + }, + ], + }, + }); const telemetry = await getInUseTotalCount(mockEsClient, 'test', undefined, [ { id: 'anotherServerLog', @@ -508,9 +506,9 @@ Object { test('getInUseTotalCount() accounts for actions namespaces', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValueOnce( + mockEsClient.search.mockResponseOnce( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { refs: { actionRefIds: { @@ -546,44 +544,44 @@ Object { }, }, }, - }) + } ); - mockEsClient.search.mockReturnValueOnce( - // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _source: { - action: { - id: '1', - actionTypeId: '.server-log', - }, - namespaces: ['test'], + mockEsClient.search.mockResponseOnce({ + hits: { + hits: [ + // @ts-expect-error not full search response + { + _source: { + action: { + id: '1', + actionTypeId: '.server-log', }, + namespaces: ['test'], }, - { - _source: { - action: { - id: '2', - actionTypeId: '.slack', - }, - namespaces: ['default'], + }, + // @ts-expect-error not full search response + { + _source: { + action: { + id: '2', + actionTypeId: '.slack', }, + namespaces: ['default'], }, - { - _source: { - action: { - id: '3', - actionTypeId: '.email', - }, - namespaces: ['test2'], + }, + // @ts-expect-error not full search response + { + _source: { + action: { + id: '3', + actionTypeId: '.email', }, + namespaces: ['test2'], }, - ], - }, - }) - ); + }, + ], + }, + }); const telemetry = await getInUseTotalCount(mockEsClient, 'test'); expect(mockEsClient.search).toHaveBeenCalledTimes(2); @@ -607,9 +605,9 @@ Object { test('getExecutionsTotalCount', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValueOnce( + mockEsClient.search.mockResponseOnce( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { totalExecutions: { byConnectorTypeId: { @@ -668,17 +666,17 @@ Object { }, }, }, - }) + } ); // for .slack connectors - mockEsClient.search.mockReturnValueOnce( + mockEsClient.search.mockResponseOnce( // @ts-expect-error not full search response - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { avgDuration: { value: 10 }, }, - }) + } ); const telemetry = await getExecutionsPerDayCount(mockEsClient, 'test'); diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.ts index d288611af5e21..473c440ed37fb 100644 --- a/x-pack/plugins/actions/server/usage/actions_telemetry.ts +++ b/x-pack/plugins/actions/server/usage/actions_telemetry.ts @@ -41,7 +41,7 @@ export async function getTotalCount( }, }; - const { body: searchResult } = await esClient.search({ + const searchResult = await esClient.search({ index: kibanaIndex, size: 0, body: { @@ -223,7 +223,7 @@ export async function getInUseTotalCount( }); } - const { body: actionResults } = await esClient.search({ + const actionResults = await esClient.search({ index: kibanaIndex, size: 0, body: { @@ -268,9 +268,7 @@ export async function getInUseTotalCount( // @ts-expect-error aggegation type is not specified actionResults.aggregations.preconfigured_actions?.preconfiguredActionRefIds.value; - const { - body: { hits: actions }, - } = await esClient.search<{ + const { hits: actions } = await esClient.search<{ action: ActionResult; namespaces: string[]; }>({ @@ -394,8 +392,8 @@ export async function getExecutionsPerDayCount( scripted_metric: { init_script: 'state.connectorTypes = [:]; state.total = 0;', map_script: ` - if (doc['kibana.saved_objects.type'].value == 'action') { - String connectorType = doc['kibana.saved_objects.type_id'].value; + if (doc['kibana.saved_objects.type'].value == 'action') { + String connectorType = doc['kibana.saved_objects.type_id'].value; state.connectorTypes.put(connectorType, state.connectorTypes.containsKey(connectorType) ? state.connectorTypes.get(connectorType) + 1 : 1); state.total++; } @@ -424,7 +422,7 @@ export async function getExecutionsPerDayCount( }, }; - const { body: actionResults } = await esClient.search({ + const actionResults = await esClient.search({ index: eventLogIndex, size: 0, body: { diff --git a/x-pack/plugins/alerting/server/lib/create_abortable_es_client_factory.test.ts b/x-pack/plugins/alerting/server/lib/create_abortable_es_client_factory.test.ts index ed334e262a3a2..d6ac850e59214 100644 --- a/x-pack/plugins/alerting/server/lib/create_abortable_es_client_factory.test.ts +++ b/x-pack/plugins/alerting/server/lib/create_abortable_es_client_factory.test.ts @@ -32,6 +32,7 @@ describe('createAbortableEsClientFactory', () => { await abortableSearchClient.asInternalUser.search(esQuery); expect(scopedClusterClient.asInternalUser.search).toHaveBeenCalledWith(esQuery, { signal: abortController.signal, + meta: true, }); expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); }); @@ -47,6 +48,7 @@ describe('createAbortableEsClientFactory', () => { await abortableSearchClient.asCurrentUser.search(esQuery); expect(scopedClusterClient.asCurrentUser.search).toHaveBeenCalledWith(esQuery, { signal: abortController.signal, + meta: true, }); expect(scopedClusterClient.asInternalUser.search).not.toHaveBeenCalled(); }); @@ -63,6 +65,7 @@ describe('createAbortableEsClientFactory', () => { expect(scopedClusterClient.asInternalUser.search).toHaveBeenCalledWith(esQuery, { ignore: [404], signal: abortController.signal, + meta: true, }); expect(scopedClusterClient.asCurrentUser.search).not.toHaveBeenCalled(); }); diff --git a/x-pack/plugins/alerting/server/lib/create_abortable_es_client_factory.ts b/x-pack/plugins/alerting/server/lib/create_abortable_es_client_factory.ts index ded375c7de9d4..a24ad544557d6 100644 --- a/x-pack/plugins/alerting/server/lib/create_abortable_es_client_factory.ts +++ b/x-pack/plugins/alerting/server/lib/create_abortable_es_client_factory.ts @@ -24,6 +24,7 @@ export interface IAbortableClusterClient { readonly asInternalUser: IAbortableEsClient; readonly asCurrentUser: IAbortableEsClient; } + export interface CreateAbortableEsClientFactoryOpts { scopedClusterClient: IScopedClusterClient; abortController: AbortController; @@ -42,6 +43,7 @@ export function createAbortableEsClientFactory(opts: CreateAbortableEsClientFact return await scopedClusterClient.asInternalUser.search(query, { ...searchOptions, signal: abortController.signal, + meta: true, }); } catch (e) { if (abortController.signal.aborted) { @@ -61,6 +63,7 @@ export function createAbortableEsClientFactory(opts: CreateAbortableEsClientFact return await scopedClusterClient.asCurrentUser.search(query, { ...searchOptions, signal: abortController.signal, + meta: true, }); } catch (e) { if (abortController.signal.aborted) { diff --git a/x-pack/plugins/alerting/server/usage/alerting_telemetry.test.ts b/x-pack/plugins/alerting/server/usage/alerting_telemetry.test.ts index d679c140733c2..4e34fc2a04f30 100644 --- a/x-pack/plugins/alerting/server/usage/alerting_telemetry.test.ts +++ b/x-pack/plugins/alerting/server/usage/alerting_telemetry.test.ts @@ -20,9 +20,9 @@ import { describe('alerting telemetry', () => { test('getTotalCountInUse should replace "." symbols with "__" in rule types names', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockResponse( // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { byRuleTypeId: { value: { @@ -40,7 +40,7 @@ describe('alerting telemetry', () => { hits: { hits: [], }, - }) + } ); const telemetry = await getTotalCountInUse(mockEsClient, 'test'); @@ -62,9 +62,9 @@ Object { test('getTotalCountAggregations should return min/max connectors in use', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockResponse( // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { byRuleTypeId: { value: { @@ -88,7 +88,7 @@ Object { hits: { hits: [], }, - }) + } ); const telemetry = await getTotalCountAggregations(mockEsClient, 'test'); @@ -135,9 +135,9 @@ Object { test('getExecutionsPerDayCount should return execution aggregations for total count, count by rule type and number of failed executions', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockResponse( // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { byRuleTypeId: { value: { @@ -169,7 +169,7 @@ Object { hits: { hits: [], }, - }) + } ); const telemetry = await getExecutionsPerDayCount(mockEsClient, 'test'); @@ -205,9 +205,9 @@ Object { test('getExecutionTimeoutsPerDayCount should return execution aggregations for total timeout count and count by rule type', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockResponse( // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { byRuleTypeId: { value: { @@ -222,7 +222,7 @@ Object { hits: { hits: [], }, - }) + } ); const telemetry = await getExecutionTimeoutsPerDayCount(mockEsClient, 'test'); @@ -241,9 +241,9 @@ Object { test('getFailedAndUnrecognizedTasksPerDay should aggregations for total count, count by status and count by status and rule type for failed and unrecognized tasks', async () => { const mockEsClient = elasticsearchClientMock.createClusterClient().asScoped().asInternalUser; - mockEsClient.search.mockReturnValue( + mockEsClient.search.mockResponse( // @ts-expect-error @elastic/elasticsearch Aggregate only allows unknown values - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { byTaskTypeId: { value: { @@ -263,7 +263,7 @@ Object { hits: { hits: [], }, - }) + } ); const telemetry = await getFailedAndUnrecognizedTasksPerDay(mockEsClient, 'test'); diff --git a/x-pack/plugins/alerting/server/usage/alerting_telemetry.ts b/x-pack/plugins/alerting/server/usage/alerting_telemetry.ts index 15d6650b2cb4b..b77083c62f000 100644 --- a/x-pack/plugins/alerting/server/usage/alerting_telemetry.ts +++ b/x-pack/plugins/alerting/server/usage/alerting_telemetry.ts @@ -43,7 +43,7 @@ const ruleTypeExecutionsWithDurationMetric = { init_script: 'state.ruleTypes = [:]; state.ruleTypesDuration = [:];', map_script: ` String ruleType = doc['rule.category'].value; - long duration = doc['event.duration'].value / (1000 * 1000); + long duration = doc['event.duration'].value / (1000 * 1000); state.ruleTypes.put(ruleType, state.ruleTypes.containsKey(ruleType) ? state.ruleTypes.get(ruleType) + 1 : 1); state.ruleTypesDuration.put(ruleType, state.ruleTypesDuration.containsKey(ruleType) ? state.ruleTypesDuration.get(ruleType) + duration : duration); `, @@ -125,12 +125,12 @@ const ruleTypeFailureExecutionsMetric = { scripted_metric: { init_script: 'state.reasons = [:]', map_script: ` - if (doc['event.outcome'].value == 'failure') { - String reason = doc['event.reason'].value; - String ruleType = doc['rule.category'].value; - Map ruleTypes = state.reasons.containsKey(reason) ? state.reasons.get(reason) : [:]; - ruleTypes.put(ruleType, ruleTypes.containsKey(ruleType) ? ruleTypes.get(ruleType) + 1 : 1); - state.reasons.put(reason, ruleTypes); + if (doc['event.outcome'].value == 'failure') { + String reason = doc['event.reason'].value; + String ruleType = doc['rule.category'].value; + Map ruleTypes = state.reasons.containsKey(reason) ? state.reasons.get(reason) : [:]; + ruleTypes.put(ruleType, ruleTypes.containsKey(ruleType) ? ruleTypes.get(ruleType) + 1 : 1); + state.reasons.put(reason, ruleTypes); } `, // Combine script is executed per cluster, but we already have a key-value pair per cluster. @@ -168,7 +168,7 @@ export async function getTotalCountAggregations( | 'count_rules_namespaces' > > { - const { body: results } = await esClient.search({ + const results = await esClient.search({ index: kibanaIndex, body: { size: 0, @@ -182,13 +182,13 @@ export async function getTotalCountAggregations( type: 'long', script: { source: ` - def alert = params._source['alert']; - if (alert != null) { - def actions = alert.actions; - if (actions != null) { - emit(actions.length); - } else { - emit(0); + def alert = params._source['alert']; + if (alert != null) { + def actions = alert.actions; + if (actions != null) { + emit(actions.length); + } else { + emit(0); } }`, }, @@ -331,7 +331,7 @@ export async function getTotalCountAggregations( } export async function getTotalCountInUse(esClient: ElasticsearchClient, kibanaIndex: string) { - const { body: searchResult } = await esClient.search({ + const searchResult = await esClient.search({ index: kibanaIndex, size: 0, body: { @@ -367,7 +367,7 @@ export async function getExecutionsPerDayCount( esClient: ElasticsearchClient, eventLogIndex: string ) { - const { body: searchResult } = await esClient.search({ + const searchResult = await esClient.search({ index: eventLogIndex, size: 0, body: { @@ -489,7 +489,7 @@ export async function getExecutionTimeoutsPerDayCount( esClient: ElasticsearchClient, eventLogIndex: string ) { - const { body: searchResult } = await esClient.search({ + const searchResult = await esClient.search({ index: eventLogIndex, size: 0, body: { @@ -544,7 +544,7 @@ export async function getFailedAndUnrecognizedTasksPerDay( esClient: ElasticsearchClient, taskManagerIndex: string ) { - const { body: searchResult } = await esClient.search({ + const searchResult = await esClient.search({ index: taskManagerIndex, size: 0, body: { diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts index bdbb1fe1dbcd3..310e9c30c71e0 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts @@ -76,14 +76,21 @@ export async function createApmTelemetry({ }); const search: CollectTelemetryParams['search'] = (params) => - unwrapEsResponse(esClient.asInternalUser.search(params)) as any; + unwrapEsResponse( + esClient.asInternalUser.search(params, { meta: true }) + ) as any; const indicesStats: CollectTelemetryParams['indicesStats'] = (params) => - unwrapEsResponse(esClient.asInternalUser.indices.stats(params)); + unwrapEsResponse( + esClient.asInternalUser.indices.stats(params, { meta: true }) + ); const transportRequest: CollectTelemetryParams['transportRequest'] = ( params - ) => unwrapEsResponse(esClient.asInternalUser.transport.request(params)); + ) => + unwrapEsResponse( + esClient.asInternalUser.transport.request(params, { meta: true }) + ); const dataTelemetry = await collectDataTelemetry({ search, diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts index 6e09e2aecfd48..ac801367662fc 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts @@ -118,7 +118,10 @@ export class APMEventClient { const searchPromise = withApmSpan(operationName, () => { const controller = new AbortController(); return cancelEsRequestOnAbort( - this.esClient.search(searchParams, { signal: controller.signal }), + this.esClient.search(searchParams, { + signal: controller.signal, + meta: true, + }), this.request, controller ); @@ -161,7 +164,7 @@ export class APMEventClient { index: Array.isArray(index) ? index.join(',') : index, ...rest, }, - { signal: controller.signal } + { signal: controller.signal, meta: true } ), this.request, controller 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 621f65f74d9f4..bd54c0916ef96 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 @@ -72,14 +72,14 @@ export function createInternalESClient({ ): Promise> => { return callEs(operationName, { requestType: 'search', - cb: (signal) => asInternalUser.search(params, { signal }), + cb: (signal) => asInternalUser.search(params, { signal, meta: true }), params, }); }, index: (operationName: string, params: APMIndexDocumentParams) => { return callEs(operationName, { requestType: 'index', - cb: (signal) => asInternalUser.index(params, { signal }), + cb: (signal) => asInternalUser.index(params, { signal, meta: true }), params, }); }, @@ -89,7 +89,7 @@ export function createInternalESClient({ ): Promise<{ result: string }> => { return callEs(operationName, { requestType: 'delete', - cb: (signal) => asInternalUser.delete(params, { signal }), + cb: (signal) => asInternalUser.delete(params, { signal, meta: true }), params, }); }, @@ -99,7 +99,8 @@ export function createInternalESClient({ ) => { return callEs(operationName, { requestType: 'indices.create', - cb: (signal) => asInternalUser.indices.create(params, { signal }), + cb: (signal) => + asInternalUser.indices.create(params, { signal, meta: true }), params, }); }, diff --git a/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts b/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts index 9cde37d1d93f7..9e7eb1ea8c021 100644 --- a/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts +++ b/x-pack/plugins/apm/server/lib/helpers/setup_request.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { elasticsearchServiceMock } from '../../../../../../src/core/server/mocks'; import { setupRequest } from './setup_request'; import { APMConfig } from '../..'; import { APMRouteHandlerResources } from '../../routes/typings'; @@ -32,14 +33,11 @@ jest.mock('../../routes/data_view/get_dynamic_data_view', () => ({ })); function getMockResources() { - const esClientMock = { - asCurrentUser: { - search: jest.fn().mockResolvedValue({ body: {} }), - }, - asInternalUser: { - search: jest.fn().mockResolvedValue({ body: {} }), - }, - }; + const esClientMock = elasticsearchServiceMock.createScopedClusterClient(); + // @ts-expect-error incomplete definition + esClientMock.asCurrentUser.search.mockResponse({}); + // @ts-expect-error incomplete definition + esClientMock.asInternalUser.search.mockResponse({}); const mockResources = { config: new Proxy( @@ -135,6 +133,7 @@ describe('setupRequest', () => { }, { signal: expect.any(Object), + meta: true, } ); }); @@ -157,6 +156,7 @@ describe('setupRequest', () => { }, { signal: expect.any(Object), + meta: true, } ); }); @@ -177,6 +177,7 @@ describe('setupRequest', () => { const params = mockResources.context.core.elasticsearch.client.asCurrentUser.search .mock.calls[0][0]; + // @ts-expect-error missing body definition expect(params.body).toEqual({ query: { bool: { @@ -205,6 +206,7 @@ describe('setupRequest', () => { const params = mockResources.context.core.elasticsearch.client.asCurrentUser.search .mock.calls[0][0]; + // @ts-expect-error missing body definition expect(params.body).toEqual({ query: { bool: { @@ -235,6 +237,7 @@ describe('without a bool filter', () => { const params = mockResources.context.core.elasticsearch.client.asCurrentUser.search.mock .calls[0][0]; + // @ts-expect-error missing body definition expect(params.body).toEqual({ query: { bool: { @@ -266,6 +269,7 @@ describe('with includeFrozen=false', () => { const params = mockResources.context.core.elasticsearch.client.asCurrentUser.search.mock .calls[0][0]; + // @ts-expect-error missing body definition expect(params.ignore_throttled).toBe(undefined); }); }); @@ -286,6 +290,7 @@ describe('with includeFrozen=true', () => { const params = mockResources.context.core.elasticsearch.client.asCurrentUser.search.mock .calls[0][0]; + // @ts-expect-error missing body definition expect(params.ignore_throttled).toBe(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 d83a7af2737cd..3b47b81a86416 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 @@ -7,25 +7,9 @@ import Boom from '@hapi/boom'; import { ApmPluginRequestHandlerContext } from '../typings'; -import { CreateApiKeyResponse } from '../../../common/agent_key_types'; -import { PrivilegeType } from '../../../common/privilege_type'; const resource = '*'; -interface SecurityHasPrivilegesResponse { - application: { - apm: { - [resource]: { - [PrivilegeType.SOURCEMAP]: boolean; - [PrivilegeType.EVENT]: boolean; - [PrivilegeType.AGENT_CONFIG]: boolean; - }; - }; - }; - has_all_requested: boolean; - username: string; -} - export async function createAgentKey({ context, requestBody, @@ -46,12 +30,10 @@ export async function createAgentKey({ // 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 const { - body: { - application: userApplicationPrivileges, - username, - has_all_requested: hasRequiredPrivileges, - }, - } = await context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges( + application: userApplicationPrivileges, + username, + has_all_requested: hasRequiredPrivileges, + } = await context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges( { body: { application: [application], @@ -97,8 +79,8 @@ export async function createAgentKey({ }, }; - const { body: agentKey } = - await context.core.elasticsearch.client.asCurrentUser.security.createApiKey( + const agentKey = + await context.core.elasticsearch.client.asCurrentUser.security.createApiKey( { body, } 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 9c5b3e04c94f2..dff7b3b5c32ab 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 @@ -36,7 +36,7 @@ export async function getAgentKeys({ body, }); - const agentKeys = apiResponse.body.api_keys.filter( + const agentKeys = apiResponse.api_keys.filter( ({ invalidated }) => !invalidated ); return { 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 4aed9314f433c..29514739f2225 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 @@ -8,14 +8,6 @@ import { ApmPluginRequestHandlerContext } from '../typings'; import { APMPluginStartDependencies } from '../../types'; -interface SecurityHasPrivilegesResponse { - cluster: { - manage_security: boolean; - manage_api_key: boolean; - manage_own_api_key: boolean; - }; -} - export async function getAgentKeysPrivileges({ context, securityPluginStart, @@ -24,23 +16,19 @@ export async function getAgentKeysPrivileges({ securityPluginStart: NonNullable; }) { const [securityHasPrivilegesResponse, areApiKeysEnabled] = await Promise.all([ - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges( - { - body: { - cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'], - }, - } - ), + context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + body: { + cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'], + }, + }), securityPluginStart.authc.apiKeys.areAPIKeysEnabled(), ]); const { - body: { - cluster: { - manage_security: manageSecurity, - manage_api_key: manageApiKey, - manage_own_api_key: manageOwnApiKey, - }, + cluster: { + manage_security: manageSecurity, + manage_api_key: manageApiKey, + manage_own_api_key: manageOwnApiKey, }, } = securityHasPrivilegesResponse; 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 1ccb63382de4e..99c5008718403 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 @@ -13,16 +13,15 @@ export async function invalidateAgentKey({ context: ApmPluginRequestHandlerContext; id: string; }) { - const { - body: { invalidated_api_keys: invalidatedAgentKeys }, - } = await context.core.elasticsearch.client.asCurrentUser.security.invalidateApiKey( - { - body: { - ids: [id], - owner: true, - }, - } - ); + const { invalidated_api_keys: invalidatedAgentKeys } = + await context.core.elasticsearch.client.asCurrentUser.security.invalidateApiKey( + { + body: { + ids: [id], + owner: true, + }, + } + ); return { invalidatedAgentKeys, diff --git a/x-pack/plugins/apm/server/routes/alerts/alerting_es_client.ts b/x-pack/plugins/apm/server/routes/alerts/alerting_es_client.ts index 9445a0f0610f6..876d02137c3f8 100644 --- a/x-pack/plugins/apm/server/routes/alerts/alerting_es_client.ts +++ b/x-pack/plugins/apm/server/routes/alerts/alerting_es_client.ts @@ -27,5 +27,5 @@ export async function alertingEsClient({ ignore_unavailable: true, }); - return response.body as unknown as ESSearchResponse; + return response as unknown as ESSearchResponse; } diff --git a/x-pack/plugins/apm/server/routes/alerts/register_error_count_alert_type.test.ts b/x-pack/plugins/apm/server/routes/alerts/register_error_count_alert_type.test.ts index 01aa64b85f720..e1e807c05400c 100644 --- a/x-pack/plugins/apm/server/routes/alerts/register_error_count_alert_type.test.ts +++ b/x-pack/plugins/apm/server/routes/alerts/register_error_count_alert_type.test.ts @@ -6,8 +6,6 @@ */ import { registerErrorCountAlertType } from './register_error_count_alert_type'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { createRuleTypeMocks } from './test_utils'; describe('Error count alert', () => { @@ -18,25 +16,23 @@ describe('Error count alert', () => { const params = { threshold: 1 }; - services.scopedClusterClient.asCurrentUser.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [], - total: { - relation: 'eq', - value: 0, - }, + services.scopedClusterClient.asCurrentUser.search.mockResponse({ + hits: { + hits: [], + total: { + relation: 'eq', + value: 0, }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - skipped: 0, - successful: 1, - total: 1, - }, - }) - ); + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }); await executor({ params }); expect(services.alertFactory.create).not.toBeCalled(); @@ -50,87 +46,85 @@ describe('Error count alert', () => { const params = { threshold: 2, windowSize: 5, windowUnit: 'm' }; - services.scopedClusterClient.asCurrentUser.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [], - total: { - relation: 'eq', - value: 2, - }, + services.scopedClusterClient.asCurrentUser.search.mockResponse({ + hits: { + hits: [], + total: { + relation: 'eq', + value: 2, }, - aggregations: { - error_counts: { - buckets: [ - { - key: ['foo', 'env-foo'], - doc_count: 5, - latest: { - top: [ - { - metrics: { - 'service.name': 'foo', - 'service.environment': 'env-foo', - }, + }, + aggregations: { + error_counts: { + buckets: [ + { + key: ['foo', 'env-foo'], + doc_count: 5, + latest: { + top: [ + { + metrics: { + 'service.name': 'foo', + 'service.environment': 'env-foo', }, - ], - }, + }, + ], }, - { - key: ['foo', 'env-foo-2'], - doc_count: 4, - latest: { - top: [ - { - metrics: { - 'service.name': 'foo', - 'service.environment': 'env-foo-2', - }, + }, + { + key: ['foo', 'env-foo-2'], + doc_count: 4, + latest: { + top: [ + { + metrics: { + 'service.name': 'foo', + 'service.environment': 'env-foo-2', }, - ], - }, + }, + ], }, - { - key: ['bar', 'env-bar'], - doc_count: 3, - latest: { - top: [ - { - metrics: { - 'service.name': 'bar', - 'service.environment': 'env-bar', - }, + }, + { + key: ['bar', 'env-bar'], + doc_count: 3, + latest: { + top: [ + { + metrics: { + 'service.name': 'bar', + 'service.environment': 'env-bar', }, - ], - }, + }, + ], }, - { - key: ['bar', 'env-bar-2'], - doc_count: 1, - latest: { - top: [ - { - metrics: { - 'service.name': 'bar', - 'service.environment': 'env-bar-2', - }, + }, + { + key: ['bar', 'env-bar-2'], + doc_count: 1, + latest: { + top: [ + { + metrics: { + 'service.name': 'bar', + 'service.environment': 'env-bar-2', }, - ], - }, + }, + ], }, - ], - }, + }, + ], }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - skipped: 0, - successful: 1, - total: 1, - }, - }) - ); + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }); await executor({ params }); [ diff --git a/x-pack/plugins/apm/server/routes/alerts/register_transaction_duration_alert_type.test.ts b/x-pack/plugins/apm/server/routes/alerts/register_transaction_duration_alert_type.test.ts index 956347098d787..debe14e41db11 100644 --- a/x-pack/plugins/apm/server/routes/alerts/register_transaction_duration_alert_type.test.ts +++ b/x-pack/plugins/apm/server/routes/alerts/register_transaction_duration_alert_type.test.ts @@ -7,8 +7,6 @@ import { registerTransactionDurationAlertType } from './register_transaction_duration_alert_type'; import { createRuleTypeMocks } from './test_utils'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; describe('registerTransactionDurationAlertType', () => { it('sends alert when value is greater than threashold', async () => { @@ -17,30 +15,28 @@ describe('registerTransactionDurationAlertType', () => { registerTransactionDurationAlertType(dependencies); - services.scopedClusterClient.asCurrentUser.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [], - total: { - relation: 'eq', - value: 2, - }, + services.scopedClusterClient.asCurrentUser.search.mockResponse({ + hits: { + hits: [], + total: { + relation: 'eq', + value: 2, }, - aggregations: { - latency: { - value: 5500000, - }, + }, + aggregations: { + latency: { + value: 5500000, }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - skipped: 0, - successful: 1, - total: 1, - }, - }) - ); + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }); const params = { threshold: 3000, diff --git a/x-pack/plugins/apm/server/routes/alerts/register_transaction_error_rate_alert_type.test.ts b/x-pack/plugins/apm/server/routes/alerts/register_transaction_error_rate_alert_type.test.ts index 64540e144d8a8..a054dcba53a3b 100644 --- a/x-pack/plugins/apm/server/routes/alerts/register_transaction_error_rate_alert_type.test.ts +++ b/x-pack/plugins/apm/server/routes/alerts/register_transaction_error_rate_alert_type.test.ts @@ -6,8 +6,6 @@ */ import { registerTransactionErrorRateAlertType } from './register_transaction_error_rate_alert_type'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { createRuleTypeMocks } from './test_utils'; describe('Transaction error rate alert', () => { @@ -20,30 +18,28 @@ describe('Transaction error rate alert', () => { const params = { threshold: 1 }; - services.scopedClusterClient.asCurrentUser.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [], - total: { - relation: 'eq', - value: 0, - }, + services.scopedClusterClient.asCurrentUser.search.mockResponse({ + hits: { + hits: [], + total: { + relation: 'eq', + value: 0, }, - took: 0, - timed_out: false, - aggregations: { - series: { - buckets: [], - }, + }, + took: 0, + timed_out: false, + aggregations: { + series: { + buckets: [], }, - _shards: { - failed: 0, - skipped: 0, - successful: 1, - total: 1, - }, - }) - ); + }, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }); await executor({ params }); expect(services.alertFactory.create).not.toBeCalled(); @@ -57,61 +53,59 @@ describe('Transaction error rate alert', () => { ...dependencies, }); - services.scopedClusterClient.asCurrentUser.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [], - total: { - relation: 'eq', - value: 0, - }, + services.scopedClusterClient.asCurrentUser.search.mockResponse({ + hits: { + hits: [], + total: { + relation: 'eq', + value: 0, }, - aggregations: { - series: { - buckets: [ - { - key: ['foo', 'env-foo', 'type-foo'], - outcomes: { - buckets: [ - { - key: 'success', - doc_count: 90, - }, - { - key: 'failure', - doc_count: 10, - }, - ], - }, + }, + aggregations: { + series: { + buckets: [ + { + key: ['foo', 'env-foo', 'type-foo'], + outcomes: { + buckets: [ + { + key: 'success', + doc_count: 90, + }, + { + key: 'failure', + doc_count: 10, + }, + ], }, - { - key: ['bar', 'env-bar', 'type-bar'], - outcomes: { - buckets: [ - { - key: 'success', - doc_count: 90, - }, - { - key: 'failure', - doc_count: 1, - }, - ], - }, + }, + { + key: ['bar', 'env-bar', 'type-bar'], + outcomes: { + buckets: [ + { + key: 'success', + doc_count: 90, + }, + { + key: 'failure', + doc_count: 1, + }, + ], }, - ], - }, + }, + ], }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - skipped: 0, - successful: 1, - total: 1, - }, - }) - ); + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + skipped: 0, + successful: 1, + total: 1, + }, + }); const params = { threshold: 10, windowSize: 5, windowUnit: 'm' }; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_boolean_field_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_boolean_field_stats.ts index 9fe1c1f882f1d..13910ef7104fb 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_boolean_field_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_boolean_field_stats.ts @@ -72,7 +72,7 @@ export const fetchBooleanFieldStats = async ( field.fieldName, termFilters ); - const { body } = await esClient.search(request); + const body = await esClient.search(request); const aggregations = body.aggregations; const stats: BooleanFieldStats = { fieldName: field.fieldName, diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_field_stats.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_field_stats.test.ts index 30bebc4c24774..1c979bc3e4c6d 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_field_stats.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_field_stats.test.ts @@ -99,31 +99,23 @@ describe('field_stats', () => { describe('fetchFieldsStats', () => { it('returns field candidates and total hits', async () => { const fieldsCaps = { - body: { - fields: { - myIpFieldName: { ip: {} }, - myKeywordFieldName: { keyword: {} }, - myMultiFieldName: { keyword: {}, text: {} }, - myHistogramFieldName: { histogram: {} }, - myNumericFieldName: { number: {} }, - }, + fields: { + myIpFieldName: { ip: {} }, + myKeywordFieldName: { keyword: {} }, + myMultiFieldName: { keyword: {}, text: {} }, + myHistogramFieldName: { histogram: {} }, + myNumericFieldName: { number: {} }, }, }; const esClientFieldCapsMock = jest.fn(() => fieldsCaps); - const fieldsToSample = Object.keys(fieldsCaps.body.fields); + const fieldsToSample = Object.keys(fieldsCaps.fields); const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - aggregations: { sample: {} }, - } as unknown as estypes.SearchResponse, - }; + aggregations: { sample: {} }, + } as unknown as estypes.SearchResponse; } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_field_value_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_field_value_stats.ts index 709e2ad4a99fd..c500d1d49dd6e 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_field_value_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_field_value_stats.ts @@ -55,7 +55,7 @@ export const fetchFieldValueFieldStats = async ( ): Promise => { const request = getFieldValueFieldStatsRequest(params, field); - const { body } = await esClient.search(request); + const body = await esClient.search(request); const aggregations = body.aggregations as { filtered_count: estypes.AggregationsSingleBucketAggregateBase; }; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_fields_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_fields_stats.ts index 513252ee65e11..e44996337f4b1 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_fields_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_fields_stats.ts @@ -34,7 +34,7 @@ export const fetchFieldsStats = async ( fields: fieldsToSample, }); - const fieldStatsPromises = Object.entries(respMapping.body.fields) + const fieldStatsPromises = Object.entries(respMapping.fields) .map(([key, value], idx) => { const field: FieldValuePair = { fieldName: key, fieldValue: '' }; const fieldTypes = Object.keys(value); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_keyword_field_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_keyword_field_stats.ts index 55ead5230e951..35b8eab5712ec 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_keyword_field_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_keyword_field_stats.ts @@ -52,6 +52,7 @@ interface SampledTopAggs extends estypes.AggregationsTermsAggregateBase { buckets: TopValueBucket[]; } + export const fetchKeywordFieldStats = async ( esClient: ElasticsearchClient, params: FieldStatsCommonRequestParams, @@ -63,10 +64,9 @@ export const fetchKeywordFieldStats = async ( field.fieldName, termFilters ); - const { body } = await esClient.search< - unknown, - { sampled_top: SampledTopAggs } - >(request); + const body = await esClient.search( + request + ); const aggregations = body.aggregations; const topValues = aggregations?.sampled_top?.buckets ?? []; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_numeric_field_stats.ts b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_numeric_field_stats.ts index 2adb4502e4043..192377b88a992 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_numeric_field_stats.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/field_stats/get_numeric_field_stats.ts @@ -82,7 +82,7 @@ export const fetchNumericFieldStats = async ( field.fieldName, termFilters ); - const { body } = await esClient.search(request); + const body = await esClient.search(request); const aggregations = body.aggregations; const docCount = aggregations?.sampled_field_stats?.doc_count ?? 0; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation.test.ts index 6cbf97a163871..8f5029c7a3e9e 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation.test.ts @@ -72,24 +72,18 @@ describe('query_correlation', () => { const KsTestLess = 0.01; const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - aggregations: { - latency_ranges: { - buckets: latencyRangesBuckets, - }, - transaction_duration_correlation: { - value: transactionDurationCorrelationValue, - }, - ks_test: { less: KsTestLess }, + aggregations: { + latency_ranges: { + buckets: latencyRangesBuckets, + }, + transaction_duration_correlation: { + value: transactionDurationCorrelationValue, }, - } as unknown as estypes.SearchResponse, - }; + ks_test: { less: KsTestLess }, + }, + } as unknown as estypes.SearchResponse; } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation.ts index caf1386fbf025..c859853f6896b 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation.ts @@ -123,16 +123,16 @@ export const fetchTransactionDurationCorrelation = async ( ) ); - if (resp.body.aggregations === undefined) { + if (resp.aggregations === undefined) { throw new Error( 'fetchTransactionDurationCorrelation failed, did not return aggregations.' ); } const result = { - ranges: resp.body.aggregations.latency_ranges.buckets, - correlation: resp.body.aggregations.transaction_duration_correlation.value, - ksTest: resp.body.aggregations.ks_test.less, + ranges: resp.aggregations.latency_ranges.buckets, + correlation: resp.aggregations.transaction_duration_correlation.value, + ksTest: resp.aggregations.ks_test.less, }; return result; }; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation_with_histogram.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation_with_histogram.test.ts index 2e1a635671794..10994c6c017e0 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation_with_histogram.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation_with_histogram.test.ts @@ -38,14 +38,8 @@ describe('query_correlation_with_histogram', () => { describe('fetchTransactionDurationCorrelationWithHistogram', () => { it(`doesn't break on failing ES queries and adds messages to the log`, async () => { const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { - return { - body: {} as unknown as estypes.SearchResponse, - }; + (req: estypes.SearchRequest): Promise => { + return Promise.resolve({} as unknown as estypes.SearchResponse); } ); @@ -81,21 +75,15 @@ describe('query_correlation_with_histogram', () => { it('returns items with correlation and ks-test value', async () => { const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { - return { - body: { - aggregations: { - latency_ranges: { buckets: [] }, - transaction_duration_correlation: { value: 0.6 }, - ks_test: { less: 0.001 }, - logspace_ranges: { buckets: [] }, - }, - } as unknown as estypes.SearchResponse, - }; + (req: estypes.SearchRequest): Promise => { + return Promise.resolve({ + aggregations: { + latency_ranges: { buckets: [] }, + transaction_duration_correlation: { value: 0.6 }, + ks_test: { less: 0.001 }, + logspace_ranges: { buckets: [] }, + }, + } as unknown as estypes.SearchResponse); } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_failure_correlation.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_failure_correlation.ts index f50a610aeac71..46a980a53ab48 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_failure_correlation.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_failure_correlation.ts @@ -80,13 +80,13 @@ export const fetchFailedTransactionsCorrelationPValues = async ( getFailureCorrelationRequest(params, fieldName) ); - if (resp.body.aggregations === undefined) { + if (resp.aggregations === undefined) { throw new Error( 'fetchErrorCorrelation failed, did not return aggregations.' ); } - const overallResult = resp.body.aggregations.failure_p_value; + const overallResult = resp.aggregations.failure_p_value; // Using for of to sequentially augment the results with histogram data. const result: FailedTransactionsCorrelation[] = []; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_field_candidates.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_field_candidates.test.ts index 957e2393558ed..0ecbd6477fda7 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_field_candidates.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_field_candidates.test.ts @@ -97,36 +97,28 @@ describe('query_field_candidates', () => { describe('fetchTransactionDurationFieldCandidates', () => { it('returns field candidates and total hits', async () => { const esClientFieldCapsMock = jest.fn(() => ({ - body: { - fields: { - myIpFieldName: { ip: {} }, - myKeywordFieldName: { keyword: {} }, - myUnpopulatedKeywordFieldName: { keyword: {} }, - myNumericFieldName: { number: {} }, - }, + fields: { + myIpFieldName: { ip: {} }, + myKeywordFieldName: { keyword: {} }, + myUnpopulatedKeywordFieldName: { keyword: {} }, + myNumericFieldName: { number: {} }, }, })); const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - hits: { - hits: [ - { - fields: { - myIpFieldName: '1.1.1.1', - myKeywordFieldName: 'myKeywordFieldValue', - myNumericFieldName: 1234, - }, + hits: { + hits: [ + { + fields: { + myIpFieldName: '1.1.1.1', + myKeywordFieldName: 'myKeywordFieldValue', + myNumericFieldName: 1234, }, - ], - }, - } as unknown as estypes.SearchResponse, - }; + }, + ], + }, + } as unknown as estypes.SearchResponse; } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_field_candidates.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_field_candidates.ts index 801bb18e8957a..2d6347362e8ea 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_field_candidates.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_field_candidates.ts @@ -70,7 +70,7 @@ export const fetchTransactionDurationFieldCandidates = async ( const finalFieldCandidates = new Set(FIELDS_TO_ADD_AS_CANDIDATE); const acceptableFields: Set = new Set(); - Object.entries(respMapping.body.fields).forEach(([key, value]) => { + Object.entries(respMapping.fields).forEach(([key, value]) => { const fieldTypes = Object.keys(value) as ES_FIELD_TYPES[]; const isSupportedType = fieldTypes.some((type) => SUPPORTED_ES_FIELD_TYPES.includes(type) @@ -87,7 +87,7 @@ export const fetchTransactionDurationFieldCandidates = async ( }); const resp = await esClient.search(getRandomDocsRequest(params)); - const sampledDocs = resp.body.hits.hits.map((d) => d.fields ?? {}); + const sampledDocs = resp.hits.hits.map((d) => d.fields ?? {}); // Get all field names for each returned doc and flatten it // to a list of unique field names used across all docs diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_field_value_pairs.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_field_value_pairs.test.ts index 80016930184b3..4f7c44e5f3107 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_field_value_pairs.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_field_value_pairs.test.ts @@ -42,20 +42,14 @@ describe('query_field_value_pairs', () => { ]; const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - aggregations: { - attribute_terms: { - buckets: [{ key: 'myValue1' }, { key: 'myValue2' }], - }, + aggregations: { + attribute_terms: { + buckets: [{ key: 'myValue1' }, { key: 'myValue2' }], }, - } as unknown as estypes.SearchResponse, - }; + }, + } as unknown as estypes.SearchResponse; } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_field_value_pairs.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_field_value_pairs.ts index ac31985ecd190..6bcec359c157a 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_field_value_pairs.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_field_value_pairs.ts @@ -55,13 +55,13 @@ const fetchTransactionDurationFieldTerms = async ( getTermsAggRequest(params, fieldName) ); - if (resp.body.aggregations === undefined) { + if (resp.aggregations === undefined) { throw new Error( 'fetchTransactionDurationFieldTerms failed, did not return aggregations.' ); } - const buckets = resp.body.aggregations.attribute_terms?.buckets; + const buckets = resp.aggregations.attribute_terms?.buckets; if (buckets?.length >= 1) { return buckets.map((d) => ({ fieldName, diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_fractions.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_fractions.test.ts index 12b054e18bab7..d8fada32cb74c 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_fractions.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_fractions.test.ts @@ -40,21 +40,15 @@ describe('query_fractions', () => { describe('fetchTransactionDurationFractions', () => { it('computes the actual percentile bucket counts and actual fractions', async () => { const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - hits: { total: { value: 3 } }, - aggregations: { - latency_ranges: { - buckets: [{ doc_count: 1 }, { doc_count: 2 }], - }, + hits: { total: { value: 3 } }, + aggregations: { + latency_ranges: { + buckets: [{ doc_count: 1 }, { doc_count: 2 }], }, - } as unknown as estypes.SearchResponse, - }; + }, + } as unknown as estypes.SearchResponse; } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_fractions.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_fractions.ts index a4e9e0c13fa59..867a4defcb01b 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_fractions.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_fractions.ts @@ -52,20 +52,20 @@ export const fetchTransactionDurationFractions = async ( getTransactionDurationRangesRequest(params, ranges) ); - if ((resp.body.hits.total as estypes.SearchTotalHits).value === 0) { + if ((resp.hits.total as estypes.SearchTotalHits).value === 0) { return { fractions: [], totalDocCount: 0, }; } - if (resp.body.aggregations === undefined) { + if (resp.aggregations === undefined) { throw new Error( 'fetchTransactionDurationFractions failed, did not return aggregations.' ); } - const buckets = resp.body.aggregations.latency_ranges?.buckets; + const buckets = resp.aggregations.latency_ranges?.buckets; const totalDocCount = buckets.reduce((acc, bucket) => { return acc + bucket.doc_count; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram.test.ts index c9ea70452bdb0..7b60d93d0b745 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram.test.ts @@ -79,20 +79,14 @@ describe('query_histogram', () => { ]; const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - aggregations: { - transaction_duration_histogram: { - buckets: histogramBucket, - }, + aggregations: { + transaction_duration_histogram: { + buckets: histogramBucket, }, - } as unknown as estypes.SearchResponse, - }; + }, + } as unknown as estypes.SearchResponse; } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram.ts index 5f32e1ef7cf5b..943718c986a7a 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram.ts @@ -52,11 +52,11 @@ export const fetchTransactionDurationHistogram = async ( { transaction_duration_histogram: Aggs } >(getTransactionDurationHistogramRequest(params, interval, termFilters)); - if (resp.body.aggregations === undefined) { + if (resp.aggregations === undefined) { throw new Error( 'fetchTransactionDurationHistogram failed, did not return aggregations.' ); } - return resp.body.aggregations.transaction_duration_histogram.buckets ?? []; + return resp.aggregations.transaction_duration_histogram.buckets ?? []; }; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram_range_steps.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram_range_steps.test.ts index 526207beaabce..891c2af077e63 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram_range_steps.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram_range_steps.test.ts @@ -75,24 +75,18 @@ describe('query_histogram_range_steps', () => { describe('fetchTransactionDurationHistogramRangeSteps', () => { it('fetches the range steps for the log histogram', async () => { const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - hits: { total: { value: 10 } }, - aggregations: { - transaction_duration_max: { - value: 10000, - }, - transaction_duration_min: { - value: 10, - }, + hits: { total: { value: 10 } }, + aggregations: { + transaction_duration_max: { + value: 10000, }, - } as unknown as estypes.SearchResponse, - }; + transaction_duration_min: { + value: 10, + }, + }, + } as unknown as estypes.SearchResponse; } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram_range_steps.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram_range_steps.ts index 159b5379df194..d260a22fb6e84 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram_range_steps.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_histogram_range_steps.ts @@ -61,18 +61,18 @@ export const fetchTransactionDurationHistogramRangeSteps = async ( } >(getHistogramIntervalRequest(params)); - if ((resp.body.hits.total as estypes.SearchTotalHits).value === 0) { + if ((resp.hits.total as estypes.SearchTotalHits).value === 0) { return getHistogramRangeSteps(0, 1, 100); } - if (resp.body.aggregations === undefined) { + if (resp.aggregations === undefined) { throw new Error( 'fetchTransactionDurationHistogramRangeSteps failed, did not return aggregations.' ); } - const min = resp.body.aggregations.transaction_duration_min.value; - const max = resp.body.aggregations.transaction_duration_max.value * 2; + const min = resp.aggregations.transaction_duration_min.value; + const max = resp.aggregations.transaction_duration_max.value * 2; return getHistogramRangeSteps(min, max, steps); }; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_percentiles.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_percentiles.test.ts index 4e637d1ca6f4a..876225179aaa7 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_percentiles.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_percentiles.test.ts @@ -85,24 +85,17 @@ describe('query_percentiles', () => { }; const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - hits: { total: { value: totalDocs } }, - aggregations: { - transaction_duration_percentiles: { - values: percentilesValues, - }, + hits: { total: { value: totalDocs } }, + aggregations: { + transaction_duration_percentiles: { + values: percentilesValues, }, - } as unknown as estypes.SearchResponse, - }; + }, + } as unknown as estypes.SearchResponse; } ); - const esClientMock = { search: esClientSearchMock, } as unknown as ElasticsearchClient; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_percentiles.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_percentiles.ts index c5d2e8a5af7fd..e7ecb03fa342e 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_percentiles.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_percentiles.ts @@ -64,19 +64,19 @@ export const fetchTransactionDurationPercentiles = async ( >(getTransactionDurationPercentilesRequest(params, percents, termFilters)); // return early with no results if the search didn't return any documents - if ((resp.body.hits.total as estypes.SearchTotalHits).value === 0) { + if ((resp.hits.total as estypes.SearchTotalHits).value === 0) { return { totalDocs: 0, percentiles: {} }; } - if (resp.body.aggregations === undefined) { + if (resp.aggregations === undefined) { throw new Error( 'fetchTransactionDurationPercentiles failed, did not return aggregations.' ); } return { - totalDocs: (resp.body.hits.total as estypes.SearchTotalHits).value, + totalDocs: (resp.hits.total as estypes.SearchTotalHits).value, percentiles: - resp.body.aggregations.transaction_duration_percentiles.values ?? {}, + resp.aggregations.transaction_duration_percentiles.values ?? {}, }; }; diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_ranges.test.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_ranges.test.ts index 5c43b771f69ee..2b233958ce273 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_ranges.test.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_ranges.test.ts @@ -110,20 +110,14 @@ describe('query_ranges', () => { ]; const esClientSearchMock = jest.fn( - ( - req: estypes.SearchRequest - ): { - body: estypes.SearchResponse; - } => { + (req: estypes.SearchRequest): estypes.SearchResponse => { return { - body: { - aggregations: { - logspace_ranges: { - buckets: logspaceRangesBuckets, - }, + aggregations: { + logspace_ranges: { + buckets: logspaceRangesBuckets, }, - } as unknown as estypes.SearchResponse, - }; + }, + } as unknown as estypes.SearchResponse; } ); diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_ranges.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_ranges.ts index 1440e9a1576d9..b2b591519dc9c 100644 --- a/x-pack/plugins/apm/server/routes/correlations/queries/query_ranges.ts +++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_ranges.ts @@ -72,13 +72,13 @@ export const fetchTransactionDurationRanges = async ( getTransactionDurationRangesRequest(params, rangesSteps, termFilters) ); - if (resp.body.aggregations === undefined) { + if (resp.aggregations === undefined) { throw new Error( 'fetchTransactionDurationCorrelation failed, did not return aggregations.' ); } - return resp.body.aggregations.logspace_ranges.buckets + return resp.aggregations.logspace_ranges.buckets .map((d) => ({ key: d.from, doc_count: d.doc_count, diff --git a/x-pack/plugins/apm/server/routes/services/annotations/get_stored_annotations.ts b/x-pack/plugins/apm/server/routes/services/annotations/get_stored_annotations.ts index 308a1b9a2db26..7ce9eddf65981 100644 --- a/x-pack/plugins/apm/server/routes/services/annotations/get_stored_annotations.ts +++ b/x-pack/plugins/apm/server/routes/services/annotations/get_stored_annotations.ts @@ -56,10 +56,13 @@ export function getStoredAnnotations({ try { const response: ESSearchResponse = (await unwrapEsResponse( - client.search({ - index: annotationsClient.index, - body, - }) + client.search( + { + index: annotationsClient.index, + body, + }, + { meta: true } + ) )) as any; return response.hits.hits.map((hit) => { diff --git a/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts b/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts index b0e219a4d886d..bd855c93ed507 100644 --- a/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts +++ b/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts @@ -152,7 +152,7 @@ const customElementCollector: TelemetryCollector = async function customElementC body: { query: { bool: { filter: { term: { type: CUSTOM_ELEMENT_TYPE } } } } }, }; - const { body: esResponse } = await esClient.search(customElementParams); + const esResponse = await esClient.search(customElementParams); if (get(esResponse, 'hits.hits.length') > 0) { const customElements = esResponse.hits.hits.map((hit) => hit._source![CUSTOM_ELEMENT_TYPE]); diff --git a/x-pack/plugins/canvas/server/collectors/workpad_collector.ts b/x-pack/plugins/canvas/server/collectors/workpad_collector.ts index 62b0ce200e320..b47ea33a24f4c 100644 --- a/x-pack/plugins/canvas/server/collectors/workpad_collector.ts +++ b/x-pack/plugins/canvas/server/collectors/workpad_collector.ts @@ -386,7 +386,7 @@ const workpadCollector: TelemetryCollector = async function (kibanaIndex, esClie body: { query: { bool: { filter: { term: { type: CANVAS_TYPE } } } } }, }; - const { body: esResponse } = await esClient.search(searchParams); + const esResponse = await esClient.search(searchParams); if (get(esResponse, 'hits.hits.length') > 0) { const workpads = esResponse.hits.hits.map((hit) => hit._source![CANVAS_TYPE]); diff --git a/x-pack/plugins/canvas/server/lib/essql_strategy.ts b/x-pack/plugins/canvas/server/lib/essql_strategy.ts index 273ffb53b0ed2..0cc5c8a21121b 100644 --- a/x-pack/plugins/canvas/server/lib/essql_strategy.ts +++ b/x-pack/plugins/canvas/server/lib/essql_strategy.ts @@ -27,23 +27,26 @@ export const essqlSearchStrategyProvider = (): ISearchStrategy< const searchUntilEnd = async () => { try { - let response = await esClient.asCurrentUser.sql.query({ - format: 'json', - body: { - query, - // @ts-expect-error `params` missing from `QuerySqlRequest` type - params, - field_multi_value_leniency: true, - time_zone: timezone, - fetch_size: count, - client_id: 'canvas', - filter: { - bool: { - must: [{ match_all: {} }, ...buildBoolArray(filter)], + let response = await esClient.asCurrentUser.sql.query( + { + format: 'json', + body: { + query, + // @ts-expect-error `params` missing from `QuerySqlRequest` type + params, + field_multi_value_leniency: true, + time_zone: timezone, + fetch_size: count, + client_id: 'canvas', + filter: { + bool: { + must: [{ match_all: {} }, ...buildBoolArray(filter)], + }, }, }, }, - }); + { meta: true } + ); let body = response.body; @@ -60,12 +63,16 @@ export const essqlSearchStrategyProvider = (): ISearchStrategy< // If we still have rows to retrieve, continue requesting data // using the cursor until we have everything while (rows.length < count && body.cursor !== undefined) { - response = await esClient.asCurrentUser.sql.query({ - format: 'json', - body: { - cursor: body.cursor, + // @ts-expect-error previous ts-ignore mess with the signature override + response = await esClient.asCurrentUser.sql.query( + { + format: 'json', + body: { + cursor: body.cursor, + }, }, - }); + { meta: true } + ); body = response.body; 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 21b3357703866..ee17b2d3035b8 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 @@ -33,29 +33,27 @@ describe('Retrieve ES Fields', () => { it(`returns 200 with fields from existing index/data view`, async () => { const index = 'test'; const mockResults = { - body: { - indices: ['test'], - fields: { - '@timestamp': { - date: { - type: 'date', - searchable: true, - aggregatable: true, - }, + indices: ['test'], + fields: { + '@timestamp': { + date: { + type: 'date', + searchable: true, + aggregatable: true, }, - name: { - text: { - type: 'text', - searchable: true, - aggregatable: false, - }, + }, + name: { + text: { + type: 'text', + searchable: true, + aggregatable: false, }, - products: { - object: { - type: 'object', - searchable: false, - aggregatable: false, - }, + }, + products: { + object: { + type: 'object', + searchable: false, + aggregatable: false, }, }, }, @@ -87,7 +85,7 @@ describe('Retrieve ES Fields', () => { it(`returns 200 with empty object when index/data view has no fields`, async () => { const index = 'test'; - const mockResults = { body: { indices: [index], fields: {} } }; + const mockResults = { indices: [index], fields: {} }; const request = httpServerMock.createKibanaRequest({ method: 'get', path, @@ -111,10 +109,8 @@ describe('Retrieve ES Fields', () => { const index = 'test'; const mockResults = { - body: { - indices: [index], - fields: {}, - }, + indices: [index], + fields: {}, }; const request = httpServerMock.createKibanaRequest({ 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 340a6cdb902ff..f9523cee0ce4d 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 @@ -37,7 +37,7 @@ export function initializeESFieldsRoute(deps: RouteInitializerDeps) { }; const esFields = await client.fieldCaps(config).then((resp) => { - return mapValues(resp.body.fields, (types) => { + return mapValues(resp.fields, (types) => { if (keys(types).length > 1) { return 'conflict'; } diff --git a/x-pack/plugins/cases/server/services/alerts/index.ts b/x-pack/plugins/cases/server/services/alerts/index.ts index 7f966a471c725..e205899ead380 100644 --- a/x-pack/plugins/cases/server/services/alerts/index.ts +++ b/x-pack/plugins/cases/server/services/alerts/index.ts @@ -48,7 +48,7 @@ export class AlertService { aggregations: builtAggs, }); - return res.body.aggregations; + return res.aggregations; } catch (error) { const aggregationNames = aggregationBuilders.map((agg) => agg.getName()); diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index 8041e0858ea84..9e4a8c484964b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -23,9 +23,7 @@ const ccrDataEnricher = async (indicesList: Index[], client: IScopedClusterClien } try { - const { - body: { follower_indices: followerIndices }, - } = await client.asCurrentUser.ccr.followInfo({ + const { follower_indices: followerIndices } = await client.asCurrentUser.ccr.followInfo({ index: '_all', }); 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 dd1481b45f875..3fe320fe5bdd4 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 @@ -56,7 +56,7 @@ export const registerCreateRoute = ({ } try { - const { body: responseBody } = await client.asCurrentUser.ccr.putAutoFollowPattern({ + const responseBody = await client.asCurrentUser.ccr.putAutoFollowPattern({ name: id, body, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts index 7b694cfe77efd..67ea716976417 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts @@ -33,19 +33,17 @@ describe('[CCR API] Fetch all auto-follow patterns', () => { it('deserializes the response from Elasticsearch', async () => { const ccrAutoFollowPatternResponseMock = { - body: { - patterns: [ - { - name: 'autoFollowPattern', - pattern: { - active: true, - remote_cluster: 'remoteCluster', - leader_index_patterns: ['leader*'], - follow_index_pattern: 'follow', - }, + patterns: [ + { + name: 'autoFollowPattern', + pattern: { + active: true, + remote_cluster: 'remoteCluster', + leader_index_patterns: ['leader*'], + follow_index_pattern: 'follow', }, - ], - }, + }, + ], }; const routeContextMock = mockRouteContext({ 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 98ce37d1054bc..7cd9508bd7372 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 @@ -26,9 +26,7 @@ export const registerFetchRoute = ({ const { client } = context.core.elasticsearch; try { - const { - body: { patterns }, - } = await client.asCurrentUser.ccr.getAutoFollowPattern(); + const { patterns } = await client.asCurrentUser.ccr.getAutoFollowPattern(); return response.ok({ body: { // @ts-expect-error Once #98266 is merged, test this again. diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts index 61fdd6e57ab7a..a2bf912a99728 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts @@ -33,19 +33,17 @@ describe('[CCR API] Get one auto-follow pattern', () => { it('should return a single resource even though ES returns an array with 1 item', async () => { const ccrAutoFollowPatternResponseMock = { - body: { - patterns: [ - { - name: 'autoFollowPattern', - pattern: { - active: true, - remote_cluster: 'remoteCluster', - leader_index_patterns: ['leader*'], - follow_index_pattern: 'follow', - }, + patterns: [ + { + name: 'autoFollowPattern', + pattern: { + active: true, + remote_cluster: 'remoteCluster', + leader_index_patterns: ['leader*'], + follow_index_pattern: 'follow', }, - ], - }, + }, + ], }; const routeContextMock = mockRouteContext({ 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 bc452982df63e..a5a70805d518d 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 @@ -39,7 +39,7 @@ export const registerGetRoute = ({ name: id, }); - const autoFollowPattern = result.body.patterns[0]; + const autoFollowPattern = result.patterns[0]; return response.ok({ // @ts-expect-error Once #98266 is merged, test this again. diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts index 5ada82049632b..19d165a80eb3b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts @@ -35,7 +35,7 @@ describe('[CCR API] Update auto-follow pattern', () => { const routeContextMock = mockRouteContext({ ccr: { // Just echo back what we send so we can inspect it. - putAutoFollowPattern: jest.fn().mockImplementation((payload) => ({ body: payload })), + putAutoFollowPattern: jest.fn().mockImplementation((payload) => payload), }, }); 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 81aaa59725e3a..98a716eb88cc6 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 @@ -44,7 +44,7 @@ export const registerUpdateRoute = ({ const body = serializeAutoFollowPattern(request.body as AutoFollowPattern); try { - const { body: responseBody } = await client.asCurrentUser.ccr.putAutoFollowPattern({ + const responseBody = await client.asCurrentUser.ccr.putAutoFollowPattern({ name: id, body, }); 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 600924e145039..dbee279a01336 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 @@ -36,13 +36,12 @@ export const registerPermissionsRoute = ({ } try { - const { - body: { has_all_requested: hasPermission, cluster }, - } = await client.asCurrentUser.security.hasPrivileges({ - body: { - cluster: ['manage', 'manage_ccr'], - }, - }); + const { has_all_requested: hasPermission, cluster } = + await client.asCurrentUser.security.hasPrivileges({ + body: { + cluster: ['manage', 'manage_ccr'], + }, + }); const missingClusterPrivileges = Object.keys(cluster).reduce( (permissions: string[], permissionName: string) => { 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 fa8f792afc419..bab31c53a83a2 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 @@ -26,9 +26,7 @@ export const registerStatsRoute = ({ const { client } = context.core.elasticsearch; try { - const { - body: { auto_follow_stats: autoFollowStats }, - } = await client.asCurrentUser.ccr.stats(); + const { auto_follow_stats: autoFollowStats } = await client.asCurrentUser.ccr.stats(); return response.ok({ // @ts-expect-error Once #98266 is merged, test this again. 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 9ddbf76cceed2..0aae8f9c115bc 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 @@ -49,7 +49,7 @@ export const registerCreateRoute = ({ const body = removeEmptyFields(serializeFollowerIndex(rest as FollowerIndex)); try { - const { body: responseBody } = await client.asCurrentUser.ccr.follow({ + const responseBody = await client.asCurrentUser.ccr.follow({ index: name, body, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts index e4063e1e64df5..3d818f40b0262 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts @@ -33,69 +33,65 @@ describe('[CCR API] Fetch all follower indices', () => { it('deserializes the response from Elasticsearch', async () => { const ccrInfoMockResponse = { - body: { - follower_indices: [ - { - follower_index: 'followerIndexName', - remote_cluster: 'remoteCluster', - leader_index: 'leaderIndex', - status: 'active', - parameters: { - max_read_request_operation_count: 1, - max_outstanding_read_requests: 1, - max_read_request_size: '1b', - max_write_request_operation_count: 1, - max_write_request_size: '1b', - max_outstanding_write_requests: 1, - max_write_buffer_count: 1, - max_write_buffer_size: '1b', - max_retry_delay: '1s', - read_poll_timeout: '1s', - }, + follower_indices: [ + { + follower_index: 'followerIndexName', + remote_cluster: 'remoteCluster', + leader_index: 'leaderIndex', + status: 'active', + parameters: { + max_read_request_operation_count: 1, + max_outstanding_read_requests: 1, + max_read_request_size: '1b', + max_write_request_operation_count: 1, + max_write_request_size: '1b', + max_outstanding_write_requests: 1, + max_write_buffer_count: 1, + max_write_buffer_size: '1b', + max_retry_delay: '1s', + read_poll_timeout: '1s', }, - ], - }, + }, + ], }; // These stats correlate to the above follower indices. const ccrStatsMockResponse = { - body: { - follow_stats: { - indices: [ - { - index: 'followerIndexName', - shards: [ - { - shard_id: 1, - leader_index: 'leaderIndex', - leader_global_checkpoint: 1, - leader_max_seq_no: 1, - follower_global_checkpoint: 1, - follower_max_seq_no: 1, - last_requested_seq_no: 1, - outstanding_read_requests: 1, - outstanding_write_requests: 1, - write_buffer_operation_count: 1, - write_buffer_size_in_bytes: 1, - follower_mapping_version: 1, - follower_settings_version: 1, - total_read_time_millis: 1, - total_read_remote_exec_time_millis: 1, - successful_read_requests: 1, - failed_read_requests: 1, - operations_read: 1, - bytes_read: 1, - total_write_time_millis: 1, - successful_write_requests: 1, - failed_write_requests: 1, - operations_written: 1, - read_exceptions: 1, - time_since_last_read_millis: 1, - }, - ], - }, - ], - }, + follow_stats: { + indices: [ + { + index: 'followerIndexName', + shards: [ + { + shard_id: 1, + leader_index: 'leaderIndex', + leader_global_checkpoint: 1, + leader_max_seq_no: 1, + follower_global_checkpoint: 1, + follower_max_seq_no: 1, + last_requested_seq_no: 1, + outstanding_read_requests: 1, + outstanding_write_requests: 1, + write_buffer_operation_count: 1, + write_buffer_size_in_bytes: 1, + follower_mapping_version: 1, + follower_settings_version: 1, + total_read_time_millis: 1, + total_read_remote_exec_time_millis: 1, + successful_read_requests: 1, + failed_read_requests: 1, + operations_read: 1, + bytes_read: 1, + total_write_time_millis: 1, + successful_write_requests: 1, + failed_write_requests: 1, + operations_written: 1, + read_exceptions: 1, + time_since_last_read_millis: 1, + }, + ], + }, + ], }, }; 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 b4d7ead75e830..7bbe2c8c05d4a 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 @@ -26,14 +26,12 @@ export const registerFetchRoute = ({ const { client } = context.core.elasticsearch; try { - const { - body: { follower_indices: followerIndices }, - } = await client.asCurrentUser.ccr.followInfo({ index: '_all' }); + const { follower_indices: followerIndices } = await client.asCurrentUser.ccr.followInfo({ + index: '_all', + }); const { - body: { - follow_stats: { indices: followerIndicesStats }, - }, + follow_stats: { indices: followerIndicesStats }, } = await client.asCurrentUser.ccr.stats(); const followerIndicesStatsMap = followerIndicesStats.reduce((map: any, stats: any) => { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts index 493703ca6de27..a0af8827b8744 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts @@ -33,68 +33,64 @@ describe('[CCR API] Get one follower index', () => { it('should return a single resource even though ES returns an array with 1 item', async () => { const ccrInfoMockResponse = { - body: { - follower_indices: [ - { - follower_index: 'followerIndexName', - remote_cluster: 'remoteCluster', - leader_index: 'leaderIndex', - status: 'active', - parameters: { - max_read_request_operation_count: 1, - max_outstanding_read_requests: 1, - max_read_request_size: '1b', - max_write_request_operation_count: 1, - max_write_request_size: '1b', - max_outstanding_write_requests: 1, - max_write_buffer_count: 1, - max_write_buffer_size: '1b', - max_retry_delay: '1s', - read_poll_timeout: '1s', - }, + follower_indices: [ + { + follower_index: 'followerIndexName', + remote_cluster: 'remoteCluster', + leader_index: 'leaderIndex', + status: 'active', + parameters: { + max_read_request_operation_count: 1, + max_outstanding_read_requests: 1, + max_read_request_size: '1b', + max_write_request_operation_count: 1, + max_write_request_size: '1b', + max_outstanding_write_requests: 1, + max_write_buffer_count: 1, + max_write_buffer_size: '1b', + max_retry_delay: '1s', + read_poll_timeout: '1s', }, - ], - }, + }, + ], }; // These stats correlate to the above follower indices. const ccrFollowerIndexStatsMockResponse = { - body: { - indices: [ - { - index: 'followerIndexName', - shards: [ - { - shard_id: 1, - leader_index: 'leaderIndex', - leader_global_checkpoint: 1, - leader_max_seq_no: 1, - follower_global_checkpoint: 1, - follower_max_seq_no: 1, - last_requested_seq_no: 1, - outstanding_read_requests: 1, - outstanding_write_requests: 1, - write_buffer_operation_count: 1, - write_buffer_size_in_bytes: 1, - follower_mapping_version: 1, - follower_settings_version: 1, - total_read_time_millis: 1, - total_read_remote_exec_time_millis: 1, - successful_read_requests: 1, - failed_read_requests: 1, - operations_read: 1, - bytes_read: 1, - total_write_time_millis: 1, - successful_write_requests: 1, - failed_write_requests: 1, - operations_written: 1, - read_exceptions: 1, - time_since_last_read_millis: 1, - }, - ], - }, - ], - }, + indices: [ + { + index: 'followerIndexName', + shards: [ + { + shard_id: 1, + leader_index: 'leaderIndex', + leader_global_checkpoint: 1, + leader_max_seq_no: 1, + follower_global_checkpoint: 1, + follower_max_seq_no: 1, + last_requested_seq_no: 1, + outstanding_read_requests: 1, + outstanding_write_requests: 1, + write_buffer_operation_count: 1, + write_buffer_size_in_bytes: 1, + follower_mapping_version: 1, + follower_settings_version: 1, + total_read_time_millis: 1, + total_read_remote_exec_time_millis: 1, + successful_read_requests: 1, + failed_read_requests: 1, + operations_read: 1, + bytes_read: 1, + total_write_time_millis: 1, + successful_write_requests: 1, + failed_write_requests: 1, + operations_written: 1, + read_exceptions: 1, + time_since_last_read_millis: 1, + }, + ], + }, + ], }; const routeContextMock = mockRouteContext({ 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 21cb9e08a6160..c33ed97c289f0 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 @@ -34,9 +34,9 @@ export const registerGetRoute = ({ const { id } = request.params; try { - const { - body: { follower_indices: followerIndices }, - } = await client.asCurrentUser.ccr.followInfo({ index: id }); + const { follower_indices: followerIndices } = await client.asCurrentUser.ccr.followInfo({ + index: id, + }); const followerIndexInfo = followerIndices && followerIndices[0]; @@ -55,9 +55,9 @@ export const registerGetRoute = ({ }), }); } else { - const { - body: { indices: followerIndicesStats }, - } = await client.asCurrentUser.ccr.followStats({ index: id }); + const { indices: followerIndicesStats } = await client.asCurrentUser.ccr.followStats({ + index: id, + }); return response.ok({ // @ts-expect-error Once #98266 is merged, test this again. diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.test.ts index 92b9c3dded08e..d2cd579687106 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.test.ts @@ -34,11 +34,9 @@ describe('[CCR API] Update follower index', () => { it('should serialize the payload before sending it to Elasticsearch', async () => { const routeContextMock = mockRouteContext({ ccr: { - followInfo: jest - .fn() - .mockResolvedValueOnce({ body: { follower_indices: [{ status: 'paused' }] } }), + followInfo: jest.fn().mockResolvedValueOnce({ follower_indices: [{ status: 'paused' }] }), // Just echo back what we send so we can inspect it. - resumeFollow: jest.fn().mockImplementation((payload) => ({ body: payload })), + resumeFollow: jest.fn().mockImplementation((payload) => payload), }, }); 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 5029c8be96043..0bacbd5fb3450 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 @@ -49,9 +49,9 @@ export const registerUpdateRoute = ({ // We need to first pause the follower and then resume it by passing the advanced settings try { - const { - body: { follower_indices: followerIndices }, - } = await client.asCurrentUser.ccr.followInfo({ index: id }); + const { follower_indices: followerIndices } = await client.asCurrentUser.ccr.followInfo({ + index: id, + }); const followerIndexInfo = followerIndices && followerIndices[0]; @@ -72,7 +72,7 @@ export const registerUpdateRoute = ({ serializeAdvancedSettings(request.body as FollowerIndexAdvancedSettings) ); - const { body: responseBody } = await client.asCurrentUser.ccr.resumeFollow({ + const responseBody = await client.asCurrentUser.ccr.resumeFollow({ index: id, body, }); diff --git a/x-pack/plugins/data_enhanced/server/collectors/fetch.test.ts b/x-pack/plugins/data_enhanced/server/collectors/fetch.test.ts index 47e6fb05c2329..ed079fe948750 100644 --- a/x-pack/plugins/data_enhanced/server/collectors/fetch.test.ts +++ b/x-pack/plugins/data_enhanced/server/collectors/fetch.test.ts @@ -5,17 +5,13 @@ * 2.0. */ -import { - ElasticsearchClient, - SavedObjectsErrorHelpers, - Logger, -} from '../../../../../src/core/server'; +import { SavedObjectsErrorHelpers, Logger } from '../../../../../src/core/server'; import { fetchProvider } from './fetch'; import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; describe('fetchProvider', () => { let fetchFn: any; - let esClient: jest.Mocked; + let esClient: ReturnType; let mockLogger: Logger; beforeEach(async () => { @@ -29,13 +25,10 @@ describe('fetchProvider', () => { }); test('returns when ES returns no results', async () => { - esClient.search.mockResolvedValue({ - statusCode: 200, - body: { - aggregations: { - persisted: { - buckets: [], - }, + esClient.search.mockResponse({ + aggregations: { + persisted: { + buckets: [], }, }, } as any); @@ -60,22 +53,19 @@ describe('fetchProvider', () => { }); test('returns when ES returns full buckets', async () => { - esClient.search.mockResolvedValue({ - statusCode: 200, - body: { - aggregations: { - persisted: { - buckets: [ - { - key_as_string: 'true', - doc_count: 10, - }, - { - key_as_string: 'false', - doc_count: 7, - }, - ], - }, + esClient.search.mockResponse({ + aggregations: { + persisted: { + buckets: [ + { + key_as_string: 'true', + doc_count: 10, + }, + { + key_as_string: 'false', + doc_count: 7, + }, + ], }, }, } as any); diff --git a/x-pack/plugins/data_enhanced/server/collectors/fetch.ts b/x-pack/plugins/data_enhanced/server/collectors/fetch.ts index b566ceb9065d2..82597a9003051 100644 --- a/x-pack/plugins/data_enhanced/server/collectors/fetch.ts +++ b/x-pack/plugins/data_enhanced/server/collectors/fetch.ts @@ -18,7 +18,7 @@ interface SessionPersistedTermsBucket { export function fetchProvider(kibanaIndex: string, logger: Logger) { return async ({ esClient }: CollectorFetchContext): Promise => { try { - const { body: esResponse } = await esClient.search({ + const esResponse = await esClient.search({ index: kibanaIndex, body: { size: 0, diff --git a/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.test.ts b/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.test.ts index 4d9ecb9221709..85bfbc8d037db 100644 --- a/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.test.ts @@ -488,7 +488,7 @@ describe('checkNonPersistedSessions', () => { config ); - expect(mockClient.asyncSearch.status).toBeCalledWith({ id: 'search-id' }); + expect(mockClient.asyncSearch.status).toBeCalledWith({ id: 'search-id' }, { meta: true }); const [updateInput] = savedObjectsClient.bulkUpdate.mock.calls[0]; const updatedAttributes = updateInput[0] as SavedObjectsBulkUpdateObject; expect(updatedAttributes.namespace).toBe('awesome'); @@ -532,7 +532,7 @@ describe('checkNonPersistedSessions', () => { config ); - expect(mockClient.asyncSearch.status).toBeCalledWith({ id: 'search-id' }); + expect(mockClient.asyncSearch.status).toBeCalledWith({ id: 'search-id' }, { meta: true }); const [updateInput] = savedObjectsClient.bulkUpdate.mock.calls[0]; const updatedAttributes = updateInput[0].attributes as SearchSessionSavedObjectAttributes; expect(updatedAttributes.status).toBe(SearchSessionStatus.COMPLETE); diff --git a/x-pack/plugins/data_enhanced/server/search/session/get_search_status.ts b/x-pack/plugins/data_enhanced/server/search/session/get_search_status.ts index a49dc30b84fb5..abfe089e82a38 100644 --- a/x-pack/plugins/data_enhanced/server/search/session/get_search_status.ts +++ b/x-pack/plugins/data_enhanced/server/search/session/get_search_status.ts @@ -22,7 +22,8 @@ export async function getSearchStatus( const apiResponse: TransportResult = await client.asyncSearch.status( { id: asyncId, - } + }, + { meta: true } ); const response = apiResponse.body; if ((response.is_partial && !response.is_running) || response.completion_status >= 400) { diff --git a/x-pack/plugins/data_enhanced/server/search/session/update_session_status.test.ts b/x-pack/plugins/data_enhanced/server/search/session/update_session_status.test.ts index d9e3fa6f8cab3..3b6b0a7a16d85 100644 --- a/x-pack/plugins/data_enhanced/server/search/session/update_session_status.test.ts +++ b/x-pack/plugins/data_enhanced/server/search/session/update_session_status.test.ts @@ -186,7 +186,7 @@ describe('bulkUpdateSessions', () => { expect(updated).toBeTruthy(); - expect(mockClient.asyncSearch.status).toBeCalledWith({ id: 'search-id' }); + expect(mockClient.asyncSearch.status).toBeCalledWith({ id: 'search-id' }, { meta: true }); expect(so.attributes.status).toBe(SearchSessionStatus.COMPLETE); expect(so.attributes.status).toBe(SearchSessionStatus.COMPLETE); expect(so.attributes.touched).not.toBe('123'); diff --git a/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts b/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts index 0d4f4136b42ed..5ff3b6c481d74 100644 --- a/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts +++ b/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { ElasticsearchClient } from 'src/core/server'; import { elasticsearchServiceMock, loggingSystemMock } from 'src/core/server/mocks'; import { ClusterClientAdapter, @@ -15,14 +14,12 @@ import { import { findOptionsSchema } from '../event_log_client'; import { delay } from '../lib/delay'; import { times } from 'lodash'; -import { DeeplyMockedKeys } from '@kbn/utility-types/jest'; import type * as estypes from '@elastic/elasticsearch/lib/api/types'; -import type { TransportResult } from '@elastic/elasticsearch'; type MockedLogger = ReturnType; let logger: MockedLogger; -let clusterClient: DeeplyMockedKeys; +let clusterClient: ReturnType; let clusterClientAdapter: IClusterClientAdapter; beforeEach(() => { @@ -191,7 +188,7 @@ describe('doesIlmPolicyExist', () => { describe('createIlmPolicy', () => { test('should call cluster client with given policy', async () => { - clusterClient.transport.request.mockResolvedValue(asApiResponse({ success: true })); + clusterClient.transport.request.mockResolvedValue({ success: true }); await clusterClientAdapter.createIlmPolicy('foo', { args: true }); expect(clusterClient.transport.request).toHaveBeenCalledWith({ method: 'PUT', @@ -217,20 +214,20 @@ describe('doesIndexTemplateExist', () => { }); test('should return true when call cluster to legacy template API returns true', async () => { - clusterClient.indices.existsTemplate.mockResolvedValue(asApiResponse(true)); - clusterClient.indices.existsIndexTemplate.mockResolvedValue(asApiResponse(false)); + clusterClient.indices.existsTemplate.mockResponse(true); + clusterClient.indices.existsIndexTemplate.mockResponse(false); await expect(clusterClientAdapter.doesIndexTemplateExist('foo')).resolves.toEqual(true); }); test('should return true when call cluster to index template API returns true', async () => { - clusterClient.indices.existsTemplate.mockResolvedValue(asApiResponse(false)); - clusterClient.indices.existsIndexTemplate.mockResolvedValue(asApiResponse(true)); + clusterClient.indices.existsTemplate.mockResponse(false); + clusterClient.indices.existsIndexTemplate.mockResponse(true); await expect(clusterClientAdapter.doesIndexTemplateExist('foo')).resolves.toEqual(true); }); test('should return false when both call cluster calls returns false', async () => { - clusterClient.indices.existsTemplate.mockResolvedValue(asApiResponse(false)); - clusterClient.indices.existsIndexTemplate.mockResolvedValue(asApiResponse(false)); + clusterClient.indices.existsTemplate.mockResponse(false); + clusterClient.indices.existsIndexTemplate.mockResponse(false); await expect(clusterClientAdapter.doesIndexTemplateExist('foo')).resolves.toEqual(false); }); @@ -265,8 +262,8 @@ describe('createIndexTemplate', () => { test(`should throw error if index template still doesn't exist after error is thrown`, async () => { clusterClient.indices.putIndexTemplate.mockRejectedValueOnce(new Error('Fail')); - clusterClient.indices.existsTemplate.mockResolvedValueOnce(asApiResponse(false)); - clusterClient.indices.existsIndexTemplate.mockResolvedValueOnce(asApiResponse(false)); + clusterClient.indices.existsTemplate.mockResponseOnce(false); + clusterClient.indices.existsIndexTemplate.mockResponseOnce(false); await expect( clusterClientAdapter.createIndexTemplate('foo', { args: true }) ).rejects.toThrowErrorMatchingInlineSnapshot(`"error creating index template: Fail"`); @@ -274,7 +271,7 @@ describe('createIndexTemplate', () => { test('should not throw error if index template exists after error is thrown', async () => { clusterClient.indices.putIndexTemplate.mockRejectedValueOnce(new Error('Fail')); - clusterClient.indices.existsTemplate.mockResolvedValueOnce(asApiResponse(true)); + clusterClient.indices.existsTemplate.mockResponseOnce(true); await clusterClientAdapter.createIndexTemplate('foo', { args: true }); }); }); @@ -300,9 +297,7 @@ describe('getExistingLegacyIndexTemplates', () => { aliases: {}, }, }; - clusterClient.indices.getTemplate.mockResolvedValue( - asApiResponse(response) - ); + clusterClient.indices.getTemplate.mockResponse(response); await expect(clusterClientAdapter.getExistingLegacyIndexTemplates('foo*')).resolves.toEqual( response ); @@ -378,9 +373,7 @@ describe('getExistingIndices', () => { }, }, }; - clusterClient.indices.getSettings.mockResolvedValue( - asApiResponse(response) - ); + clusterClient.indices.getSettings.mockResponse(response as estypes.IndicesGetSettingsResponse); await expect(clusterClientAdapter.getExistingIndices('foo*')).resolves.toEqual(response); }); @@ -436,9 +429,7 @@ describe('getExistingIndexAliases', () => { }, }, }; - clusterClient.indices.getAlias.mockResolvedValue( - asApiResponse(response) - ); + clusterClient.indices.getAlias.mockResponse(response as estypes.IndicesGetAliasResponse); await expect(clusterClientAdapter.getExistingIndexAliases('foo*')).resolves.toEqual(response); }); @@ -524,12 +515,12 @@ describe('doesAliasExist', () => { }); test('should return true when call cluster returns true', async () => { - clusterClient.indices.existsAlias.mockResolvedValueOnce(asApiResponse(true)); + clusterClient.indices.existsAlias.mockResponse(true); await expect(clusterClientAdapter.doesAliasExist('foo')).resolves.toEqual(true); }); test('should return false when call cluster returns false', async () => { - clusterClient.indices.existsAlias.mockResolvedValueOnce(asApiResponse(false)); + clusterClient.indices.existsAlias.mockResponse(false); await expect(clusterClientAdapter.doesAliasExist('foo')).resolves.toEqual(false); }); @@ -577,22 +568,20 @@ describe('queryEventsBySavedObject', () => { const DEFAULT_OPTIONS = findOptionsSchema.validate({}); test('should call cluster with proper arguments with non-default namespace', async () => { - clusterClient.search.mockResolvedValue( - asApiResponse({ - hits: { - hits: [], - total: { relation: 'eq', value: 0 }, - }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - successful: 0, - total: 0, - skipped: 0, - }, - }) - ); + clusterClient.search.mockResponse({ + hits: { + hits: [], + total: { relation: 'eq', value: 0 }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + successful: 0, + total: 0, + skipped: 0, + }, + }); await clusterClientAdapter.queryEventsBySavedObjects({ index: 'index-name', namespace: 'namespace', @@ -789,22 +778,20 @@ describe('queryEventsBySavedObject', () => { }); test('should call cluster with proper arguments with default namespace', async () => { - clusterClient.search.mockResolvedValue( - asApiResponse({ - hits: { - hits: [], - total: { relation: 'eq', value: 0 }, - }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - successful: 0, - total: 0, - skipped: 0, - }, - }) - ); + clusterClient.search.mockResponse({ + hits: { + hits: [], + total: { relation: 'eq', value: 0 }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + successful: 0, + total: 0, + skipped: 0, + }, + }); await clusterClientAdapter.queryEventsBySavedObjects({ index: 'index-name', namespace: undefined, @@ -908,22 +895,20 @@ describe('queryEventsBySavedObject', () => { }); test('should call cluster with sort', async () => { - clusterClient.search.mockResolvedValue( - asApiResponse({ - hits: { - hits: [], - total: { relation: 'eq', value: 0 }, - }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - successful: 0, - total: 0, - skipped: 0, - }, - }) - ); + clusterClient.search.mockResponse({ + hits: { + hits: [], + total: { relation: 'eq', value: 0 }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + successful: 0, + total: 0, + skipped: 0, + }, + }); await clusterClientAdapter.queryEventsBySavedObjects({ index: 'index-name', namespace: 'namespace', @@ -942,22 +927,20 @@ describe('queryEventsBySavedObject', () => { }); test('supports open ended date', async () => { - clusterClient.search.mockResolvedValue( - asApiResponse({ - hits: { - hits: [], - total: { relation: 'eq', value: 0 }, - }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - successful: 0, - total: 0, - skipped: 0, - }, - }) - ); + clusterClient.search.mockResponse({ + hits: { + hits: [], + total: { relation: 'eq', value: 0 }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + successful: 0, + total: 0, + skipped: 0, + }, + }); const start = '2020-07-08T00:52:28.350Z'; @@ -1069,22 +1052,20 @@ describe('queryEventsBySavedObject', () => { }); test('supports optional date range', async () => { - clusterClient.search.mockResolvedValue( - asApiResponse({ - hits: { - hits: [], - total: { relation: 'eq', value: 0 }, - }, - took: 0, - timed_out: false, - _shards: { - failed: 0, - successful: 0, - total: 0, - skipped: 0, - }, - }) - ); + clusterClient.search.mockResponse({ + hits: { + hits: [], + total: { relation: 'eq', value: 0 }, + }, + took: 0, + timed_out: false, + _shards: { + failed: 0, + successful: 0, + total: 0, + skipped: 0, + }, + }); const start = '2020-07-08T00:52:28.350Z'; const end = '2020-07-08T00:00:00.000Z'; @@ -1254,12 +1235,6 @@ type RetryableFunction = () => boolean; const RETRY_UNTIL_DEFAULT_COUNT = 20; const RETRY_UNTIL_DEFAULT_WAIT = 1000; // milliseconds -function asApiResponse(body: T): TransportResult { - return { - body, - } as TransportResult; -} - async function retryUntil( label: string, fn: RetryableFunction, diff --git a/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts b/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts index dd740aa5533b9..010d162c62ea1 100644 --- a/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts +++ b/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts @@ -120,9 +120,9 @@ export class ClusterClientAdapter { try { const esClient = await this.elasticsearchClientPromise; - const { body: legacyResult } = await esClient.indices.existsTemplate({ name }); - const { body: indexTemplateResult } = await esClient.indices.existsIndexTemplate({ name }); + const legacyResult = await esClient.indices.existsTemplate({ name }); + const indexTemplateResult = await esClient.indices.existsIndexTemplate({ name }); return (legacyResult as boolean) || (indexTemplateResult as boolean); } catch (err) { throw new Error(`error checking existence of index template: ${err.message}`); @@ -200,11 +200,7 @@ export class ClusterClientAdapter { try { const esClient = await this.elasticsearchClientPromise; - const { body: templates } = await esClient.indices.getTemplate( - { name: indexTemplatePattern }, - { ignore: [404] } - ); - return templates; + return await esClient.indices.getTemplate({ name: indexTemplatePattern }, { ignore: [404] }); } catch (err) { throw new Error(`error getting existing legacy index templates: ${err.message}`); } @@ -238,11 +234,7 @@ export class ClusterClientAdapter { try { const esClient = await this.elasticsearchClientPromise; - const { body: indexSettings } = await esClient.indices.getSettings( - { index: indexPattern }, - { ignore: [404] } - ); - return indexSettings; + return await esClient.indices.getSettings({ index: indexPattern }, { ignore: [404] }); } catch (err) { throw new Error( `error getting existing indices matching pattern ${indexPattern}: ${err.message}` @@ -269,11 +261,7 @@ export class ClusterClientAdapter { try { const esClient = await this.elasticsearchClientPromise; - const { body: indexAliases } = await esClient.indices.getAlias( - { index: indexPattern }, - { ignore: [404] } - ); - return indexAliases; + return await esClient.indices.getAlias({ index: indexPattern }, { ignore: [404] }); } catch (err) { throw new Error( `error getting existing index aliases matching pattern ${indexPattern}: ${err.message}` @@ -318,7 +306,7 @@ export class ClusterClientAdapter { try { const esClient = await this.elasticsearchClientPromise; - const { body } = await esClient.indices.existsAlias({ name }); + const body = await esClient.indices.existsAlias({ name }); return body as boolean; } catch (err) { throw new Error(`error checking existance of initial index: ${err.message}`); @@ -527,9 +515,7 @@ export class ClusterClientAdapter({ index, track_total_hits: true, diff --git a/x-pack/plugins/event_log/server/es/context.test.ts b/x-pack/plugins/event_log/server/es/context.test.ts index 97d68b64d1f39..f6b4178ce7f11 100644 --- a/x-pack/plugins/event_log/server/es/context.test.ts +++ b/x-pack/plugins/event_log/server/es/context.test.ts @@ -6,19 +6,18 @@ */ import { createEsContext } from './context'; -import { ElasticsearchClient, Logger } from '../../../../../src/core/server'; +import { Logger } from '../../../../../src/core/server'; import { elasticsearchServiceMock, loggingSystemMock } from '../../../../../src/core/server/mocks'; -import { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import type { TransportResult } from '@elastic/elasticsearch'; + jest.mock('../lib/../../../../package.json', () => ({ version: '1.2.3' })); jest.mock('./init'); let logger: Logger; -let elasticsearchClient: DeeplyMockedKeys; +let elasticsearchClient: ReturnType; beforeEach(() => { logger = loggingSystemMock.createLogger(); - elasticsearchClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + elasticsearchClient = elasticsearchServiceMock.createElasticsearchClient(); }); describe('createEsContext', () => { @@ -64,9 +63,9 @@ describe('createEsContext', () => { elasticsearchClientPromise: Promise.resolve(elasticsearchClient), }); - elasticsearchClient.indices.existsTemplate.mockResolvedValue(asApiResponse(false)); - elasticsearchClient.indices.existsIndexTemplate.mockResolvedValue(asApiResponse(false)); - elasticsearchClient.indices.existsAlias.mockResolvedValue(asApiResponse(false)); + elasticsearchClient.indices.existsTemplate.mockResponse(false); + elasticsearchClient.indices.existsIndexTemplate.mockResponse(false); + elasticsearchClient.indices.existsAlias.mockResponse(false); const doesAliasExist = await context.esAdapter.doesAliasExist(context.esNames.alias); expect(doesAliasExist).toBeFalsy(); @@ -83,7 +82,7 @@ describe('createEsContext', () => { kibanaVersion: '1.2.3', elasticsearchClientPromise: Promise.resolve(elasticsearchClient), }); - elasticsearchClient.indices.existsTemplate.mockResolvedValue(asApiResponse(true)); + elasticsearchClient.indices.existsTemplate.mockResponse(true); context.initialize(); const doesIlmPolicyExist = await context.esAdapter.doesIlmPolicyExist( @@ -113,9 +112,3 @@ describe('createEsContext', () => { expect(success).toBe(false); }); }); - -function asApiResponse(body: T): TransportResult { - return { - body, - } as TransportResult; -} diff --git a/x-pack/plugins/file_upload/server/analyze_file.tsx b/x-pack/plugins/file_upload/server/analyze_file.tsx index cdb0bddecb395..ae2b1aeef81bd 100644 --- a/x-pack/plugins/file_upload/server/analyze_file.tsx +++ b/x-pack/plugins/file_upload/server/analyze_file.tsx @@ -19,7 +19,7 @@ export async function analyzeFile( overrides: InputOverrides ): Promise { overrides.explain = overrides.explain === undefined ? 'true' : overrides.explain; - const { body } = await client.asInternalUser.textStructure.findStructure( + const body = await client.asInternalUser.textStructure.findStructure( { body: data, ...overrides, diff --git a/x-pack/plugins/file_upload/server/get_time_field_range.ts b/x-pack/plugins/file_upload/server/get_time_field_range.ts index 84fc6ac002008..9da8e7fb2b7e4 100644 --- a/x-pack/plugins/file_upload/server/get_time_field_range.ts +++ b/x-pack/plugins/file_upload/server/get_time_field_range.ts @@ -22,9 +22,7 @@ export async function getTimeFieldRange( }> { const obj = { success: true, start: { epoch: 0, string: '' }, end: { epoch: 0, string: '' } }; - const { - body: { aggregations }, - } = await client.asCurrentUser.search({ + const { aggregations } = await client.asCurrentUser.search({ index, size: 0, body: { diff --git a/x-pack/plugins/file_upload/server/import_data.ts b/x-pack/plugins/file_upload/server/import_data.ts index c2975fca959f0..c093cfcee190c 100644 --- a/x-pack/plugins/file_upload/server/import_data.ts +++ b/x-pack/plugins/file_upload/server/import_data.ts @@ -120,7 +120,7 @@ export function importDataProvider({ asCurrentUser }: IScopedClusterClient) { settings.pipeline = pipelineId; } - const { body: resp } = await asCurrentUser.bulk(settings, { maxRetries: 0 }); + const resp = await asCurrentUser.bulk(settings, { maxRetries: 0 }); if (resp.errors) { throw resp; } else { @@ -153,8 +153,7 @@ export function importDataProvider({ asCurrentUser }: IScopedClusterClient) { } async function createPipeline(id: string, pipeline: any) { - const { body } = await asCurrentUser.ingest.putPipeline({ id, body: pipeline }); - return body; + return await asCurrentUser.ingest.putPipeline({ id, body: pipeline }); } function getFailures(items: any[], data: InputData): ImportFailure[] { diff --git a/x-pack/plugins/file_upload/server/routes.ts b/x-pack/plugins/file_upload/server/routes.ts index e8d32152c8afc..eeb22faefb1ca 100644 --- a/x-pack/plugins/file_upload/server/routes.ts +++ b/x-pack/plugins/file_upload/server/routes.ts @@ -182,8 +182,9 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge }, async (context, request, response) => { try { - const { body: indexExists } = - await context.core.elasticsearch.client.asCurrentUser.indices.exists(request.body); + const indexExists = await context.core.elasticsearch.client.asCurrentUser.indices.exists( + request.body + ); return response.ok({ body: { exists: indexExists } }); } catch (e) { return response.customError(wrapError(e)); diff --git a/x-pack/plugins/fleet/server/routes/app/index.ts b/x-pack/plugins/fleet/server/routes/app/index.ts index b9f9f0ee494fc..079850dc07478 100644 --- a/x-pack/plugins/fleet/server/routes/app/index.ts +++ b/x-pack/plugins/fleet/server/routes/app/index.ts @@ -39,9 +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 { - body: { has_all_requested: hasAllPrivileges }, - } = await esClient.security.hasPrivileges({ + const { has_all_requested: hasAllPrivileges } = await esClient.security.hasPrivileges({ body: { cluster: ['manage_service_account'] }, }); @@ -63,7 +61,7 @@ export const generateServiceTokenHandler: RequestHandler = async (context, reque // 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; try { - const { body: tokenResponse } = await esClient.transport.request<{ + const tokenResponse = await esClient.transport.request<{ created?: boolean; token?: GenerateServiceTokenResponse; }>({ 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 bc64d9bf02f0c..070def907bcff 100644 --- a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts @@ -15,6 +15,7 @@ import { getPackageSavedObjects } from '../../services/epm/packages/get'; import { defaultIngestErrorHandler } from '../../errors'; const DATA_STREAM_INDEX_PATTERN = 'logs-*-*,metrics-*-*,traces-*-*,synthetics-*-*'; + interface ESDataStreamInfo { name: string; timestamp_field: { @@ -54,12 +55,8 @@ export const getListHandler: RequestHandler = async (context, request, response) try { // Get matching data streams, their stats, and package SOs const [ - { - body: { data_streams: dataStreamsInfo }, - }, - { - body: { data_streams: dataStreamStats }, - }, + { data_streams: dataStreamsInfo }, + { data_streams: dataStreamStats }, packageSavedObjects, ] = await Promise.all([ esClient.indices.getDataStream({ name: DATA_STREAM_INDEX_PATTERN }), @@ -134,9 +131,7 @@ export const getListHandler: RequestHandler = async (context, request, response) }; // Query backing indices to extract data stream dataset, namespace, and type values - const { - body: { aggregations: dataStreamAggs }, - } = await esClient.search({ + const { aggregations: dataStreamAggs } = await esClient.search({ index: dataStream.name, body: { size: 0, diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index cf06fc605e8de..50586badbe0c8 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -678,7 +678,7 @@ class AgentPolicyService { return null; } - return res.body.hits.hits[0]._source; + return res.hits.hits[0]._source; } public async getFullAgentConfigMap( diff --git a/x-pack/plugins/fleet/server/services/agents/crud.test.ts b/x-pack/plugins/fleet/server/services/agents/crud.test.ts index 01b7d21ef2809..6ae8fbd471238 100644 --- a/x-pack/plugins/fleet/server/services/agents/crud.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/crud.test.ts @@ -26,19 +26,19 @@ describe('Agents CRUD test', () => { search: searchMock, } as unknown as ElasticsearchClient; }); + function getEsResponse(ids: string[], total: number) { return { - body: { - hits: { - total: { value: total }, - hits: ids.map((id: string) => ({ - _id: id, - _source: {}, - })), - }, + hits: { + total: { value: total }, + hits: ids.map((id: string) => ({ + _id: id, + _source: {}, + })), }, }; } + it('should return upgradeable on first page', async () => { searchMock .mockImplementationOnce(() => Promise.resolve(getEsResponse(['1', '2', '3', '4', '5'], 7))) diff --git a/x-pack/plugins/fleet/server/services/agents/crud.ts b/x-pack/plugins/fleet/server/services/agents/crud.ts index b37073b11c2ad..426bddd1bd9b9 100644 --- a/x-pack/plugins/fleet/server/services/agents/crud.ts +++ b/x-pack/plugins/fleet/server/services/agents/crud.ts @@ -136,8 +136,8 @@ export async function getAgentsByKuery( }); const res = await queryAgents((page - 1) * perPage, perPage); - let agents = res.body.hits.hits.map(searchHitToAgent); - let total = (res.body.hits.total as estypes.SearchTotalHits).value; + let agents = res.hits.hits.map(searchHitToAgent); + let total = (res.hits.total as estypes.SearchTotalHits).value; // filtering for a range on the version string will not work, // nor does filtering on a flattened field (local_metadata), so filter here if (showUpgradeable) { @@ -146,7 +146,7 @@ export async function getAgentsByKuery( // if there are more than SO_SEARCH_LIMIT agents, the logic falls back to same as before if (total < SO_SEARCH_LIMIT) { const response = await queryAgents(0, SO_SEARCH_LIMIT); - agents = response.body.hits.hits + agents = response.hits.hits .map(searchHitToAgent) .filter((agent) => isAgentUpgradeable(agent, appContextService.getKibanaVersion())); total = agents.length; @@ -217,11 +217,11 @@ export async function getAgentById(esClient: ElasticsearchClient, agentId: strin id: agentId, }); - if (agentHit.body.found === false) { + if (agentHit.found === false) { throw agentNotFoundError; } - return searchHitToAgent(agentHit.body); + return searchHitToAgent(agentHit); } catch (err) { if (isESClientError(err) && err.meta.statusCode === 404) { throw agentNotFoundError; @@ -247,7 +247,7 @@ export async function getAgentDocuments( body: { docs: agentIds.map((_id) => ({ _id })) }, }); - return res.body.docs || []; + return res.docs || []; } export async function getAgentsById( @@ -276,7 +276,7 @@ export async function getAgentByAccessAPIKeyId( q: `access_api_key_id:${escapeSearchQueryPhrase(accessAPIKeyId)}`, }); - const searchHit = res.body.hits.hits[0]; + const searchHit = res.hits.hits[0]; const agent = searchHit && searchHitToAgent(searchHit); if (!searchHit || !agent) { @@ -334,7 +334,7 @@ export async function bulkUpdateAgents( }); return { - items: res.body.items.map((item) => ({ + items: res.items.map((item) => ({ id: item.update!._id as string, success: !item.update!.error, // @ts-expect-error it not assignable to ErrorCause diff --git a/x-pack/plugins/fleet/server/services/agents/reassign.test.ts b/x-pack/plugins/fleet/server/services/agents/reassign.test.ts index 71935ffa5f90c..3a25efc6d49d1 100644 --- a/x-pack/plugins/fleet/server/services/agents/reassign.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/reassign.test.ts @@ -129,7 +129,7 @@ function createClientsMock() { const esClientMock = elasticsearchServiceMock.createClusterClient().asInternalUser; // @ts-expect-error - esClientMock.mget.mockImplementation(async () => { + esClientMock.mget.mockResponseImplementation(() => { return { body: { docs: [agentInHostedDoc, agentInRegularDoc, agentInHostedDoc2], @@ -137,7 +137,7 @@ function createClientsMock() { }; }); // @ts-expect-error - esClientMock.get.mockImplementation(async ({ id }) => { + esClientMock.get.mockResponseImplementation(({ id }) => { switch (id) { case agentInHostedDoc._id: return { body: agentInHostedDoc }; @@ -147,10 +147,10 @@ function createClientsMock() { throw new Error(`${id} not found`); } }); - esClientMock.bulk.mockResolvedValue({ + esClientMock.bulk.mockResponse( // @ts-expect-error not full interface - body: { items: [] }, - }); + { items: [] } + ); return { soClient: soClientMock, esClient: esClientMock }; } diff --git a/x-pack/plugins/fleet/server/services/agents/status.test.ts b/x-pack/plugins/fleet/server/services/agents/status.test.ts index 35300dfc02769..a6fd604ea0e30 100644 --- a/x-pack/plugins/fleet/server/services/agents/status.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/status.test.ts @@ -12,26 +12,26 @@ import { getAgentStatusById } from './status'; describe('Agent status service', () => { it('should return inactive when agent is not active', async () => { const mockElasticsearchClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - mockElasticsearchClient.get.mockResolvedValue({ + mockElasticsearchClient.get.mockResponse( // @ts-expect-error not full interface - body: { + { _id: 'id', _source: { active: false, local_metadata: {}, user_provided_metadata: {}, }, - }, - }); + } + ); const status = await getAgentStatusById(mockElasticsearchClient, 'id'); expect(status).toEqual('inactive'); }); it('should return online when agent is active', async () => { const mockElasticsearchClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - mockElasticsearchClient.get.mockResolvedValue({ + mockElasticsearchClient.get.mockResponse( // @ts-expect-error not full interface - body: { + { _id: 'id', _source: { active: true, @@ -39,36 +39,35 @@ describe('Agent status service', () => { local_metadata: {}, user_provided_metadata: {}, }, - }, - }); + } + ); const status = await getAgentStatusById(mockElasticsearchClient, 'id'); expect(status).toEqual('online'); }); it('should return enrolling when agent is active but never checkin', async () => { const mockElasticsearchClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - mockElasticsearchClient.get.mockResolvedValue({ + mockElasticsearchClient.get.mockResponse( // @ts-expect-error not full interface - body: { + { _id: 'id', _source: { active: true, local_metadata: {}, user_provided_metadata: {}, }, - }, - }); + } + ); const status = await getAgentStatusById(mockElasticsearchClient, 'id'); expect(status).toEqual('enrolling'); }); it('should return unenrolling when agent is unenrolling', async () => { const mockElasticsearchClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - mockElasticsearchClient.get.mockResolvedValue({ + mockElasticsearchClient.get.mockResponse( // @ts-expect-error not full interface - body: { + { _id: 'id', - _source: { active: true, last_checkin: new Date().toISOString(), @@ -76,8 +75,8 @@ describe('Agent status service', () => { local_metadata: {}, user_provided_metadata: {}, }, - }, - }); + } + ); const status = await getAgentStatusById(mockElasticsearchClient, 'id'); expect(status).toEqual('unenrolling'); }); diff --git a/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts b/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts index 7f744ba6a59f4..181b517159c6f 100644 --- a/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts @@ -263,7 +263,7 @@ function createClientMock() { const esClientMock = elasticsearchServiceMock.createClusterClient().asInternalUser; // @ts-expect-error - esClientMock.get.mockImplementation(async ({ id }) => { + esClientMock.get.mockResponseImplementation(({ id }) => { switch (id) { case agentInHostedDoc._id: return { body: agentInHostedDoc }; @@ -275,13 +275,12 @@ function createClientMock() { throw new Error('not found'); } }); - esClientMock.bulk.mockResolvedValue({ + esClientMock.bulk.mockResponse( // @ts-expect-error not full interface - body: { items: [] }, - }); + { items: [] } + ); - // @ts-expect-error - esClientMock.mget.mockImplementation(async (params) => { + esClientMock.mget.mockResponseImplementation((params) => { // @ts-expect-error const docs = params?.body.docs.map(({ _id }) => { switch (_id) { diff --git a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts index 045e6495c9675..03c9e4f979953 100644 --- a/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts +++ b/x-pack/plugins/fleet/server/services/api_keys/enrollment_api_key.ts @@ -51,12 +51,12 @@ export async function listEnrollmentApiKeys( }); // @ts-expect-error @elastic/elasticsearch _source is optional - const items = res.body.hits.hits.map(esDocToEnrollmentApiKey); + const items = res.hits.hits.map(esDocToEnrollmentApiKey); return { items, // @ts-expect-error value is number | TotalHits - total: res.body.hits.total.value, + total: res.hits.total.value, page, perPage, }; @@ -78,13 +78,13 @@ export async function getEnrollmentAPIKey( id: string ): Promise { try { - const res = await esClient.get({ + const body = await esClient.get({ index: ENROLLMENT_API_KEYS_INDEX, id, }); // @ts-expect-error esDocToEnrollmentApiKey doesn't accept optional _source - return esDocToEnrollmentApiKey(res.body); + return esDocToEnrollmentApiKey(body); } catch (e) { if (e instanceof errors.ResponseError && e.statusCode === 404) { throw Boom.notFound(`Enrollment api key ${id} not found`); @@ -207,7 +207,7 @@ export async function generateEnrollmentAPIKey( const name = providedKeyName ? `${providedKeyName} (${id})` : id; - const { body: key } = await esClient.security + const key = await esClient.security .createApiKey({ body: { name, @@ -264,7 +264,7 @@ export async function generateEnrollmentAPIKey( }); return { - id: res.body._id, + id: res._id, ...body, }; } @@ -300,7 +300,7 @@ export async function getEnrollmentAPIKeyById(esClient: ElasticsearchClient, api }); // @ts-expect-error esDocToEnrollmentApiKey doesn't accept optional _source - const [enrollmentAPIKey] = res.body.hits.hits.map(esDocToEnrollmentApiKey); + const [enrollmentAPIKey] = res.hits.hits.map(esDocToEnrollmentApiKey); if (enrollmentAPIKey?.api_key_id !== apiKeyId) { throw new Error( diff --git a/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts b/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts index 745fc1ab196bc..fedb89c1e779b 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts @@ -44,11 +44,7 @@ describe('When using the artifacts services', () => { describe('and calling `getArtifact()`', () => { it('should get artifact using id', async () => { // @ts-expect-error not full interface - esClientMock.get.mockImplementation(() => { - return elasticsearchServiceMock.createSuccessTransportRequestPromise( - generateArtifactEsGetSingleHitMock() - ); - }); + esClientMock.get.mockResponse(generateArtifactEsGetSingleHitMock()); expect(await getArtifact(esClientMock, '123')).toEqual(generateArtifactMock()); expect(esClientMock.get).toHaveBeenCalledWith({ @@ -140,11 +136,7 @@ describe('When using the artifacts services', () => { describe('and calling `listArtifacts()`', () => { beforeEach(() => { - esClientMock.search.mockImplementation(() => { - return elasticsearchServiceMock.createSuccessTransportRequestPromise( - generateArtifactEsSearchResultHitsMock() - ); - }); + esClientMock.search.mockResponse(generateArtifactEsSearchResultHitsMock()); }); it('should use defaults when options is not provided', async () => { diff --git a/x-pack/plugins/fleet/server/services/artifacts/artifacts.ts b/x-pack/plugins/fleet/server/services/artifacts/artifacts.ts index 3a6db6fd0d04f..336a03e841266 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/artifacts.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/artifacts.ts @@ -48,7 +48,7 @@ export const getArtifact = async ( }); // @ts-expect-error @elastic/elasticsearch _source is optional - return esSearchHitToArtifact(esData.body); + return esSearchHitToArtifact(esData); } catch (e) { if (isElasticsearchItemNotFoundError(e)) { return; @@ -114,11 +114,11 @@ export const listArtifacts = async ( return { // @ts-expect-error @elastic/elasticsearch _source is optional - items: searchResult.body.hits.hits.map((hit) => esSearchHitToArtifact(hit)), + items: searchResult.hits.hits.map((hit) => esSearchHitToArtifact(hit)), page, perPage, // @ts-expect-error doesn't handle total as number - total: searchResult.body.hits.total.value, + total: searchResult.hits.total.value, }; } catch (e) { throw new ArtifactsElasticsearchError(e); diff --git a/x-pack/plugins/fleet/server/services/artifacts/client.test.ts b/x-pack/plugins/fleet/server/services/artifacts/client.test.ts index 8b98dc861a756..d5aa2765908c1 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/client.test.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/client.test.ts @@ -29,9 +29,7 @@ describe('When using the Fleet Artifacts Client', () => { } // @ts-expect-error not full interface - esClientMock.get.mockImplementation(() => { - return elasticsearchServiceMock.createSuccessTransportRequestPromise(singleHit); - }); + esClientMock.get.mockResponse(singleHit); }; beforeEach(() => { @@ -105,11 +103,7 @@ describe('When using the Fleet Artifacts Client', () => { describe('and calling `listArtifacts()`', () => { beforeEach(() => { - esClientMock.search.mockImplementation(() => { - return elasticsearchServiceMock.createSuccessTransportRequestPromise( - generateArtifactEsSearchResultHitsMock() - ); - }); + esClientMock.search.mockResponse(generateArtifactEsSearchResultHitsMock()); }); it('should retrieve list bound to packageName', async () => { diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts index d857d7c6bc2fb..7f7e7b2ec10e9 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts @@ -262,7 +262,7 @@ export async function ensureFleetFinalPipelineIsInstalled( }; const res = await esClient.ingest.getPipeline( { id: FLEET_FINAL_PIPELINE_ID }, - esClientRequestOptions + { ...esClientRequestOptions, meta: true } ); const installedVersion = res?.body[FLEET_FINAL_PIPELINE_ID]?.version; diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.test.ts index 554105bb00a92..84dbe324891bc 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.test.ts @@ -63,9 +63,7 @@ describe('EPM install', () => { it('tests installPackage to use correct priority and index_patterns for data stream with dataset_is_prefix set to false', async () => { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - esClient.indices.getIndexTemplate.mockImplementation(() => - elasticsearchServiceMock.createSuccessTransportRequestPromise({ index_templates: [] }) - ); + esClient.indices.getIndexTemplate.mockResponse({ index_templates: [] }); const fields: Field[] = []; const dataStreamDatasetIsPrefixFalse = { @@ -104,9 +102,7 @@ describe('EPM install', () => { it('tests installPackage to use correct priority and index_patterns for data stream with dataset_is_prefix set to true', async () => { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - esClient.indices.getIndexTemplate.mockImplementation(() => - elasticsearchServiceMock.createSuccessTransportRequestPromise({ index_templates: [] }) - ); + esClient.indices.getIndexTemplate.mockResponse({ index_templates: [] }); const fields: Field[] = []; const dataStreamDatasetIsPrefixTrue = { @@ -145,20 +141,19 @@ describe('EPM install', () => { it('tests installPackage remove the aliases property if the property existed', async () => { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - // @ts-expect-error not full interface - esClient.indices.getIndexTemplate.mockImplementation(() => - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - index_templates: [ - { - name: 'metrics-package.dataset', - index_template: { - index_patterns: ['metrics-package.dataset-*'], - template: { aliases: {} }, - }, + + esClient.indices.getIndexTemplate.mockResponse({ + index_templates: [ + { + name: 'metrics-package.dataset', + // @ts-expect-error not full interface + index_template: { + index_patterns: ['metrics-package.dataset-*'], + template: { aliases: {} }, }, - ], - }) - ); + }, + ], + }); const fields: Field[] = []; const dataStreamDatasetIsPrefixUnset = { diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts index 4224ff6b01a19..6bd346f3aff89 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts @@ -203,7 +203,9 @@ interface TemplateMapEntry { settings: NonNullable | object; }; } + type TemplateMap = Record; + function putComponentTemplate( esClient: ElasticsearchClient, logger: Logger, @@ -300,7 +302,7 @@ async function installDataStreamComponentTemplates(params: { () => esClient.cluster.getComponentTemplate({ name }, { ignore: [404] }), { logger } ); - const hasUserSettingsTemplate = result.body.component_templates?.length === 1; + const hasUserSettingsTemplate = result.component_templates?.length === 1; if (!hasUserSettingsTemplate) { // only add if one isn't already present const { clusterPromise } = putComponentTemplate(esClient, logger, { @@ -323,7 +325,7 @@ export async function ensureDefaultComponentTemplate( esClient: ElasticsearchClient, logger: Logger ) { - const { body: getTemplateRes } = await retryTransientEsErrors( + const getTemplateRes = await retryTransientEsErrors( () => esClient.cluster.getComponentTemplate( { @@ -378,7 +380,7 @@ export async function installTemplate({ } // Datastream now throw an error if the aliases field is present so ensure that we remove that field. - const { body: getTemplateRes } = await retryTransientEsErrors( + const getTemplateRes = await retryTransientEsErrors( () => esClient.indices.getIndexTemplate( { diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts index 927b7cb75816c..7999cfa40a11a 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts @@ -841,10 +841,8 @@ describe('EPM template', () => { describe('updateCurrentWriteIndices', () => { it('update all the index matching, index template index pattern', async () => { const esClient = elasticsearchServiceMock.createElasticsearchClient(); - esClient.indices.getDataStream.mockResolvedValue({ - body: { - data_streams: [{ name: 'test.prefix1-default' }], - }, + esClient.indices.getDataStream.mockResponse({ + data_streams: [{ name: 'test.prefix1-default' }], } as any); const logger = loggerMock.create(); await updateCurrentWriteIndices(esClient, logger, [ @@ -868,13 +866,11 @@ describe('EPM template', () => { }); it('update non replicated datastream', async () => { const esClient = elasticsearchServiceMock.createElasticsearchClient(); - esClient.indices.getDataStream.mockResolvedValue({ - body: { - data_streams: [ - { name: 'test-non-replicated' }, - { name: 'test-replicated', replicated: true }, - ], - }, + esClient.indices.getDataStream.mockResponse({ + data_streams: [ + { name: 'test-non-replicated' }, + { name: 'test-replicated', replicated: true }, + ], } as any); const logger = loggerMock.create(); await updateCurrentWriteIndices(esClient, logger, [ diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts index 1988be042a235..a144663546ef3 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts @@ -470,7 +470,7 @@ const getDataStreams = async ( ): Promise => { const { indexTemplate } = template; - const { body } = await esClient.indices.getDataStream({ + const body = await esClient.indices.getDataStream({ name: indexTemplate.index_patterns.join(','), }); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/remove.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/remove.ts index 39681401ac955..6a2284e0df742 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/remove.ts @@ -28,17 +28,8 @@ export const deleteTransforms = async (esClient: ElasticsearchClient, transformI } await Promise.all( transformIds.map(async (transformId) => { - interface TransformResponse { - count: number; - transforms?: Array<{ - dest: { - index: string; - }; - }>; - } - // get the index the transform - const { body: transformResponse } = await esClient.transform.getTransform( + const transformResponse = await esClient.transform.getTransform( { transform_id: transformId }, { ignore: [404] } ); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/transform.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/transform.test.ts index 144bd2240aa01..879c7614fedbf 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/transform.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/transform/transform.test.ts @@ -19,8 +19,7 @@ jest.mock('./common', () => { }); import { errors } from '@elastic/elasticsearch'; -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import type { ElasticsearchClient, SavedObject, SavedObjectsClientContract } from 'kibana/server'; +import type { SavedObject, SavedObjectsClientContract } from 'kibana/server'; import { loggerMock } from '@kbn/logging-mocks'; import { ElasticsearchAssetType } from '../../../../types'; @@ -38,7 +37,7 @@ import { installTransform } from './install'; import { getAsset } from './common'; describe('test transform install', () => { - let esClient: DeeplyMockedKeys; + let esClient: ReturnType; let savedObjectsClient: jest.Mocked; beforeEach(() => { appContextService.start(createAppContextStartContractMock()); @@ -104,18 +103,16 @@ describe('test transform install', () => { } as unknown as SavedObject) ); - esClient.transform.getTransform.mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - count: 1, - transforms: [ - { - dest: { - index: 'index', - }, + esClient.transform.getTransform.mockResponseOnce({ + count: 1, + transforms: [ + { + dest: { + index: 'index', }, - ], - }) - ); + }, + ], + }); await installTransform( { @@ -394,18 +391,16 @@ describe('test transform install', () => { } as unknown as SavedObject) ); - esClient.transform.getTransform.mockReturnValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - count: 1, - transforms: [ - { - dest: { - index: 'index', - }, + esClient.transform.getTransform.mockResponseOnce({ + count: 1, + transforms: [ + { + dest: { + index: 'index', }, - ], - }) - ); + }, + ], + }); await installTransform( { diff --git a/x-pack/plugins/fleet/server/services/fleet_server/index.ts b/x-pack/plugins/fleet/server/services/fleet_server/index.ts index 55b0fb0dff225..0ac47df1bfdaf 100644 --- a/x-pack/plugins/fleet/server/services/fleet_server/index.ts +++ b/x-pack/plugins/fleet/server/services/fleet_server/index.ts @@ -19,5 +19,5 @@ export async function hasFleetServers(esClient: ElasticsearchClient) { }); // @ts-expect-error value is number | TotalHits - return res.body.hits.total.value > 0; + return res.hits.total.value > 0; } diff --git a/x-pack/plugins/fleet/server/telemetry/sender.ts b/x-pack/plugins/fleet/server/telemetry/sender.ts index 2377f5e016deb..47f8a90f6cd68 100644 --- a/x-pack/plugins/fleet/server/telemetry/sender.ts +++ b/x-pack/plugins/fleet/server/telemetry/sender.ts @@ -110,8 +110,7 @@ export class TelemetryEventsSender { throw Error('elasticsearch client is unavailable: cannot retrieve cluster infomation'); } - const { body } = await this.esClient.info(); - return body; + return await this.esClient.info(); } public async sendEvents( diff --git a/x-pack/plugins/graph/server/routes/explore.ts b/x-pack/plugins/graph/server/routes/explore.ts index 7109eee3b9111..6318d8574c397 100644 --- a/x-pack/plugins/graph/server/routes/explore.ts +++ b/x-pack/plugins/graph/server/routes/explore.ts @@ -49,13 +49,11 @@ export function registerExploreRoute({ try { return response.ok({ body: { - resp: ( - await esClient.asCurrentUser.transport.request({ - path: '/' + encodeURIComponent(request.body.index) + '/_graph/explore', - body: request.body.query, - method: 'POST', - }) - ).body, + resp: await esClient.asCurrentUser.transport.request({ + path: '/' + encodeURIComponent(request.body.index) + '/_graph/explore', + body: request.body.query, + method: 'POST', + }), }, }); } catch (error) { diff --git a/x-pack/plugins/graph/server/routes/search.ts b/x-pack/plugins/graph/server/routes/search.ts index 92f3d7a02b072..ba169bf291751 100644 --- a/x-pack/plugins/graph/server/routes/search.ts +++ b/x-pack/plugins/graph/server/routes/search.ts @@ -44,14 +44,12 @@ export function registerSearchRoute({ 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 } : {}), - }) - ).body, + resp: await esClient.asCurrentUser.search({ + index: request.body.index, + body: request.body.body, + track_total_hits: true, + ...(includeFrozen ? { ignore_throttled: false } : {}), + }), }, }); } catch (error) { 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 1f2927436d4ae..fb20812f3307e 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 @@ -39,9 +39,7 @@ export function registerGrokSimulateRoute(framework: KibanaFramework) { await requestContext.core.elasticsearch.client.asCurrentUser.ingest.simulate({ body: grokdebuggerRequest.upstreamJSON, }); - const grokdebuggerResponse = GrokdebuggerResponse.fromUpstreamJSON( - simulateResponseFromES.body - ); + const grokdebuggerResponse = GrokdebuggerResponse.fromUpstreamJSON(simulateResponseFromES); return response.ok({ body: grokdebuggerResponse, }); diff --git a/x-pack/plugins/index_lifecycle_management/server/plugin.ts b/x-pack/plugins/index_lifecycle_management/server/plugin.ts index 08b1033371ad5..e8f675ea7e674 100644 --- a/x-pack/plugins/index_lifecycle_management/server/plugin.ts +++ b/x-pack/plugins/index_lifecycle_management/server/plugin.ts @@ -26,9 +26,7 @@ const indexLifecycleDataEnricher = async ( return []; } - const { - body: { indices: ilmIndicesData }, - } = await client.asCurrentUser.ilm.explainLifecycle({ + const { indices: ilmIndicesData } = await client.asCurrentUser.ilm.explainLifecycle({ index: '*', }); // @ts-expect-error IndexLifecyclePolicy is not compatible with IlmExplainLifecycleResponse @@ -100,5 +98,6 @@ export class IndexLifecycleManagementServerPlugin implements Plugin { const policyEntry = policiesMap[lifecycleName]; @@ -50,6 +51,7 @@ async function fetchPolicies(client: ElasticsearchClient): Promise { const response = await client.indices.getTemplate({ name: templateName }); - return response.body[templateName]; + return response[templateName]; } async function getIndexTemplate( @@ -39,7 +39,7 @@ async function getIndexTemplate( options ); - const { index_templates: templates } = response.body as { + const { index_templates: templates } = response as { index_templates: TemplateFromEs[]; }; return templates.find((template) => template.name === templateName)?.index_template; 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 34a1bac2c4fd9..11811c7b7d26c 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 @@ -74,7 +74,7 @@ async function fetchTemplates( const response = isLegacy ? await client.indices.getTemplate({}, options) : await client.indices.getIndexTemplate({}, options); - return response.body; + return response; } const querySchema = schema.object({ diff --git a/x-pack/plugins/index_management/server/lib/fetch_indices.test.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.test.ts index 900e3ecc32501..570e609219263 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.test.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.test.ts @@ -33,15 +33,11 @@ describe('[Index management API Routes] fetch indices lib function', () => { test('regular index', async () => { getIndices.mockResolvedValue({ - body: { - regular_index: createTestIndexState(), - }, + regular_index: createTestIndexState(), }); getIndicesStats.mockResolvedValue({ - body: { - indices: { - regular_index: createTestIndexStats({ uuid: 'regular_index' }), - }, + indices: { + regular_index: createTestIndexStats({ uuid: 'regular_index' }), }, }); @@ -51,17 +47,13 @@ describe('[Index management API Routes] fetch indices lib function', () => { }); test('index with aliases', async () => { getIndices.mockResolvedValue({ - body: { - index_with_aliases: createTestIndexState({ - aliases: { test_alias: {}, another_alias: {} }, - }), - }, + index_with_aliases: createTestIndexState({ + aliases: { test_alias: {}, another_alias: {} }, + }), }); getIndicesStats.mockResolvedValue({ - body: { - indices: { - index_with_aliases: createTestIndexStats({ uuid: 'index_with_aliases' }), - }, + indices: { + index_with_aliases: createTestIndexStats({ uuid: 'index_with_aliases' }), }, }); @@ -77,18 +69,14 @@ describe('[Index management API Routes] fetch indices lib function', () => { }); test('frozen index', async () => { getIndices.mockResolvedValue({ - body: { - frozen_index: createTestIndexState({ - // @ts-expect-error - settings: { index: { number_of_shards: 1, number_of_replicas: 1, frozen: 'true' } }, - }), - }, + frozen_index: createTestIndexState({ + // @ts-expect-error + settings: { index: { number_of_shards: 1, number_of_replicas: 1, frozen: 'true' } }, + }), }); getIndicesStats.mockResolvedValue({ - body: { - indices: { - frozen_index: createTestIndexStats({ uuid: 'frozen_index' }), - }, + indices: { + frozen_index: createTestIndexStats({ uuid: 'frozen_index' }), }, }); @@ -104,17 +92,13 @@ describe('[Index management API Routes] fetch indices lib function', () => { }); test('hidden index', async () => { getIndices.mockResolvedValue({ - body: { - hidden_index: createTestIndexState({ - settings: { index: { number_of_shards: 1, number_of_replicas: 1, hidden: 'true' } }, - }), - }, + hidden_index: createTestIndexState({ + settings: { index: { number_of_shards: 1, number_of_replicas: 1, hidden: 'true' } }, + }), }); getIndicesStats.mockResolvedValue({ - body: { - indices: { - hidden_index: createTestIndexStats({ uuid: 'hidden_index' }), - }, + indices: { + hidden_index: createTestIndexStats({ uuid: 'hidden_index' }), }, }); @@ -130,17 +114,13 @@ describe('[Index management API Routes] fetch indices lib function', () => { }); test('data stream index', async () => { getIndices.mockResolvedValue({ - body: { - data_stream_index: createTestIndexState({ - data_stream: 'test_data_stream', - }), - }, + data_stream_index: createTestIndexState({ + data_stream: 'test_data_stream', + }), }); getIndicesStats.mockResolvedValue({ - body: { - indices: { - data_stream_index: createTestIndexStats({ uuid: 'data_stream_index' }), - }, + indices: { + data_stream_index: createTestIndexStats({ uuid: 'data_stream_index' }), }, }); @@ -156,17 +136,13 @@ describe('[Index management API Routes] fetch indices lib function', () => { }); test('index missing in stats call', async () => { getIndices.mockResolvedValue({ - body: { - index_missing_stats: createTestIndexState(), - }, + index_missing_stats: createTestIndexState(), }); // simulates when an index has been deleted after get indices call // deleted index won't be present in the indices stats call response getIndicesStats.mockResolvedValue({ - body: { - indices: { - some_other_index: createTestIndexStats({ uuid: 'some_other_index' }), - }, + indices: { + some_other_index: createTestIndexStats({ uuid: 'some_other_index' }), }, }); await expect(router.runRequest(mockRequest)).resolves.toEqual({ diff --git a/x-pack/plugins/index_management/server/lib/fetch_indices.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.ts index f4b39784dde22..9e8a8b23a7d9d 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.ts @@ -17,7 +17,7 @@ async function fetchIndicesCall( const indexNamesString = indexNames && indexNames.length ? indexNames.join(',') : '*'; // This call retrieves alias and settings (incl. hidden status) information about indices - const { body: indices } = await client.asCurrentUser.indices.get({ + const indices = await client.asCurrentUser.indices.get({ index: indexNamesString, expand_wildcards: ['hidden', 'all'], // only get specified index properties from ES to keep the response under 536MB @@ -39,9 +39,7 @@ async function fetchIndicesCall( return []; } - const { - body: { indices: indicesStats = {} }, - } = await client.asCurrentUser.indices.stats({ + const { indices: indicesStats = {} } = await client.asCurrentUser.indices.stats({ index: indexNamesString, expand_wildcards: ['hidden', 'all'], forbid_closed_indices: false, diff --git a/x-pack/plugins/index_management/server/lib/get_managed_templates.ts b/x-pack/plugins/index_management/server/lib/get_managed_templates.ts index 8e60044dc4951..c224799a8c35c 100644 --- a/x-pack/plugins/index_management/server/lib/get_managed_templates.ts +++ b/x-pack/plugins/index_management/server/lib/get_managed_templates.ts @@ -13,9 +13,7 @@ export const getCloudManagedTemplatePrefix = async ( client: IScopedClusterClient ): Promise => { try { - const { - body: { persistent, transient, defaults }, - } = await client.asCurrentUser.cluster.getSettings({ + const { persistent, transient, defaults } = await client.asCurrentUser.cluster.getSettings({ filter_path: '*.*managed_index_templates', flat_settings: true, include_defaults: true, 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 b4683f1b8cb14..296dcd726e52a 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 @@ -32,11 +32,10 @@ export const registerCreateRoute = ({ try { // Check that a component template with the same name doesn't already exist - const { - body: { component_templates: componentTemplates }, - } = await client.asCurrentUser.cluster.getComponentTemplate({ - name, - }); + const { component_templates: componentTemplates } = + await client.asCurrentUser.cluster.getComponentTemplate({ + name, + }); if (componentTemplates.length) { return response.conflict({ @@ -55,7 +54,7 @@ export const registerCreateRoute = ({ } try { - const { body: responseBody } = await client.asCurrentUser.cluster.putComponentTemplate({ + const responseBody = await client.asCurrentUser.cluster.putComponentTemplate({ name, // @ts-expect-error ComponentTemplateSerialized conflicts with @elastic/elasticsearch ClusterPutComponentTemplateRequest body: serializedComponentTemplate, 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 a77aa90c52f73..039eb24f4d9d6 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 @@ -27,13 +27,11 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep const { client } = context.core.elasticsearch; try { - const { - body: { component_templates: componentTemplates }, - } = await client.asCurrentUser.cluster.getComponentTemplate(); + const { component_templates: componentTemplates } = + await client.asCurrentUser.cluster.getComponentTemplate(); - const { - body: { index_templates: indexTemplates }, - } = await client.asCurrentUser.indices.getIndexTemplate(); + const { index_templates: indexTemplates } = + await client.asCurrentUser.indices.getIndexTemplate(); const body = componentTemplates.map((componentTemplate: ComponentTemplateFromEs) => { const deserializedComponentTemplateListItem = deserializeComponentTemplateList( @@ -63,15 +61,13 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep const { name } = request.params; try { - const { - body: { component_templates: componentTemplates }, - } = await client.asCurrentUser.cluster.getComponentTemplate({ - name, - }); + const { component_templates: componentTemplates } = + await client.asCurrentUser.cluster.getComponentTemplate({ + name, + }); - const { - body: { index_templates: indexTemplates }, - } = await client.asCurrentUser.indices.getIndexTemplate(); + const { index_templates: indexTemplates } = + await client.asCurrentUser.indices.getIndexTemplate(); return response.ok({ body: deserializeComponentTemplate(componentTemplates[0], indexTemplates), diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.test.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.test.ts index 2c5070ab846ad..dd37ad56ea4b4 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.test.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/register_privileges_route.test.ts @@ -58,13 +58,11 @@ describe('GET privileges', () => { it('should return the correct response when a user has privileges', async () => { const privilegesResponseMock = { - body: { - username: 'elastic', - has_all_requested: true, - cluster: { manage_index_templates: true }, - index: {}, - application: {}, - }, + username: 'elastic', + has_all_requested: true, + cluster: { manage_index_templates: true }, + index: {}, + application: {}, }; const routeContextMock = mockRouteContext({ @@ -84,13 +82,11 @@ describe('GET privileges', () => { it('should return the correct response when a user does not have privileges', async () => { const privilegesResponseMock = { - body: { - username: 'elastic', - has_all_requested: false, - cluster: { manage_index_templates: false }, - index: {}, - application: {}, - }, + username: 'elastic', + has_all_requested: false, + cluster: { manage_index_templates: false }, + index: {}, + application: {}, }; const routeContextMock = mockRouteContext({ 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 327e6421525c6..b99e16f7eb1f2 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 @@ -43,13 +43,12 @@ export const registerPrivilegesRoute = ({ const { client } = context.core.elasticsearch; try { - const { - body: { has_all_requested: hasAllPrivileges, cluster }, - } = await client.asCurrentUser.security.hasPrivileges({ - body: { - cluster: ['manage_index_templates'], - }, - }); + const { has_all_requested: hasAllPrivileges, cluster } = + await client.asCurrentUser.security.hasPrivileges({ + body: { + cluster: ['manage_index_templates'], + }, + }); if (!hasAllPrivileges) { privilegesResult.missingPrivileges.cluster = extractMissingPrivileges(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 c2235b9eb85ab..97d7c52dde044 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 @@ -37,7 +37,7 @@ export const registerUpdateRoute = ({ // Verify component exists; ES will throw 404 if not await client.asCurrentUser.cluster.getComponentTemplate({ name }); - const { body: responseBody } = await client.asCurrentUser.cluster.putComponentTemplate({ + const responseBody = await client.asCurrentUser.cluster.putComponentTemplate({ name, body: { template: template as estypes.IndicesIndexState, 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 87eecfbfbbbad..4c44d1a8212f9 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 @@ -108,24 +108,20 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: const includeStats = (request.query as TypeOf).includeStats === 'true'; try { - const { - body: { data_streams: dataStreams }, - } = await getDataStreams(client); + const { data_streams: dataStreams } = await getDataStreams(client); let dataStreamsStats; let dataStreamsPrivileges; if (includeStats) { - ({ - body: { data_streams: dataStreamsStats }, - } = await getDataStreamsStats(client)); + ({ data_streams: dataStreamsStats } = await getDataStreamsStats(client)); } if (config.isSecurityEnabled() && dataStreams.length > 0) { - ({ body: dataStreamsPrivileges } = await getDataStreamsPrivileges( + dataStreamsPrivileges = await getDataStreamsPrivileges( client, dataStreams.map((dataStream) => dataStream.name) - )); + ); } const enhancedDataStreams = enhanceDataStreams({ @@ -158,21 +154,13 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: const { name } = request.params as TypeOf; const { client } = context.core.elasticsearch; try { - const [ - { - body: { data_streams: dataStreams }, - }, - { - body: { data_streams: dataStreamsStats }, - }, - ] = await Promise.all([getDataStreams(client, name), getDataStreamsStats(client, name)]); + const [{ data_streams: dataStreams }, { data_streams: dataStreamsStats }] = + await Promise.all([getDataStreams(client, name), getDataStreamsStats(client, name)]); if (dataStreams[0]) { let dataStreamsPrivileges; if (config.isSecurityEnabled()) { - ({ body: dataStreamsPrivileges } = await getDataStreamsPrivileges(client, [ - dataStreams[0].name, - ])); + dataStreamsPrivileges = await getDataStreamsPrivileges(client, [dataStreams[0].name]); } const enhancedDataStreams = enhanceDataStreams({ 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 1bb54798c6804..cef20539f9403 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 @@ -33,7 +33,7 @@ export function registerMappingRoute({ router, lib: { handleEsError } }: RouteDe }; try { - const { body: hit } = await client.asCurrentUser.indices.getMapping(params); + const hit = await client.asCurrentUser.indices.getMapping(params); const responseBody = formatHit(hit, indexName); return response.ok({ body: responseBody }); } catch (error) { diff --git a/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.test.ts b/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.test.ts index aa3591d2d064f..fb104b3dc868f 100644 --- a/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.test.ts +++ b/x-pack/plugins/index_management/server/routes/api/nodes/register_nodes_route.test.ts @@ -29,14 +29,12 @@ describe('[Index management API Routes] Nodes info', () => { // Mock the response from the ES client ('nodes.info()') getNodesInfo.mockResolvedValue({ - body: { - nodes: { - node1: { - plugins: [{ name: 'plugin-1' }, { name: 'plugin-2' }], - }, - node2: { - plugins: [{ name: 'plugin-1' }, { name: 'plugin-3' }], - }, + nodes: { + node1: { + plugins: [{ name: 'plugin-1' }, { name: 'plugin-2' }], + }, + node2: { + plugins: [{ name: 'plugin-1' }, { name: 'plugin-3' }], }, }, }); 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 f2cfae32d00fe..5c9751c8506cf 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 @@ -16,7 +16,7 @@ export function registerNodesRoute({ router, lib: { handleEsError } }: RouteDepe const { client } = context.core.elasticsearch; try { - const { body } = await client.asCurrentUser.nodes.info(); + const body = await client.asCurrentUser.nodes.info(); const plugins: Set = Object.values(body.nodes).reduce((acc, nodeInfo) => { nodeInfo.plugins?.forEach(({ name }) => { acc.add(name); 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 b942f1976b2fd..ceb59916811d8 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 @@ -36,7 +36,7 @@ export function registerLoadRoute({ router, lib: { handleEsError } }: RouteDepen }; try { - const { body: hit } = await client.asCurrentUser.indices.getSettings(params); + const hit = await client.asCurrentUser.indices.getSettings(params); return response.ok({ body: formatHit(hit) }); } catch (error) { return handleEsError({ error, response }); 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 4021af3b75014..b7a38cb04782e 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 @@ -34,7 +34,7 @@ export function registerUpdateRoute({ router, lib: { handleEsError } }: RouteDep }; try { - const { body: responseBody } = await client.asCurrentUser.indices.putSettings(params); + const responseBody = await client.asCurrentUser.indices.putSettings(params); return response.ok({ body: responseBody }); } catch (error) { return handleEsError({ error, response }); 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 6e74523dbd197..f178cc8ace6bc 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 @@ -41,7 +41,7 @@ export function registerStatsRoute({ router, lib: { handleEsError } }: RouteDepe }; try { - const { body: hit } = await client.asCurrentUser.indices.stats(params); + const hit = await client.asCurrentUser.indices.stats(params); return response.ok({ body: formatHit(hit, indexName) }); } catch (error) { 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 21be254eb9d73..20a3e1e97dd6c 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 @@ -28,7 +28,7 @@ export function registerCreateRoute({ router, lib: { handleEsError } }: RouteDep } = template; // Check that template with the same name doesn't already exist - const { body: templateExists } = await doesTemplateExist({ + const templateExists = await doesTemplateExist({ name: template.name, client, isLegacy, @@ -48,7 +48,7 @@ export function registerCreateRoute({ router, lib: { handleEsError } }: RouteDep } // Otherwise create new index template - const { body: responseBody } = await saveTemplate({ template, client, isLegacy }); + const responseBody = await saveTemplate({ template, client, isLegacy }); return response.ok({ body: responseBody }); } catch (error) { 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 9d0b7302b5587..8eedcee590fd5 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 @@ -26,10 +26,9 @@ export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDep try { const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(client); - const { body: legacyTemplatesEs } = await client.asCurrentUser.indices.getTemplate(); - const { - body: { index_templates: templatesEs }, - } = await client.asCurrentUser.indices.getIndexTemplate(); + const legacyTemplatesEs = await client.asCurrentUser.indices.getTemplate(); + const { index_templates: templatesEs } = + await client.asCurrentUser.indices.getIndexTemplate(); const legacyTemplates = deserializeLegacyTemplateList( legacyTemplatesEs, @@ -74,7 +73,7 @@ export function registerGetOneRoute({ router, lib: { handleEsError } }: RouteDep const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(client); if (isLegacy) { - const { body: indexTemplateByName } = await client.asCurrentUser.indices.getTemplate({ + const indexTemplateByName = await client.asCurrentUser.indices.getTemplate({ name, }); @@ -87,9 +86,8 @@ export function registerGetOneRoute({ router, lib: { handleEsError } }: RouteDep }); } } else { - const { - body: { index_templates: indexTemplates }, - } = await client.asCurrentUser.indices.getIndexTemplate({ name }); + const { index_templates: indexTemplates } = + await client.asCurrentUser.indices.getIndexTemplate({ name }); if (indexTemplates.length > 0) { return response.ok({ 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 e45d86f3e2b27..ab937fc366d4c 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 @@ -23,7 +23,7 @@ export function registerSimulateRoute({ router, lib: { handleEsError } }: RouteD const template = request.body as TypeOf; try { - const { body: templatePreview } = await client.asCurrentUser.indices.simulateTemplate({ + const templatePreview = await client.asCurrentUser.indices.simulateTemplate({ body: { ...template, // Until ES fixes a bug on their side we need to send a fake index pattern 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 669a1fff66317..f700497e924b4 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 @@ -35,14 +35,14 @@ export function registerUpdateRoute({ router, lib: { handleEsError } }: RouteDep } = template; // Verify the template exists (ES will throw 404 if not) - const { body: templateExists } = await doesTemplateExist({ name, client, isLegacy }); + const templateExists = await doesTemplateExist({ name, client, isLegacy }); if (!templateExists) { return response.notFound(); } // Next, update index template - const { body: responseBody } = await saveTemplate({ template, client, isLegacy }); + const responseBody = await saveTemplate({ template, client, isLegacy }); return response.ok({ body: responseBody }); } catch (error) { 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 0c0284e328dd3..3ed94af04031f 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 @@ -199,7 +199,7 @@ export class KibanaFramework { } as estypes.MlGetBucketsRequest); break; } - return apiResult ? (await apiResult).body : undefined; + return apiResult ? await apiResult : undefined; } public async getIndexPatternsServiceWithRequestContext( diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/lib/get_data.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/lib/get_data.ts index 83751087d9aff..9f8bd5674dcef 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/lib/get_data.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/lib/get_data.ts @@ -84,7 +84,7 @@ export const getData = async ( filterQuery, customMetric ); - const { body } = await esClient.search(request); + const body = await esClient.search(request); if (body.aggregations) { return handleResponse(body.aggregations, previousNodes); } diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index f817b68b919ba..674ba977e09c0 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -759,7 +759,7 @@ const getQueryMappingForComparator = (comparator: Comparator) => { }; const getUngroupedResults = async (query: object, esClient: ElasticsearchClient) => { - return decodeOrThrow(UngroupedSearchQueryResponseRT)((await esClient.search(query)).body); + return decodeOrThrow(UngroupedSearchQueryResponseRT)(await esClient.search(query)); }; const getGroupedResults = async (query: object, esClient: ElasticsearchClient) => { @@ -770,7 +770,7 @@ const getGroupedResults = async (query: object, esClient: ElasticsearchClient) = const queryWithAfterKey: any = { ...query }; queryWithAfterKey.body.aggregations.groups.composite.after = lastAfterKey; const groupResponse: GroupedSearchQueryResponse = decodeOrThrow(GroupedSearchQueryResponseRT)( - (await esClient.search(queryWithAfterKey)).body + await esClient.search(queryWithAfterKey) ); compositeGroupBuckets = [ ...compositeGroupBuckets, diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/evaluate_rule.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/evaluate_rule.ts index 4fbac02cff19b..744fd80134aec 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/evaluate_rule.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/evaluate_rule.ts @@ -199,7 +199,7 @@ const getMetric: ( ); const compositeBuckets = (await getAllCompositeData( // @ts-expect-error @elastic/elasticsearch SearchResponse.body.timeout is not required - (body) => esClient.search({ body, index }), + (body) => esClient.search({ body, index }, { meta: true }), searchBody, bucketSelector, afterKeyHandler @@ -218,7 +218,7 @@ const getMetric: ( } return groupedResults; } - const { body: result } = await esClient.search({ + const result = await esClient.search({ body: searchBody, index, }); diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts index 57001d8cbdb1a..1929a91d763d1 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts @@ -5,8 +5,6 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { AlertInstanceContext as AlertContext, AlertInstanceState as AlertState, @@ -784,43 +782,39 @@ const services: AlertServicesMock & LifecycleAlertServices { - const from = params?.body.query.bool.filter[0]?.range['@timestamp'].gte; - if (params.index === 'alternatebeat-*') return mocks.changedSourceIdResponse(from); +services.scopedClusterClient.asCurrentUser.search.mockResponseImplementation( + (params?: any): any => { + const from = params?.body.query.bool.filter[0]?.range['@timestamp'].gte; - if (params.index === 'empty-response') return mocks.emptyMetricResponse; + if (params.index === 'alternatebeat-*') return { body: mocks.changedSourceIdResponse(from) }; - const metric = params?.body.query.bool.filter[1]?.exists.field; - if (metric === 'test.metric.3') { - return elasticsearchClientMock.createSuccessTransportRequestPromise( - params?.body.aggs.aggregatedIntervals?.aggregations.aggregatedValueMax - ? mocks.emptyRateResponse - : mocks.emptyMetricResponse - ); - } - if (params?.body.aggs.groupings) { - if (params?.body.aggs.groupings.composite.after) { - return elasticsearchClientMock.createSuccessTransportRequestPromise( - mocks.compositeEndResponse - ); + if (params.index === 'empty-response') return { body: mocks.emptyMetricResponse }; + + const metric = params?.body.query.bool.filter[1]?.exists.field; + if (metric === 'test.metric.3') { + return { + body: params?.body.aggs.aggregatedIntervals?.aggregations.aggregatedValueMax + ? mocks.emptyRateResponse + : mocks.emptyMetricResponse, + }; + } + if (params?.body.aggs.groupings) { + if (params?.body.aggs.groupings.composite.after) { + return { body: mocks.compositeEndResponse }; + } + if (metric === 'test.metric.2') { + return { body: mocks.alternateCompositeResponse(from) }; + } + return { body: mocks.basicCompositeResponse(from) }; } if (metric === 'test.metric.2') { - return elasticsearchClientMock.createSuccessTransportRequestPromise( - mocks.alternateCompositeResponse(from) - ); + return { body: mocks.alternateMetricResponse() }; } - return elasticsearchClientMock.createSuccessTransportRequestPromise( - mocks.basicCompositeResponse(from) - ); + return { body: mocks.basicMetricResponse() }; } - if (metric === 'test.metric.2') { - return elasticsearchClientMock.createSuccessTransportRequestPromise( - mocks.alternateMetricResponse() - ); - } - return elasticsearchClientMock.createSuccessTransportRequestPromise(mocks.basicMetricResponse()); -}); +); + services.savedObjectsClient.get.mockImplementation(async (type: string, sourceId: string) => { if (sourceId === 'alternate') return { @@ -909,7 +903,9 @@ declare global { namespace jest { interface Matchers { toBeAlertAction(action?: Action): R; + toBeNoDataAction(action?: Action): R; + toBeErrorAction(action?: Action): R; } } diff --git a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts index d1d136c741876..316f868589064 100644 --- a/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts +++ b/x-pack/plugins/infra/server/lib/log_analysis/log_entry_categories_analysis.ts @@ -416,20 +416,18 @@ async function fetchLogEntryCategoryExamples( const { hits: { hits }, } = decodeOrThrow(logEntryCategoryExamplesResponseRT)( - ( - await requestContext.core.elasticsearch.client.asCurrentUser.search( - createLogEntryCategoryExamplesQuery( - indices, - runtimeMappings, - timestampField, - tiebreakerField, - startTime, - endTime, - categoryQuery, - exampleCount - ) + await requestContext.core.elasticsearch.client.asCurrentUser.search( + createLogEntryCategoryExamplesQuery( + indices, + runtimeMappings, + timestampField, + tiebreakerField, + startTime, + endTime, + categoryQuery, + exampleCount ) - ).body + ) ); const esSearchSpan = finalizeEsSearchSpan(); 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 b078ca051a272..90893b2841cc0 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/create.ts @@ -38,7 +38,7 @@ export const registerCreateRoute = ({ try { // Check that a pipeline with the same name doesn't already exist - const { body: pipelineByName } = await clusterClient.asCurrentUser.ingest.getPipeline({ + const pipelineByName = await clusterClient.asCurrentUser.ingest.getPipeline({ id: name, }); @@ -59,7 +59,7 @@ export const registerCreateRoute = ({ } try { - const { body: response } = await clusterClient.asCurrentUser.ingest.putPipeline({ + const response = await clusterClient.asCurrentUser.ingest.putPipeline({ id: name, body: { description, 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 6f7233c70dbfe..d9f27ed84f899 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/documents.ts @@ -31,7 +31,7 @@ export const registerDocumentsRoute = ({ const { index, id } = req.params; try { - const { body: document } = await clusterClient.asCurrentUser.get({ index, id }); + const document = await clusterClient.asCurrentUser.get({ index, id }); const { _id, _index, _source } = document; 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 b512ebda5ecdb..7da2cf3e6a13a 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/get.ts @@ -21,7 +21,7 @@ export const registerGetRoutes = ({ router, lib: { handleEsError } }: RouteDepen const { client: clusterClient } = ctx.core.elasticsearch; try { - const { body: pipelines } = await clusterClient.asCurrentUser.ingest.getPipeline(); + const pipelines = await clusterClient.asCurrentUser.ingest.getPipeline(); return res.ok({ body: deserializePipelines(pipelines) }); } catch (error) { @@ -48,7 +48,7 @@ export const registerGetRoutes = ({ router, lib: { handleEsError } }: RouteDepen const { name } = req.params; try { - const { body: pipelines } = await clusterClient.asCurrentUser.ingest.getPipeline({ + const pipelines = await clusterClient.asCurrentUser.ingest.getPipeline({ id: name, }); 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 a2882fd7855d6..c1d79eabceb04 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/privileges.ts @@ -38,12 +38,11 @@ export const registerPrivilegesRoute = ({ router, config }: RouteDependencies) = const { client: clusterClient } = ctx.core.elasticsearch; - const { - body: { has_all_requested: hasAllPrivileges, cluster }, - } = await clusterClient.asCurrentUser.security.hasPrivileges({ - // @ts-expect-error @elastic/elasticsearch SecurityClusterPrivilege doesn’t contain all the priviledges - body: { cluster: APP_CLUSTER_REQUIRED_PRIVILEGES }, - }); + const { has_all_requested: hasAllPrivileges, cluster } = + await clusterClient.asCurrentUser.security.hasPrivileges({ + // @ts-expect-error @elastic/elasticsearch SecurityClusterPrivilege doesn’t contain all the priviledges + body: { cluster: APP_CLUSTER_REQUIRED_PRIVILEGES }, + }); if (!hasAllPrivileges) { privilegesResult.missingPrivileges.cluster = extractMissingPrivileges(cluster); 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 c6d628294a734..9e4e894e2c7cb 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/simulate.ts @@ -34,7 +34,7 @@ export const registerSimulateRoute = ({ const { pipeline, documents, verbose } = req.body; try { - const { body: response } = await clusterClient.asCurrentUser.ingest.simulate({ + const response = await clusterClient.asCurrentUser.ingest.simulate({ verbose, body: { pipeline, 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 35af1395f5e37..51983f12e6a60 100644 --- a/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts +++ b/x-pack/plugins/ingest_pipelines/server/routes/api/update.ts @@ -39,7 +39,7 @@ export const registerUpdateRoute = ({ // Verify pipeline exists; ES will throw 404 if it doesn't await clusterClient.asCurrentUser.ingest.getPipeline({ id: name }); - const { body: response } = await clusterClient.asCurrentUser.ingest.putPipeline({ + const response = await clusterClient.asCurrentUser.ingest.putPipeline({ id: name, body: { description, diff --git a/x-pack/plugins/lens/server/routes/existing_fields.ts b/x-pack/plugins/lens/server/routes/existing_fields.ts index 0ee1d92d1b4ec..c5f7cfab9c245 100644 --- a/x-pack/plugins/lens/server/routes/existing_fields.ts +++ b/x-pack/plugins/lens/server/routes/existing_fields.ts @@ -231,7 +231,7 @@ async function fetchIndexPatternStats({ const scriptedFields = fields.filter((f) => f.isScript); const runtimeFields = fields.filter((f) => f.runtimeField); - const { body: result } = await client.search( + const result = await client.search( { index, ...(includeFrozen ? { ignore_throttled: false } : {}), diff --git a/x-pack/plugins/lens/server/routes/field_stats.ts b/x-pack/plugins/lens/server/routes/field_stats.ts index 9e48c00b9d8cb..6c1a93759030a 100644 --- a/x-pack/plugins/lens/server/routes/field_stats.ts +++ b/x-pack/plugins/lens/server/routes/field_stats.ts @@ -89,7 +89,7 @@ export async function initFieldsRoute(setup: CoreSetup) { }, {} as Record); const search = async (aggs: Record) => { - const { body: result } = await requestClient.search({ + const result = await requestClient.search({ index: indexPattern.title, track_total_hits: true, body: { diff --git a/x-pack/plugins/lens/server/usage/saved_objects_metric_factory.ts b/x-pack/plugins/lens/server/usage/saved_objects_metric_factory.ts index 883bd1269cd73..568b79ca47780 100644 --- a/x-pack/plugins/lens/server/usage/saved_objects_metric_factory.ts +++ b/x-pack/plugins/lens/server/usage/saved_objects_metric_factory.ts @@ -26,7 +26,7 @@ export function createMetricQuery( bucketsToObject?: (arg: unknown) => Record; }): Promise { const esClient = await getEsClient(); - const { body: results } = await esClient.search({ + const results = await esClient.search({ index: kibanaIndex, body: { query: { diff --git a/x-pack/plugins/lens/server/usage/task.ts b/x-pack/plugins/lens/server/usage/task.ts index 22a57017b0d1b..53af2e5551b6a 100644 --- a/x-pack/plugins/lens/server/usage/task.ts +++ b/x-pack/plugins/lens/server/usage/task.ts @@ -113,23 +113,23 @@ export async function getDailyEvents( }, }; - const { body: metrics } = await esClient.search< - ESSearchResponse - >({ - index: kibanaIndex, - body: { - query: { - bool: { - filter: [ - { term: { type: 'lens-ui-telemetry' } }, - { range: { 'lens-ui-telemetry.date': { gte: 'now-90d/d' } } }, - ], + const metrics = await esClient.search>( + { + index: kibanaIndex, + body: { + query: { + bool: { + filter: [ + { term: { type: 'lens-ui-telemetry' } }, + { range: { 'lens-ui-telemetry.date': { gte: 'now-90d/d' } } }, + ], + }, }, + aggs, }, - aggs, - }, - size: 0, - }); + size: 0, + } + ); const byDateByType: Record> = {}; const suggestionsByDate: Record> = {}; diff --git a/x-pack/plugins/license_management/server/lib/license.ts b/x-pack/plugins/license_management/server/lib/license.ts index f23aba4c1d3ef..12f831f3d780a 100644 --- a/x-pack/plugins/license_management/server/lib/license.ts +++ b/x-pack/plugins/license_management/server/lib/license.ts @@ -17,7 +17,7 @@ interface PutLicenseArg { export async function putLicense({ acknowledge, client, licensing, license }: PutLicenseArg) { try { - const { body: response } = await client.asCurrentUser.license.post({ + const response = await client.asCurrentUser.license.post({ body: license, acknowledge, }); diff --git a/x-pack/plugins/license_management/server/lib/permissions.ts b/x-pack/plugins/license_management/server/lib/permissions.ts index 06395fb6302b6..64ccabcd5ee68 100644 --- a/x-pack/plugins/license_management/server/lib/permissions.ts +++ b/x-pack/plugins/license_management/server/lib/permissions.ts @@ -21,7 +21,7 @@ export async function getPermissions({ isSecurityEnabled, client }: GetPermissio } try { - const { body: response } = await client.asCurrentUser.security.hasPrivileges({ + const response = await client.asCurrentUser.security.hasPrivileges({ body: { cluster: ['manage'], // License management requires "manage" cluster privileges }, diff --git a/x-pack/plugins/license_management/server/lib/start_basic.ts b/x-pack/plugins/license_management/server/lib/start_basic.ts index e45c758b304de..8c077332f0709 100644 --- a/x-pack/plugins/license_management/server/lib/start_basic.ts +++ b/x-pack/plugins/license_management/server/lib/start_basic.ts @@ -16,7 +16,7 @@ interface StartBasicArg { export async function startBasic({ acknowledge, client, licensing }: StartBasicArg) { try { - const { body: response } = await client.asCurrentUser.license.postStartBasic({ acknowledge }); + const response = await client.asCurrentUser.license.postStartBasic({ acknowledge }); const { basic_was_started: basicWasStarted } = response; if (basicWasStarted) { await licensing.refresh(); diff --git a/x-pack/plugins/license_management/server/lib/start_trial.ts b/x-pack/plugins/license_management/server/lib/start_trial.ts index c1558f54b39b2..dfacee52c5c75 100644 --- a/x-pack/plugins/license_management/server/lib/start_trial.ts +++ b/x-pack/plugins/license_management/server/lib/start_trial.ts @@ -10,7 +10,7 @@ import { LicensingPluginStart } from '../../../licensing/server'; export async function canStartTrial(client: IScopedClusterClient) { try { - const { body: response } = await client.asCurrentUser.license.getTrialStatus(); + const response = await client.asCurrentUser.license.getTrialStatus(); return response.eligible_to_start_trial; } catch (error) { return error.body; @@ -24,7 +24,7 @@ interface StartTrialArg { export async function startTrial({ client, licensing }: StartTrialArg) { try { - const { body: response } = await client.asCurrentUser.license.postStartTrial({ + const response = await client.asCurrentUser.license.postStartTrial({ acknowledge: true, }); const { trial_was_started: trialWasStarted } = response; diff --git a/x-pack/plugins/licensing/server/plugin.test.ts b/x-pack/plugins/licensing/server/plugin.test.ts index 71a98098bb0f5..88f08a27a255f 100644 --- a/x-pack/plugins/licensing/server/plugin.test.ts +++ b/x-pack/plugins/licensing/server/plugin.test.ts @@ -54,9 +54,7 @@ describe('licensing plugin', () => { const createEsClient = (response?: Record) => { const client = elasticsearchServiceMock.createClusterClient(); if (response) { - client.asInternalUser.xpack.info.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise(response as any) - ); + client.asInternalUser.xpack.info.mockResponse(response as any); } return client; }; @@ -109,7 +107,7 @@ describe('licensing plugin', () => { const esClient = createEsClient(); esClient.asInternalUser.xpack.info.mockImplementation(() => { - return elasticsearchServiceMock.createSuccessTransportRequestPromise({ + return Promise.resolve({ license: buildRawLicense({ type: types.shift() }), features: {}, } as estypes.XpackInfoResponse); @@ -162,12 +160,12 @@ describe('licensing plugin', () => { esClient.asInternalUser.xpack.info.mockImplementation(() => { i++; if (i === 1) { - return elasticsearchServiceMock.createErrorTransportRequestPromise(error1); + return Promise.reject(error1); } if (i === 2) { - return elasticsearchServiceMock.createErrorTransportRequestPromise(error2); + return Promise.reject(error2); } - return elasticsearchServiceMock.createSuccessTransportRequestPromise({ + return Promise.resolve({ license: buildRawLicense(), features: {}, } as estypes.XpackInfoResponse); @@ -227,7 +225,7 @@ describe('licensing plugin', () => { const esClient = createEsClient(); esClient.asInternalUser.xpack.info.mockImplementation(() => { - return elasticsearchServiceMock.createSuccessTransportRequestPromise({ + return Promise.resolve({ license: buildRawLicense({ type: types.shift() }), features: {}, } as estypes.XpackInfoResponse); diff --git a/x-pack/plugins/licensing/server/plugin.ts b/x-pack/plugins/licensing/server/plugin.ts index 43c8135127871..490bf0be3b5a8 100644 --- a/x-pack/plugins/licensing/server/plugin.ts +++ b/x-pack/plugins/licensing/server/plugin.ts @@ -177,7 +177,7 @@ export class LicensingPlugin implements Plugin): Promise => { const client = isPromise(clusterClient) ? await clusterClient : clusterClient; try { - const { body: response } = await client.asInternalUser.xpack.info(); + const response = await client.asInternalUser.xpack.info(); const normalizedLicense = response.license && response.license.type !== 'missing' ? normalizeServerLicense(response.license) diff --git a/x-pack/plugins/lists/server/services/items/create_list_item.test.ts b/x-pack/plugins/lists/server/services/items/create_list_item.test.ts index d601f7f3eff45..305aa98f0e9ed 100644 --- a/x-pack/plugins/lists/server/services/items/create_list_item.test.ts +++ b/x-pack/plugins/lists/server/services/items/create_list_item.test.ts @@ -27,9 +27,9 @@ describe('crete_list_item', () => { test('it returns a list item as expected with the id changed out for the elastic id', async () => { const options = getCreateListItemOptionsMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.index.mockReturnValue( + esClient.index.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' }) + { _id: 'elastic-id-123' } ); const listItem = await createListItem({ ...options, esClient }); const expected = getListItemResponseMock(); @@ -54,9 +54,9 @@ describe('crete_list_item', () => { const options = getCreateListItemOptionsMock(); options.id = undefined; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.index.mockReturnValue( + esClient.index.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' }) + { _id: 'elastic-id-123' } ); const list = await createListItem({ ...options, esClient }); const expected = getListItemResponseMock(); diff --git a/x-pack/plugins/lists/server/services/items/create_list_item.ts b/x-pack/plugins/lists/server/services/items/create_list_item.ts index ccdb8ab4779b6..18a9f3ebe7726 100644 --- a/x-pack/plugins/lists/server/services/items/create_list_item.ts +++ b/x-pack/plugins/lists/server/services/items/create_list_item.ts @@ -68,7 +68,7 @@ export const createListItem = async ({ ...baseBody, ...elasticQuery, }; - const { body: response } = await esClient.index({ + const response = await esClient.index({ body, id, index: listItemIndex, diff --git a/x-pack/plugins/lists/server/services/items/find_list_item.test.ts b/x-pack/plugins/lists/server/services/items/find_list_item.test.ts index 098c8d20ae5ce..48625a74b9ae1 100644 --- a/x-pack/plugins/lists/server/services/items/find_list_item.test.ts +++ b/x-pack/plugins/lists/server/services/items/find_list_item.test.ts @@ -19,42 +19,40 @@ describe('find_list_item', () => { test('should find a simple single list item', async () => { const options = getFindListItemOptionsMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.count.mockReturnValue( + esClient.count.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ count: 1 }) + { count: 1 } ); - esClient.search.mockReturnValue( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - _scroll_id: '123', - _shards: getShardMock(), - hits: { - hits: [ - { - _id: 'some-list-item-id', - _source: { - _version: 'undefined', - created_at: '2020-04-20T15:25:31.830Z', - created_by: 'some user', - date_range: '127.0.0.1', - deserializer: undefined, - list_id: 'some-list-id', - meta: {}, - serializer: undefined, - tie_breaker_id: '6a76b69d-80df-4ab2-8c3e-85f466b06a0e', - type: 'ip', - updated_at: '2020-04-20T15:25:31.830Z', - updated_by: 'some user', - }, + esClient.search.mockResponse({ + _scroll_id: '123', + _shards: getShardMock(), + hits: { + hits: [ + // @ts-expect-error not full response interface + { + _id: 'some-list-item-id', + _source: { + _version: 'undefined', + created_at: '2020-04-20T15:25:31.830Z', + created_by: 'some user', + date_range: '127.0.0.1', + deserializer: undefined, + list_id: 'some-list-id', + meta: {}, + serializer: undefined, + tie_breaker_id: '6a76b69d-80df-4ab2-8c3e-85f466b06a0e', + type: 'ip', + updated_at: '2020-04-20T15:25:31.830Z', + updated_by: 'some user', }, - ], - max_score: 0, - total: 1, - }, - timed_out: false, - took: 10, - }) - ); + }, + ], + max_score: 0, + total: 1, + }, + timed_out: false, + took: 10, + }); const item = await findListItem({ ...options, esClient }); const expected = getFoundListItemSchemaMock(); expect(item).toEqual(expected); @@ -63,9 +61,7 @@ describe('find_list_item', () => { test('should return null if the list is null', async () => { const options = getFindListItemOptionsMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(getEmptySearchListMock()) - ); + esClient.search.mockResponse(getEmptySearchListMock()); const item = await findListItem({ ...options, esClient }); expect(item).toEqual(null); }); diff --git a/x-pack/plugins/lists/server/services/items/find_list_item.ts b/x-pack/plugins/lists/server/services/items/find_list_item.ts index 4ab8c11cc5b2f..459cadfe0abcf 100644 --- a/x-pack/plugins/lists/server/services/items/find_list_item.ts +++ b/x-pack/plugins/lists/server/services/items/find_list_item.ts @@ -74,7 +74,7 @@ export const findListItem = async ({ sortOrder, }); - const { body: respose } = await esClient.count({ + const respose = await esClient.count({ body: { query, }, @@ -86,7 +86,7 @@ export const findListItem = async ({ // Note: This typing of response = await esClient> // is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have // to explicitly define the type . - const { body: response } = await esClient.search({ + const response = await esClient.search({ body: { query, search_after: scroll.searchAfter, diff --git a/x-pack/plugins/lists/server/services/items/get_list_item.test.ts b/x-pack/plugins/lists/server/services/items/get_list_item.test.ts index f6ec534a39ebb..7b867db9868d4 100644 --- a/x-pack/plugins/lists/server/services/items/get_list_item.test.ts +++ b/x-pack/plugins/lists/server/services/items/get_list_item.test.ts @@ -33,9 +33,7 @@ describe('get_list_item', () => { test('it returns a list item as expected if the list item is found', async () => { const data = getSearchListItemMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const list = await getListItem({ esClient, id: LIST_ID, listItemIndex: LIST_INDEX }); const expected = getListItemResponseMock(); expect(list).toEqual(expected); @@ -45,9 +43,7 @@ describe('get_list_item', () => { const data = getSearchListItemMock(); data.hits.hits = []; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const list = await getListItem({ esClient, id: LIST_ID, listItemIndex: LIST_INDEX }); expect(list).toEqual(null); }); @@ -89,9 +85,7 @@ describe('get_list_item', () => { updated_by: USER, }; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const list = await getListItem({ esClient, id: LIST_ID, listItemIndex: LIST_INDEX }); expect(list).toEqual(null); }); diff --git a/x-pack/plugins/lists/server/services/items/get_list_item.ts b/x-pack/plugins/lists/server/services/items/get_list_item.ts index f7b9c06349870..6a59a7f051fe1 100644 --- a/x-pack/plugins/lists/server/services/items/get_list_item.ts +++ b/x-pack/plugins/lists/server/services/items/get_list_item.ts @@ -26,7 +26,7 @@ export const getListItem = async ({ // Note: This typing of response = await esClient> // is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have // to explicitly define the type . - const { body: listItemES } = await esClient.search({ + const listItemES = await esClient.search({ body: { query: { term: { diff --git a/x-pack/plugins/lists/server/services/items/get_list_item_by_values.test.ts b/x-pack/plugins/lists/server/services/items/get_list_item_by_values.test.ts index f3c72794b6dd9..d57fe0e2ead92 100644 --- a/x-pack/plugins/lists/server/services/items/get_list_item_by_values.test.ts +++ b/x-pack/plugins/lists/server/services/items/get_list_item_by_values.test.ts @@ -37,9 +37,7 @@ describe('get_list_item_by_values', () => { const data = getSearchListItemMock(); data.hits.hits = []; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const listItem = await getListItemByValues({ esClient, listId: LIST_ID, @@ -54,9 +52,7 @@ describe('get_list_item_by_values', () => { test('Returns transformed list item if the data exists within ES', async () => { const data = getSearchListItemMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const listItem = await getListItemByValues({ esClient, listId: LIST_ID, diff --git a/x-pack/plugins/lists/server/services/items/get_list_item_by_values.ts b/x-pack/plugins/lists/server/services/items/get_list_item_by_values.ts index 38e2283af98a7..2fb713526fce8 100644 --- a/x-pack/plugins/lists/server/services/items/get_list_item_by_values.ts +++ b/x-pack/plugins/lists/server/services/items/get_list_item_by_values.ts @@ -30,7 +30,7 @@ export const getListItemByValues = async ({ type, value, }: GetListItemByValuesOptions): Promise => { - const { body: response } = await esClient.search({ + const response = await esClient.search({ body: { query: { bool: { diff --git a/x-pack/plugins/lists/server/services/items/search_list_item_by_values.test.ts b/x-pack/plugins/lists/server/services/items/search_list_item_by_values.test.ts index 174a44ce16600..2511db01d1901 100644 --- a/x-pack/plugins/lists/server/services/items/search_list_item_by_values.test.ts +++ b/x-pack/plugins/lists/server/services/items/search_list_item_by_values.test.ts @@ -27,9 +27,7 @@ describe('search_list_item_by_values', () => { const data = getSearchListItemMock(); data.hits.hits = []; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const listItem = await searchListItemByValues({ esClient, listId: LIST_ID, @@ -45,9 +43,7 @@ describe('search_list_item_by_values', () => { const data = getSearchListItemMock(); data.hits.hits = []; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const listItem = await searchListItemByValues({ esClient, listId: LIST_ID, @@ -66,9 +62,7 @@ describe('search_list_item_by_values', () => { test('Returns transformed list item if the data exists within ES', async () => { const data = getSearchListItemMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const listItem = await searchListItemByValues({ esClient, listId: LIST_ID, diff --git a/x-pack/plugins/lists/server/services/items/search_list_item_by_values.ts b/x-pack/plugins/lists/server/services/items/search_list_item_by_values.ts index ad4a79e69683f..fb81594137861 100644 --- a/x-pack/plugins/lists/server/services/items/search_list_item_by_values.ts +++ b/x-pack/plugins/lists/server/services/items/search_list_item_by_values.ts @@ -30,7 +30,7 @@ export const searchListItemByValues = async ({ type, value, }: SearchListItemByValuesOptions): Promise => { - const { body: response } = await esClient.search({ + const response = await esClient.search({ body: { query: { bool: { diff --git a/x-pack/plugins/lists/server/services/items/update_list_item.test.ts b/x-pack/plugins/lists/server/services/items/update_list_item.test.ts index 37cb665eb906e..a42253d3c1ae9 100644 --- a/x-pack/plugins/lists/server/services/items/update_list_item.test.ts +++ b/x-pack/plugins/lists/server/services/items/update_list_item.test.ts @@ -33,9 +33,9 @@ describe('update_list_item', () => { (getListItem as unknown as jest.Mock).mockResolvedValueOnce(listItem); const options = getUpdateListItemOptionsMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.update.mockReturnValue( + esClient.update.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' }) + { _id: 'elastic-id-123' } ); const updatedList = await updateListItem({ ...options, esClient }); const expected: ListItemSchema = { ...getListItemResponseMock(), id: 'elastic-id-123' }; diff --git a/x-pack/plugins/lists/server/services/items/update_list_item.ts b/x-pack/plugins/lists/server/services/items/update_list_item.ts index 78651bb83d73b..17e706228fb46 100644 --- a/x-pack/plugins/lists/server/services/items/update_list_item.ts +++ b/x-pack/plugins/lists/server/services/items/update_list_item.ts @@ -60,7 +60,7 @@ export const updateListItem = async ({ ...elasticQuery, }; - const { body: response } = await esClient.update({ + const response = await esClient.update({ ...decodeVersion(_version), body: { doc, diff --git a/x-pack/plugins/lists/server/services/items/write_list_items_to_stream.test.ts b/x-pack/plugins/lists/server/services/items/write_list_items_to_stream.test.ts index 0918b9ebdedae..1bc0b708bdc0a 100644 --- a/x-pack/plugins/lists/server/services/items/write_list_items_to_stream.test.ts +++ b/x-pack/plugins/lists/server/services/items/write_list_items_to_stream.test.ts @@ -41,9 +41,7 @@ describe('write_list_items_to_stream', () => { const firstResponse = getSearchListItemMock(); firstResponse.hits.hits = []; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(firstResponse) - ); + esClient.search.mockResponse(firstResponse); exportListItemsToStream({ ...options, esClient }); let chunks: string[] = []; @@ -61,9 +59,7 @@ describe('write_list_items_to_stream', () => { const options = getExportListItemsToStreamOptionsMock(); const response = getSearchListItemMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(response) - ); + esClient.search.mockResponse(response); exportListItemsToStream({ ...options, esClient }); let chunks: string[] = []; @@ -83,9 +79,7 @@ describe('write_list_items_to_stream', () => { const secondResponse = getSearchListItemMock(); firstResponse.hits.hits = [...firstResponse.hits.hits, ...secondResponse.hits.hits]; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(firstResponse) - ); + esClient.search.mockResponse(firstResponse); exportListItemsToStream({ ...options, esClient }); let chunks: string[] = []; @@ -111,12 +105,8 @@ describe('write_list_items_to_stream', () => { } const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(firstResponse) - ); - esClient.search.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(secondResponse) - ); + esClient.search.mockResponseOnce(firstResponse); + esClient.search.mockResponseOnce(secondResponse); exportListItemsToStream({ ...options, esClient }); let chunks: string[] = []; @@ -136,9 +126,7 @@ describe('write_list_items_to_stream', () => { const options = getWriteNextResponseOptions(); const listItem = getSearchListItemMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(listItem) - ); + esClient.search.mockResponse(listItem); const searchAfter = await writeNextResponse({ ...options, esClient }); expect(searchAfter).toEqual(undefined); }); @@ -148,9 +136,7 @@ describe('write_list_items_to_stream', () => { listItem.hits.hits[0].sort = ['sort-value-1']; const options = getWriteNextResponseOptions(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(listItem) - ); + esClient.search.mockResponse(listItem); const searchAfter = await writeNextResponse({ ...options, esClient }); expect(searchAfter).toEqual(['sort-value-1']); }); @@ -160,9 +146,7 @@ describe('write_list_items_to_stream', () => { listItem.hits.hits = []; const options = getWriteNextResponseOptions(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(listItem) - ); + esClient.search.mockResponse(listItem); const searchAfter = await writeNextResponse({ ...options, esClient }); expect(searchAfter).toEqual(undefined); }); diff --git a/x-pack/plugins/lists/server/services/items/write_list_items_to_stream.ts b/x-pack/plugins/lists/server/services/items/write_list_items_to_stream.ts index 565e8a3e196c5..1e9db1ef062f0 100644 --- a/x-pack/plugins/lists/server/services/items/write_list_items_to_stream.ts +++ b/x-pack/plugins/lists/server/services/items/write_list_items_to_stream.ts @@ -117,22 +117,20 @@ export const getResponse = async ({ listItemIndex, size = SIZE, }: GetResponseOptions): Promise> => { - return ( - await esClient.search({ - body: { - query: { - term: { - list_id: listId, - }, + return (await esClient.search({ + body: { + query: { + term: { + list_id: listId, }, - search_after: searchAfter, - sort: [{ tie_breaker_id: 'asc' }], }, - ignore_unavailable: true, - index: listItemIndex, - size, - }) - ).body as unknown as estypes.SearchResponse; + search_after: searchAfter, + sort: [{ tie_breaker_id: 'asc' }], + }, + ignore_unavailable: true, + index: listItemIndex, + size, + })) as unknown as estypes.SearchResponse; }; export interface WriteResponseHitsToStreamOptions { diff --git a/x-pack/plugins/lists/server/services/lists/create_list.test.ts b/x-pack/plugins/lists/server/services/lists/create_list.test.ts index 0474f1bac2700..b2ccbd0d84fa0 100644 --- a/x-pack/plugins/lists/server/services/lists/create_list.test.ts +++ b/x-pack/plugins/lists/server/services/lists/create_list.test.ts @@ -28,9 +28,9 @@ describe('crete_list', () => { test('it returns a list as expected with the id changed out for the elastic id', async () => { const options = getCreateListOptionsMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.index.mockReturnValue( + esClient.index.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' }) + { _id: 'elastic-id-123' } ); const list = await createList({ ...options, esClient }); const expected: ListSchema = { ...getListResponseMock(), id: 'elastic-id-123' }; @@ -44,9 +44,9 @@ describe('crete_list', () => { serializer: '(?)', }; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.index.mockReturnValue( + esClient.index.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' }) + { _id: 'elastic-id-123' } ); const list = await createList({ ...options, esClient }); const expected: ListSchema = { @@ -75,9 +75,9 @@ describe('crete_list', () => { const options = getCreateListOptionsMock(); options.id = undefined; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.index.mockReturnValue( + esClient.index.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' }) + { _id: 'elastic-id-123' } ); const list = await createList({ ...options, esClient }); const expected: ListSchema = { ...getListResponseMock(), id: 'elastic-id-123' }; diff --git a/x-pack/plugins/lists/server/services/lists/create_list.ts b/x-pack/plugins/lists/server/services/lists/create_list.ts index 521a38a51d6eb..eefcd0f41e448 100644 --- a/x-pack/plugins/lists/server/services/lists/create_list.ts +++ b/x-pack/plugins/lists/server/services/lists/create_list.ts @@ -72,7 +72,7 @@ export const createList = async ({ updated_by: user, version, }; - const { body: response } = await esClient.index({ + const response = await esClient.index({ body, id, index: listIndex, diff --git a/x-pack/plugins/lists/server/services/lists/find_list.ts b/x-pack/plugins/lists/server/services/lists/find_list.ts index ed46c053cda9e..63f636370a144 100644 --- a/x-pack/plugins/lists/server/services/lists/find_list.ts +++ b/x-pack/plugins/lists/server/services/lists/find_list.ts @@ -63,7 +63,7 @@ export const findList = async ({ sortOrder, }); - const { body: totalCount } = await esClient.count({ + const totalCount = await esClient.count({ body: { query, }, @@ -75,7 +75,7 @@ export const findList = async ({ // Note: This typing of response = await esClient> // is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have // to explicitly define the type . - const { body: response } = await esClient.search({ + const response = await esClient.search({ body: { query, search_after: scroll.searchAfter, diff --git a/x-pack/plugins/lists/server/services/lists/get_list.test.ts b/x-pack/plugins/lists/server/services/lists/get_list.test.ts index f599e5ef8b6c5..f9e64fe70eeca 100644 --- a/x-pack/plugins/lists/server/services/lists/get_list.test.ts +++ b/x-pack/plugins/lists/server/services/lists/get_list.test.ts @@ -26,9 +26,7 @@ describe('get_list', () => { test('it returns a list as expected if the list is found', async () => { const data = getSearchListMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const list = await getList({ esClient, id: LIST_ID, listIndex: LIST_INDEX }); const expected = getListResponseMock(); expect(list).toEqual(expected); @@ -38,9 +36,7 @@ describe('get_list', () => { const data = getSearchListMock(); data.hits.hits = []; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(data) - ); + esClient.search.mockResponse(data); const list = await getList({ esClient, id: LIST_ID, listIndex: LIST_INDEX }); expect(list).toEqual(null); }); diff --git a/x-pack/plugins/lists/server/services/lists/get_list.ts b/x-pack/plugins/lists/server/services/lists/get_list.ts index 9b120ca0dd358..a1e34bdce6319 100644 --- a/x-pack/plugins/lists/server/services/lists/get_list.ts +++ b/x-pack/plugins/lists/server/services/lists/get_list.ts @@ -25,7 +25,7 @@ export const getList = async ({ // Note: This typing of response = await esClient> // is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have // to explicitly define the type . - const { body: response } = await esClient.search({ + const response = await esClient.search({ body: { query: { term: { diff --git a/x-pack/plugins/lists/server/services/lists/update_list.test.ts b/x-pack/plugins/lists/server/services/lists/update_list.test.ts index ab8ea71a82b1e..2b9bdd21a40d1 100644 --- a/x-pack/plugins/lists/server/services/lists/update_list.test.ts +++ b/x-pack/plugins/lists/server/services/lists/update_list.test.ts @@ -33,9 +33,9 @@ describe('update_list', () => { (getList as unknown as jest.Mock).mockResolvedValueOnce(list); const options = getUpdateListOptionsMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.update.mockReturnValue( + esClient.update.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' }) + { _id: 'elastic-id-123' } ); const updatedList = await updateList({ ...options, esClient }); const expected: ListSchema = { ...getListResponseMock(), id: 'elastic-id-123' }; @@ -51,9 +51,9 @@ describe('update_list', () => { (getList as unknown as jest.Mock).mockResolvedValueOnce(list); const options = getUpdateListOptionsMock(); const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.update.mockReturnValue( + esClient.update.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ _id: 'elastic-id-123' }) + { _id: 'elastic-id-123' } ); const updatedList = await updateList({ ...options, esClient }); const expected: ListSchema = { diff --git a/x-pack/plugins/lists/server/services/lists/update_list.ts b/x-pack/plugins/lists/server/services/lists/update_list.ts index 11868a6187bbf..aed0b409b5bbe 100644 --- a/x-pack/plugins/lists/server/services/lists/update_list.ts +++ b/x-pack/plugins/lists/server/services/lists/update_list.ts @@ -59,7 +59,7 @@ export const updateList = async ({ updated_at: updatedAt, updated_by: user, }; - const { body: response } = await esClient.update({ + const response = await esClient.update({ ...decodeVersion(_version), body: { doc }, id, diff --git a/x-pack/plugins/lists/server/services/utils/get_search_after_scroll.ts b/x-pack/plugins/lists/server/services/utils/get_search_after_scroll.ts index dbc83bb44e5fd..6e50d7414cf11 100644 --- a/x-pack/plugins/lists/server/services/utils/get_search_after_scroll.ts +++ b/x-pack/plugins/lists/server/services/utils/get_search_after_scroll.ts @@ -43,7 +43,7 @@ export const getSearchAfterScroll = async ({ const query = getQueryFilter({ filter }); let newSearchAfter = searchAfter; for (let i = 0; i < hops; ++i) { - const { body: response } = await esClient.search>({ + const response = await esClient.search>({ body: { _source: getSourceWithTieBreaker({ sortField }), query, diff --git a/x-pack/plugins/logstash/server/routes/cluster/load.ts b/x-pack/plugins/logstash/server/routes/cluster/load.ts index 1b8dc7880e8dc..1c84dd038abf2 100644 --- a/x-pack/plugins/logstash/server/routes/cluster/load.ts +++ b/x-pack/plugins/logstash/server/routes/cluster/load.ts @@ -19,7 +19,7 @@ export function registerClusterLoadRoute(router: LogstashPluginRouter) { wrapRouteWithLicenseCheck(checkLicense, async (context, request, response) => { try { const { client } = context.core.elasticsearch; - const { body: info } = await client.asCurrentUser.info(); + const info = await client.asCurrentUser.info(); return response.ok({ body: { cluster: Cluster.fromUpstreamJSON(info).downstreamJSON, diff --git a/x-pack/plugins/logstash/server/routes/pipeline/load.ts b/x-pack/plugins/logstash/server/routes/pipeline/load.ts index 33f24a4ad6e26..615e3998dbd24 100644 --- a/x-pack/plugins/logstash/server/routes/pipeline/load.ts +++ b/x-pack/plugins/logstash/server/routes/pipeline/load.ts @@ -28,10 +28,7 @@ export function registerPipelineLoadRoute(router: LogstashPluginRouter) { const { id } = request.params; const { client } = context.core.elasticsearch; - const { body: result } = await client.asCurrentUser.logstash.getPipeline( - { id }, - { ignore: [404] } - ); + const result = await client.asCurrentUser.logstash.getPipeline({ id }, { ignore: [404] }); if (result[request.params.id] === undefined) { return response.notFound(); diff --git a/x-pack/plugins/logstash/server/routes/pipelines/delete.ts b/x-pack/plugins/logstash/server/routes/pipelines/delete.ts index 3609ac1520683..a532dc6fc4997 100644 --- a/x-pack/plugins/logstash/server/routes/pipelines/delete.ts +++ b/x-pack/plugins/logstash/server/routes/pipelines/delete.ts @@ -18,7 +18,7 @@ async function deletePipelines(client: ElasticsearchClient, pipelineIds: string[ .deletePipeline({ id: pipelineId, }) - .then((response) => ({ success: response.body })) + .then((response) => ({ success: response })) .catch((error) => ({ error })); }); diff --git a/x-pack/plugins/logstash/server/routes/pipelines/list.ts b/x-pack/plugins/logstash/server/routes/pipelines/list.ts index 2ce57d18d3118..a2072a78902ee 100644 --- a/x-pack/plugins/logstash/server/routes/pipelines/list.ts +++ b/x-pack/plugins/logstash/server/routes/pipelines/list.ts @@ -14,14 +14,13 @@ import { PipelineListItem } from '../../models/pipeline_list_item'; import { checkLicense } from '../../lib/check_license'; async function fetchPipelines(client: ElasticsearchClient) { - const { body } = await client.transport.request( + return await client.transport.request( { method: 'GET', path: '/_logstash/pipeline', }, { ignore: [404] } ); - return body; } export function registerPipelinesListRoute(router: LogstashPluginRouter) { diff --git a/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts b/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts index e09063f99ec8c..0760d7a079a3b 100644 --- a/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts +++ b/x-pack/plugins/maps/server/data_indexing/get_indexes_matching_pattern.ts @@ -14,7 +14,7 @@ export async function getMatchingIndexes( logger: Logger ) { try { - const { body: indexResults } = await asCurrentUser.cat.indices({ + const indexResults = await asCurrentUser.cat.indices({ index: indexPattern, format: 'JSON', }); diff --git a/x-pack/plugins/maps/server/data_indexing/index_data.ts b/x-pack/plugins/maps/server/data_indexing/index_data.ts index 0dc22ed3cb3cc..7b26c94e07782 100644 --- a/x-pack/plugins/maps/server/data_indexing/index_data.ts +++ b/x-pack/plugins/maps/server/data_indexing/index_data.ts @@ -15,7 +15,7 @@ export async function writeDataToIndex( asCurrentUser: ElasticsearchClient ) { try { - const { body: indexExists } = await asCurrentUser.indices.exists({ index }); + const indexExists = await asCurrentUser.indices.exists({ index }); if (!indexExists) { throw new Error( i18n.translate('xpack.maps.indexData.indexExists', { @@ -27,7 +27,7 @@ export async function writeDataToIndex( ); } const settings: WriteSettings = { index, body: data, refresh: true }; - const { body: resp } = await asCurrentUser.index(settings); + const resp = await asCurrentUser.index(settings); // @ts-expect-error always false if (resp.result === 'Error') { throw resp; 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 d9518228ecb52..4a7c90439beed 100644 --- a/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts +++ b/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts @@ -123,7 +123,7 @@ export function initIndexingRoutes({ }, async (context, request, response) => { try { - const { body: resp } = await context.core.elasticsearch.client.asCurrentUser.delete({ + const resp = await context.core.elasticsearch.client.asCurrentUser.delete({ index: request.body.index, id: request.params.featureId, refresh: true, @@ -194,7 +194,7 @@ export function initIndexingRoutes({ async (context, request, response) => { const { index } = request.query; try { - const { body: mappingsResp } = + const mappingsResp = await context.core.elasticsearch.client.asCurrentUser.indices.getMapping({ index: request.query.index, }); 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 2eb55056692d6..193a3d74e2dca 100644 --- a/x-pack/plugins/maps/server/mvt/get_grid_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts @@ -70,6 +70,7 @@ export async function getEsGridTile({ 'Accept-Encoding': 'gzip', }, asStream: true, + meta: true, } ); } diff --git a/x-pack/plugins/maps/server/mvt/get_tile.ts b/x-pack/plugins/maps/server/mvt/get_tile.ts index 50b21433ebf2c..2c8b6dd4b113d 100644 --- a/x-pack/plugins/maps/server/mvt/get_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_tile.ts @@ -71,6 +71,7 @@ export async function getEsTile({ 'Accept-Encoding': 'gzip', }, asStream: true, + meta: true, } ); } diff --git a/x-pack/plugins/maps/server/routes.ts b/x-pack/plugins/maps/server/routes.ts index 56e178741b21d..21720afdc7edc 100644 --- a/x-pack/plugins/maps/server/routes.ts +++ b/x-pack/plugins/maps/server/routes.ts @@ -77,7 +77,7 @@ export async function initRoutes(coreSetup: CoreSetup, logger: Logger): Promise< index: query.indexPatternTitle, }); const indexPatternSettings = getIndexPatternSettings( - resp.body as unknown as Record + resp as unknown as Record ); return response.ok({ body: indexPatternSettings, diff --git a/x-pack/plugins/metrics_entities/server/services/get_transforms.ts b/x-pack/plugins/metrics_entities/server/services/get_transforms.ts index 08189f4b3361a..07c3d95b0943a 100644 --- a/x-pack/plugins/metrics_entities/server/services/get_transforms.ts +++ b/x-pack/plugins/metrics_entities/server/services/get_transforms.ts @@ -16,7 +16,7 @@ interface GetTransformsOptions { // TODO: Type the Promise to a stronger type export const getTransforms = async ({ esClient }: GetTransformsOptions): Promise => { - const { body } = await esClient.transform.getTransform({ + const body = await esClient.transform.getTransform({ size: 1000, transform_id: '*', }); diff --git a/x-pack/plugins/metrics_entities/server/services/utils/get_index_exists.ts b/x-pack/plugins/metrics_entities/server/services/utils/get_index_exists.ts index bcc37ce047d24..7bac15d516221 100644 --- a/x-pack/plugins/metrics_entities/server/services/utils/get_index_exists.ts +++ b/x-pack/plugins/metrics_entities/server/services/utils/get_index_exists.ts @@ -19,7 +19,7 @@ export const getIndexExists = async ( index: string ): Promise => { try { - const { body: response } = await esClient.search({ + const response = await esClient.search({ allow_no_indices: true, body: { terminate_after: 1, diff --git a/x-pack/plugins/metrics_entities/server/services/utils/get_transform_exists.ts b/x-pack/plugins/metrics_entities/server/services/utils/get_transform_exists.ts index 4dffce5f4ecbe..f6b9266baca91 100644 --- a/x-pack/plugins/metrics_entities/server/services/utils/get_transform_exists.ts +++ b/x-pack/plugins/metrics_entities/server/services/utils/get_transform_exists.ts @@ -12,9 +12,7 @@ export const getTransformExists = async ( id: string ): Promise => { try { - const { - body: { count }, - } = await esClient.transform.getTransform({ + const { count } = await esClient.transform.getTransform({ size: 1000, transform_id: id, }); diff --git a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts index a34ac14d95767..85b69118334fe 100644 --- a/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts +++ b/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts @@ -26,7 +26,6 @@ import { TopHitsResultsKeys, } from '../../../common/types/alerts'; import { AnomalyDetectionAlertContext } from './register_anomaly_detection_alert_type'; -import { MlJobsResponse } from '../../../common/types/job_service'; import { resolveMaxTimeInterval } from '../../../common/util/job_utils'; import { isDefined } from '../../../common/types/guards'; import { getTopNBuckets, resolveLookbackInterval } from '../../../common/util/alerts'; @@ -375,9 +374,7 @@ export function alertingServiceProvider( ]; // Extract jobs from group ids and make sure provided jobs assigned to a current space - const jobsResponse = ( - await mlClient.getJobs({ job_id: jobAndGroupIds.join(',') }) - ).body.jobs; + const jobsResponse = (await mlClient.getJobs({ job_id: jobAndGroupIds.join(',') })).jobs; if (jobsResponse.length === 0) { // Probably assigned groups don't contain any jobs anymore. @@ -454,7 +451,7 @@ export function alertingServiceProvider( : getResultTypeAggRequest(params.resultType, params.severity), }; - const response = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { // @ts-expect-error body: requestBody, @@ -462,7 +459,7 @@ export function alertingServiceProvider( jobIds ); - const result = response.body.aggregations; + const result = body.aggregations; const resultsLabel = getAggResultsLabel(params.resultType); @@ -512,9 +509,7 @@ export function alertingServiceProvider( ]; // Extract jobs from group ids and make sure provided jobs assigned to a current space - const jobsResponse = ( - await mlClient.getJobs({ job_id: jobAndGroupIds.join(',') }) - ).body.jobs; + const jobsResponse = (await mlClient.getJobs({ job_id: jobAndGroupIds.join(',') })).jobs; if (jobsResponse.length === 0) { // Probably assigned groups don't contain any jobs anymore. @@ -595,7 +590,7 @@ export function alertingServiceProvider( }, }; - const response = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { // @ts-expect-error body: requestBody, @@ -603,7 +598,7 @@ export function alertingServiceProvider( jobIds ); - const result = response.body.aggregations as { + const result = body.aggregations as { alerts_over_time: { buckets: Array< { diff --git a/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.test.ts b/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.test.ts index e824e34a1779b..b31cd191d3b32 100644 --- a/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.test.ts +++ b/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.test.ts @@ -76,47 +76,39 @@ describe('JobsHealthService', () => { ]; } - return Promise.resolve({ - body: { - jobs, - }, - }); + return Promise.resolve({ jobs }); }), getJobStats: jest.fn().mockImplementation(({ job_id: jobIdsStr }) => { const jobsIds = jobIdsStr.split(','); return Promise.resolve({ - body: { - jobs: jobsIds.map((j: string) => { - return { - job_id: j, - state: j === 'test_job_02' || 'test_job_01' ? 'opened' : 'closed', - model_size_stats: { - memory_status: j === 'test_job_01' ? 'hard_limit' : 'ok', - log_time: 1626935914540, - model_bytes: 1000000, - model_bytes_memory_limit: 800000, - peak_model_bytes: 1000000, - model_bytes_exceeded: 200000, - }, - }; - }) as MlJobStats, - }, + jobs: jobsIds.map((j: string) => { + return { + job_id: j, + state: j === 'test_job_02' || 'test_job_01' ? 'opened' : 'closed', + model_size_stats: { + memory_status: j === 'test_job_01' ? 'hard_limit' : 'ok', + log_time: 1626935914540, + model_bytes: 1000000, + model_bytes_memory_limit: 800000, + peak_model_bytes: 1000000, + model_bytes_exceeded: 200000, + }, + }; + }) as MlJobStats, }); }), getDatafeedStats: jest.fn().mockImplementation(({ datafeed_id: datafeedIdsStr }) => { const datafeedIds = datafeedIdsStr.split(','); return Promise.resolve({ - body: { - datafeeds: datafeedIds.map((d: string) => { - return { - datafeed_id: d, - state: d === 'test_datafeed_02' ? 'stopped' : 'started', - timing_stats: { - job_id: d.replace('datafeed', 'job'), - }, - }; - }) as MlJobStats, - }, + datafeeds: datafeedIds.map((d: string) => { + return { + datafeed_id: d, + state: d === 'test_datafeed_02' ? 'stopped' : 'started', + timing_stats: { + job_id: d.replace('datafeed', 'job'), + }, + }; + }) as MlJobStats, }); }), } as unknown as jest.Mocked; diff --git a/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.ts b/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.ts index 2fbda6a4b37f6..805b51ce6567b 100644 --- a/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.ts +++ b/x-pack/plugins/ml/server/lib/alerts/jobs_health_service.ts @@ -83,7 +83,7 @@ export function jobsHealthServiceProvider( await mlClient.getJobs({ ...(includeAllJobs ? {} : { job_id: jobAndGroupIds }), }) - ).body.jobs; + ).jobs; let resultJobs = jobsResponse; @@ -96,7 +96,7 @@ export function jobsHealthServiceProvider( await mlClient.getJobs({ job_id: excludedJobAndGroupIds, }) - ).body.jobs; + ).jobs; const excludedJobsIds: Set = new Set(excludedJobsResponse.map((v) => v.job_id)); @@ -133,7 +133,7 @@ export function jobsHealthServiceProvider( const getDatafeeds = memoize(datafeedsService.getDatafeedByJobId); const getJobStats = memoize( - async (jobIds: string[]) => (await mlClient.getJobStats({ job_id: jobIds.join(',') })).body.jobs + async (jobIds: string[]) => (await mlClient.getJobStats({ job_id: jobIds.join(',') })).jobs ); /** Gets values for translation string */ @@ -158,9 +158,7 @@ export function jobsHealthServiceProvider( if (datafeeds) { const jobsStats = await getJobStats(jobIds); - const { - body: { datafeeds: datafeedsStats }, - } = await mlClient.getDatafeedStats({ + const { datafeeds: datafeedsStats } = await mlClient.getDatafeedStats({ datafeed_id: datafeeds.map((d) => d.datafeed_id).join(','), }); diff --git a/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts b/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts index c72b4d5cb5dd7..c853179e7121f 100644 --- a/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts +++ b/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts @@ -26,17 +26,13 @@ const mlIsNotEnabled = async () => false; const mlClientNonUpgrade = { info: async () => ({ - body: { - upgrade_mode: false, - }, + upgrade_mode: false, }), } as unknown as MlClient; const mlClientUpgrade = { info: async () => ({ - body: { - upgrade_mode: true, - }, + upgrade_mode: true, }), } as unknown as MlClient; diff --git a/x-pack/plugins/ml/server/lib/capabilities/upgrade.ts b/x-pack/plugins/ml/server/lib/capabilities/upgrade.ts index 24d1ce5f2dbe0..e0c604d80ee63 100644 --- a/x-pack/plugins/ml/server/lib/capabilities/upgrade.ts +++ b/x-pack/plugins/ml/server/lib/capabilities/upgrade.ts @@ -12,7 +12,7 @@ export function upgradeCheckProvider(mlClient: MlClient) { async function isUpgradeInProgress(): Promise { let upgradeInProgress = false; try { - const { body } = await mlClient.info(); + const body = await mlClient.info(); // if ml indices are currently being migrated, upgrade_mode will be set to true // pass this back with the privileges to allow for the disabling of UI controls. upgradeInProgress = body.upgrade_mode === true; diff --git a/x-pack/plugins/ml/server/lib/check_annotations/index.ts b/x-pack/plugins/ml/server/lib/check_annotations/index.ts index e64b4658588cb..50c237566761e 100644 --- a/x-pack/plugins/ml/server/lib/check_annotations/index.ts +++ b/x-pack/plugins/ml/server/lib/check_annotations/index.ts @@ -20,7 +20,7 @@ import { // in the metadata of the indices they point to, so it's impossible to have an alias that doesn't point to any index. export async function isAnnotationsFeatureAvailable({ asInternalUser }: IScopedClusterClient) { try { - const { body: annotationsReadAliasExists } = await asInternalUser.indices.existsAlias({ + const annotationsReadAliasExists = await asInternalUser.indices.existsAlias({ index: ML_ANNOTATIONS_INDEX_ALIAS_READ, name: ML_ANNOTATIONS_INDEX_ALIAS_READ, }); @@ -29,7 +29,7 @@ export async function isAnnotationsFeatureAvailable({ asInternalUser }: IScopedC return false; } - const { body: annotationsWriteAliasExists } = await asInternalUser.indices.existsAlias({ + const annotationsWriteAliasExists = await asInternalUser.indices.existsAlias({ index: ML_ANNOTATIONS_INDEX_ALIAS_WRITE, name: ML_ANNOTATIONS_INDEX_ALIAS_WRITE, }); diff --git a/x-pack/plugins/ml/server/lib/ml_client/ml_client.ts b/x-pack/plugins/ml/server/lib/ml_client/ml_client.ts index 6155ae8ce90d7..3dc71cc64add9 100644 --- a/x-pack/plugins/ml/server/lib/ml_client/ml_client.ts +++ b/x-pack/plugins/ml/server/lib/ml_client/ml_client.ts @@ -102,7 +102,7 @@ export function getMlClient( // similar to groupIdsCheck above, however we need to load the jobs first to get the groups information const ids = getADJobIdsFromRequest(p); if (ids.length) { - const { body } = await mlClient.getJobs(...p); + const body = await mlClient.getJobs(...p); await groupIdsCheck(p, body.jobs, filteredJobIds); } } @@ -207,14 +207,14 @@ export function getMlClient( return mlClient.getCalendarEvents(...p); }, async getCalendars(...p: Parameters) { - const { body } = await mlClient.getCalendars(...p); - const { - body: { jobs: allJobs }, - } = await mlClient.getJobs<{ jobs: Job[] }>(); + const [params, options = {}] = p; + const meta = options.meta ?? false; + const response = await mlClient.getCalendars(params, { ...options, meta: true }); + const { jobs: allJobs } = await mlClient.getJobs(); const allJobIds = allJobs.map((j) => j.job_id); // flatten the list of all jobs ids and check which ones are valid - const calJobIds = [...new Set(body.calendars.map((c) => c.job_ids).flat())]; + const calJobIds = [...new Set(response.body.calendars.map((c) => c.job_ids).flat())]; // find groups by getting the cal job ids which aren't real jobs. const groups = calJobIds.filter((j) => allJobIds.includes(j) === false); @@ -223,12 +223,19 @@ export function getMlClient( 'anomaly-detector', calJobIds ); - const calendars = body.calendars.map((c) => ({ + const calendars = response.body.calendars.map((c) => ({ ...c, job_ids: c.job_ids.filter((id) => filteredJobIds.includes(id) || groups.includes(id)), total_job_count: calJobIds.length, })); - return { body: { ...body, calendars } }; + + const enhancedBody = { ...response.body, calendars }; + + if (meta) { + return { ...response, body: enhancedBody }; + } else { + return enhancedBody; + } }, async getCategories(...p: Parameters) { await jobIdsCheck('anomaly-detector', p); @@ -237,16 +244,23 @@ export function getMlClient( async getDataFrameAnalytics(...p: Parameters) { await jobIdsCheck('data-frame-analytics', p, true); try { - const { body } = await mlClient.getDataFrameAnalytics<{ - data_frame_analytics: DataFrameAnalyticsConfig[]; - }>(...p); + const [params, options = {}] = p; + const meta = options.meta ?? false; + + const response = await mlClient.getDataFrameAnalytics(params, { ...options, meta: true }); const jobs = await jobSavedObjectService.filterJobsForSpace( 'data-frame-analytics', // @ts-expect-error @elastic-elasticsearch Data frame types incomplete - body.data_frame_analytics, + response.body.data_frame_analytics, 'id' ); - return { body: { ...body, count: jobs.length, data_frame_analytics: jobs } }; + + const enhancedBody = { ...response.body, count: jobs.length, data_frame_analytics: jobs }; + if (meta) { + return { ...response, body: enhancedBody }; + } else { + return enhancedBody; + } } catch (error) { if (error.statusCode === 404) { throw new MLJobNotFound(error.body.error.reason); @@ -258,15 +272,26 @@ export function getMlClient( // this should use DataFrameAnalyticsStats, but needs a refactor to move DataFrameAnalyticsStats to common await jobIdsCheck('data-frame-analytics', p, true); try { - const { body } = (await mlClient.getDataFrameAnalyticsStats(...p)) as unknown as { + const [params, options = {}] = p; + const meta = options.meta ?? false; + const response = (await mlClient.getDataFrameAnalyticsStats(params, { + ...options, + meta: true, + })) as unknown as { body: { data_frame_analytics: DataFrameAnalyticsConfig[] }; }; const jobs = await jobSavedObjectService.filterJobsForSpace( 'data-frame-analytics', - body.data_frame_analytics, + response.body.data_frame_analytics, 'id' ); - return { body: { ...body, count: jobs.length, data_frame_analytics: jobs } }; + + const enhancedBody = { ...response.body, count: jobs.length, data_frame_analytics: jobs }; + if (meta) { + return { ...response, body: enhancedBody }; + } else { + return enhancedBody; + } } catch (error) { if (error.statusCode === 404) { throw new MLJobNotFound(error.body.error.reason); @@ -277,13 +302,21 @@ export function getMlClient( async getDatafeedStats(...p: Parameters) { await datafeedIdsCheck(p, true); try { - const { body } = await mlClient.getDatafeedStats(...p); + const [params, options = {}] = p; + const meta = options.meta ?? false; + const response = await mlClient.getDatafeedStats(params, { ...options, meta: true }); const datafeeds = await jobSavedObjectService.filterDatafeedsForSpace( 'anomaly-detector', - body.datafeeds, + response.body.datafeeds, 'datafeed_id' ); - return { body: { ...body, count: datafeeds.length, datafeeds } }; + + const enhancedBody = { ...response.body, count: datafeeds.length, datafeeds }; + if (meta) { + return { ...response, body: enhancedBody }; + } else { + return enhancedBody; + } } catch (error) { if (error.statusCode === 404) { throw new MLJobNotFound(error.body.error.reason); @@ -294,13 +327,21 @@ export function getMlClient( async getDatafeeds(...p: Parameters) { await datafeedIdsCheck(p, true); try { - const { body } = await mlClient.getDatafeeds(...p); + const [params, options = {}] = p; + const meta = options.meta ?? false; + const response = await mlClient.getDatafeeds(params, { ...options, meta: true }); const datafeeds = await jobSavedObjectService.filterDatafeedsForSpace( 'anomaly-detector', - body.datafeeds, + response.body.datafeeds, 'datafeed_id' ); - return { body: { ...body, count: datafeeds.length, datafeeds } }; + + const enhancedBody = { ...response.body, count: datafeeds.length, datafeeds }; + if (meta) { + return { ...response, body: enhancedBody }; + } else { + return enhancedBody; + } } catch (error) { if (error.statusCode === 404) { throw new MLJobNotFound(error.body.error.reason); @@ -317,17 +358,25 @@ export function getMlClient( }, async getJobStats(...p: Parameters) { try { - const { body } = await mlClient.getJobStats(...p); + const [params, options = {}] = p; + const meta = options.meta ?? false; + const response = await mlClient.getJobStats(params, { ...options, meta: true }); const jobs = await jobSavedObjectService.filterJobsForSpace( 'anomaly-detector', - body.jobs, + response.body.jobs, 'job_id' ); await groupIdsCheckFromJobStats( jobs.map((j) => j.job_id), ...p ); - return { body: { ...body, count: jobs.length, jobs } }; + + const enhancedBody = { ...response.body, count: jobs.length, jobs }; + if (meta) { + return { ...response, body: enhancedBody }; + } else { + return enhancedBody; + } } catch (error) { if (error instanceof MLJobNotFound) { throw error; @@ -340,18 +389,26 @@ export function getMlClient( }, async getJobs(...p: Parameters) { try { - const { body } = await mlClient.getJobs<{ jobs: Job[] }>(...p); + const [params, options = {}] = p; + const meta = options.meta ?? false; + const response = await mlClient.getJobs(params, { ...options, meta: true }); const jobs = await jobSavedObjectService.filterJobsForSpace( 'anomaly-detector', - body.jobs, + response.body.jobs, 'job_id' ); await groupIdsCheck( p, - body.jobs, + response.body.jobs, jobs.map((j) => j.job_id) ); - return { body: { ...body, count: jobs.length, jobs } }; + + const enhancedBody = { ...response.body, count: jobs.length, jobs }; + if (meta) { + return { ...response, body: enhancedBody }; + } else { + return enhancedBody; + } } catch (error) { if (error instanceof MLJobNotFound) { throw error; @@ -485,11 +542,14 @@ export function getMlClient( // @ts-expect-error body doesn't exist in the type const { datafeed_id: id, body } = p[0]; - return client.asInternalUser.transport.request({ - method: 'POST', - path: `/_ml/datafeeds/${id}/_update`, - body, - }); + return client.asInternalUser.transport.request( + { + method: 'POST', + path: `/_ml/datafeeds/${id}/_update`, + body, + }, + p[1] + ); // this should be reinstated once https://github.com/elastic/elasticsearch-js/issues/1601 // is fixed diff --git a/x-pack/plugins/ml/server/lib/ml_client/search.ts b/x-pack/plugins/ml/server/lib/ml_client/search.ts index bdcee216cf669..6ba75478d5988 100644 --- a/x-pack/plugins/ml/server/lib/ml_client/search.ts +++ b/x-pack/plugins/ml/server/lib/ml_client/search.ts @@ -8,7 +8,12 @@ import Boom from '@hapi/boom'; import { IScopedClusterClient } from 'kibana/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { TransportResult } from '@elastic/elasticsearch'; +import type { + TransportResult, + TransportRequestOptions, + TransportRequestOptionsWithMeta, + TransportRequestOptionsWithOutMeta, +} from '@elastic/elasticsearch'; import { JobSavedObjectService } from '../../saved_objects'; import { ML_RESULTS_INDEX_PATTERN } from '../../../common/constants/index_patterns'; @@ -30,15 +35,35 @@ export function searchProvider( async function anomalySearch( searchParams: estypes.SearchRequest, - jobIds: string[] - ): Promise, unknown>> { + jobIds: string[], + options?: TransportRequestOptionsWithOutMeta + ): Promise>; + async function anomalySearch( + searchParams: estypes.SearchRequest, + jobIds: string[], + options?: TransportRequestOptionsWithMeta + ): Promise>>; + async function anomalySearch( + searchParams: estypes.SearchRequest, + jobIds: string[], + options?: TransportRequestOptions + ): Promise>; + async function anomalySearch( + searchParams: estypes.SearchRequest, + jobIds: string[], + options?: TransportRequestOptions + ): Promise, unknown> | estypes.SearchResponse> { await jobIdsCheck('anomaly-detector', jobIds); const { asInternalUser } = client; - const resp = await asInternalUser.search({ - ...searchParams, - index: ML_RESULTS_INDEX_PATTERN, - }); + const resp = await asInternalUser.search( + { + ...searchParams, + index: ML_RESULTS_INDEX_PATTERN, + }, + options + ); return resp; } + return { anomalySearch }; } diff --git a/x-pack/plugins/ml/server/lib/node_utils.ts b/x-pack/plugins/ml/server/lib/node_utils.ts index a13e44b307a7b..d5ec53148b402 100644 --- a/x-pack/plugins/ml/server/lib/node_utils.ts +++ b/x-pack/plugins/ml/server/lib/node_utils.ts @@ -9,7 +9,7 @@ import { IScopedClusterClient } from 'kibana/server'; import { MlNodeCount } from '../../common/types/ml_server_info'; export async function getMlNodeCount(client: IScopedClusterClient): Promise { - const { body } = await client.asInternalUser.nodes.info({ + const body = await client.asInternalUser.nodes.info({ filter_path: 'nodes.*.attributes', }); @@ -31,7 +31,7 @@ export async function getMlNodeCount(client: IScopedClusterClient): Promise { beforeEach(() => { const callAs = { - delete: jest.fn(() => Promise.resolve({ body: acknowledgedResponseMock })), - index: jest.fn(() => Promise.resolve({ body: acknowledgedResponseMock })), - search: jest.fn(() => Promise.resolve({ body: getAnnotationsResponseMock })), + delete: jest.fn(() => Promise.resolve(acknowledgedResponseMock)), + index: jest.fn(() => Promise.resolve(acknowledgedResponseMock)), + search: jest.fn(() => Promise.resolve(getAnnotationsResponseMock)), }; mlClusterClientSpy = { @@ -84,7 +84,7 @@ describe('annotation_service', () => { const mlClusterClientSpyError: any = { asInternalUser: { - search: jest.fn(() => Promise.resolve({ body: mockEsError })), + search: jest.fn(() => Promise.resolve(mockEsError)), }, }; diff --git a/x-pack/plugins/ml/server/models/annotation_service/annotation.ts b/x-pack/plugins/ml/server/models/annotation_service/annotation.ts index 663fcdc11f828..4717a2ea1ce28 100644 --- a/x-pack/plugins/ml/server/models/annotation_service/annotation.ts +++ b/x-pack/plugins/ml/server/models/annotation_service/annotation.ts @@ -105,8 +105,7 @@ export function annotationProvider({ asInternalUser }: IScopedClusterClient) { delete params.body.key; } - const { body } = await asInternalUser.index(params); - return body; + return await asInternalUser.index(params); } async function getAnnotations({ @@ -283,7 +282,7 @@ export function annotationProvider({ asInternalUser }: IScopedClusterClient) { }; try { - const { body } = await asInternalUser.search(params); + const body = await asInternalUser.search(params); // @ts-expect-error TODO fix search response types if (body.error !== undefined && body.message !== undefined) { @@ -375,7 +374,7 @@ export function annotationProvider({ asInternalUser }: IScopedClusterClient) { }, }; - const { body } = await asInternalUser.search(params); + const body = await asInternalUser.search(params); const annotations = ( (body.aggregations!.by_job as estypes.AggregationsTermsAggregateBase) @@ -401,7 +400,7 @@ export function annotationProvider({ asInternalUser }: IScopedClusterClient) { }, }; - const { body } = await asInternalUser.search(searchParams); + const body = await asInternalUser.search(searchParams); const totalCount = typeof body.hits.total === 'number' ? body.hits.total : body.hits.total!.value; @@ -417,8 +416,7 @@ export function annotationProvider({ asInternalUser }: IScopedClusterClient) { refresh: 'wait_for', }; - const { body: deleteResponse } = await asInternalUser.delete(deleteParams); - return deleteResponse; + return await asInternalUser.delete(deleteParams); } return { diff --git a/x-pack/plugins/ml/server/models/bucket_span_estimator/bucket_span_estimator.js b/x-pack/plugins/ml/server/models/bucket_span_estimator/bucket_span_estimator.js index 29961918e7aba..8575ca7781ab7 100644 --- a/x-pack/plugins/ml/server/models/bucket_span_estimator/bucket_span_estimator.js +++ b/x-pack/plugins/ml/server/models/bucket_span_estimator/bucket_span_estimator.js @@ -277,7 +277,7 @@ export function estimateBucketSpanFactory(client) { }, ...(indicesOptions ?? {}), }) - .then(({ body }) => { + .then((body) => { const value = get(body, ['aggregations', 'field_count', 'value'], 0); resolve(value); }) @@ -317,7 +317,7 @@ export function estimateBucketSpanFactory(client) { }, ...(indicesOptions ?? {}), }) - .then(({ body }) => { + .then((body) => { // eslint-disable-next-line camelcase if (body.aggregations?.fields_bucket_counts?.buckets !== undefined) { const buckets = body.aggregations.fields_bucket_counts.buckets; @@ -365,7 +365,7 @@ export function estimateBucketSpanFactory(client) { include_defaults: true, filter_path: '*.*max_buckets', }) - .then(({ body }) => { + .then((body) => { if (typeof body !== 'object') { reject('Unable to retrieve cluster settings'); } diff --git a/x-pack/plugins/ml/server/models/bucket_span_estimator/polled_data_checker.js b/x-pack/plugins/ml/server/models/bucket_span_estimator/polled_data_checker.js index 5fe783e1fc1d5..6c2c90e0d96d4 100644 --- a/x-pack/plugins/ml/server/models/bucket_span_estimator/polled_data_checker.js +++ b/x-pack/plugins/ml/server/models/bucket_span_estimator/polled_data_checker.js @@ -72,7 +72,7 @@ export function polledDataCheckerFactory({ asCurrentUser }) { async performSearch(intervalMs) { const searchBody = this.createSearch(intervalMs); - const { body } = await asCurrentUser.search({ + const body = await asCurrentUser.search({ index: this.index, size: 0, body: searchBody, diff --git a/x-pack/plugins/ml/server/models/bucket_span_estimator/single_series_checker.js b/x-pack/plugins/ml/server/models/bucket_span_estimator/single_series_checker.js index f9f01070f2f82..4a6956db25e6a 100644 --- a/x-pack/plugins/ml/server/models/bucket_span_estimator/single_series_checker.js +++ b/x-pack/plugins/ml/server/models/bucket_span_estimator/single_series_checker.js @@ -200,7 +200,7 @@ export function singleSeriesCheckerFactory({ asCurrentUser }) { async performSearch(intervalMs) { const searchBody = this.createSearch(intervalMs); - const { body } = await asCurrentUser.search({ + const body = await asCurrentUser.search({ index: this.index, size: 0, body: searchBody, diff --git a/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.ts b/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.ts index 4eb2c2421debf..206627005e77d 100644 --- a/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.ts +++ b/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.ts @@ -10,7 +10,6 @@ import { IScopedClusterClient } from 'kibana/server'; import { MLCATEGORY } from '../../../common/constants/field_types'; import { AnalysisConfig, Datafeed } from '../../../common/types/anomaly_detection_jobs'; import { fieldsServiceProvider } from '../fields_service'; -import { MlInfoResponse } from '../../../common/types/ml_server_info'; import type { MlClient } from '../../lib/ml_client'; export interface ModelMemoryEstimationResult { @@ -153,7 +152,7 @@ export function calculateModelMemoryLimitProvider( allowMMLGreaterThanMax = false, datafeedConfig?: Datafeed ): Promise { - const { body: info } = await mlClient.info(); + const info = await mlClient.info(); const maxModelMemoryLimit = info.limits.max_model_memory_limit?.toUpperCase(); const effectiveMaxModelMemoryLimit = info.limits.effective_max_model_memory_limit?.toUpperCase(); @@ -168,7 +167,7 @@ export function calculateModelMemoryLimitProvider( datafeedConfig ); - const { body } = await mlClient.estimateModelMemory({ + const body = await mlClient.estimateModelMemory({ body: { analysis_config: analysisConfig, overall_cardinality: overallCardinality, diff --git a/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts b/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts index 508abcffd0776..03ad89ba5b02c 100644 --- a/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts +++ b/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts @@ -36,7 +36,7 @@ export class CalendarManager { } async getCalendar(calendarId: string) { - const { body } = await this._mlClient.getCalendars({ + const body = await this._mlClient.getCalendars({ calendar_id: calendarId, }); @@ -47,7 +47,7 @@ export class CalendarManager { } async getAllCalendars() { - const { body } = await this._mlClient.getCalendars({ body: { page: { from: 0, size: 1000 } } }); + const body = await this._mlClient.getCalendars({ body: { page: { from: 0, size: 1000 } } }); const events: ScheduledEvent[] = await this._eventManager.getAllEvents(); const calendars: Calendar[] = body.calendars as Calendar[]; @@ -141,7 +141,7 @@ export class CalendarManager { } async deleteCalendar(calendarId: string) { - const { body } = await this._mlClient.deleteCalendar({ calendar_id: calendarId }); + const body = await this._mlClient.deleteCalendar({ calendar_id: calendarId }); return body; } } diff --git a/x-pack/plugins/ml/server/models/calendar/event_manager.ts b/x-pack/plugins/ml/server/models/calendar/event_manager.ts index 46ad415167387..ae92be8d84eea 100644 --- a/x-pack/plugins/ml/server/models/calendar/event_manager.ts +++ b/x-pack/plugins/ml/server/models/calendar/event_manager.ts @@ -18,15 +18,14 @@ export class EventManager { } async getCalendarEvents(calendarId: string) { - const { body } = await this._mlClient.getCalendarEvents({ calendar_id: calendarId }); - + const body = await this._mlClient.getCalendarEvents({ calendar_id: calendarId }); return body.events; } // jobId is optional async getAllEvents(jobId?: string) { const calendarId = GLOBAL_CALENDAR; - const { body } = await this._mlClient.getCalendarEvents({ + const body = await this._mlClient.getCalendarEvents({ calendar_id: calendarId, job_id: jobId, }); diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_audit_messages.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_audit_messages.ts index 34b59c5712265..c8395e2eb0ed6 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_audit_messages.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_audit_messages.ts @@ -69,7 +69,7 @@ export function analyticsAuditMessagesProvider({ asInternalUser }: IScopedCluste }); } - const { body } = await asInternalUser.search({ + const body = await asInternalUser.search({ index: ML_NOTIFICATION_INDEX_PATTERN, ignore_unavailable: true, size: SIZE, diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_manager.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_manager.ts index bf0ffc05dd014..c6e44fc5b3f4c 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_manager.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/analytics_manager.ts @@ -104,21 +104,19 @@ export class AnalyticsManager { const resp = await this._mlClient.getTrainedModels({ model_id: modelId, }); - const modelData = resp?.body?.trained_model_configs[0]; + const modelData = resp?.trained_model_configs[0]; return modelData; } private async getAnalyticsModels() { const resp = await this._mlClient.getTrainedModels(); - const models = resp?.body?.trained_model_configs; + const models = resp?.trained_model_configs; return models; } private async getAnalyticsStats() { - const resp = await this._mlClient.getDataFrameAnalyticsStats<{ - data_frame_analytics: DataFrameAnalyticsStats[]; - }>({ size: 1000 }); - const stats = resp?.body?.data_frame_analytics; + const resp = await this._mlClient.getDataFrameAnalyticsStats({ size: 1000 }); + const stats = resp?.data_frame_analytics; return stats; } @@ -129,9 +127,7 @@ export class AnalyticsManager { } : undefined; const resp = await this._mlClient.getDataFrameAnalytics(options); - let jobData = analyticsId - ? resp?.body?.data_frame_analytics[0] - : resp?.body?.data_frame_analytics; + let jobData = analyticsId ? resp?.data_frame_analytics[0] : resp?.data_frame_analytics; if (analyticsId !== undefined) { const jobStats = this.findJobStats(analyticsId); @@ -152,14 +148,14 @@ export class AnalyticsManager { const indexData = await this._client.asInternalUser.indices.get({ index, }); - return indexData?.body; + return indexData; } private async getTransformData(transformId: string) { const transform = await this._client.asInternalUser.transform.getTransform({ transform_id: transformId, }); - const transformData = transform?.body?.transforms[0]; + const transformData = transform?.transforms[0]; return transformData; } diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.test.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.test.ts index ddff6b59ca8ac..22e803540f0d2 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.test.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.test.ts @@ -17,83 +17,81 @@ describe('Model service', () => { nodes: { stats: jest.fn(() => { return Promise.resolve({ - body: { - _nodes: { - total: 3, - successful: 3, - failed: 0, - }, - cluster_name: 'test_cluster', - nodes: { - '3qIoLFnbSi-DwVrYioUCdw': { - timestamp: 1635167166946, - name: 'node3', - transport_address: '10.10.10.2:9353', - host: '10.10.10.2', - ip: '10.10.10.2:9353', - roles: ['data', 'ingest', 'master', 'ml', 'transform'], - attributes: { - 'ml.machine_memory': '15599742976', - 'xpack.installed': 'true', - 'ml.max_jvm_size': '1073741824', - }, - os: { - mem: { - total_in_bytes: 15599742976, - adjusted_total_in_bytes: 15599742976, - free_in_bytes: 376324096, - used_in_bytes: 15223418880, - free_percent: 2, - used_percent: 98, - }, - }, + _nodes: { + total: 3, + successful: 3, + failed: 0, + }, + cluster_name: 'test_cluster', + nodes: { + '3qIoLFnbSi-DwVrYioUCdw': { + timestamp: 1635167166946, + name: 'node3', + transport_address: '10.10.10.2:9353', + host: '10.10.10.2', + ip: '10.10.10.2:9353', + roles: ['data', 'ingest', 'master', 'ml', 'transform'], + attributes: { + 'ml.machine_memory': '15599742976', + 'xpack.installed': 'true', + 'ml.max_jvm_size': '1073741824', }, - 'DpCy7SOBQla3pu0Dq-tnYw': { - timestamp: 1635167166946, - name: 'node2', - transport_address: '10.10.10.2:9352', - host: '10.10.10.2', - ip: '10.10.10.2:9352', - roles: ['data', 'master', 'ml', 'transform'], - attributes: { - 'ml.machine_memory': '15599742976', - 'xpack.installed': 'true', - 'ml.max_jvm_size': '1073741824', - }, - os: { - timestamp: 1635167166959, - mem: { - total_in_bytes: 15599742976, - adjusted_total_in_bytes: 15599742976, - free_in_bytes: 376324096, - used_in_bytes: 15223418880, - free_percent: 2, - used_percent: 98, - }, + os: { + mem: { + total_in_bytes: 15599742976, + adjusted_total_in_bytes: 15599742976, + free_in_bytes: 376324096, + used_in_bytes: 15223418880, + free_percent: 2, + used_percent: 98, }, }, - 'pt7s6lKHQJaP4QHKtU-Q0Q': { - timestamp: 1635167166945, - name: 'node1', - transport_address: '10.10.10.2:9351', - host: '10.10.10.2', - ip: '10.10.10.2:9351', - roles: ['data', 'master', 'ml'], - attributes: { - 'ml.machine_memory': '15599742976', - 'xpack.installed': 'true', - 'ml.max_jvm_size': '1073741824', + }, + 'DpCy7SOBQla3pu0Dq-tnYw': { + timestamp: 1635167166946, + name: 'node2', + transport_address: '10.10.10.2:9352', + host: '10.10.10.2', + ip: '10.10.10.2:9352', + roles: ['data', 'master', 'ml', 'transform'], + attributes: { + 'ml.machine_memory': '15599742976', + 'xpack.installed': 'true', + 'ml.max_jvm_size': '1073741824', + }, + os: { + timestamp: 1635167166959, + mem: { + total_in_bytes: 15599742976, + adjusted_total_in_bytes: 15599742976, + free_in_bytes: 376324096, + used_in_bytes: 15223418880, + free_percent: 2, + used_percent: 98, }, - os: { - timestamp: 1635167166959, - mem: { - total_in_bytes: 15599742976, - adjusted_total_in_bytes: 15599742976, - free_in_bytes: 376324096, - used_in_bytes: 15223418880, - free_percent: 2, - used_percent: 98, - }, + }, + }, + 'pt7s6lKHQJaP4QHKtU-Q0Q': { + timestamp: 1635167166945, + name: 'node1', + transport_address: '10.10.10.2:9351', + host: '10.10.10.2', + ip: '10.10.10.2:9351', + roles: ['data', 'master', 'ml'], + attributes: { + 'ml.machine_memory': '15599742976', + 'xpack.installed': 'true', + 'ml.max_jvm_size': '1073741824', + }, + os: { + timestamp: 1635167166959, + mem: { + total_in_bytes: 15599742976, + adjusted_total_in_bytes: 15599742976, + free_in_bytes: 376324096, + used_in_bytes: 15223418880, + free_percent: 2, + used_percent: 98, }, }, }, @@ -106,9 +104,7 @@ describe('Model service', () => { const mlClient = { getTrainedModelsStats: jest.fn(() => { return Promise.resolve({ - body: { - trained_model_stats: mockResponse, - }, + trained_model_stats: mockResponse, }); }), } as unknown as jest.Mocked; diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.ts index a5f0eb6e569c5..aba12ae93fdec 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/models_provider.ts @@ -55,7 +55,7 @@ export function modelsProvider( ); try { - const { body } = await client.asCurrentUser.ingest.getPipeline(); + const body = await client.asCurrentUser.ingest.getPipeline(); for (const [pipelineName, pipelineDefinition] of Object.entries(body)) { const { processors } = pipelineDefinition as { processors: Array> }; @@ -92,16 +92,12 @@ export function modelsProvider( throw new Error('Memory overview service is not provided'); } - const { - body: { trained_model_stats: trainedModelStats }, - } = await mlClient.getTrainedModelsStats({ + const { trained_model_stats: trainedModelStats } = await mlClient.getTrainedModelsStats({ model_id: '_all', size: 10000, }); - const { - body: { nodes: clusterNodes }, - } = await client.asInternalUser.nodes.stats(); + const { nodes: clusterNodes } = await client.asInternalUser.nodes.stats(); const mlNodes = Object.entries(clusterNodes).filter(([, node]) => node.roles?.includes('ml')); diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/validation.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/validation.ts index 436ca86b5a603..f534c9e91cef4 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/validation.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/validation.ts @@ -259,7 +259,7 @@ async function getValidationCheckMessages( } try { - const { body } = await asCurrentUser.search({ + const body = await asCurrentUser.search({ index, size: 0, track_total_hits: true, diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts index d0d6965121ba3..dad1ecb7bc4ba 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts @@ -19,7 +19,6 @@ import { merge } from 'lodash'; import type { DataViewsService } from '../../../../../../src/plugins/data_views/common'; import type { AnalysisLimits } from '../../../common/types/anomaly_detection_jobs'; import { getAuthorizationHeader } from '../../lib/request_authorization'; -import type { MlInfoResponse } from '../../../common/types/ml_server_info'; import type { MlClient } from '../../lib/ml_client'; import { ML_MODULE_SAVED_OBJECT_TYPE } from '../../../common/types/saved_objects'; import type { @@ -52,7 +51,6 @@ import { fieldsServiceProvider } from '../fields_service'; import { jobServiceProvider } from '../job_service'; import { resultsServiceProvider } from '../results_service'; import type { JobExistResult, JobStat } from '../../../common/types/data_recognizer'; -import type { MlJobsStatsResponse } from '../../../common/types/job_service'; import type { Datafeed } from '../../../common/types/anomaly_detection_jobs'; import type { JobSavedObjectService } from '../../saved_objects'; import { isDefined } from '../../../common/types/guards'; @@ -289,7 +287,7 @@ export class DataRecognizer { query: moduleConfig.query, }; - const { body } = await this._client.asCurrentUser.search({ + const body = await this._client.asCurrentUser.search({ index, size, body: searchBody, @@ -590,7 +588,7 @@ export class DataRecognizer { if (doJobsExist === true) { // Get the IDs of the jobs created from the module, and their earliest / latest timestamps. - const { body } = await this._mlClient.getJobStats({ + const body = await this._mlClient.getJobStats({ job_id: jobIds.join(), }); const jobStatsJobs: JobStat[] = []; @@ -843,7 +841,7 @@ export class DataRecognizer { const result = { started: false } as DatafeedResponse; let opened = false; try { - const { body } = await this._mlClient.openJob({ + const body = await this._mlClient.openJob({ job_id: datafeed.config.job_id, }); opened = body.opened; @@ -867,12 +865,7 @@ export class DataRecognizer { duration.end = String(end); } - const { - body: { started, node }, - } = await this._mlClient.startDatafeed<{ - started: boolean; - node: string; - }>({ + const { started, node } = await this._mlClient.startDatafeed({ datafeed_id: datafeed.id, ...duration, }); @@ -1168,9 +1161,7 @@ export class DataRecognizer { } } - const { - body: { limits }, - } = await this._mlClient.info(); + const { limits } = await this._mlClient.info(); const maxMml = limits.max_model_memory_limit; if (!maxMml) { diff --git a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts index 5d841ce5d94d0..eb9e88b62a09a 100644 --- a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts +++ b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts @@ -204,7 +204,7 @@ const getAggIntervals = async ( return aggs; }, {} as Record); - const { body } = await asCurrentUser.search({ + const body = await asCurrentUser.search({ index: indexPattern, size: 0, body: { @@ -290,7 +290,7 @@ export const getHistogramsForFields = async ( return []; } - const { body } = await asCurrentUser.search({ + const body = await asCurrentUser.search({ index: indexPattern, size: 0, body: { @@ -666,7 +666,7 @@ export class DataVisualizer { : {}), }; - const { body } = await this._asCurrentUser.search({ + const body = await this._asCurrentUser.search({ index, track_total_hits: true, size, @@ -757,7 +757,7 @@ export class DataVisualizer { }; filterCriteria.push({ exists: { field } }); - const { body } = await this._asCurrentUser.search({ + const body = await this._asCurrentUser.search({ index, size, body: searchBody, @@ -802,7 +802,7 @@ export class DataVisualizer { ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), }; - const { body } = await this._asCurrentUser.search({ + const body = await this._asCurrentUser.search({ index, size, body: searchBody, @@ -907,7 +907,7 @@ export class DataVisualizer { ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), }; - const { body } = await this._asCurrentUser.search({ + const body = await this._asCurrentUser.search({ index, size, body: searchBody, @@ -1030,7 +1030,7 @@ export class DataVisualizer { ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), }; - const { body } = await this._asCurrentUser.search({ + const body = await this._asCurrentUser.search({ index, size, body: searchBody, @@ -1106,7 +1106,7 @@ export class DataVisualizer { ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), }; - const { body } = await this._asCurrentUser.search({ + const body = await this._asCurrentUser.search({ index, size, body: searchBody, @@ -1175,7 +1175,7 @@ export class DataVisualizer { ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), }; - const { body } = await this._asCurrentUser.search({ + const body = await this._asCurrentUser.search({ index, size, body: searchBody, @@ -1240,7 +1240,7 @@ export class DataVisualizer { ...(isPopulatedObject(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}), }; - const { body } = await this._asCurrentUser.search({ + const body = await this._asCurrentUser.search({ index, size, body: searchBody, diff --git a/x-pack/plugins/ml/server/models/fields_service/fields_service.ts b/x-pack/plugins/ml/server/models/fields_service/fields_service.ts index 128517777bb46..c8828ab6c5416 100644 --- a/x-pack/plugins/ml/server/models/fields_service/fields_service.ts +++ b/x-pack/plugins/ml/server/models/fields_service/fields_service.ts @@ -16,6 +16,7 @@ import { getDatafeedAggregations } from '../../../common/util/datafeed_utils'; import { Datafeed, IndicesOptions } from '../../../common/types/anomaly_detection_jobs'; import { RuntimeMappings } from '../../../common/types/fields'; import { isPopulatedObject } from '../../../common/util/object_utils'; + /** * Service for carrying out queries to obtain data * specific to fields in Elasticsearch indices. @@ -44,7 +45,7 @@ export function fieldsServiceProvider({ asCurrentUser }: IScopedClusterClient) { fieldNames: string[], datafeedConfig?: Datafeed ): Promise { - const { body } = await asCurrentUser.fieldCaps({ + const body = await asCurrentUser.fieldCaps({ index, fields: fieldNames, }); @@ -179,9 +180,7 @@ export function fieldsServiceProvider({ asCurrentUser }: IScopedClusterClient) { ...runtimeMappings, }; - const { - body: { aggregations }, - } = await asCurrentUser.search({ + const { aggregations } = await asCurrentUser.search({ index, body, ...(datafeedConfig?.indices_options ?? {}), @@ -223,9 +222,7 @@ export function fieldsServiceProvider({ asCurrentUser }: IScopedClusterClient) { }> { const obj = { success: true, start: { epoch: 0, string: '' }, end: { epoch: 0, string: '' } }; - const { - body: { aggregations }, - } = await asCurrentUser.search({ + const { aggregations } = await asCurrentUser.search({ index, size: 0, body: { @@ -400,9 +397,7 @@ export function fieldsServiceProvider({ asCurrentUser }: IScopedClusterClient) { }, }; - const { - body: { aggregations }, - } = await asCurrentUser.search({ + const { aggregations } = await asCurrentUser.search({ index, body, ...(datafeedConfig?.indices_options ?? {}), diff --git a/x-pack/plugins/ml/server/models/filter/filter_manager.ts b/x-pack/plugins/ml/server/models/filter/filter_manager.ts index 3a0d7a706e69c..baad35de6e590 100644 --- a/x-pack/plugins/ml/server/models/filter/filter_manager.ts +++ b/x-pack/plugins/ml/server/models/filter/filter_manager.ts @@ -64,18 +64,13 @@ export class FilterManager { this._mlClient.getFilters({ filter_id: filterId }), ]); - if ( - results[FILTERS] && - (results[FILTERS].body as estypes.MlGetFiltersResponse).filters.length - ) { + if (results[FILTERS] && (results[FILTERS] as estypes.MlGetFiltersResponse).filters.length) { let filtersInUse: FiltersInUse = {}; - if (results[JOBS] && (results[JOBS].body as estypes.MlGetJobsResponse).jobs) { - filtersInUse = this.buildFiltersInUse( - (results[JOBS].body as estypes.MlGetJobsResponse).jobs - ); + if (results[JOBS] && (results[JOBS] as estypes.MlGetJobsResponse).jobs) { + filtersInUse = this.buildFiltersInUse((results[JOBS] as estypes.MlGetJobsResponse).jobs); } - const filter = (results[FILTERS].body as estypes.MlGetFiltersResponse).filters[0]; + const filter = (results[FILTERS] as estypes.MlGetFiltersResponse).filters[0]; return { ...filter, used_by: filtersInUse[filter.filter_id], @@ -91,7 +86,7 @@ export class FilterManager { async getAllFilters() { try { - const { body } = await this._mlClient.getFilters({ size: 1000 }); + const body = await this._mlClient.getFilters({ size: 1000 }); return body.filters; } catch (error) { throw Boom.badRequest(error); @@ -108,10 +103,8 @@ export class FilterManager { // Build a map of filter_ids against jobs and detectors using that filter. let filtersInUse: FiltersInUse = {}; - if (results[JOBS] && (results[JOBS].body as estypes.MlGetJobsResponse).jobs) { - filtersInUse = this.buildFiltersInUse( - (results[JOBS].body as estypes.MlGetJobsResponse).jobs - ); + if (results[JOBS] && (results[JOBS] as estypes.MlGetJobsResponse).jobs) { + filtersInUse = this.buildFiltersInUse((results[JOBS] as estypes.MlGetJobsResponse).jobs); } // For each filter, return just @@ -120,18 +113,16 @@ export class FilterManager { // item_count // jobs using the filter const filterStats: FilterStats[] = []; - if (results[FILTERS] && (results[FILTERS].body as estypes.MlGetFiltersResponse).filters) { - (results[FILTERS].body as estypes.MlGetFiltersResponse).filters.forEach( - (filter: Filter) => { - const stats: FilterStats = { - filter_id: filter.filter_id, - description: filter.description, - item_count: filter.items.length, - used_by: filtersInUse[filter.filter_id], - }; - filterStats.push(stats); - } - ); + if (results[FILTERS] && (results[FILTERS] as estypes.MlGetFiltersResponse).filters) { + (results[FILTERS] as estypes.MlGetFiltersResponse).filters.forEach((filter: Filter) => { + const stats: FilterStats = { + filter_id: filter.filter_id, + description: filter.description, + item_count: filter.items.length, + used_by: filtersInUse[filter.filter_id], + }; + filterStats.push(stats); + }); } return filterStats; @@ -144,8 +135,7 @@ export class FilterManager { const { filterId, ...body } = filter; try { // Returns the newly created filter. - const { body: resp } = await this._mlClient.putFilter({ filter_id: filterId, body }); - return resp; + return await this._mlClient.putFilter({ filter_id: filterId, body }); } catch (error) { throw Boom.badRequest(error); } @@ -165,7 +155,7 @@ export class FilterManager { } // Returns the newly updated filter. - const { body: resp } = await this._mlClient.updateFilter({ + const resp = await this._mlClient.updateFilter({ filter_id: filterId, body, }); @@ -176,8 +166,7 @@ export class FilterManager { } async deleteFilter(filterId: string) { - const { body } = await this._mlClient.deleteFilter({ filter_id: filterId }); - return body; + return await this._mlClient.deleteFilter({ filter_id: filterId }); } buildFiltersInUse(jobsList: Job[]) { diff --git a/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.ts b/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.ts index 50c77aaf2053d..79b54b9a635a8 100644 --- a/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.ts +++ b/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.ts @@ -82,8 +82,8 @@ export function jobAuditMessagesProvider( let gte = null; if (jobId !== undefined && from === undefined) { const jobs = await mlClient.getJobs({ job_id: jobId }); - if (jobs.body.count > 0 && jobs.body.jobs !== undefined) { - gte = moment(jobs.body.jobs[0].create_time).valueOf(); + if (jobs.count > 0 && jobs.jobs !== undefined) { + gte = moment(jobs.jobs[0].create_time).valueOf(); } } else if (from !== undefined) { gte = `now-${from}`; @@ -150,7 +150,7 @@ export function jobAuditMessagesProvider( }); } - const { body } = await asInternalUser.search({ + const body = await asInternalUser.search({ index: ML_NOTIFICATION_INDEX_PATTERN, ignore_unavailable: true, size: SIZE, @@ -222,7 +222,7 @@ export function jobAuditMessagesProvider( }, }; - const { body } = await asInternalUser.search({ + const body = await asInternalUser.search({ index: ML_NOTIFICATION_INDEX_PATTERN, ignore_unavailable: true, size: 0, @@ -428,7 +428,7 @@ export function jobAuditMessagesProvider( jobIds: string[], earliestMs?: number ): Promise { - const { body } = await asInternalUser.search({ + const body = await asInternalUser.search({ index: ML_NOTIFICATION_INDEX_PATTERN, ignore_unavailable: true, size: 0, diff --git a/x-pack/plugins/ml/server/models/job_service/datafeeds.ts b/x-pack/plugins/ml/server/models/job_service/datafeeds.ts index a699402f9b47a..c74b8bad75e79 100644 --- a/x-pack/plugins/ml/server/models/job_service/datafeeds.ts +++ b/x-pack/plugins/ml/server/models/job_service/datafeeds.ts @@ -17,6 +17,7 @@ export interface MlDatafeedsResponse { datafeeds: Datafeed[]; count: number; } + export interface MlDatafeedsStatsResponse { datafeeds: DatafeedStats[]; count: number; @@ -90,7 +91,7 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie async function openJob(jobId: string) { let opened = false; try { - const { body } = await mlClient.openJob({ job_id: jobId }); + const body = await mlClient.openJob({ job_id: jobId }); opened = body.opened; } catch (error) { if (error.statusCode === 409) { @@ -117,7 +118,7 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie for (const datafeedId of datafeedIds) { try { - const { body } = await mlClient.stopDatafeed({ + const body = await mlClient.stopDatafeed({ datafeed_id: datafeedId, }); results[datafeedId] = { stopped: body.stopped }; @@ -137,7 +138,7 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie } async function forceDeleteDatafeed(datafeedId: string) { - const { body } = await mlClient.deleteDatafeed<{ acknowledged: boolean }>({ + const body = await mlClient.deleteDatafeed({ datafeed_id: datafeedId, force: true, }); @@ -145,9 +146,7 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie } async function getDatafeedIdsByJobId() { - const { - body: { datafeeds }, - } = await mlClient.getDatafeeds(); + const { datafeeds } = await mlClient.getDatafeeds(); return datafeeds.reduce((acc, cur) => { acc[cur.job_id] = cur.datafeed_id; @@ -156,9 +155,7 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie } async function getJobIdsByDatafeedId() { - const { - body: { datafeeds }, - } = await mlClient.getDatafeeds(); + const { datafeeds } = await mlClient.getDatafeeds(); return datafeeds.reduce((acc, cur) => { acc[cur.datafeed_id] = cur.job_id; @@ -185,9 +182,9 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie async function findDatafeed() { // if the job was doesn't use the standard datafeedId format // get all the datafeeds and match it with the jobId - const { - body: { datafeeds }, - } = await mlClient.getDatafeeds(excludeGenerated ? { exclude_generated: true } : {}); + const { datafeeds } = await mlClient.getDatafeeds( + excludeGenerated ? { exclude_generated: true } : {} + ); if (typeof jobId === 'string') { return datafeeds.find((v) => v.job_id === jobId); } @@ -196,13 +193,12 @@ export function datafeedsProvider(client: IScopedClusterClient, mlClient: MlClie return datafeeds.filter((v) => jobIds.includes(v.job_id)); } } + // if the job was created by the wizard, // then we can assume it uses the standard format of the datafeedId const assumedDefaultDatafeedId = jobIds.map((v) => `datafeed-${v}`).join(','); try { - const { - body: { datafeeds: datafeedsResults }, - } = await mlClient.getDatafeeds({ + const { datafeeds: datafeedsResults } = await mlClient.getDatafeeds({ datafeed_id: assumedDefaultDatafeedId, ...(excludeGenerated ? { exclude_generated: true } : {}), }); diff --git a/x-pack/plugins/ml/server/models/job_service/groups.ts b/x-pack/plugins/ml/server/models/job_service/groups.ts index 02d3771bcb644..c898e10f424a7 100644 --- a/x-pack/plugins/ml/server/models/job_service/groups.ts +++ b/x-pack/plugins/ml/server/models/job_service/groups.ts @@ -7,7 +7,6 @@ import { CalendarManager } from '../calendar'; import { GLOBAL_CALENDAR } from '../../../common/constants/calendars'; -import { MlJobsResponse } from '../../../common/types/job_service'; import type { MlClient } from '../../lib/ml_client'; export interface Group { @@ -29,10 +28,7 @@ export function groupsProvider(mlClient: MlClient) { async function getAllGroups() { const groups: { [id: string]: Group } = {}; const jobIds: { [id: string]: undefined | null } = {}; - const [{ body }, calendars] = await Promise.all([ - mlClient.getJobs(), - calMngr.getAllCalendars(), - ]); + const [body, calendars] = await Promise.all([mlClient.getJobs(), calMngr.getAllCalendars()]); const { jobs } = body; if (jobs) { diff --git a/x-pack/plugins/ml/server/models/job_service/jobs.ts b/x-pack/plugins/ml/server/models/job_service/jobs.ts index c4e215fc3c38e..81e1b1f693449 100644 --- a/x-pack/plugins/ml/server/models/job_service/jobs.ts +++ b/x-pack/plugins/ml/server/models/job_service/jobs.ts @@ -30,14 +30,12 @@ import { Job, } from '../../../common/types/anomaly_detection_jobs'; import { - MlJobsResponse, - MlJobsStatsResponse, JobsExistResponse, BulkCreateResults, ResetJobsResponse, } from '../../../common/types/job_service'; import { GLOBAL_CALENDAR } from '../../../common/constants/calendars'; -import { datafeedsProvider, MlDatafeedsResponse, MlDatafeedsStatsResponse } from './datafeeds'; +import { datafeedsProvider } from './datafeeds'; import { jobAuditMessagesProvider } from '../job_audit_messages'; import { resultsServiceProvider } from '../results_service'; import { CalendarManager } from '../calendar'; @@ -158,10 +156,8 @@ export function jobsProvider( const results: ResetJobsResponse = {}; for (const jobId of jobIds) { try { - const { - // @ts-expect-error @elastic-elasticsearch resetJob response incorrect, missing task - body: { task }, - } = await mlClient.resetJob({ + // @ts-expect-error @elastic-elasticsearch resetJob response incorrect, missing task + const { task } = await mlClient.resetJob({ job_id: jobId, wait_for_completion: false, }); @@ -184,7 +180,7 @@ export function jobsProvider( throw Boom.notFound(`Cannot find datafeed for job ${jobId}`); } - const { body } = await mlClient.stopDatafeed({ + const body = await mlClient.stopDatafeed({ datafeed_id: datafeedId, body: { force: true }, }); @@ -274,7 +270,7 @@ export function jobsProvider( } async function getJobIdsWithGeo(): Promise { - const { body } = await mlClient.getJobs(); + const body = await mlClient.getJobs(); return body.jobs.filter(isJobWithGeoData).map((job) => job.job_id); } @@ -314,8 +310,8 @@ export function jobsProvider( } async function getJobForCloning(jobId: string) { - const [{ body: jobResults }, datafeedResult] = await Promise.all([ - mlClient.getJobs({ job_id: jobId, exclude_generated: true }), + const [jobResults, datafeedResult] = await Promise.all([ + mlClient.getJobs({ job_id: jobId, exclude_generated: true }), getDatafeedByJobId(jobId, true), ]); const result: { datafeed?: Datafeed; job?: Job } = { job: undefined, datafeed: undefined }; @@ -349,19 +345,17 @@ export function jobsProvider( const jobIdsString = jobIds.join(); const [ - { body: jobResults }, - { body: jobStatsResults }, - { body: datafeedResults }, - { body: datafeedStatsResults }, + jobResults, + jobStatsResults, + datafeedResults, + datafeedStatsResults, calendarResults, latestBucketTimestampByJob, ] = await Promise.all([ - mlClient.getJobs(jobIds.length > 0 ? { job_id: jobIdsString } : undefined), - mlClient.getJobStats( - jobIds.length > 0 ? { job_id: jobIdsString } : undefined - ), - mlClient.getDatafeeds(), - mlClient.getDatafeedStats(), + mlClient.getJobs(jobIds.length > 0 ? { job_id: jobIdsString } : undefined), + mlClient.getJobStats(jobIds.length > 0 ? { job_id: jobIdsString } : undefined), + mlClient.getDatafeeds(), + mlClient.getDatafeedStats(), calMngr.getAllCalendars(), getLatestBucketTimestampByJob(), ]); @@ -505,7 +499,7 @@ export function jobsProvider( async function blockingJobTasks() { const jobs: Array> = []; try { - const { body } = await asInternalUser.tasks.list({ + const body = await asInternalUser.tasks.list({ actions: JOB_ACTION_TASKS, detailed: true, }); @@ -527,9 +521,7 @@ export function jobsProvider( } catch (e) { // if the user doesn't have permission to load the task list, // use the jobs list to get the ids of deleting jobs - const { - body: { jobs: tempJobs }, - } = await mlClient.getJobs(); + const { jobs: tempJobs } = await mlClient.getJobs(); jobs.push( ...tempJobs @@ -555,11 +547,11 @@ export function jobsProvider( continue; } - const { body } = allSpaces - ? await client.asInternalUser.ml.getJobs({ + const body = allSpaces + ? await client.asInternalUser.ml.getJobs({ job_id: jobId, }) - : await mlClient.getJobs({ + : await mlClient.getJobs({ job_id: jobId, }); @@ -578,7 +570,7 @@ export function jobsProvider( async function getAllJobAndGroupIds() { const { getAllGroups } = groupsProvider(mlClient); - const { body } = await mlClient.getJobs(); + const body = await mlClient.getJobs(); const jobIds = body.jobs.map((job) => job.job_id); const groups = await getAllGroups(); const groupIds = groups.map((group) => group.id); @@ -591,8 +583,8 @@ export function jobsProvider( async function getLookBackProgress(jobId: string, start: number, end: number) { const datafeedId = `datafeed-${jobId}`; - const [{ body }, isRunning] = await Promise.all([ - mlClient.getJobStats({ job_id: jobId }), + const [body, isRunning] = await Promise.all([ + mlClient.getJobStats({ job_id: jobId }), isDatafeedRunning(datafeedId), ]); @@ -611,7 +603,7 @@ export function jobsProvider( } async function isDatafeedRunning(datafeedId: string) { - const { body } = await mlClient.getDatafeedStats({ + const body = await mlClient.getDatafeedStats({ datafeed_id: datafeedId, }); if (body.datafeeds.length) { diff --git a/x-pack/plugins/ml/server/models/job_service/model_snapshots.ts b/x-pack/plugins/ml/server/models/job_service/model_snapshots.ts index 56221f9a72c89..76e81120c6f3a 100644 --- a/x-pack/plugins/ml/server/models/job_service/model_snapshots.ts +++ b/x-pack/plugins/ml/server/models/job_service/model_snapshots.ts @@ -17,6 +17,7 @@ export interface ModelSnapshotsResponse { count: number; model_snapshots: ModelSnapshot[]; } + export interface RevertModelSnapshotResponse { model: ModelSnapshot; } @@ -53,15 +54,13 @@ export function modelSnapshotProvider(client: IScopedClusterClient, mlClient: Ml } // ensure the snapshot exists - const { body: snapshot } = await mlClient.getModelSnapshots({ + const snapshot = await mlClient.getModelSnapshots({ job_id: jobId, snapshot_id: snapshotId, }); // apply the snapshot revert - const { - body: { model }, - } = await mlClient.revertModelSnapshot({ + const { model } = await mlClient.revertModelSnapshot({ job_id: jobId, snapshot_id: snapshotId, body: { diff --git a/x-pack/plugins/ml/server/models/job_service/new_job/categorization/examples.ts b/x-pack/plugins/ml/server/models/job_service/new_job/categorization/examples.ts index a5510977d2ade..f3ea82b837caa 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job/categorization/examples.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job/categorization/examples.ts @@ -62,7 +62,7 @@ export function categorizationExamplesProvider({ } } } - const { body } = await asCurrentUser.search>({ + const body = await asCurrentUser.search>({ index: indexPatternTitle, size, body: { @@ -126,9 +126,7 @@ export function categorizationExamplesProvider({ } async function loadTokens(examples: string[], analyzer: CategorizationAnalyzer) { - const { - body: { tokens }, - } = await asInternalUser.indices.analyze({ + const { tokens } = await asInternalUser.indices.analyze({ body: { ...getAnalyzer(analyzer), text: examples, diff --git a/x-pack/plugins/ml/server/models/job_service/new_job/categorization/top_categories.ts b/x-pack/plugins/ml/server/models/job_service/new_job/categorization/top_categories.ts index 65fa3769d0fed..046b0e4784e86 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job/categorization/top_categories.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job/categorization/top_categories.ts @@ -12,7 +12,7 @@ import type { MlClient } from '../../../../lib/ml_client'; export function topCategoriesProvider(mlClient: MlClient) { async function getTotalCategories(jobId: string): Promise { - const { body } = await mlClient.anomalySearch>( + const body = await mlClient.anomalySearch>( { size: 0, body: { @@ -40,7 +40,7 @@ export function topCategoriesProvider(mlClient: MlClient) { } async function getTopCategoryCounts(jobId: string, numberOfCategories: number) { - const { body } = await mlClient.anomalySearch>( + const body = await mlClient.anomalySearch>( { size: 0, body: { @@ -105,7 +105,7 @@ export function topCategoriesProvider(mlClient: MlClient) { field: 'category_id', }, }; - const { body } = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { size, body: { diff --git a/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts b/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts index e6a2432e28dc1..44bf280fcc86a 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job/line_chart.ts @@ -57,7 +57,7 @@ export function newJobLineChartProvider({ asCurrentUser }: IScopedClusterClient) indicesOptions ); - const { body } = await asCurrentUser.search(json); + const body = await asCurrentUser.search(json); return processSearchResults( body, aggFieldNamePairs.map((af) => af.field) diff --git a/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts b/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts index 2385ffef67191..5654f48b39596 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job/population_chart.ts @@ -20,10 +20,12 @@ const OVER_FIELD_EXAMPLES_COUNT = 40; type DtrIndex = number; type TimeStamp = number; type Value = number | undefined | null; + interface Thing { label: string; value: Value; } + interface Result { time: TimeStamp; values: Thing[]; @@ -61,7 +63,7 @@ export function newJobPopulationChartProvider({ asCurrentUser }: IScopedClusterC indicesOptions ); - const { body } = await asCurrentUser.search(json); + const body = await asCurrentUser.search(json); return processSearchResults( body, aggFieldNamePairs.map((af) => af.field) diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts index 3682245b1b640..f553e3ee8ccc1 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/field_service.ts @@ -62,11 +62,10 @@ class FieldsService { } private async loadFieldCaps(): Promise { - const { body } = await this._mlClusterClient.asCurrentUser.fieldCaps({ + return await this._mlClusterClient.asCurrentUser.fieldCaps({ index: this._indexPattern, fields: '*', }); - return body; } // create field object from the results from _field_caps diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.test.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.test.ts index c0f270f1df96c..021244afce2cb 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.test.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/new_job_caps.test.ts @@ -6,6 +6,7 @@ */ import { newJobCapsProvider } from './index'; +import { elasticsearchServiceMock } from '../../../../../../../src/core/server/mocks'; import farequoteFieldCaps from './__mocks__/responses/farequote_field_caps.json'; import cloudwatchFieldCaps from './__mocks__/responses/cloudwatch_field_caps.json'; @@ -22,19 +23,18 @@ describe('job_service - job_caps', () => { let dataViews: any; beforeEach(() => { - const asNonRollupMock = { - fieldCaps: jest.fn(() => ({ body: farequoteFieldCaps })), - }; + const asNonRollupMock = elasticsearchServiceMock.createElasticsearchClient(); + asNonRollupMock.fieldCaps.mockResponse(farequoteFieldCaps); mlClusterClientNonRollupMock = { asCurrentUser: asNonRollupMock, asInternalUser: asNonRollupMock, }; - const callAsRollupMock = { - fieldCaps: jest.fn(() => ({ body: cloudwatchFieldCaps })), - rollup: { getRollupIndexCaps: jest.fn(() => Promise.resolve({ body: rollupCaps })) }, - }; + const callAsRollupMock = elasticsearchServiceMock.createElasticsearchClient(); + callAsRollupMock.fieldCaps.mockResponse(cloudwatchFieldCaps); + // @ts-expect-error incomplete type type + callAsRollupMock.rollup.getRollupIndexCaps.mockResponse(rollupCaps); mlClusterClientRollupMock = { asCurrentUser: callAsRollupMock, diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts index f0f9a53879962..a4eb5b9135c8c 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts @@ -36,7 +36,7 @@ export async function rollupServiceProvider( rollupIndexPatternObject.typeMeta?.params !== undefined ) { const rollUpIndex: string = rollupIndexPatternObject.typeMeta.params.rollup_index; - const { body: rollupCaps } = await asCurrentUser.rollup.getRollupIndexCaps({ + const rollupCaps = await asCurrentUser.rollup.getRollupIndexCaps({ index: rollUpIndex, }); diff --git a/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts b/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts index 83140d9655d38..b9ac2831e5bf0 100644 --- a/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts +++ b/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts @@ -6,19 +6,20 @@ */ import { IScopedClusterClient } from 'kibana/server'; +import { elasticsearchServiceMock } from '../../../../../../src/core/server/mocks'; import { validateJob, ValidateJobPayload } from './job_validation'; import { ES_CLIENT_TOTAL_HITS_RELATION } from '../../../common/types/es_client'; import type { MlClient } from '../../lib/ml_client'; import type { AuthorizationHeader } from '../../lib/request_authorization'; -const callAs = { - fieldCaps: () => Promise.resolve({ body: { fields: [] } }), - search: () => - Promise.resolve({ - body: { hits: { total: { value: 1, relation: ES_CLIENT_TOTAL_HITS_RELATION.EQ } } }, - }), -}; +const callAs = elasticsearchServiceMock.createElasticsearchClient(); +// @ts-expect-error incorrect types +callAs.fieldCaps.mockResponse({ fields: [] }); +callAs.search.mockResponse({ + // @ts-expect-error incorrect types + hits: { total: { value: 1, relation: ES_CLIENT_TOTAL_HITS_RELATION.EQ } }, +}); const authHeader: AuthorizationHeader = {}; @@ -30,14 +31,12 @@ const mlClusterClient = { const mlClient = { info: () => Promise.resolve({ - body: { - limits: { - effective_max_model_memory_limit: '100MB', - max_model_memory_limit: '1GB', - }, + limits: { + effective_max_model_memory_limit: '100MB', + max_model_memory_limit: '1GB', }, }), - previewDatafeed: () => Promise.resolve({ body: [{}] }), + previewDatafeed: () => Promise.resolve([{}]), } as unknown as MlClient; // Note: The tests cast `payload` as any diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.test.ts b/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.test.ts index c49768d55047a..7c64f9201c373 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.test.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.test.ts @@ -27,13 +27,13 @@ const mlClusterClientFactory = ( fail = false ): IScopedClusterClient => { const callAs = { - search: () => Promise.resolve({ body: responses.search }), - fieldCaps: () => Promise.resolve({ body: responses.fieldCaps }), + search: () => Promise.resolve(responses.search), + fieldCaps: () => Promise.resolve(responses.fieldCaps), }; const callAsFail = { - search: () => Promise.reject({ body: {} }), - fieldCaps: () => Promise.reject({ body: {} }), + search: () => Promise.reject({}), + fieldCaps: () => Promise.reject({}), }; return { diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.ts b/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.ts index 403d6738a4ce6..151ae4a9e739a 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.ts @@ -83,7 +83,7 @@ const validateFactory = (client: IScopedClusterClient, job: CombinedJob): Valida ] as string[]; // use fieldCaps endpoint to get data about whether fields are aggregatable - const { body: fieldCaps } = await asCurrentUser.fieldCaps({ + const fieldCaps = await asCurrentUser.fieldCaps({ index: job.datafeed_config.indices.join(','), fields: uniqueFieldNames, }); diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_datafeed_preview.ts b/x-pack/plugins/ml/server/models/job_validation/validate_datafeed_preview.ts index 0775de7ae0e13..60d092ee6acbe 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_datafeed_preview.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_datafeed_preview.ts @@ -30,7 +30,7 @@ export async function validateDatafeedPreview( ): Promise { const { datafeed_config: datafeed, ...tempJob } = job; try { - const { body } = (await mlClient.previewDatafeed( + const body = (await mlClient.previewDatafeed( { body: { job_config: tempJob, diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_model_memory_limit.test.ts b/x-pack/plugins/ml/server/models/job_validation/validate_model_memory_limit.test.ts index 452e12b5a51ba..5c50ac31281f2 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_model_memory_limit.test.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_model_memory_limit.test.ts @@ -82,8 +82,8 @@ describe('ML - validateModelMemoryLimit', () => { // - to retrieve field capabilities used in search for split field cardinality const getMockMlClusterClient = (): IScopedClusterClient => { const callAs = { - search: () => Promise.resolve({ body: cardinalitySearchResponse }), - fieldCaps: () => Promise.resolve({ body: fieldCapsResponse }), + search: () => Promise.resolve(cardinalitySearchResponse), + fieldCaps: () => Promise.resolve(fieldCapsResponse), }; return { @@ -96,9 +96,9 @@ describe('ML - validateModelMemoryLimit', () => { estimateModelMemory: estimateModelMemory, }: MockAPICallResponse = {}): MlClient => { const callAs = { - info: () => Promise.resolve({ body: mlInfoResponse }), + info: () => Promise.resolve(mlInfoResponse), estimateModelMemory: () => - Promise.resolve({ body: estimateModelMemory || modelMemoryEstimateResponse }), + Promise.resolve(estimateModelMemory || modelMemoryEstimateResponse), }; return callAs as MlClient; diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_model_memory_limit.ts b/x-pack/plugins/ml/server/models/job_validation/validate_model_memory_limit.ts index 4c06e26b81a04..7687f3acd313e 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_model_memory_limit.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_model_memory_limit.ts @@ -11,7 +11,6 @@ import { CombinedJob } from '../../../common/types/anomaly_detection_jobs'; import { validateJobObject } from './validate_job_object'; import { calculateModelMemoryLimitProvider } from '../calculate_model_memory_limit'; import { ALLOWED_DATA_UNITS } from '../../../common/constants/validation'; -import { MlInfoResponse } from '../../../common/types/ml_server_info'; import type { MlClient } from '../../lib/ml_client'; // The minimum value the backend expects is 1MByte @@ -54,7 +53,7 @@ export async function validateModelMemoryLimit( // retrieve the max_model_memory_limit value from the server // this will be unset unless the user has set this on their cluster - const { body } = await mlClient.info(); + const body = await mlClient.info(); const maxModelMemoryLimit = body.limits.max_model_memory_limit?.toUpperCase(); const effectiveMaxModelMemoryLimit = body.limits.effective_max_model_memory_limit?.toUpperCase(); diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_time_range.test.ts b/x-pack/plugins/ml/server/models/job_validation/validate_time_range.test.ts index 5983604ae576c..0d6840c3574fd 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_time_range.test.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_time_range.test.ts @@ -24,8 +24,8 @@ const mockSearchResponse = { const mlClusterClientFactory = (response: any): IScopedClusterClient => { const callAs = { - fieldCaps: () => Promise.resolve({ body: response.fieldCaps }), - search: () => Promise.resolve({ body: response.search }), + fieldCaps: () => Promise.resolve(response.fieldCaps), + search: () => Promise.resolve(response.search), }; return { asCurrentUser: callAs, diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_time_range.ts b/x-pack/plugins/ml/server/models/job_validation/validate_time_range.ts index 813d6733e7b57..d498114911c23 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_time_range.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_time_range.ts @@ -32,7 +32,7 @@ export async function isValidTimeField({ asCurrentUser }: IScopedClusterClient, const timeField = job.data_description.time_field!; // check if time_field is of type 'date' or 'date_nanos' - const { body: fieldCaps } = await asCurrentUser.fieldCaps({ + const fieldCaps = await asCurrentUser.fieldCaps({ index, fields: [timeField], }); diff --git a/x-pack/plugins/ml/server/models/memory_overview/memory_overview_service.ts b/x-pack/plugins/ml/server/models/memory_overview/memory_overview_service.ts index 05a5cde0d2720..e7bbc95ded742 100644 --- a/x-pack/plugins/ml/server/models/memory_overview/memory_overview_service.ts +++ b/x-pack/plugins/ml/server/models/memory_overview/memory_overview_service.ts @@ -33,9 +33,7 @@ export function memoryOverviewServiceProvider(mlClient: MlClient) { * Retrieves memory consumed my started DFA jobs. */ async getDFAMemoryOverview(): Promise { - const { - body: { data_frame_analytics: dfaStats }, - } = await mlClient.getDataFrameAnalyticsStats(); + const { data_frame_analytics: dfaStats } = await mlClient.getDataFrameAnalyticsStats(); const dfaMemoryReport = dfaStats .filter((dfa) => dfa.state === 'started') @@ -52,9 +50,7 @@ export function memoryOverviewServiceProvider(mlClient: MlClient) { const dfaMemoryKeyByJobId = keyBy(dfaMemoryReport, 'job_id'); - const { - body: { data_frame_analytics: startedDfaJobs }, - } = await mlClient.getDataFrameAnalytics({ + const { data_frame_analytics: startedDfaJobs } = await mlClient.getDataFrameAnalytics({ id: dfaMemoryReport.map((v) => v.job_id).join(','), }); @@ -72,9 +68,7 @@ export function memoryOverviewServiceProvider(mlClient: MlClient) { * Retrieves memory consumed by opened Anomaly Detection jobs. */ async getAnomalyDetectionMemoryOverview(): Promise { - const { - body: { jobs: jobsStats }, - } = await mlClient.getJobStats(); + const { jobs: jobsStats } = await mlClient.getJobStats(); return jobsStats .filter((v) => v.state === 'opened') diff --git a/x-pack/plugins/ml/server/models/results_service/get_partition_fields_values.ts b/x-pack/plugins/ml/server/models/results_service/get_partition_fields_values.ts index be1786d64f2aa..189aa99e24ce5 100644 --- a/x-pack/plugins/ml/server/models/results_service/get_partition_fields_values.ts +++ b/x-pack/plugins/ml/server/models/results_service/get_partition_fields_values.ts @@ -145,7 +145,7 @@ export const getPartitionFieldsValuesFactory = (mlClient: MlClient) => latestMs: number, fieldsConfig: FieldsConfig = {} ) { - const { body: jobsResponse } = await mlClient.getJobs({ job_id: jobId }); + const jobsResponse = await mlClient.getJobs({ job_id: jobId }); if (jobsResponse.count === 0 || jobsResponse.jobs === undefined) { throw Boom.notFound(`Job with the id "${jobId}" not found`); } @@ -219,7 +219,7 @@ export const getPartitionFieldsValuesFactory = (mlClient: MlClient) => }, }; - const { body } = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { size: 0, body: requestBody, diff --git a/x-pack/plugins/ml/server/models/results_service/results_service.ts b/x-pack/plugins/ml/server/models/results_service/results_service.ts index 5ffe8ed5eb481..aa92ada043c29 100644 --- a/x-pack/plugins/ml/server/models/results_service/results_service.ts +++ b/x-pack/plugins/ml/server/models/results_service/results_service.ts @@ -24,7 +24,6 @@ import { defaultSearchQuery, DatafeedResultsChartDataParams, } from '../../../common/types/results'; -import { MlJobsResponse } from '../../../common/types/job_service'; import type { MlClient } from '../../lib/ml_client'; import { datafeedsProvider } from '../job_service/datafeeds'; import { annotationServiceProvider } from '../annotation_service'; @@ -190,7 +189,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust }); } - const { body } = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { size: maxRecords, body: { @@ -345,7 +344,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust }, }; - const { body } = await mlClient.anomalySearch(query, jobIds); + const body = await mlClient.anomalySearch(query, jobIds); const maxScore = get(body, ['aggregations', 'max_score', 'value'], null); return { maxScore }; @@ -383,7 +382,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust // Size of job terms agg, consistent with maximum number of jobs supported by Java endpoints. const maxJobs = 10000; - const { body } = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { size: 0, body: { @@ -429,7 +428,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust // from the given index and job ID. // Returned response consists of a list of examples against category ID. async function getCategoryExamples(jobId: string, categoryIds: any, maxExamples: number) { - const { body } = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { size: ANOMALIES_TABLE_DEFAULT_QUERY_SIZE, // Matches size of records in anomaly summary table. body: { @@ -466,7 +465,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust // Returned response contains four properties - categoryId, regex, examples // and terms (space delimited String of the common tokens matched in values of the category). async function getCategoryDefinition(jobId: string, categoryId: string) { - const { body } = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { size: 1, body: { @@ -509,7 +508,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust }, }); } - const { body } = await mlClient.anomalySearch( + const body = await mlClient.anomalySearch( { body: { query: { @@ -540,7 +539,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust }; // first determine from job config if stop_on_warn is true // if false return [] - const { body } = await mlClient.getJobs({ + const body = await mlClient.getJobs({ job_id: jobIds.join(), }); @@ -598,7 +597,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust }, }, ]; - const { body: results } = await mlClient.anomalySearch( + const results = await mlClient.anomalySearch( { size: 0, body: { @@ -662,7 +661,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust const { getDatafeedByJobId } = datafeedsProvider(client!, mlClient); - const [datafeedConfig, { body: jobsResponse }] = await Promise.all([ + const [datafeedConfig, jobsResponse] = await Promise.all([ getDatafeedByJobId(jobId), mlClient.getJobs({ job_id: jobId }), ]); @@ -725,9 +724,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust }; if (client) { - const { - body: { aggregations }, - } = await client.asCurrentUser.search(esSearchRequest); + const { aggregations } = await client.asCurrentUser.search(esSearchRequest); finalResults.datafeedResults = // @ts-expect-error incorrect search response type @@ -739,7 +736,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust const { getAnnotations } = annotationServiceProvider(client!); - const [bucketResp, annotationResp, { body: modelSnapshotsResp }] = await Promise.all([ + const [bucketResp, annotationResp, modelSnapshotsResp] = await Promise.all([ mlClient.getBuckets({ job_id: jobId, body: { desc: true, start: String(start), end: String(end), page: { from: 0, size: 1000 } }, @@ -757,7 +754,7 @@ export function resultsServiceProvider(mlClient: MlClient, client?: IScopedClust }), ]); - const bucketResults = bucketResp?.body?.buckets ?? []; + const bucketResults = bucketResp?.buckets ?? []; bucketResults.forEach((dataForTime) => { const timestamp = Number(dataForTime?.timestamp); const eventCount = dataForTime?.event_count; diff --git a/x-pack/plugins/ml/server/routes/anomaly_detectors.ts b/x-pack/plugins/ml/server/routes/anomaly_detectors.ts index 4e222e05c1b19..7989334c3852b 100644 --- a/x-pack/plugins/ml/server/routes/anomaly_detectors.ts +++ b/x-pack/plugins/ml/server/routes/anomaly_detectors.ts @@ -50,7 +50,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, response }) => { try { - const { body } = await mlClient.getJobs(); + const body = await mlClient.getJobs(); return response.ok({ body, }); @@ -82,7 +82,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { jobId } = request.params; - const { body } = await mlClient.getJobs({ job_id: jobId }); + const body = await mlClient.getJobs({ job_id: jobId }); return response.ok({ body, }); @@ -112,7 +112,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, response }) => { try { - const { body } = await mlClient.getJobStats(); + const body = await mlClient.getJobStats(); return response.ok({ body, }); @@ -144,7 +144,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { jobId } = request.params; - const { body } = await mlClient.getJobStats({ job_id: jobId }); + const body = await mlClient.getJobStats({ job_id: jobId }); return response.ok({ body, }); @@ -180,7 +180,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { jobId } = request.params; - const { body } = await mlClient.putJob({ + const body = await mlClient.putJob({ job_id: jobId, // @ts-expect-error job type custom_rules is incorrect body: request.body, @@ -219,7 +219,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { jobId } = request.params; - const { body } = await mlClient.updateJob({ + const body = await mlClient.updateJob({ job_id: jobId, // @ts-expect-error MlDetector is not compatible body: request.body, @@ -255,7 +255,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { jobId } = request.params; - const { body } = await mlClient.openJob({ job_id: jobId }); + const body = await mlClient.openJob({ job_id: jobId }); return response.ok({ body, }); @@ -295,7 +295,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { if (force !== undefined) { options.force = force; } - const { body } = await mlClient.closeJob(options); + const body = await mlClient.closeJob(options); return response.ok({ body, }); @@ -335,7 +335,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { ? { wait_for_completion: request.query.wait_for_completion } : {}), }; - const { body } = await mlClient.resetJob(options); + const body = await mlClient.resetJob(options); return response.ok({ body, }); @@ -376,7 +376,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { if (force !== undefined) { options.force = force; } - const { body } = await mlClient.deleteJob(options); + const body = await mlClient.deleteJob(options); return response.ok({ body, }); @@ -405,7 +405,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.validateDetector({ body: request.body }); + const body = await mlClient.validateDetector({ body: request.body }); return response.ok({ body, }); @@ -440,7 +440,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { try { const jobId = request.params.jobId; const duration = request.body.duration; - const { body } = await mlClient.forecast({ + const body = await mlClient.forecast({ job_id: jobId, body: { duration, @@ -481,7 +481,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.getRecords({ + const body = await mlClient.getRecords({ job_id: request.params.jobId, body: request.body, }); @@ -520,7 +520,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.getBuckets({ + const body = await mlClient.getBuckets({ job_id: request.params.jobId, timestamp: request.params.timestamp, body: request.body, @@ -560,7 +560,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.getOverallBuckets({ + const body = await mlClient.getOverallBuckets({ job_id: request.params.jobId, top_n: request.body.topN, bucket_span: request.body.bucketSpan, @@ -598,7 +598,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.getCategories({ + const body = await mlClient.getCategories({ job_id: request.params.jobId, category_id: request.params.categoryId, }); @@ -632,7 +632,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.getModelSnapshots({ + const body = await mlClient.getModelSnapshots({ job_id: request.params.jobId, }); return response.ok({ @@ -665,7 +665,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.getModelSnapshots({ + const body = await mlClient.getModelSnapshots({ job_id: request.params.jobId, snapshot_id: request.params.snapshotId, }); @@ -701,7 +701,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.updateModelSnapshot({ + const body = await mlClient.updateModelSnapshot({ job_id: request.params.jobId, snapshot_id: request.params.snapshotId, body: request.body, @@ -736,7 +736,7 @@ export function jobRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.deleteModelSnapshot({ + const body = await mlClient.deleteModelSnapshot({ job_id: request.params.jobId, snapshot_id: request.params.snapshotId, }); diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index 21e1678c7fd41..2ab10bda36190 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -96,7 +96,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout return true; } - const { body } = await client.asCurrentUser.security.hasPrivileges({ + const body = await client.asCurrentUser.security.hasPrivileges({ body: { index: [ { @@ -130,7 +130,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, response }) => { try { - const { body } = await mlClient.getDataFrameAnalytics({ + const body = await mlClient.getDataFrameAnalytics({ size: 1000, }); return response.ok({ @@ -167,7 +167,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout const { analyticsId } = request.params; const { excludeGenerated } = request.query; - const { body } = await mlClient.getDataFrameAnalytics({ + const body = await mlClient.getDataFrameAnalytics({ id: analyticsId, ...(excludeGenerated ? { exclude_generated: true } : {}), }); @@ -197,7 +197,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, response }) => { try { - const { body } = await mlClient.getDataFrameAnalyticsStats({ size: 1000 }); + const body = await mlClient.getDataFrameAnalyticsStats({ size: 1000 }); return response.ok({ body, }); @@ -229,7 +229,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { analyticsId } = request.params; - const { body } = await mlClient.getDataFrameAnalyticsStats({ + const body = await mlClient.getDataFrameAnalyticsStats({ id: analyticsId, }); return response.ok({ @@ -266,7 +266,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { analyticsId } = request.params; - const { body } = await mlClient.putDataFrameAnalytics( + const body = await mlClient.putDataFrameAnalytics( { id: analyticsId, // @ts-expect-error @elastic-elasticsearch Data frame types incomplete @@ -304,7 +304,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.evaluateDataFrame( + const body = await mlClient.evaluateDataFrame( { // @ts-expect-error @elastic-elasticsearch Data frame types incomplete body: request.body, @@ -342,7 +342,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.explainDataFrameAnalytics( + const body = await mlClient.explainDataFrameAnalytics( { body: request.body, }, @@ -391,7 +391,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout try { // Check if analyticsId is valid and get destination index - const { body } = await mlClient.getDataFrameAnalytics({ + const body = await mlClient.getDataFrameAnalytics({ id: analyticsId, }); if (Array.isArray(body.data_frame_analytics) && body.data_frame_analytics.length > 0) { @@ -484,7 +484,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { analyticsId } = request.params; - const { body } = await mlClient.startDataFrameAnalytics({ + const body = await mlClient.startDataFrameAnalytics({ id: analyticsId, }); return response.ok({ @@ -519,7 +519,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { - const { body } = await mlClient.stopDataFrameAnalytics({ + const body = await mlClient.stopDataFrameAnalytics({ id: request.params.analyticsId, force: request.query.force, }); @@ -556,7 +556,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { analyticsId } = request.params; - const { body } = await mlClient.updateDataFrameAnalytics( + const body = await mlClient.updateDataFrameAnalytics( { id: analyticsId, body: request.body, @@ -632,7 +632,7 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense, routeGuard }: Rout const results: { [id: string]: { exists: boolean } } = {}; for (const id of analyticsIds) { try { - const { body } = allSpaces + const body = allSpaces ? await client.asInternalUser.ml.getDataFrameAnalytics({ id, }) diff --git a/x-pack/plugins/ml/server/routes/datafeeds.ts b/x-pack/plugins/ml/server/routes/datafeeds.ts index c3414b2fbc55c..d5da9f7f420b4 100644 --- a/x-pack/plugins/ml/server/routes/datafeeds.ts +++ b/x-pack/plugins/ml/server/routes/datafeeds.ts @@ -37,7 +37,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, response }) => { try { - const { body } = await mlClient.getDatafeeds(); + const body = await mlClient.getDatafeeds(); return response.ok({ body, }); @@ -69,7 +69,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const { body } = await mlClient.getDatafeeds({ datafeed_id: datafeedId }); + const body = await mlClient.getDatafeeds({ datafeed_id: datafeedId }); return response.ok({ body, @@ -97,7 +97,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { }, routeGuard.fullLicenseAPIGuard(async ({ mlClient, response }) => { try { - const { body } = await mlClient.getDatafeedStats(); + const body = await mlClient.getDatafeedStats(); return response.ok({ body, }); @@ -129,7 +129,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const { body } = await mlClient.getDatafeedStats({ + const body = await mlClient.getDatafeedStats({ datafeed_id: datafeedId, }); @@ -166,7 +166,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const { body } = await mlClient.putDatafeed( + const body = await mlClient.putDatafeed( { datafeed_id: datafeedId, body: request.body, @@ -207,7 +207,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const { body } = await mlClient.updateDatafeed( + const body = await mlClient.updateDatafeed( { datafeed_id: datafeedId, body: request.body, @@ -255,7 +255,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { options.force = force; } - const { body } = await mlClient.deleteDatafeed(options); + const body = await mlClient.deleteDatafeed(options); return response.ok({ body, @@ -292,7 +292,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { const datafeedId = request.params.datafeedId; const { start, end } = request.body; - const { body } = await mlClient.startDatafeed({ + const body = await mlClient.startDatafeed({ datafeed_id: datafeedId, body: { start: start !== undefined ? String(start) : undefined, @@ -332,7 +332,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { try { const datafeedId = request.params.datafeedId; - const { body } = await mlClient.stopDatafeed({ + const body = await mlClient.stopDatafeed({ datafeed_id: datafeedId, }); @@ -367,7 +367,7 @@ export function dataFeedRoutes({ router, routeGuard }: RouteInitialization) { routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const datafeedId = request.params.datafeedId; - const { body } = await mlClient.previewDatafeed( + const body = await mlClient.previewDatafeed( { datafeed_id: datafeedId, }, diff --git a/x-pack/plugins/ml/server/routes/indices.ts b/x-pack/plugins/ml/server/routes/indices.ts index 03d9a52cadc7a..65df5287ac75f 100644 --- a/x-pack/plugins/ml/server/routes/indices.ts +++ b/x-pack/plugins/ml/server/routes/indices.ts @@ -41,7 +41,7 @@ export function indicesRoutes({ router, routeGuard }: RouteInitialization) { requestFields !== undefined && Array.isArray(requestFields) ? requestFields.join(',') : '*'; - const { body } = await client.asCurrentUser.fieldCaps({ index, fields }); + const body = await client.asCurrentUser.fieldCaps({ index, fields }); return response.ok({ body }); } catch (e) { return response.customError(wrapError(e)); diff --git a/x-pack/plugins/ml/server/routes/job_service.ts b/x-pack/plugins/ml/server/routes/job_service.ts index 123b38e9cd7de..e67095d022901 100644 --- a/x-pack/plugins/ml/server/routes/job_service.ts +++ b/x-pack/plugins/ml/server/routes/job_service.ts @@ -896,7 +896,7 @@ export function jobServiceRoutes({ router, routeGuard }: RouteInitialization) { }, } as estypes.MlPreviewDatafeedRequest); - const { body } = await mlClient.previewDatafeed(payload, getAuthorizationHeader(request)); + const body = await mlClient.previewDatafeed(payload, getAuthorizationHeader(request)); return response.ok({ body, }); diff --git a/x-pack/plugins/ml/server/routes/results_service.ts b/x-pack/plugins/ml/server/routes/results_service.ts index fe1a759caf8e6..78f05f0d731aa 100644 --- a/x-pack/plugins/ml/server/routes/results_service.ts +++ b/x-pack/plugins/ml/server/routes/results_service.ts @@ -284,7 +284,7 @@ export function resultsServiceRoutes({ router, routeGuard }: RouteInitialization routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { jobIds, query } = request.body; - const { body } = await mlClient.anomalySearch(query, jobIds); + const body = await mlClient.anomalySearch(query, jobIds); return response.ok({ body, }); diff --git a/x-pack/plugins/ml/server/routes/system.ts b/x-pack/plugins/ml/server/routes/system.ts index c0fb32df0fd18..36a381444a855 100644 --- a/x-pack/plugins/ml/server/routes/system.ts +++ b/x-pack/plugins/ml/server/routes/system.ts @@ -43,7 +43,7 @@ export function systemRoutes( const { asCurrentUser } = client; let upgradeInProgress = false; try { - const { body } = await mlClient.info(); + const body = await mlClient.info(); // if ml indices are currently being migrated, upgrade_mode will be set to true // pass this back with the privileges to allow for the disabling of UI controls. upgradeInProgress = body.upgrade_mode === true; @@ -70,7 +70,7 @@ export function systemRoutes( }, }); } else { - const { body } = await asCurrentUser.security.hasPrivileges({ body: request.body }); + const body = await asCurrentUser.security.hasPrivileges({ body: request.body }); return response.ok({ body: { ...body, @@ -164,7 +164,7 @@ export function systemRoutes( }, routeGuard.basicLicenseAPIGuard(async ({ mlClient, response }) => { try { - const { body } = await mlClient.info(); + const body = await mlClient.info(); const cloudId = cloud && cloud.cloudId; return response.ok({ body: { ...body, cloudId }, @@ -195,7 +195,7 @@ export function systemRoutes( }, routeGuard.fullLicenseAPIGuard(async ({ client, request, response }) => { try { - const { body } = await client.asCurrentUser.search(request.body); + const body = await client.asCurrentUser.search(request.body); return response.ok({ body, }); @@ -234,7 +234,7 @@ export function systemRoutes( ); const result = indices.reduce((acc, cur, i) => { - acc[cur] = { exists: results[i].body }; + acc[cur] = { exists: results[i] }; return acc; }, {} as Record); diff --git a/x-pack/plugins/ml/server/routes/trained_models.ts b/x-pack/plugins/ml/server/routes/trained_models.ts index e213efc203704..72b93ba45a104 100644 --- a/x-pack/plugins/ml/server/routes/trained_models.ts +++ b/x-pack/plugins/ml/server/routes/trained_models.ts @@ -41,7 +41,7 @@ export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) try { const { modelId } = request.params; const { with_pipelines: withPipelines, ...query } = request.query; - const { body } = await mlClient.getTrainedModels({ + const body = await mlClient.getTrainedModels({ // @ts-expect-error @elastic-elasticsearch not sure why this is an error, size is a number size: 1000, ...query, @@ -111,7 +111,7 @@ export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { modelId } = request.params; - const { body } = await mlClient.getTrainedModelsStats({ + const body = await mlClient.getTrainedModelsStats({ ...(modelId ? { model_id: modelId } : {}), }); return response.ok({ @@ -175,7 +175,7 @@ export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { modelId } = request.params; - const { body } = await mlClient.deleteTrainedModel({ + const body = await mlClient.deleteTrainedModel({ model_id: modelId, }); return response.ok({ @@ -243,7 +243,7 @@ export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { modelId } = request.params; - const { body } = await mlClient.startTrainedModelDeployment({ + const body = await mlClient.startTrainedModelDeployment({ model_id: modelId, }); return response.ok({ @@ -276,7 +276,7 @@ export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) routeGuard.fullLicenseAPIGuard(async ({ mlClient, request, response }) => { try { const { modelId } = request.params; - const { body } = await mlClient.stopTrainedModelDeployment({ + const body = await mlClient.stopTrainedModelDeployment({ model_id: modelId, force: request.query.force ?? false, }); diff --git a/x-pack/plugins/ml/server/saved_objects/checks.ts b/x-pack/plugins/ml/server/saved_objects/checks.ts index f3bc89a6d9bea..f4085d99ad636 100644 --- a/x-pack/plugins/ml/server/saved_objects/checks.ts +++ b/x-pack/plugins/ml/server/saved_objects/checks.ts @@ -49,12 +49,11 @@ export function checksFactory( const jobObjects = await jobSavedObjectService.getAllJobObjects(undefined, false); // load all non-space jobs and datafeeds - const { body: adJobs } = await client.asInternalUser.ml.getJobs(); - const { body: datafeeds } = await client.asInternalUser.ml.getDatafeeds(); - const { body: dfaJobs } = - (await client.asInternalUser.ml.getDataFrameAnalytics()) as unknown as { - body: { data_frame_analytics: DataFrameAnalyticsConfig[] }; - }; + const adJobs = await client.asInternalUser.ml.getJobs(); + const datafeeds = await client.asInternalUser.ml.getDatafeeds(); + const dfaJobs = (await client.asInternalUser.ml.getDataFrameAnalytics()) as unknown as { + data_frame_analytics: DataFrameAnalyticsConfig[]; + }; const savedObjectsStatus: JobSavedObjectStatus[] = jobObjects.map( ({ attributes, namespaces }) => { diff --git a/x-pack/plugins/ml/server/saved_objects/initialization/initialization.ts b/x-pack/plugins/ml/server/saved_objects/initialization/initialization.ts index 96a834229553e..c0ab8600794c6 100644 --- a/x-pack/plugins/ml/server/saved_objects/initialization/initialization.ts +++ b/x-pack/plugins/ml/server/saved_objects/initialization/initialization.ts @@ -106,10 +106,8 @@ export function jobSavedObjectsInitializationFactory( // }); // return body.count > 0; - const { body: adJobs } = await client.asInternalUser.ml.getJobs<{ count: number }>(); - const { body: dfaJobs } = await client.asInternalUser.ml.getDataFrameAnalytics<{ - count: number; - }>(); + const adJobs = await client.asInternalUser.ml.getJobs(); + const dfaJobs = await client.asInternalUser.ml.getDataFrameAnalytics(); return adJobs.count > 0 || dfaJobs.count > 0; } diff --git a/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/logs.ts b/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/logs.ts index 40285742af2b9..b7e0affb51fa5 100644 --- a/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/logs.ts +++ b/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/logs.ts @@ -8,7 +8,6 @@ import { IScopedClusterClient } from 'kibana/server'; import RE2 from 're2'; import { mlLog } from '../../../lib/log'; -import { Job } from '../../../../common/types/anomaly_detection_jobs'; const GROUP = 'logs-ui'; const MODULE_PREFIX = 'kibana-logs-ui'; @@ -22,7 +21,7 @@ export async function logJobsSpaces({ asInternalUser, }: IScopedClusterClient): Promise> { try { - const { body } = await asInternalUser.ml.getJobs<{ jobs: Job[] }>({ + const body = await asInternalUser.ml.getJobs({ job_id: GROUP, }); if (body.jobs.length === 0) { diff --git a/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/metrics.ts b/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/metrics.ts index 125b3e32b1efb..e2b8f587c25e6 100644 --- a/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/metrics.ts +++ b/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/metrics.ts @@ -8,7 +8,6 @@ import { IScopedClusterClient } from 'kibana/server'; import RE2 from 're2'; import { mlLog } from '../../../lib/log'; -import { Job } from '../../../../common/types/anomaly_detection_jobs'; const GROUP = 'metrics'; const MODULE_PREFIX = 'kibana-metrics-ui'; @@ -29,7 +28,7 @@ export async function metricsJobsSpaces({ asInternalUser, }: IScopedClusterClient): Promise> { try { - const { body } = await asInternalUser.ml.getJobs<{ jobs: Job[] }>({ + const body = await asInternalUser.ml.getJobs({ job_id: GROUP, }); if (body.jobs.length === 0) { diff --git a/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/space_overrides.test.ts b/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/space_overrides.test.ts index 72cce2ff1c13a..b5b4e8db2dd58 100644 --- a/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/space_overrides.test.ts +++ b/x-pack/plugins/ml/server/saved_objects/initialization/space_overrides/space_overrides.test.ts @@ -51,11 +51,7 @@ const result = { const callAs = { ml: { - getJobs: jest.fn(() => - Promise.resolve({ - body: { jobs }, - }) - ), + getJobs: jest.fn(() => Promise.resolve({ jobs })), }, }; diff --git a/x-pack/plugins/ml/server/saved_objects/sync.ts b/x-pack/plugins/ml/server/saved_objects/sync.ts index f8895c039bd8e..d77cdddcfa863 100644 --- a/x-pack/plugins/ml/server/saved_objects/sync.ts +++ b/x-pack/plugins/ml/server/saved_objects/sync.ts @@ -17,8 +17,6 @@ import { checksFactory } from './checks'; import type { JobStatus } from './checks'; import { getSavedObjectClientError } from './util'; -import { Datafeed } from '../../common/types/anomaly_detection_jobs'; - export interface JobSpaceOverrides { overrides: { [type in JobType]: { [jobId: string]: string[] }; @@ -39,9 +37,7 @@ export function syncSavedObjectsFactory( datafeedsRemoved: {}, }; - const { body: datafeeds } = await client.asInternalUser.ml.getDatafeeds<{ - datafeeds: Datafeed[]; - }>(); + const datafeeds = await client.asInternalUser.ml.getDatafeeds(); const tasks: Array<() => Promise> = []; diff --git a/x-pack/plugins/ml/server/shared_services/providers/anomaly_detectors.ts b/x-pack/plugins/ml/server/shared_services/providers/anomaly_detectors.ts index dae7e60b92c2c..f091db10b9763 100644 --- a/x-pack/plugins/ml/server/shared_services/providers/anomaly_detectors.ts +++ b/x-pack/plugins/ml/server/shared_services/providers/anomaly_detectors.ts @@ -38,10 +38,9 @@ export function getAnomalyDetectorsProvider(getGuards: GetGuards): AnomalyDetect .isFullLicense() .hasMlCapabilities(['canGetJobs']) .ok(async ({ mlClient }) => { - const { body } = await mlClient.getJobs<{ - count: number; - jobs: Job[]; - }>(jobId !== undefined ? { job_id: jobId } : undefined); + const body = await mlClient.getJobs( + jobId !== undefined ? { job_id: jobId } : undefined + ); return body; }); }, @@ -50,10 +49,9 @@ export function getAnomalyDetectorsProvider(getGuards: GetGuards): AnomalyDetect .isFullLicense() .hasMlCapabilities(['canGetJobs']) .ok(async ({ mlClient }) => { - const { body } = await mlClient.getJobStats<{ - count: number; - jobs: JobStats[]; - }>(jobId !== undefined ? { job_id: jobId } : undefined); + const body = await mlClient.getJobStats( + jobId !== undefined ? { job_id: jobId } : undefined + ); return body; }); }, @@ -62,10 +60,9 @@ export function getAnomalyDetectorsProvider(getGuards: GetGuards): AnomalyDetect .isFullLicense() .hasMlCapabilities(['canGetDatafeeds']) .ok(async ({ mlClient }) => { - const { body } = await mlClient.getDatafeeds<{ - count: number; - datafeeds: Datafeed[]; - }>(datafeedId !== undefined ? { datafeed_id: datafeedId } : undefined); + const body = await mlClient.getDatafeeds( + datafeedId !== undefined ? { datafeed_id: datafeedId } : undefined + ); return body; }); }, @@ -74,10 +71,9 @@ export function getAnomalyDetectorsProvider(getGuards: GetGuards): AnomalyDetect .isFullLicense() .hasMlCapabilities(['canGetDatafeeds']) .ok(async ({ mlClient }) => { - const { body } = await mlClient.getDatafeedStats<{ - count: number; - datafeeds: DatafeedStats[]; - }>(datafeedId !== undefined ? { datafeed_id: datafeedId } : undefined); + const body = await mlClient.getDatafeedStats( + datafeedId !== undefined ? { datafeed_id: datafeedId } : undefined + ); return body; }); }, diff --git a/x-pack/plugins/ml/server/shared_services/providers/system.ts b/x-pack/plugins/ml/server/shared_services/providers/system.ts index b198e5d8345f0..977288210299a 100644 --- a/x-pack/plugins/ml/server/shared_services/providers/system.ts +++ b/x-pack/plugins/ml/server/shared_services/providers/system.ts @@ -62,7 +62,7 @@ export function getMlSystemProvider( return await getGuards(request, savedObjectsClient) .isMinimumLicense() .ok(async ({ mlClient }) => { - const { body: info } = await mlClient.info(); + const info = await mlClient.info(); const cloudId = cloud && cloud.cloudId; return { ...info, @@ -78,8 +78,7 @@ export function getMlSystemProvider( .isFullLicense() .hasMlCapabilities(['canAccessML']) .ok(async ({ mlClient }) => { - const { body } = await mlClient.anomalySearch(searchParams, jobIds); - return body; + return await mlClient.anomalySearch(searchParams, jobIds); }); }, }; diff --git a/x-pack/plugins/ml/server/usage/collector.ts b/x-pack/plugins/ml/server/usage/collector.ts index ca865a8f48770..abfef308951a9 100644 --- a/x-pack/plugins/ml/server/usage/collector.ts +++ b/x-pack/plugins/ml/server/usage/collector.ts @@ -115,7 +115,7 @@ export function registerCollector(usageCollection: UsageCollectionSetup, kibanaI }, }); - const aggResponse = result.body.aggregations as { + const aggResponse = result.aggregations as { count_by_result_type: { buckets: Array<{ key: AnomalyResultType; @@ -151,7 +151,7 @@ export function registerCollector(usageCollection: UsageCollectionSetup, kibanaI }, }); - const resultsByCheckType = jobsHealthRuleInstances.body.hits.hits.reduce( + const resultsByCheckType = jobsHealthRuleInstances.hits.hits.reduce( (acc, curr) => { const doc = curr._source; if (!doc) return acc; diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_es_usage.test.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_es_usage.test.ts index 4f53ae9b84edf..eadf6af15bdc8 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_es_usage.test.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_es_usage.test.ts @@ -13,30 +13,28 @@ describe('fetchESUsage', () => { const index = '.monitoring-es-*'; const callCluster = { search: jest.fn().mockImplementation(() => ({ - body: { - hits: { - hits: [ - { - _source: { - cluster_stats: { - nodes: { - count: { - total: 10, - }, + hits: { + hits: [ + { + _source: { + cluster_stats: { + nodes: { + count: { + total: 10, }, }, }, }, - ], - }, - aggregations: { - indices: { - buckets: [ - { - key: '.monitoring-es-2', - }, - ], }, + ], + }, + aggregations: { + indices: { + buckets: [ + { + key: '.monitoring-es-2', + }, + ], }, }, })), @@ -54,30 +52,28 @@ describe('fetchESUsage', () => { it('should handle some indices coming from Metricbeat', async () => { const customCallCluster = { search: jest.fn().mockImplementation(() => ({ - body: { - hits: { - hits: [ - { - _source: { - cluster_stats: { - nodes: { - count: { - total: 10, - }, + hits: { + hits: [ + { + _source: { + cluster_stats: { + nodes: { + count: { + total: 10, }, }, }, }, - ], - }, - aggregations: { - indices: { - buckets: [ - { - key: '.monitoring-es-mb-2', - }, - ], }, + ], + }, + aggregations: { + indices: { + buckets: [ + { + key: '.monitoring-es-mb-2', + }, + ], }, }, })), @@ -93,10 +89,8 @@ describe('fetchESUsage', () => { it('should handle no monitoring data', async () => { const customCallCluster = { search: jest.fn().mockImplementation(() => ({ - body: { - hits: { - hits: [], - }, + hits: { + hits: [], }, })), } as unknown as ElasticsearchClient; diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_es_usage.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_es_usage.ts index 884b4e6466e60..c6b62563a88f6 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_es_usage.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_es_usage.ts @@ -85,7 +85,7 @@ export async function fetchESUsage( }, }; - const { body: response } = await callCluster.search(params); + const response = await callCluster.search(params); const esResponse = response as estypes.SearchResponse; if (esResponse.hits.hits.length === 0) { return { diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.test.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.test.ts index 93e21072d0e34..5069f17d8795b 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.test.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.test.ts @@ -13,18 +13,16 @@ describe('fetchLicenseType', () => { const availableCcs = false; const callCluster = { search: jest.fn().mockImplementation(() => ({ - body: { - hits: { - hits: [ - { - _source: { - license: { - type: 'trial', - }, + hits: { + hits: [ + { + _source: { + license: { + type: 'trial', }, }, - ], - }, + }, + ], }, })), } as unknown as ElasticsearchClient; @@ -37,10 +35,8 @@ describe('fetchLicenseType', () => { it('should handle no license data', async () => { const customCallCluster = { search: jest.fn().mockImplementation(() => ({ - body: { - hits: { - hits: [], - }, + hits: { + hits: [], }, })), } as unknown as ElasticsearchClient; diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.ts index 5a0c714c8f1d3..1dedf63065884 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.ts @@ -55,6 +55,6 @@ export async function fetchLicenseType( }, }, }; - const { body: response } = await client.search(params); + const response = await client.search(params); return get(response, 'hits.hits[0]._source.license.type', null); } diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.test.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.test.ts index 4239617a39b11..bebcdcb80bd34 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.test.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.test.ts @@ -18,22 +18,20 @@ describe('fetchStackProductUsage', () => { it('should use appropiate query parameters', async () => { const searchMock = jest.fn().mockImplementation(() => ({ - body: { - aggregations: { - uuids: { - buckets: [ - { - key: 'sadfsdf', - indices: { - buckets: [ - { - key: '.monitoring-kibana-8', - }, - ], - }, + aggregations: { + uuids: { + buckets: [ + { + key: 'sadfsdf', + indices: { + buckets: [ + { + key: '.monitoring-kibana-8', + }, + ], }, - ], - }, + }, + ], }, }, })); @@ -65,22 +63,20 @@ describe('fetchStackProductUsage', () => { it('should get the usage data', async () => { const callCluster = { search: jest.fn().mockImplementation(() => ({ - body: { - aggregations: { - uuids: { - buckets: [ - { - key: 'sadfsdf', - indices: { - buckets: [ - { - key: '.monitoring-kibana-8', - }, - ], - }, + aggregations: { + uuids: { + buckets: [ + { + key: 'sadfsdf', + indices: { + buckets: [ + { + key: '.monitoring-kibana-8', + }, + ], }, - ], - }, + }, + ], }, }, })), @@ -105,25 +101,23 @@ describe('fetchStackProductUsage', () => { it('should handle both collection types', async () => { const callCluster = { search: jest.fn().mockImplementation(() => ({ - body: { - aggregations: { - uuids: { - buckets: [ - { - key: 'sadfsdf', - indices: { - buckets: [ - { - key: '.monitoring-kibana-8', - }, - { - key: '.monitoring-kibana-mb-8', - }, - ], - }, + aggregations: { + uuids: { + buckets: [ + { + key: 'sadfsdf', + indices: { + buckets: [ + { + key: '.monitoring-kibana-8', + }, + { + key: '.monitoring-kibana-mb-8', + }, + ], }, - ], - }, + }, + ], }, }, })), diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.ts index bcb872912394c..2a090f2182931 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.ts @@ -95,7 +95,7 @@ export async function fetchStackProductUsage( }, }; - const { body: responseBody } = await callCluster.search(params); + const responseBody = await callCluster.search(params); const response = responseBody as estypes.SearchResponse; const uuidBuckets = get(response, 'aggregations.uuids.buckets', []) as UuidBucket[]; const count = uuidBuckets.length; diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.test.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.test.ts index a9d7fa05883c5..81a23c5af6765 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.test.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.test.ts @@ -18,10 +18,8 @@ describe('getStackProductsUsage', () => { const availableCcs = false; const callCluster = { search: jest.fn().mockImplementation(() => ({ - body: { - hits: { - hits: [], - }, + hits: { + hits: [], }, })), } as unknown as ElasticsearchClient; diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/lib/send_bulk_payload.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/lib/send_bulk_payload.ts index 175f9b69ef523..8be30a29e1f97 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/lib/send_bulk_payload.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/lib/send_bulk_payload.ts @@ -16,11 +16,10 @@ export async function sendBulkPayload( interval: number, payload: object[] ) { - const { body } = await esClient.monitoring.bulk({ + return await esClient.monitoring.bulk({ system_id: KIBANA_SYSTEM_ID, system_api_version: MONITORING_SYSTEM_API_VERSION, interval: interval + 'ms', body: payload, }); - return body; } diff --git a/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts b/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts index e1dfb89386989..cffc5ffbbfda3 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/disable_watcher_cluster_alerts.ts @@ -24,7 +24,7 @@ interface DisableWatchesResponse { async function callMigrationApi(callCluster: ElasticsearchClient, logger: Logger) { try { - const { body: response } = await callCluster.transport.request({ + const response = await callCluster.transport.request({ method: 'post', path: '/monitoring.disableWatches', }); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_available_ccs.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_available_ccs.test.ts index 19d6168dbb5d0..1c128fb61b760 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_available_ccs.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_available_ccs.test.ts @@ -6,8 +6,6 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { fetchAvailableCcs } from './fetch_available_ccs'; @@ -23,7 +21,7 @@ describe('fetchAvailableCcs', () => { const connectedRemote = 'myRemote'; const esClient = elasticsearchServiceMock.createScopedClusterClient().asCurrentUser; esClient.cluster.remoteInfo.mockImplementation(() => - elasticsearchClientMock.createSuccessTransportRequestPromise({ + Promise.resolve({ [connectedRemote]: { connected: true, } as estypes.ClusterRemoteInfoClusterRemoteInfo, @@ -38,7 +36,7 @@ describe('fetchAvailableCcs', () => { const disconnectedRemote = 'myRemote'; const esClient = elasticsearchServiceMock.createScopedClusterClient().asCurrentUser; esClient.cluster.remoteInfo.mockImplementation(() => - elasticsearchClientMock.createSuccessTransportRequestPromise({ + Promise.resolve({ [disconnectedRemote]: { connected: false, } as estypes.ClusterRemoteInfoClusterRemoteInfo, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_available_ccs.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_available_ccs.ts index 0dd0def028e36..ff8db2e3a4330 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_available_ccs.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_available_ccs.ts @@ -9,7 +9,7 @@ import { ElasticsearchClient } from 'kibana/server'; export async function fetchAvailableCcs(esClient: ElasticsearchClient): Promise { const availableCcs = []; - const { body: response } = await esClient.cluster.remoteInfo(); + const response = await esClient.cluster.remoteInfo(); for (const remoteName in response) { if (!response.hasOwnProperty(remoteName)) { continue; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.test.ts index da94cc5f975d9..b399f6a876385 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.test.ts @@ -31,9 +31,9 @@ describe('fetchCCReadExceptions', () => { }, }; const esClient = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise(esRes) + esRes ); it('should call ES with correct query', async () => { await fetchCCRReadExceptions(esClient, 1643306331418, 1643309869056, 10000); @@ -104,7 +104,7 @@ describe('fetchCCReadExceptions', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise(esRes as any); + return Promise.resolve(esRes as any); }); await fetchCCRReadExceptions(esClient, 1643306331418, 1643309869056, 10000); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.ts index d9dd035b92c4d..cdc136ffd5972 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.ts @@ -108,7 +108,7 @@ export async function fetchCCRReadExceptions( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const stats: CCRReadExceptionsStats[] = []; // @ts-expect-error declare aggegations type explicitly const { buckets: remoteClusterBuckets = [] } = response.aggregations?.remote_clusters; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.test.ts index 46299ff994f6b..596d95cff93f8 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.test.ts @@ -9,6 +9,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { elasticsearchClientMock } from '../../../../../../src/core/server/elasticsearch/client/mocks'; import { fetchClusterHealth } from './fetch_cluster_health'; + jest.mock('../../static_globals', () => ({ Globals: { app: { @@ -28,23 +29,21 @@ describe('fetchClusterHealth', () => { const clusterUuid = 'sdfdsaj34434'; const clusters = [{ clusterUuid, clusterName: 'foo' }]; const status = 'green'; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _index: '.monitoring-es-7', - _source: { - cluster_state: { - status, - }, - cluster_uuid: clusterUuid, + esClient.search.mockResponse({ + hits: { + hits: [ + { + _index: '.monitoring-es-7', + _source: { + cluster_state: { + status, }, + cluster_uuid: clusterUuid, }, - ], - }, - } as estypes.SearchResponse) - ); + }, + ], + }, + } as estypes.SearchResponse); const health = await fetchClusterHealth(esClient, clusters); expect(health).toEqual([ @@ -101,7 +100,7 @@ describe('fetchClusterHealth', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); await fetchClusterHealth(esClient, [{ clusterUuid: '1', clusterName: 'foo1' }]); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.ts index 59fd379344b4c..7103014cb199e 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.ts @@ -6,7 +6,7 @@ */ import { ElasticsearchClient } from 'kibana/server'; import { AlertCluster, AlertClusterHealth } from '../../../common/types/alerts'; -import { ElasticsearchSource, ElasticsearchResponse } from '../../../common/types/es'; +import { ElasticsearchSource } from '../../../common/types/es'; import { createDatasetFilter } from './create_dataset_query_filter'; import { Globals } from '../../static_globals'; import { getConfigCcs } from '../../../common/ccs_utils'; @@ -74,8 +74,7 @@ export async function fetchClusterHealth( // meh } - const result = await esClient.search(params); - const response: ElasticsearchResponse = result.body as ElasticsearchResponse; + const response = await esClient.search(params); return (response.hits?.hits ?? []).map((hit) => { return { health: hit._source!.cluster_state?.status, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.test.ts index 5c4f44df4ac7c..1eeedf3a7a574 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.test.ts @@ -6,8 +6,6 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { fetchClusters } from './fetch_clusters'; @@ -30,20 +28,19 @@ describe('fetchClusters', () => { it('return a list of clusters', async () => { const esClient = elasticsearchServiceMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _source: { - cluster_uuid: clusterUuid, - cluster_name: clusterName, - }, + esClient.search.mockResponse({ + hits: { + hits: [ + { + _source: { + cluster_uuid: clusterUuid, + cluster_name: clusterName, }, - ], - }, - } as estypes.SearchResponse) - ); + }, + ], + }, + } as estypes.SearchResponse); + const result = await fetchClusters(esClient); expect(result).toEqual([{ clusterUuid, clusterName }]); }); @@ -51,27 +48,25 @@ describe('fetchClusters', () => { it('return the metadata name if available', async () => { const metadataName = 'custom-monitoring'; const esClient = elasticsearchServiceMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _source: { - cluster_uuid: clusterUuid, - cluster_name: clusterName, - cluster_settings: { - cluster: { - metadata: { - display_name: metadataName, - }, + esClient.search.mockResponse({ + hits: { + hits: [ + { + _source: { + cluster_uuid: clusterUuid, + cluster_name: clusterName, + cluster_settings: { + cluster: { + metadata: { + display_name: metadataName, }, }, }, }, - ], - }, - } as estypes.SearchResponse) - ); + }, + ], + }, + } as estypes.SearchResponse); const result = await fetchClusters(esClient); expect(result).toEqual([{ clusterUuid, clusterName: metadataName }]); }); @@ -123,7 +118,7 @@ describe('fetchClusters', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); await fetchClusters(esClient); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts index 159fe205df291..ac6520eb3948d 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts @@ -55,7 +55,7 @@ export async function fetchClusters( }, }; - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); return get(response, 'hits.hits', []).map((hit: any) => { const clusterName: string = get(hit, '_source.cluster_settings.cluster.metadata.display_name') || diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.test.ts index fd7b61b5f92ff..b77c2ff686ca8 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.test.ts @@ -35,9 +35,9 @@ describe('fetchCpuUsageNodeStats', () => { const size = 10; it('fetch normal stats', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { clusters: { buckets: [ @@ -71,7 +71,7 @@ describe('fetchCpuUsageNodeStats', () => { ], }, }, - }) + } ); const result = await fetchCpuUsageNodeStats(esClient, clusters, startMs, endMs, size); expect(result).toEqual([ @@ -89,9 +89,9 @@ describe('fetchCpuUsageNodeStats', () => { }); it('fetch container stats', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { clusters: { buckets: [ @@ -138,7 +138,7 @@ describe('fetchCpuUsageNodeStats', () => { ], }, }, - }) + } ); const result = await fetchCpuUsageNodeStats(esClient, clusters, startMs, endMs, size); expect(result).toEqual([ @@ -156,9 +156,9 @@ describe('fetchCpuUsageNodeStats', () => { }); it('fetch properly return ccs', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { clusters: { buckets: [ @@ -198,7 +198,7 @@ describe('fetchCpuUsageNodeStats', () => { ], }, }, - }) + } ); const result = await fetchCpuUsageNodeStats(esClient, clusters, startMs, endMs, size); expect(result[0].ccs).toBe('foo'); @@ -208,9 +208,7 @@ describe('fetchCpuUsageNodeStats', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise( - {} as estypes.SearchResponse - ); + return Promise.resolve({} as estypes.SearchResponse); }); const filterQuery = '{"bool":{"should":[{"exists":{"field":"cluster_uuid"}}],"minimum_should_match":1}}'; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts index 99fc9db7d097b..aef39d09e26b2 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts @@ -156,7 +156,7 @@ export async function fetchCpuUsageNodeStats( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const stats: AlertCpuUsageNodeStats[] = []; const clusterBuckets = get( response, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.test.ts index 5c7e57818f713..9e53c85e743fe 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.test.ts @@ -5,8 +5,6 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from '../../../../../../src/core/server/elasticsearch/client/mocks'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { fetchDiskUsageNodeStats } from './fetch_disk_usage_node_stats'; @@ -71,9 +69,9 @@ describe('fetchDiskUsageNodeStats', () => { }, }; it('fetch normal stats', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise(esRes) + esRes ); const result = await fetchDiskUsageNodeStats(esClient, clusters, duration, size); @@ -147,7 +145,7 @@ describe('fetchDiskUsageNodeStats', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise(esRes as any); + return Promise.resolve(esRes as any); }); await fetchDiskUsageNodeStats(esClient, clusters, duration, size); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts index 9116d47727854..6ea9ad5140158 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts @@ -114,7 +114,7 @@ export async function fetchDiskUsageNodeStats( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const stats: AlertDiskUsageNodeStats[] = []; // @ts-expect-error declare type for aggregations explicitly const { buckets: clusterBuckets } = response.aggregations?.clusters; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.test.ts index ca57ddd007cab..8f34136b70b68 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.test.ts @@ -5,8 +5,6 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from '../../../../../../src/core/server/elasticsearch/client/mocks'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { fetchElasticsearchVersions } from './fetch_elasticsearch_versions'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; @@ -38,25 +36,23 @@ describe('fetchElasticsearchVersions', () => { const versions = ['8.0.0', '7.2.1']; it('fetch as expected', async () => { - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _index: `Monitoring:${index}`, - _source: { - cluster_uuid: 'cluster123', - cluster_stats: { - nodes: { - versions, - }, + esClient.search.mockResponse({ + hits: { + hits: [ + { + _index: `Monitoring:${index}`, + _source: { + cluster_uuid: 'cluster123', + cluster_stats: { + nodes: { + versions, }, }, }, - ], - }, - } as estypes.SearchResponse) - ); + }, + ], + }, + } as estypes.SearchResponse); const result = await fetchElasticsearchVersions(esClient, clusters, size); expect(result).toEqual([ @@ -107,9 +103,7 @@ describe('fetchElasticsearchVersions', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise( - {} as estypes.SearchResponse - ); + return Promise.resolve({} as estypes.SearchResponse); }); await fetchElasticsearchVersions(esClient, clusters, size); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.ts index 16c7f67851f3d..fc5d0cf1cf056 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.ts @@ -6,7 +6,7 @@ */ import { ElasticsearchClient } from 'kibana/server'; import { AlertCluster, AlertVersions } from '../../../common/types/alerts'; -import { ElasticsearchSource, ElasticsearchResponse } from '../../../common/types/es'; +import { ElasticsearchSource } from '../../../common/types/es'; import { createDatasetFilter } from './create_dataset_query_filter'; import { Globals } from '../../static_globals'; import { getConfigCcs } from '../../../common/ccs_utils'; @@ -75,8 +75,7 @@ export async function fetchElasticsearchVersions( // meh } - const result = await esClient.search(params); - const response: ElasticsearchResponse = result.body as ElasticsearchResponse; + const response = await esClient.search(params); return (response.hits?.hits ?? []).map((hit) => { const versions = hit._source!.cluster_stats?.nodes?.versions ?? []; return { diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.test.ts index 65b8be811fff3..e7020360113e8 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.test.ts @@ -5,8 +5,6 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from '../../../../../../src/core/server/elasticsearch/client/mocks'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { fetchIndexShardSize } from './fetch_index_shard_size'; @@ -121,9 +119,9 @@ describe('fetchIndexShardSize', () => { }, }; it('fetch as expected', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise(esRes) + esRes ); const result = await fetchIndexShardSize( @@ -206,7 +204,7 @@ describe('fetchIndexShardSize', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise(esRes as any); + return Promise.resolve(esRes as any); }); await fetchIndexShardSize(esClient, clusters, threshold, shardIndexPatterns, size); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts index 65ed31f5db510..539b6c20c1e37 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts @@ -112,7 +112,7 @@ export async function fetchIndexShardSize( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); // @ts-expect-error declare aggegations type explicitly const { buckets: clusterBuckets } = response.aggregations?.clusters; const stats: IndexShardSizeStats[] = []; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.test.ts index 2e12f0741715b..54a7f308fea67 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.test.ts @@ -6,8 +6,6 @@ */ import { fetchKibanaVersions } from './fetch_kibana_versions'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from '../../../../../../src/core/server/elasticsearch/client/mocks'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; jest.mock('../../static_globals', () => ({ @@ -35,9 +33,9 @@ describe('fetchKibanaVersions', () => { const size = 10; it('fetch as expected', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { index: { buckets: [ @@ -76,7 +74,7 @@ describe('fetchKibanaVersions', () => { ], }, }, - }) + } ); const result = await fetchKibanaVersions(esClient, clusters, size); @@ -143,7 +141,7 @@ describe('fetchKibanaVersions', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); await fetchKibanaVersions(esClient, clusters, size); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.ts index 48465954e8afb..886e96ae3331d 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.ts @@ -104,7 +104,7 @@ export async function fetchKibanaVersions( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const indexName = get(response, 'aggregations.index.buckets[0].key', ''); const clusterList = get(response, 'aggregations.cluster.buckets', []) as ESAggResponse[]; return clusterList.map((cluster) => { diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.test.ts index 190b5956925b1..98f52188f0fb6 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.test.ts @@ -5,8 +5,6 @@ * 2.0. */ import { fetchLicenses } from './fetch_licenses'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from '../../../../../../src/core/server/elasticsearch/client/mocks'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; jest.mock('../../static_globals', () => ({ @@ -33,20 +31,18 @@ describe('fetchLicenses', () => { it('return a list of licenses', async () => { const esClient = elasticsearchServiceMock.createScopedClusterClient().asCurrentUser; - esClient.search.mockReturnValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - hits: [ - { - _source: { - license, - cluster_uuid: clusterUuid, - }, + esClient.search.mockResponse({ + hits: { + hits: [ + { + _source: { + license, + cluster_uuid: clusterUuid, }, - ], - }, - } as any) - ); + }, + ], + }, + } as any); const clusters = [{ clusterUuid, clusterName }]; const result = await fetchLicenses(esClient, clusters); expect(result).toEqual([ @@ -79,7 +75,7 @@ describe('fetchLicenses', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); const clusters = [{ clusterUuid, clusterName }]; await fetchLicenses(esClient, clusters); @@ -122,7 +118,7 @@ describe('fetchLicenses', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); const clusters = [{ clusterUuid, clusterName }]; await fetchLicenses(esClient, clusters); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts index 0d21227112ecf..10537fdbaacee 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts @@ -74,7 +74,7 @@ export async function fetchLicenses( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); return ( response?.hits?.hits.map((hit) => { const rawLicense = hit._source!.license ?? {}; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.test.ts index 754c5d3500dc1..00f48f1ac27c7 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.test.ts @@ -6,8 +6,6 @@ */ import { fetchLogstashVersions } from './fetch_logstash_versions'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from '../../../../../../src/core/server/elasticsearch/client/mocks'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; jest.mock('../../static_globals', () => ({ @@ -35,9 +33,9 @@ describe('fetchLogstashVersions', () => { const size = 10; it('fetch as expected', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { index: { buckets: [ @@ -76,7 +74,7 @@ describe('fetchLogstashVersions', () => { ], }, }, - }) + } ); const result = await fetchLogstashVersions(esClient, clusters, size); @@ -92,7 +90,7 @@ describe('fetchLogstashVersions', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); await fetchLogstashVersions(esClient, clusters, size); expect(params).toStrictEqual({ @@ -148,7 +146,7 @@ describe('fetchLogstashVersions', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); await fetchLogstashVersions(esClient, clusters, size); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.ts index 3527223c3b07a..7f36572326742 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.ts @@ -104,7 +104,7 @@ export async function fetchLogstashVersions( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const indexName = get(response, 'aggregations.index.buckets[0].key', ''); const clusterList = get(response, 'aggregations.cluster.buckets', []) as ESAggResponse[]; return clusterList.map((cluster) => { diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.test.ts index c2cecd4f21fa5..488818b3167e4 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.test.ts @@ -93,9 +93,9 @@ describe('fetchMemoryUsageNodeStats', () => { }; it('fetch stats', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise(esRes) + esRes ); const result = await fetchMemoryUsageNodeStats(esClient, clusters, startMs, endMs, size); expect(result).toEqual([ @@ -113,7 +113,7 @@ describe('fetchMemoryUsageNodeStats', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise(esRes as any); + return Promise.resolve(esRes as any); }); await fetchMemoryUsageNodeStats(esClient, clusters, startMs, endMs, size); expect(params).toStrictEqual({ @@ -164,7 +164,7 @@ describe('fetchMemoryUsageNodeStats', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise(esRes as any); + return Promise.resolve(esRes as any); }); await fetchMemoryUsageNodeStats(esClient, clusters, startMs, endMs, size); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts index 96462462ada6b..01d2b97ebac75 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts @@ -107,7 +107,7 @@ export async function fetchMemoryUsageNodeStats( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const stats: AlertMemoryUsageNodeStats[] = []; // @ts-expect-error declare type for aggregations explicitly const { buckets: clusterBuckets } = response.aggregations?.clusters; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.test.ts index e47c48d28d19d..1d4f00e828c67 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.test.ts @@ -67,9 +67,9 @@ describe('fetchMissingMonitoringData', () => { }, ]; - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { clusters: { buckets: clusters.map((cluster) => ({ @@ -97,7 +97,7 @@ describe('fetchMissingMonitoringData', () => { })), }, }, - }) + } ); const result = await fetchMissingMonitoringData(esClient, clusters, size, now, startMs); expect(result).toEqual([ @@ -126,9 +126,9 @@ describe('fetchMissingMonitoringData', () => { clusterName: 'clusterName1', }, ]; - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ + { aggregations: { clusters: { buckets: clusters.map((cluster) => ({ @@ -147,7 +147,7 @@ describe('fetchMissingMonitoringData', () => { })), }, }, - }) + } ); const result = await fetchMissingMonitoringData(esClient, clusters, size, now, startMs); expect(result).toEqual([ @@ -172,7 +172,7 @@ describe('fetchMissingMonitoringData', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); await fetchMissingMonitoringData(esClient, clusters, size, now, startMs); expect(params).toStrictEqual({ @@ -234,7 +234,7 @@ describe('fetchMissingMonitoringData', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise({} as any); + return Promise.resolve({} as any); }); await fetchMissingMonitoringData(esClient, clusters, size, now, startMs); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts index 9119792dbd988..f97f0e749f420 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts @@ -138,7 +138,7 @@ export async function fetchMissingMonitoringData( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const clusterBuckets = get( response, 'aggregations.clusters.buckets', diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.test.ts index 285baa75375ec..82b0c9910976f 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.test.ts @@ -125,9 +125,9 @@ describe('fetchNodesFromClusterStats', () => { }; it('fetch stats', async () => { - esClient.search.mockReturnValue( + esClient.search.mockResponse( // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise(esRes) + esRes ); const result = await fetchNodesFromClusterStats(esClient, clusters); expect(result).toEqual([ @@ -155,7 +155,7 @@ describe('fetchNodesFromClusterStats', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise(esRes as any); + return Promise.resolve(esRes as any); }); await fetchNodesFromClusterStats(esClient, clusters); expect(params).toStrictEqual({ @@ -204,7 +204,7 @@ describe('fetchNodesFromClusterStats', () => { let params = null; esClient.search.mockImplementation((...args) => { params = args[0]; - return elasticsearchClientMock.createSuccessTransportRequestPromise(esRes as any); + return Promise.resolve(esRes as any); }); await fetchNodesFromClusterStats(esClient, clusters); // @ts-ignore diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.ts index b67d071afcc0d..40de85226e1f9 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.ts @@ -103,7 +103,7 @@ export async function fetchNodesFromClusterStats( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const nodes: AlertClusterStatsNodes[] = []; // @ts-expect-error declare type for aggregations explicitly const clusterBuckets = response.aggregations?.clusters?.buckets; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts index 472bf0e955a2d..8c3ec15e15407 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts @@ -109,7 +109,7 @@ export async function fetchThreadPoolRejectionStats( // meh } - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); const stats: AlertThreadPoolRejectionsStats[] = []; // @ts-expect-error declare type for aggregations explicitly const { buckets: clusterBuckets } = response.aggregations?.clusters; 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 46626066005ad..a99729407931d 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 @@ -46,7 +46,7 @@ const queryBody = { const checkLatestMonitoringIsLegacy = async (context: RequestHandlerContext, index: string) => { const client = context.core.elasticsearch.client.asCurrentUser; - const { body: result } = await client.search>({ + const result = await client.search>({ index, body: queryBody, } as estypes.SearchRequest); diff --git a/x-pack/plugins/monitoring/server/static_globals.ts b/x-pack/plugins/monitoring/server/static_globals.ts index ac0cab7a68388..c93d1a6359763 100644 --- a/x-pack/plugins/monitoring/server/static_globals.ts +++ b/x-pack/plugins/monitoring/server/static_globals.ts @@ -82,7 +82,7 @@ export class Globals { 'cluster.getSettings': (p) => client.cluster.getSettings(p), 'cluster.putSettings': (p) => client.cluster.putSettings(p), }; - const { body } = await endpointMap[endpoint](params); + const body = await endpointMap[endpoint](params); return body; }); diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts index b2841213a12d3..81bee3ab09197 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts @@ -164,18 +164,18 @@ describe('get_all_stats', () => { searchMock .onCall(0) - .returns(Promise.resolve({ body: esStatsResponse })) + .returns(Promise.resolve(esStatsResponse)) .onCall(1) - .returns(Promise.resolve({ body: kibanaStatsResponse })) + .returns(Promise.resolve(kibanaStatsResponse)) .onCall(2) - .returns(Promise.resolve({ body: logstashStatsResponse })) - .returns(Promise.resolve({ body: logstashStatsResponse })) + .returns(Promise.resolve(logstashStatsResponse)) + .returns(Promise.resolve(logstashStatsResponse)) .onCall(3) - .returns(Promise.resolve({ body: {} })) // Beats stats + .returns(Promise.resolve({})) // Beats stats .onCall(4) - .returns(Promise.resolve({ body: {} })) // Beats state + .returns(Promise.resolve({})) // Beats state .onCall(5) - .returns(Promise.resolve({ body: {} })); // Logstash state + .returns(Promise.resolve({})); // Logstash state expect(await getAllStats(['a'], callCluster, timestamp, 1)).toStrictEqual(allClusters); }); @@ -185,7 +185,7 @@ describe('get_all_stats', () => { aggregations: { cluster_uuids: { buckets: [] } }, }; - searchMock.returns(Promise.resolve({ body: clusterUuidsResponse })); + searchMock.returns(Promise.resolve(clusterUuidsResponse)); expect(await getAllStats([], callCluster, timestamp, 1)).toStrictEqual([]); }); diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_beats_stats.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_beats_stats.test.ts index fd3b4b0446f81..9621df5ca04cd 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_beats_stats.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_beats_stats.test.ts @@ -34,7 +34,7 @@ describe('Get Beats Stats', () => { }); it('should set `from: 0, to: 10000` in the query', async () => { - searchMock.returns(Promise.resolve({ body: {} })); + searchMock.returns(Promise.resolve({})); await fetchBeatsStats(callCluster, clusterUuids, start, end, {} as any); const { args } = searchMock.firstCall; const [{ body }] = args; @@ -44,7 +44,7 @@ describe('Get Beats Stats', () => { }); it('should set `from: 10000, from: 10000` in the query', async () => { - searchMock.returns(Promise.resolve({ body: {} })); + searchMock.returns(Promise.resolve({})); await fetchBeatsStats(callCluster, clusterUuids, start, end, { page: 1 } as any); const { args } = searchMock.firstCall; const [{ body }] = args; @@ -54,7 +54,7 @@ describe('Get Beats Stats', () => { }); it('should set `from: 20000, from: 10000` in the query', async () => { - searchMock.returns(Promise.resolve({ body: {} })); + searchMock.returns(Promise.resolve({})); await fetchBeatsStats(callCluster, clusterUuids, start, end, { page: 2 } as any); const { args } = searchMock.firstCall; const [{ body }] = args; diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_beats_stats.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_beats_stats.ts index 8da551a923f04..b98daa9dc304c 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_beats_stats.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_beats_stats.ts @@ -361,7 +361,7 @@ async function fetchBeatsByType( }, }; - const { body: results } = await callCluster.search(params); + const results = await callCluster.search(params); const hitsLength = results?.hits?.hits.length || 0; if (hitsLength > 0) { // further augment the clusters object with more stats diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.test.ts index 4b6c578c8b7e1..b6c9dcd51aa81 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.test.ts @@ -22,18 +22,14 @@ describe('get_cluster_uuids', () => { }); const response = { - body: { - aggregations: { - cluster_uuids: { - buckets: [{ key: 'abc' }, { key: 'xyz' }, { key: '123' }], - }, + aggregations: { + cluster_uuids: { + buckets: [{ key: 'abc' }, { key: 'xyz' }, { key: '123' }], }, }, }; - const expectedUuids = response.body.aggregations.cluster_uuids.buckets.map( - (bucket) => bucket.key - ); + const expectedUuids = response.aggregations.cluster_uuids.buckets.map((bucket) => bucket.key); const timestamp = Date.now(); @@ -47,7 +43,7 @@ describe('get_cluster_uuids', () => { describe('fetchClusterUuids', () => { it('searches for clusters', async () => { searchMock.returns(Promise.resolve(response)); - expect(await fetchClusterUuids(callCluster, timestamp, 1)).toStrictEqual(response.body); + expect(await fetchClusterUuids(callCluster, timestamp, 1)).toStrictEqual(response); }); }); @@ -59,7 +55,7 @@ describe('get_cluster_uuids', () => { }); it('handles valid response', () => { - const clusterUuids = handleClusterUuidsResponse(response.body); + const clusterUuids = handleClusterUuidsResponse(response); expect(clusterUuids).toStrictEqual(expectedUuids); }); diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.ts index eda038ac19395..4fe0cdd37c341 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.ts @@ -57,8 +57,7 @@ export async function fetchClusterUuids( }, }; - const { body: response } = await callCluster.search(params); - return response; + return await callCluster.search(params); } /** diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_es_stats.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_es_stats.test.ts index f2d9f343bf1f0..57034716cc00c 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_es_stats.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_es_stats.test.ts @@ -31,7 +31,7 @@ describe('get_es_stats', () => { describe('getElasticsearchStats', () => { it('returns clusters', async () => { - searchMock.returns(Promise.resolve({ body })); + searchMock.returns(Promise.resolve(body)); expect(await getElasticsearchStats(client, clusterUuids, maxBucketSize)).toStrictEqual( expectedClusters @@ -41,7 +41,7 @@ describe('get_es_stats', () => { describe('fetchElasticsearchStats', () => { it('searches for clusters', async () => { - searchMock.returns({ body }); + searchMock.returns(body); expect(await fetchElasticsearchStats(client, clusterUuids, maxBucketSize)).toStrictEqual( body diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_es_stats.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_es_stats.ts index 8155c0080e44e..d6261c373bdc7 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_es_stats.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_es_stats.ts @@ -69,8 +69,7 @@ export async function fetchElasticsearchStats( }, }; - const { body: response } = await callCluster.search(params); - return response; + return await callCluster.search(params); } export interface ESClusterStats { diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_high_level_stats.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_high_level_stats.test.ts index edaf73e43b73b..ab394f9ebb058 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_high_level_stats.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_high_level_stats.test.ts @@ -234,7 +234,7 @@ describe('get_high_level_stats', () => { describe('getHighLevelStats', () => { it('returns clusters', async () => { - searchMock.returns(Promise.resolve({ body })); + searchMock.returns(Promise.resolve(body)); expect( await getHighLevelStats(callCluster, clusterUuids, start, end, product, maxBucketSize) @@ -244,7 +244,7 @@ describe('get_high_level_stats', () => { describe('fetchHighLevelStats', () => { it('searches for clusters', async () => { - searchMock.returns(Promise.resolve({ body })); + searchMock.returns(Promise.resolve(body)); expect( await fetchHighLevelStats(callCluster, clusterUuids, start, end, product, maxBucketSize) diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_high_level_stats.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_high_level_stats.ts index 79c38c4d15a87..3991df4b83347 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_high_level_stats.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_high_level_stats.ts @@ -331,7 +331,7 @@ export async function fetchHighLevelStats< }, }; - const { body: response } = await callCluster.search(params, { + const response = await callCluster.search(params, { headers: { 'X-QUERY-SOURCE': TELEMETRY_QUERY_SOURCE, }, diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_licenses.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_licenses.test.ts index 90d5d0e5a7fe2..6ebb23188e2a6 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_licenses.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_licenses.test.ts @@ -31,7 +31,7 @@ describe('get_licenses', () => { describe('getLicenses', () => { it('returns clusters', async () => { - searchMock.returns(Promise.resolve({ body })); + searchMock.returns(Promise.resolve(body)); expect(await getLicenses(clusterUuids, client, 1)).toStrictEqual(expectedLicenses); }); @@ -39,7 +39,7 @@ describe('get_licenses', () => { describe('fetchLicenses', () => { it('searches for clusters', async () => { - searchMock.returns({ body }); + searchMock.returns(body); expect(await fetchLicenses(client, clusterUuids, 1)).toStrictEqual(body); }); diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_licenses.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_licenses.ts index d70bfdfd70ad6..b5e653e0b2aaf 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_licenses.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_licenses.ts @@ -59,8 +59,7 @@ export async function fetchLicenses( }, }; - const { body: response } = await callCluster.search(params); - return response; + return await callCluster.search(params); } export interface ESClusterStatsWithLicense { diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_logstash_stats.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_logstash_stats.test.ts index d093cfbf3a7fb..df5ec54433168 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_logstash_stats.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_logstash_stats.test.ts @@ -38,7 +38,7 @@ describe('Get Logstash Stats', () => { const callCluster = { search: searchMock } as unknown as ElasticsearchClient; beforeEach(() => { - searchMock.returns(Promise.resolve({ body: {} })); + searchMock.returns(Promise.resolve({})); }); afterEach(() => { diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_logstash_stats.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_logstash_stats.ts index 736c61130bc67..83e318c8fbada 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_logstash_stats.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_logstash_stats.ts @@ -300,7 +300,7 @@ export async function fetchLogstashStats( }, }; - const { body: results } = await callCluster.search(params, { + const results = await callCluster.search(params, { headers: { 'X-QUERY-SOURCE': TELEMETRY_QUERY_SOURCE, }, @@ -361,7 +361,7 @@ export async function fetchLogstashState( }, }; - const { body: results } = await callCluster.search(params, { + const results = await callCluster.search(params, { headers: { 'X-QUERY-SOURCE': TELEMETRY_QUERY_SOURCE, }, diff --git a/x-pack/plugins/observability/server/lib/annotations/create_annotations_client.ts b/x-pack/plugins/observability/server/lib/annotations/create_annotations_client.ts index 98e8908cd60a5..3fa81e77165d4 100644 --- a/x-pack/plugins/observability/server/lib/annotations/create_annotations_client.ts +++ b/x-pack/plugins/observability/server/lib/annotations/create_annotations_client.ts @@ -57,9 +57,12 @@ export function createAnnotationsClient(params: { createParams: CreateParams ): Promise<{ _id: string; _index: string; _source: Annotation }> => { const indexExists = await unwrapEsResponse( - esClient.indices.exists({ - index, - }) + esClient.indices.exists( + { + index, + }, + { meta: true } + ) ); if (!indexExists) { @@ -74,18 +77,24 @@ export function createAnnotationsClient(params: { }; const body = await unwrapEsResponse( - esClient.index({ - index, - body: annotation, - refresh: 'wait_for', - }) + esClient.index( + { + index, + body: annotation, + refresh: 'wait_for', + }, + { meta: true } + ) ); return ( - await esClient.get({ - index, - id: body._id, - }) + await esClient.get( + { + index, + id: body._id, + }, + { meta: true } + ) ).body as { _id: string; _index: string; _source: Annotation }; } ), @@ -93,21 +102,27 @@ export function createAnnotationsClient(params: { const { id } = getByIdParams; return unwrapEsResponse( - esClient.get({ - id, - index, - }) + esClient.get( + { + id, + index, + }, + { meta: true } + ) ); }), delete: ensureGoldLicense(async (deleteParams: DeleteParams) => { const { id } = deleteParams; return unwrapEsResponse( - esClient.delete({ - index, - id, - refresh: 'wait_for', - }) + esClient.delete( + { + index, + id, + refresh: 'wait_for', + }, + { meta: true } + ) ); }), }; diff --git a/x-pack/plugins/observability/server/utils/create_or_update_index.ts b/x-pack/plugins/observability/server/utils/create_or_update_index.ts index 9cd4cf9c9334f..a9d583bbf86af 100644 --- a/x-pack/plugins/observability/server/utils/create_or_update_index.ts +++ b/x-pack/plugins/observability/server/utils/create_or_update_index.ts @@ -33,7 +33,7 @@ export async function createOrUpdateIndex({ */ await pRetry( async () => { - const indexExists = (await client.indices.exists({ index })).body; + const indexExists = await client.indices.exists({ index }); const result = indexExists ? await updateExistingIndex({ index, @@ -46,7 +46,7 @@ export async function createOrUpdateIndex({ mappings, }); - if (!result.body.acknowledged) { + if (!result.acknowledged) { const bodyWithError: { body?: { error: any } } = result as any; const resultError = JSON.stringify(bodyWithError?.body?.error); throw new Error(resultError); 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 1135e948f42f2..a4672e46dcce1 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 @@ -74,7 +74,7 @@ export const createActionRoute = (router: IRouter, osqueryContext: OsqueryAppCon (value) => !isEmpty(value) ), }; - const actionResponse = await esClient.index<{}, {}>({ + const actionResponse = await esClient.index({ index: '.fleet-actions', body: action, }); diff --git a/x-pack/plugins/osquery/server/usage/fetchers.ts b/x-pack/plugins/osquery/server/usage/fetchers.ts index 00af0d05fbf60..8565d6ccf4289 100644 --- a/x-pack/plugins/osquery/server/usage/fetchers.ts +++ b/x-pack/plugins/osquery/server/usage/fetchers.ts @@ -68,7 +68,7 @@ export async function getPolicyLevelUsage( index: '.fleet-agents', ignore_unavailable: true, }); - const policied = agentResponse.body.aggregations?.policied; + const policied = agentResponse.aggregations?.policied; if (policied && typeof policied.doc_count === 'number') { result.agent_info = { enrolled: policied.doc_count, @@ -116,7 +116,7 @@ export async function getLiveQueryUsage( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient ) { - const { body: metricResponse } = await esClient.search< + const metricResponse = await esClient.search< unknown, { queries: AggregationsSingleBucketAggregateBase; @@ -206,7 +206,7 @@ export function extractBeatUsageMetrics( } export async function getBeatUsage(esClient: ElasticsearchClient) { - const { body: metricResponse } = await esClient.search({ + const metricResponse = await esClient.search({ body: { size: 0, aggs: { 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 0316809805200..bc850f9e8043d 100644 --- a/x-pack/plugins/painless_lab/server/routes/api/execute.ts +++ b/x-pack/plugins/painless_lab/server/routes/api/execute.ts @@ -32,7 +32,7 @@ export function registerExecuteRoute({ router, license }: RouteDependencies) { }); return res.ok({ - body: response.body, + body: response, }); } catch (error) { // Assume invalid painless script was submitted diff --git a/x-pack/plugins/remote_clusters/server/lib/does_cluster_exist.ts b/x-pack/plugins/remote_clusters/server/lib/does_cluster_exist.ts index f76854bead41d..2723d3bf6badd 100644 --- a/x-pack/plugins/remote_clusters/server/lib/does_cluster_exist.ts +++ b/x-pack/plugins/remote_clusters/server/lib/does_cluster_exist.ts @@ -12,7 +12,7 @@ export async function doesClusterExist( clusterName: string ): Promise { try { - const { body: clusterInfoByName } = await clusterClient.asCurrentUser.cluster.remoteInfo(); + const clusterInfoByName = await clusterClient.asCurrentUser.cluster.remoteInfo(); return Boolean(clusterInfoByName && clusterInfoByName[clusterName]); } catch (err) { throw new Error('Unable to check if cluster already exists.'); 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 b648554842a5c..fffddbd8e56c1 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 @@ -11,12 +11,7 @@ import { kibanaResponseFactory } from '../../../../../../src/core/server'; import { licensingMock } from '../../../../../plugins/licensing/server/mocks'; -import { - elasticsearchServiceMock, - httpServerMock, - httpServiceMock, - coreMock, -} from '../../../../../../src/core/server/mocks'; +import { httpServerMock, httpServiceMock, coreMock } from '../../../../../../src/core/server/mocks'; import { API_BASE_PATH } from '../../../common/constants'; @@ -26,8 +21,6 @@ import { register } from './add_route'; import { ScopedClusterClientMock } from './types'; -const { createApiResponse } = elasticsearchServiceMock; - // Re-implement the mock that was imported directly from `x-pack/mocks` function createCoreRequestHandlerContextMock() { return { @@ -88,30 +81,26 @@ describe('ADD remote clusters', () => { describe('success', () => { test(`adds remote cluster with "sniff" mode`, async () => { - remoteInfoMockFn.mockResolvedValueOnce(createApiResponse({ body: {} })); - putSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - acknowledged: true, - persistent: { - cluster: { - remote: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }, - }, + remoteInfoMockFn.mockResponseOnce({}); + putSettingsMockFn.mockResponseOnce({ + acknowledged: true, + persistent: { + cluster: { + remote: { + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: false, }, }, - transient: {}, }, - }) - ); + }, + transient: {}, + }); const mockRequest = createMockRequest(); @@ -143,30 +132,26 @@ describe('ADD remote clusters', () => { }); test(`adds remote cluster with "proxy" mode`, async () => { - remoteInfoMockFn.mockResolvedValueOnce(createApiResponse({ body: {} })); - putSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - acknowledged: true, - persistent: { - cluster: { - remote: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }, - }, + remoteInfoMockFn.mockResponseOnce({}); + putSettingsMockFn.mockResponseOnce({ + acknowledged: true, + persistent: { + cluster: { + remote: { + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: false, }, }, - transient: {}, }, - }) - ); + }, + transient: {}, + }); const mockRequest = createMockRequest({ name: 'test', @@ -206,21 +191,17 @@ describe('ADD remote clusters', () => { describe('failure', () => { test('returns 409 if remote cluster already exists', async () => { - remoteInfoMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }, - }, - }) - ); + remoteInfoMockFn.mockResponseOnce({ + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: false, + }, + }); const mockRequest = createMockRequest(); @@ -236,8 +217,8 @@ describe('ADD remote clusters', () => { }); test('returns 400 ES did not acknowledge remote cluster', async () => { - remoteInfoMockFn.mockResolvedValueOnce(createApiResponse({ body: {} })); - putSettingsMockFn.mockResolvedValueOnce(createApiResponse({ body: {} as any })); + remoteInfoMockFn.mockResponseOnce({}); + putSettingsMockFn.mockResponseOnce({} as any); const mockRequest = createMockRequest(); 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 3b6ba618c8975..915af70f7ffd5 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 @@ -61,11 +61,9 @@ export const register = (deps: RouteDependencies): void => { } const addClusterPayload = serializeCluster(request.body as Cluster); - const { body: updateClusterResponse } = await clusterClient.asCurrentUser.cluster.putSettings( - { - body: addClusterPayload, - } - ); + const updateClusterResponse = await clusterClient.asCurrentUser.cluster.putSettings({ + body: addClusterPayload, + }); const acknowledged = get(updateClusterResponse, 'acknowledged'); const cluster = get(updateClusterResponse, `persistent.cluster.remote.${name}`); 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 d83472fc564b0..7b9b6fae0f66e 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 @@ -11,19 +11,12 @@ import { API_BASE_PATH } from '../../../common/constants'; import { licensingMock } from '../../../../../plugins/licensing/server/mocks'; -import { - elasticsearchServiceMock, - httpServerMock, - httpServiceMock, - coreMock, -} from '../../../../../../src/core/server/mocks'; +import { httpServerMock, httpServiceMock, coreMock } from '../../../../../../src/core/server/mocks'; import { handleEsError } from '../../shared_imports'; import { ScopedClusterClientMock } from './types'; -const { createApiResponse } = elasticsearchServiceMock; - // Re-implement the mock that was imported directly from `x-pack/mocks` function createCoreRequestHandlerContextMock() { return { @@ -91,48 +84,36 @@ describe('DELETE remote clusters', () => { describe('success', () => { test('deletes remote cluster', async () => { - getSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - persistent: { - cluster: { - remote: { - test: { - seeds: ['127.0.0.1:9300'], - skip_unavailable: false, - mode: 'sniff', - }, - }, + getSettingsMockFn.mockResponseOnce({ + persistent: { + cluster: { + remote: { + test: { + seeds: ['127.0.0.1:9300'], + skip_unavailable: false, + mode: 'sniff', }, }, - transient: {}, - }, - }) - ); - remoteInfoMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }, - }, - }) - ); - putSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - acknowledged: true, - persistent: {}, - transient: {}, }, - }) - ); + }, + transient: {}, + }); + remoteInfoMockFn.mockResponseOnce({ + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: false, + }, + }); + putSettingsMockFn.mockResponseOnce({ + acknowledged: true, + persistent: {}, + transient: {}, + }); const mockRequest = createMockRequest(); @@ -170,23 +151,15 @@ describe('DELETE remote clusters', () => { describe('failure', () => { test('returns errors array with 404 error if remote cluster does not exist', async () => { - getSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - persistent: { - cluster: { - remote: {}, - }, - }, - transient: {}, + getSettingsMockFn.mockResponseOnce({ + persistent: { + cluster: { + remote: {}, }, - }) - ); - remoteInfoMockFn.mockResolvedValueOnce( - createApiResponse({ - body: {}, - }) - ); + }, + transient: {}, + }); + remoteInfoMockFn.mockResponseOnce({}); const mockRequest = createMockRequest(); @@ -219,63 +192,51 @@ describe('DELETE remote clusters', () => { }); test('returns errors array with 400 error if ES still returns cluster information', async () => { - getSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - persistent: { - cluster: { - remote: { - test: { - seeds: ['127.0.0.1:9300'], - skip_unavailable: false, - mode: 'sniff', - }, - }, + getSettingsMockFn.mockResponseOnce({ + persistent: { + cluster: { + remote: { + test: { + seeds: ['127.0.0.1:9300'], + skip_unavailable: false, + mode: 'sniff', }, }, - transient: {}, }, - }) - ); - remoteInfoMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }, - }, - }) - ); + }, + transient: {}, + }); + remoteInfoMockFn.mockResponseOnce({ + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: false, + }, + }); - putSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - acknowledged: true, - persistent: { - cluster: { - remote: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: true, - }, - }, + putSettingsMockFn.mockResponseOnce({ + acknowledged: true, + persistent: { + cluster: { + remote: { + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: true, }, }, - transient: {}, }, - }) - ); + }, + transient: {}, + }); const mockRequest = createMockRequest(); 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 ac5a89139d52a..bb2bd4a073245 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 @@ -42,7 +42,7 @@ export const register = (deps: RouteDependencies): void => { const itemsDeleted: any[] = []; const errors: any[] = []; - const { body: clusterSettings } = await clusterClient.asCurrentUser.cluster.getSettings(); + const clusterSettings = await clusterClient.asCurrentUser.cluster.getSettings(); // Validator that returns an error if the remote cluster does not exist. const validateClusterDoesExist = async (name: string) => { @@ -74,10 +74,9 @@ export const register = (deps: RouteDependencies): void => { try { const body = serializeCluster({ name, hasDeprecatedProxySetting }); - const { body: updateClusterResponse } = - await clusterClient.asCurrentUser.cluster.putSettings({ - body, - }); + const updateClusterResponse = await clusterClient.asCurrentUser.cluster.putSettings({ + body, + }); const acknowledged = get(updateClusterResponse, 'acknowledged'); const cluster = get(updateClusterResponse, `persistent.cluster.remote.${name}`); 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 e57d9528efded..8fbbb33415fda 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 @@ -9,12 +9,7 @@ import { errors } from '@elastic/elasticsearch'; import { RequestHandler } from 'src/core/server'; -import { - elasticsearchServiceMock, - httpServerMock, - httpServiceMock, - coreMock, -} from '../../../../../../src/core/server/mocks'; +import { httpServerMock, httpServiceMock, coreMock } from '../../../../../../src/core/server/mocks'; import { kibanaResponseFactory } from '../../../../../../src/core/server'; import { licensingMock } from '../../../../../plugins/licensing/server/mocks'; @@ -26,8 +21,6 @@ import { handleEsError } from '../../shared_imports'; import { register } from './get_route'; import { ScopedClusterClientMock } from './types'; -const { createApiResponse } = elasticsearchServiceMock; - // Re-implement the mock that was imported directly from `x-pack/mocks` function createCoreRequestHandlerContextMock() { return { @@ -80,39 +73,31 @@ describe('GET remote clusters', () => { describe('success', () => { test('returns remote clusters', async () => { - getSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - persistent: { - cluster: { - remote: { - test: { - seeds: ['127.0.0.1:9300'], - skip_unavailable: false, - mode: 'sniff', - }, - }, + getSettingsMockFn.mockResponseOnce({ + persistent: { + cluster: { + remote: { + test: { + seeds: ['127.0.0.1:9300'], + skip_unavailable: false, + mode: 'sniff', }, }, - transient: {}, - }, - }) - ); - remoteInfoMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }, }, - }) - ); + }, + transient: {}, + }); + remoteInfoMockFn.mockResponseOnce({ + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: false, + }, + }); const mockRequest = createMockRequest(); @@ -138,8 +123,8 @@ describe('GET remote clusters', () => { }); test('returns an empty array when ES responds with an empty object', async () => { - getSettingsMockFn.mockResolvedValueOnce(createApiResponse({ body: {} as any })); - remoteInfoMockFn.mockResolvedValueOnce(createApiResponse({ body: {} })); + getSettingsMockFn.mockResponseOnce({} as any); + remoteInfoMockFn.mockResponseOnce({} as any); const mockRequest = createMockRequest(); @@ -183,24 +168,20 @@ describe('GET remote clusters', () => { }); test('returns an error if failure to get cluster remote info', async () => { - getSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - persistent: { - cluster: { - remote: { - test: { - seeds: ['127.0.0.1:9300'], - skip_unavailable: false, - mode: 'sniff', - }, - }, + getSettingsMockFn.mockResponseOnce({ + persistent: { + cluster: { + remote: { + test: { + seeds: ['127.0.0.1:9300'], + skip_unavailable: false, + mode: 'sniff', }, }, - transient: {}, }, - }) - ); + }, + transient: {}, + }); remoteInfoMockFn.mockRejectedValueOnce(error); 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 c98f523450686..3e0d5846387b1 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 @@ -22,7 +22,7 @@ export const register = (deps: RouteDependencies): void => { const allHandler: RequestHandler = async (ctx, request, response) => { try { const { client: clusterClient } = ctx.core.elasticsearch; - const { body: clusterSettings } = await clusterClient.asCurrentUser.cluster.getSettings(); + const clusterSettings = await clusterClient.asCurrentUser.cluster.getSettings(); const transientClusterNames = Object.keys( get(clusterSettings, 'transient.cluster.remote') || {} @@ -31,7 +31,7 @@ export const register = (deps: RouteDependencies): void => { get(clusterSettings, 'persistent.cluster.remote') || {} ); - const { body: clustersByName } = await clusterClient.asCurrentUser.cluster.remoteInfo(); + const clustersByName = await clusterClient.asCurrentUser.cluster.remoteInfo(); const clusterNames = (clustersByName && Object.keys(clustersByName)) || []; const body = clusterNames.map((clusterName: string): any => { 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 856b8062e320e..89ab33da0ad94 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 @@ -7,12 +7,7 @@ import { RequestHandler } from 'src/core/server'; import { kibanaResponseFactory } from '../../../../../../src/core/server'; -import { - elasticsearchServiceMock, - httpServerMock, - httpServiceMock, - coreMock, -} from '../../../../../../src/core/server/mocks'; +import { httpServerMock, httpServiceMock, coreMock } from '../../../../../../src/core/server/mocks'; import { licensingMock } from '../../../../../plugins/licensing/server/mocks'; @@ -23,8 +18,6 @@ import { handleEsError } from '../../shared_imports'; import { register } from './update_route'; import { ScopedClusterClientMock } from './types'; -const { createApiResponse } = elasticsearchServiceMock; - // Re-implement the mock that was imported directly from `x-pack/mocks` function createCoreRequestHandlerContextMock() { return { @@ -84,44 +77,36 @@ describe('UPDATE remote clusters', () => { describe('success', () => { test('updates remote cluster', async () => { - remoteInfoMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }, - }, - }) - ); - putSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - acknowledged: true, - persistent: { - cluster: { - remote: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: true, - }, - }, + remoteInfoMockFn.mockResponseOnce({ + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: false, + }, + }); + putSettingsMockFn.mockResponseOnce({ + acknowledged: true, + persistent: { + cluster: { + remote: { + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: true, }, }, - transient: {}, }, - }) - ); + }, + transient: {}, + }); const mockRequest = createMockRequest(); @@ -163,43 +148,35 @@ describe('UPDATE remote clusters', () => { }); test('updates v1 proxy cluster', async () => { - remoteInfoMockFn.mockResolvedValueOnce( + remoteInfoMockFn.mockResponseOnce({ // @ts-expect-error not full interface - createApiResponse({ - body: { - test: { - connected: true, - initial_connect_timeout: '30s', - skip_unavailable: false, - seeds: ['127.0.0.1:9300'], - max_connections_per_cluster: 20, - num_nodes_connected: 1, - }, - }, - }) - ); - putSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - acknowledged: true, - persistent: { - cluster: { - remote: { - test: { - connected: true, - proxy_address: '127.0.0.1:9300', - initial_connect_timeout: '30s', - skip_unavailable: true, - mode: 'proxy', - proxy_socket_connections: 18, - }, - }, + test: { + connected: true, + initial_connect_timeout: '30s', + skip_unavailable: false, + seeds: ['127.0.0.1:9300'], + max_connections_per_cluster: 20, + num_nodes_connected: 1, + }, + }); + putSettingsMockFn.mockResponseOnce({ + acknowledged: true, + persistent: { + cluster: { + remote: { + test: { + connected: true, + proxy_address: '127.0.0.1:9300', + initial_connect_timeout: '30s', + skip_unavailable: true, + mode: 'proxy', + proxy_socket_connections: 18, }, }, - transient: {}, }, - }) - ); + }, + transient: {}, + }); const mockRequest = createMockRequest({ proxyAddress: '127.0.0.1:9300', @@ -249,11 +226,7 @@ describe('UPDATE remote clusters', () => { describe('failure', () => { test('returns 404 if remote cluster does not exist', async () => { - remoteInfoMockFn.mockResolvedValueOnce( - createApiResponse({ - body: {} as any, - }) - ); + remoteInfoMockFn.mockResponseOnce({} as any); const mockRequest = createMockRequest({ seeds: ['127.0.0.1:9300'], @@ -273,26 +246,18 @@ describe('UPDATE remote clusters', () => { }); test('returns 400 if ES did not acknowledge remote cluster', async () => { - remoteInfoMockFn.mockResolvedValueOnce( - createApiResponse({ - body: { - test: { - connected: true, - mode: 'sniff', - seeds: ['127.0.0.1:9300'], - num_nodes_connected: 1, - max_connections_per_cluster: 3, - initial_connect_timeout: '30s', - skip_unavailable: false, - }, - }, - }) - ); - putSettingsMockFn.mockResolvedValueOnce( - createApiResponse({ - body: {} as any, - }) - ); + remoteInfoMockFn.mockResponseOnce({ + test: { + connected: true, + mode: 'sniff', + seeds: ['127.0.0.1:9300'], + num_nodes_connected: 1, + max_connections_per_cluster: 3, + initial_connect_timeout: '30s', + skip_unavailable: false, + }, + }); + putSettingsMockFn.mockResponseOnce({} as any); const mockRequest = createMockRequest({ seeds: ['127.0.0.1:9300'], 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 efe259b40ec25..d4547b135ed1d 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 @@ -69,11 +69,9 @@ export const register = (deps: RouteDependencies): void => { // Update cluster as new settings const updateClusterPayload = serializeCluster({ ...request.body, name } as Cluster); - const { body: updateClusterResponse } = await clusterClient.asCurrentUser.cluster.putSettings( - { - body: updateClusterPayload, - } - ); + const updateClusterResponse = await clusterClient.asCurrentUser.cluster.putSettings({ + body: updateClusterPayload, + }); const acknowledged = get(updateClusterResponse, 'acknowledged'); const cluster = get( diff --git a/x-pack/plugins/reporting/server/deprecations/migrate_existing_indices_ilm_policy.test.ts b/x-pack/plugins/reporting/server/deprecations/migrate_existing_indices_ilm_policy.test.ts index 766e23a90293f..ca838c2d09914 100644 --- a/x-pack/plugins/reporting/server/deprecations/migrate_existing_indices_ilm_policy.test.ts +++ b/x-pack/plugins/reporting/server/deprecations/migrate_existing_indices_ilm_policy.test.ts @@ -17,8 +17,6 @@ type ScopedClusterClientMock = ReturnType< typeof elasticsearchServiceMock.createScopedClusterClient >; -const { createApiResponse } = elasticsearchServiceMock; - describe("Migrate existing indices' ILM policy deprecations", () => { let esClient: ScopedClusterClientMock; let deprecationsCtx: GetDeprecationsContext; @@ -43,14 +41,10 @@ describe("Migrate existing indices' ILM policy deprecations", () => { }); it('returns deprecation information when reporting indices are not using the reporting ILM policy', async () => { - esClient.asInternalUser.indices.getSettings.mockResolvedValueOnce( - createApiResponse({ - body: { - indexA: createIndexSettings('not-reporting-lifecycle'), - indexB: createIndexSettings('kibana-reporting'), - }, - }) - ); + esClient.asInternalUser.indices.getSettings.mockResponse({ + indexA: createIndexSettings('not-reporting-lifecycle'), + indexB: createIndexSettings('kibana-reporting'), + }); expect(await getDeprecationsInfo(deprecationsCtx, { reportingCore })).toMatchInlineSnapshot(` Array [ @@ -73,24 +67,16 @@ describe("Migrate existing indices' ILM policy deprecations", () => { }); it('does not return deprecations when all reporting indices are managed by the provisioned ILM policy', async () => { - esClient.asInternalUser.indices.getSettings.mockResolvedValueOnce( - createApiResponse({ - body: { - indexA: createIndexSettings('kibana-reporting'), - indexB: createIndexSettings('kibana-reporting'), - }, - }) - ); + esClient.asInternalUser.indices.getSettings.mockResponse({ + indexA: createIndexSettings('kibana-reporting'), + indexB: createIndexSettings('kibana-reporting'), + }); expect(await getDeprecationsInfo(deprecationsCtx, { reportingCore })).toMatchInlineSnapshot( `Array []` ); - esClient.asInternalUser.indices.getSettings.mockResolvedValueOnce( - createApiResponse({ - body: {}, - }) - ); + esClient.asInternalUser.indices.getSettings.mockResponse({}); expect(await getDeprecationsInfo(deprecationsCtx, { reportingCore })).toMatchInlineSnapshot( `Array []` diff --git a/x-pack/plugins/reporting/server/deprecations/reporting_role.test.ts b/x-pack/plugins/reporting/server/deprecations/reporting_role.test.ts index 2286a9767f000..03765801b2629 100644 --- a/x-pack/plugins/reporting/server/deprecations/reporting_role.test.ts +++ b/x-pack/plugins/reporting/server/deprecations/reporting_role.test.ts @@ -26,8 +26,10 @@ beforeEach(async () => { esClient = elasticsearchServiceMock.createScopedClusterClient(); esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({ - body: { xyz: { username: 'normal_user', roles: ['data_analyst'] } }, + xyz: { username: 'normal_user', roles: ['data_analyst'] }, }); + esClient.asCurrentUser.security.getRoleMapping = jest.fn().mockResolvedValue({}); + context = { esClient } as unknown as GetDeprecationsContext; }); @@ -38,7 +40,10 @@ test('logs no deprecations when setup has no issues', async () => { describe('users assigned to a deprecated role', () => { test('logs a deprecation when a user was found with a deprecated reporting_user role', async () => { esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({ - body: { reportron: { username: 'reportron', roles: ['kibana_admin', 'reporting_user'] } }, + reportron: { + username: 'reportron', + roles: ['kibana_admin', 'reporting_user'], + }, }); reportingCore = await createMockReportingCore(createMockConfigSchema()); @@ -51,9 +56,7 @@ describe('users assigned to a deprecated role', () => { createMockConfigSchema({ roles: { allow: ['my_test_reporting_user'] } }) ); esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({ - body: { - reportron: { username: 'reportron', roles: ['kibana_admin', 'my_test_reporting_user'] }, - }, + reportron: { username: 'reportron', roles: ['kibana_admin', 'my_test_reporting_user'] }, }); expect(await getDeprecationsInfo(context, { reportingCore })).toMatchSnapshot(); @@ -61,7 +64,10 @@ describe('users assigned to a deprecated role', () => { test('includes steps to remove the incompatible config, when applicable', async () => { esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({ - body: { reportron: { username: 'reportron', roles: ['kibana_admin', 'reporting_user'] } }, + reportron: { + username: 'reportron', + roles: ['kibana_admin', 'reporting_user'], + }, }); reportingCore = await createMockReportingCore( @@ -74,9 +80,9 @@ describe('users assigned to a deprecated role', () => { describe('roles mapped to a deprecated role', () => { test('logs a deprecation when a role was found that maps to the deprecated reporting_user role', async () => { - esClient.asCurrentUser.security.getRoleMapping = jest.fn().mockResolvedValue({ - body: { dungeon_master: { roles: ['reporting_user'] } }, - }); + esClient.asCurrentUser.security.getRoleMapping = jest + .fn() + .mockResolvedValue({ dungeon_master: { roles: ['reporting_user'] } }); reportingCore = await createMockReportingCore(createMockConfigSchema()); @@ -87,16 +93,19 @@ describe('roles mapped to a deprecated role', () => { reportingCore = await createMockReportingCore( createMockConfigSchema({ roles: { allow: ['my_test_reporting_user'] } }) ); - esClient.asCurrentUser.security.getRoleMapping = jest.fn().mockResolvedValue({ - body: { dungeon_master: { roles: ['my_test_reporting_user'] } }, - }); + esClient.asCurrentUser.security.getRoleMapping = jest + .fn() + .mockResolvedValue({ dungeon_master: { roles: ['my_test_reporting_user'] } }); expect(await getDeprecationsInfo(context, { reportingCore })).toMatchSnapshot(); }); test('includes steps to remove the incompatible config, when applicable', async () => { esClient.asCurrentUser.security.getUser = jest.fn().mockResolvedValue({ - body: { reportron: { username: 'reportron', roles: ['kibana_admin', 'reporting_user'] } }, + reportron: { + username: 'reportron', + roles: ['kibana_admin', 'reporting_user'], + }, }); reportingCore = await createMockReportingCore( diff --git a/x-pack/plugins/reporting/server/deprecations/reporting_role.ts b/x-pack/plugins/reporting/server/deprecations/reporting_role.ts index 6fe40ceb38815..453620bccc01d 100644 --- a/x-pack/plugins/reporting/server/deprecations/reporting_role.ts +++ b/x-pack/plugins/reporting/server/deprecations/reporting_role.ts @@ -98,7 +98,7 @@ async function getUsersDeprecations( let users: SecurityGetUserResponse; try { - users = (await client.security.getUser()).body; + users = await client.security.getUser(); } catch (err) { const { logger } = reportingCore.getPluginSetupDeps(); if (deprecations.getErrorStatusCode(err) === 403) { @@ -185,7 +185,7 @@ async function getRoleMappingsDeprecations( let roleMappings: SecurityGetRoleMappingResponse; try { - roleMappings = (await client.security.getRoleMapping()).body; + roleMappings = await client.security.getRoleMapping(); } catch (err) { const { logger } = reportingCore.getPluginSetupDeps(); if (deprecations.getErrorStatusCode(err) === 403) { diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts index 0f6652943da25..61b0a862d245b 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts @@ -298,16 +298,14 @@ it('uses the scrollId to page all the data', async () => { }) ); mockEsClient.asCurrentUser.scroll = jest.fn().mockResolvedValue({ - body: { - hits: { - hits: range(0, HITS_TOTAL / 10).map(() => ({ - fields: { - date: ['2020-12-31T00:14:28.000Z'], - ip: ['110.135.176.89'], - message: ['hit from a subsequent scroll'], - }, - })), - }, + hits: { + hits: range(0, HITS_TOTAL / 10).map(() => ({ + fields: { + date: ['2020-12-31T00:14:28.000Z'], + ip: ['110.135.176.89'], + message: ['hit from a subsequent scroll'], + }, + })), }, }); diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts index f0d7db2260f27..7b1f82f226e5e 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts @@ -86,13 +86,11 @@ export class CsvGenerator { private async scroll(scrollId: string, scrollSettings: CsvExportSettings['scroll']) { this.logger.debug(`executing scroll request`); - const results = ( - await this.clients.es.asCurrentUser.scroll({ - scroll: scrollSettings.duration, - scroll_id: scrollId, - }) - ).body; - return results; + + return await this.clients.es.asCurrentUser.scroll({ + scroll: scrollSettings.duration, + scroll_id: scrollId, + }); } /* diff --git a/x-pack/plugins/reporting/server/lib/content_stream.test.ts b/x-pack/plugins/reporting/server/lib/content_stream.test.ts index da55b4728d10e..0c45ef2d5f5ce 100644 --- a/x-pack/plugins/reporting/server/lib/content_stream.test.ts +++ b/x-pack/plugins/reporting/server/lib/content_stream.test.ts @@ -11,7 +11,7 @@ import { createMockLevelLogger } from '../test_helpers'; import { ContentStream } from './content_stream'; describe('ContentStream', () => { - let client: ReturnType['asInternalUser']; + let client: ReturnType; let logger: ReturnType; let stream: ContentStream; let base64Stream: ContentStream; @@ -33,8 +33,8 @@ describe('ContentStream', () => { index: 'somewhere', }); - client.search.mockResolvedValue( - set({}, 'body.hits.hits.0._source', { + client.search.mockResponse( + set({}, 'hits.hits.0._source', { jobtype: 'pdf', output: { content: 'some content', @@ -65,7 +65,7 @@ describe('ContentStream', () => { }); it('should be an empty stream on empty response', async () => { - client.search.mockResolvedValueOnce({ body: {} } as any); + client.search.mockResponseOnce({} as any); const onData = jest.fn(); stream.on('data', onData); @@ -84,10 +84,10 @@ describe('ContentStream', () => { }); it('should decode base64 encoded content', async () => { - client.search.mockResolvedValueOnce( + client.search.mockResponseOnce( set( {}, - 'body.hits.hits.0._source.output.content', + 'hits.hits.0._source.output.content', Buffer.from('encoded content').toString('base64') ) ); @@ -97,8 +97,8 @@ describe('ContentStream', () => { }); it('should compound content from multiple chunks', async () => { - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source', { + client.search.mockResponseOnce( + set({}, 'hits.hits.0._source', { jobtype: 'pdf', output: { content: '12', @@ -106,12 +106,8 @@ describe('ContentStream', () => { }, }) ); - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source.output.content', '34') - ); - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source.output.content', '56') - ); + client.search.mockResponseOnce(set({}, 'hits.hits.0._source.output.content', '34')); + client.search.mockResponseOnce(set({}, 'hits.hits.0._source.output.content', '56')); let data = ''; for await (const chunk of stream) { data += chunk; @@ -139,8 +135,8 @@ describe('ContentStream', () => { }); it('should stop reading on empty chunk', async () => { - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source', { + client.search.mockResponseOnce( + set({}, 'hits.hits.0._source', { jobtype: 'pdf', output: { content: '12', @@ -148,12 +144,8 @@ describe('ContentStream', () => { }, }) ); - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source.output.content', '34') - ); - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source.output.content', '') - ); + client.search.mockResponseOnce(set({}, 'hits.hits.0._source.output.content', '34')); + client.search.mockResponseOnce(set({}, 'hits.hits.0._source.output.content', '')); let data = ''; for await (const chunk of stream) { data += chunk; @@ -164,18 +156,16 @@ describe('ContentStream', () => { }); it('should read until chunks are present when there is no size', async () => { - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source', { + client.search.mockResponseOnce( + set({}, 'hits.hits.0._source', { jobtype: 'pdf', output: { content: '12', }, }) ); - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source.output.content', '34') - ); - client.search.mockResolvedValueOnce({ body: {} } as any); + client.search.mockResponseOnce(set({}, 'hits.hits.0._source.output.content', '34')); + client.search.mockResponseOnce({} as any); let data = ''; for await (const chunk of stream) { data += chunk; @@ -186,8 +176,8 @@ describe('ContentStream', () => { }); it('should decode every chunk separately', async () => { - client.search.mockResolvedValueOnce( - set({}, 'body.hits.hits.0._source', { + client.search.mockResponseOnce( + set({}, 'hits.hits.0._source', { jobtype: 'pdf', output: { content: Buffer.from('12').toString('base64'), @@ -195,19 +185,11 @@ describe('ContentStream', () => { }, }) ); - client.search.mockResolvedValueOnce( - set( - {}, - 'body.hits.hits.0._source.output.content', - Buffer.from('34').toString('base64') - ) + client.search.mockResponseOnce( + set({}, 'hits.hits.0._source.output.content', Buffer.from('34').toString('base64')) ); - client.search.mockResolvedValueOnce( - set( - {}, - 'body.hits.hits.0._source.output.content', - Buffer.from('56').toString('base64') - ) + client.search.mockResponseOnce( + set({}, 'hits.hits.0._source.output.content', Buffer.from('56').toString('base64')) ); let data = ''; for await (const chunk of base64Stream) { @@ -259,11 +241,9 @@ describe('ContentStream', () => { }); it('should update _seq_no and _primary_term from the response', async () => { - client.update.mockResolvedValueOnce({ - body: { - _primary_term: 1, - _seq_no: 10, - }, + client.update.mockResponseOnce({ + _primary_term: 1, + _seq_no: 10, } as any); stream.end('something'); @@ -300,8 +280,8 @@ describe('ContentStream', () => { }); it('should split raw data into chunks', async () => { - client.cluster.getSettings.mockResolvedValueOnce( - set({}, 'body.defaults.http.max_content_length', 1028) + client.cluster.getSettings.mockResponseOnce( + set({}, 'defaults.http.max_content_length', 1028) ); stream.end('123456'); await new Promise((resolve) => stream.once('finish', resolve)); @@ -342,8 +322,8 @@ describe('ContentStream', () => { }); it('should encode every chunk separately', async () => { - client.cluster.getSettings.mockResolvedValueOnce( - set({}, 'body.defaults.http.max_content_length', 1028) + client.cluster.getSettings.mockResponseOnce( + set({}, 'defaults.http.max_content_length', 1028) ); base64Stream.end('12345678'); await new Promise((resolve) => base64Stream.once('finish', resolve)); diff --git a/x-pack/plugins/reporting/server/lib/content_stream.ts b/x-pack/plugins/reporting/server/lib/content_stream.ts index b8ae7d0a17670..c0b2d458b4d59 100644 --- a/x-pack/plugins/reporting/server/lib/content_stream.ts +++ b/x-pack/plugins/reporting/server/lib/content_stream.ts @@ -104,7 +104,7 @@ export class ContentStream extends Duplex { } private async getMaxContentSize() { - const { body } = await this.client.cluster.getSettings({ include_defaults: true }); + const body = await this.client.cluster.getSettings({ include_defaults: true }); const { persistent, transient, defaults: defaultSettings } = body; const settings = defaults({}, persistent, transient, defaultSettings); const maxContentSize = get(settings, 'http.max_content_length', '100mb'); @@ -146,7 +146,7 @@ export class ContentStream extends Duplex { this.logger.debug(`Reading report contents.`); const response = await this.client.search({ body, index }); - const hits = response?.body.hits?.hits?.[0]; + const hits = response?.hits?.hits?.[0]; this.jobSize = hits?._source?.output?.size; @@ -172,7 +172,7 @@ export class ContentStream extends Duplex { this.logger.debug(`Reading chunk #${this.chunksRead}.`); const response = await this.client.search({ body, index }); - const hits = response?.body.hits?.hits?.[0]; + const hits = response?.hits?.hits?.[0]; return hits?._source?.output.content; } @@ -220,7 +220,7 @@ export class ContentStream extends Duplex { private async writeHead(content: string) { this.logger.debug(`Updating report contents.`); - const { body } = await this.client.update({ + const body = await this.client.update({ ...this.document, body: { doc: { diff --git a/x-pack/plugins/reporting/server/lib/deprecations/check_ilm_migration_status.ts b/x-pack/plugins/reporting/server/lib/deprecations/check_ilm_migration_status.ts index 74f0a03ef2981..a7b9ecc7dc437 100644 --- a/x-pack/plugins/reporting/server/lib/deprecations/check_ilm_migration_status.ts +++ b/x-pack/plugins/reporting/server/lib/deprecations/check_ilm_migration_status.ts @@ -22,7 +22,7 @@ export const checkIlmMigrationStatus = async ({ const store = await reportingCore.getStore(); const indexPattern = store.getReportingIndexPattern(); - const { body: reportingIndicesSettings } = await elasticsearchClient.indices.getSettings({ + const reportingIndicesSettings = await elasticsearchClient.indices.getSettings({ index: indexPattern, }); diff --git a/x-pack/plugins/reporting/server/lib/store/store.test.ts b/x-pack/plugins/reporting/server/lib/store/store.test.ts index aa893baf72e1e..81ba2454124c0 100644 --- a/x-pack/plugins/reporting/server/lib/store/store.test.ts +++ b/x-pack/plugins/reporting/server/lib/store/store.test.ts @@ -5,8 +5,6 @@ * 2.0. */ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import { ElasticsearchClient } from 'src/core/server'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { ReportingCore } from '../../'; import { @@ -16,12 +14,10 @@ import { } from '../../test_helpers'; import { Report, ReportDocument, ReportingStore, SavedReport } from './'; -const { createApiResponse } = elasticsearchServiceMock; - describe('ReportingStore', () => { const mockLogger = createMockLevelLogger(); let mockCore: ReportingCore; - let mockEsClient: DeeplyMockedKeys; + let mockEsClient: ReturnType; beforeEach(async () => { const reportingConfig = { @@ -31,12 +27,12 @@ describe('ReportingStore', () => { mockCore = await createMockReportingCore(createMockConfigSchema(reportingConfig)); mockEsClient = (await mockCore.getEsClient()).asInternalUser as typeof mockEsClient; - mockEsClient.indices.create.mockResolvedValue({} as any); - mockEsClient.indices.exists.mockResolvedValue({} as any); - mockEsClient.indices.refresh.mockResolvedValue({} as any); - mockEsClient.get.mockResolvedValue({} as any); - mockEsClient.index.mockResolvedValue({ body: { _id: 'stub-id', _index: 'stub-index' } } as any); - mockEsClient.update.mockResolvedValue({} as any); + mockEsClient.indices.create.mockResponse({} as any); + mockEsClient.indices.exists.mockResponse({} as any); + mockEsClient.indices.refresh.mockResponse({} as any); + mockEsClient.get.mockResponse({} as any); + mockEsClient.index.mockResponse({ _id: 'stub-id', _index: 'stub-index' } as any); + mockEsClient.update.mockResponse({} as any); }); describe('addReport', () => { @@ -85,7 +81,7 @@ describe('ReportingStore', () => { it('handles error creating the index', async () => { // setup - mockEsClient.indices.exists.mockResolvedValue({ body: false } as any); + mockEsClient.indices.exists.mockResponse(false); mockEsClient.indices.create.mockRejectedValue(new Error('horrible error')); const store = new ReportingStore(mockCore, mockLogger); @@ -108,7 +104,7 @@ describe('ReportingStore', () => { */ it('ignores index creation error if the index already exists and continues adding the report', async () => { // setup - mockEsClient.indices.exists.mockResolvedValue({ body: false } as any); + mockEsClient.indices.exists.mockResponse(false); mockEsClient.indices.create.mockRejectedValue(new Error('devastating error')); const store = new ReportingStore(mockCore, mockLogger); @@ -125,7 +121,7 @@ describe('ReportingStore', () => { it('skips creating the index if already exists', async () => { // setup - mockEsClient.indices.exists.mockResolvedValue({ body: false } as any); + mockEsClient.indices.exists.mockResponse(false); // will be triggered but ignored mockEsClient.indices.create.mockRejectedValue(new Error('resource_already_exists_exception')); @@ -149,7 +145,7 @@ describe('ReportingStore', () => { it('allows username string to be `false`', async () => { // setup - mockEsClient.indices.exists.mockResolvedValue({ body: false } as any); + mockEsClient.indices.exists.mockResponse(false); // will be triggered but ignored mockEsClient.indices.create.mockRejectedValue(new Error('resource_already_exists_exception')); @@ -199,7 +195,7 @@ describe('ReportingStore', () => { output: null, }, }; - mockEsClient.get.mockResolvedValue({ body: mockReport } as any); + mockEsClient.get.mockResponse(mockReport as any); const store = new ReportingStore(mockCore, mockLogger); const report = new Report({ ...mockReport, @@ -405,8 +401,8 @@ describe('ReportingStore', () => { describe('start', () => { it('creates an ILM policy for managing reporting indices if there is not already one', async () => { - mockEsClient.ilm.getLifecycle.mockRejectedValueOnce(createApiResponse({ statusCode: 404 })); - mockEsClient.ilm.putLifecycle.mockResolvedValueOnce(createApiResponse()); + mockEsClient.ilm.getLifecycle.mockRejectedValue({ statusCode: 404 }); + mockEsClient.ilm.putLifecycle.mockResponse({} as any); const store = new ReportingStore(mockCore, mockLogger); await store.start(); @@ -429,7 +425,7 @@ describe('ReportingStore', () => { }); it('does not create an ILM policy for managing reporting indices if one already exists', async () => { - mockEsClient.ilm.getLifecycle.mockResolvedValueOnce(createApiResponse()); + mockEsClient.ilm.getLifecycle.mockResponse({}); const store = new ReportingStore(mockCore, mockLogger); await store.start(); diff --git a/x-pack/plugins/reporting/server/lib/store/store.ts b/x-pack/plugins/reporting/server/lib/store/store.ts index 94375d66c00ad..492838d61ca74 100644 --- a/x-pack/plugins/reporting/server/lib/store/store.ts +++ b/x-pack/plugins/reporting/server/lib/store/store.ts @@ -110,7 +110,7 @@ export class ReportingStore { private async createIndex(indexName: string) { const client = await this.getClient(); - const { body: exists } = await client.indices.exists({ index: indexName }); + const exists = await client.indices.exists({ index: indexName }); if (exists) { return exists; @@ -166,9 +166,7 @@ export class ReportingStore { }, }; const client = await this.getClient(); - const { body } = await client.index(doc); - - return body; + return await client.index(doc); } /* @@ -239,7 +237,7 @@ export class ReportingStore { try { const client = await this.getClient(); - const { body: document } = await client.get({ + const document = await client.get({ index: taskJson.index, id: taskJson.id, }); @@ -283,16 +281,14 @@ export class ReportingStore { let body: UpdateResponse; try { const client = await this.getClient(); - body = ( - await client.update({ - id: report._id, - index: report._index, - if_seq_no: report._seq_no, - if_primary_term: report._primary_term, - refresh: true, - body: { doc }, - }) - ).body; + body = await client.update({ + id: report._id, + index: report._index, + if_seq_no: report._seq_no, + if_primary_term: report._primary_term, + refresh: true, + body: { doc }, + }); } catch (err) { this.logError(`Error in updating status to processing! Report: ${jobDebugMessage(report)}`, err, report); // prettier-ignore throw err; @@ -321,16 +317,14 @@ export class ReportingStore { let body: UpdateResponse; try { const client = await this.getClient(); - body = ( - await client.update({ - id: report._id, - index: report._index, - if_seq_no: report._seq_no, - if_primary_term: report._primary_term, - refresh: true, - body: { doc }, - }) - ).body; + body = await client.update({ + id: report._id, + index: report._index, + if_seq_no: report._seq_no, + if_primary_term: report._primary_term, + refresh: true, + body: { doc }, + }); } catch (err) { this.logError(`Error in updating status to failed! Report: ${jobDebugMessage(report)}`, err, report); // prettier-ignore throw err; @@ -358,16 +352,14 @@ export class ReportingStore { let body: UpdateResponse; try { const client = await this.getClient(); - body = ( - await client.update({ - id: report._id, - index: report._index, - if_seq_no: report._seq_no, - if_primary_term: report._primary_term, - refresh: true, - body: { doc }, - }) - ).body; + body = await client.update({ + id: report._id, + index: report._index, + if_seq_no: report._seq_no, + if_primary_term: report._primary_term, + refresh: true, + body: { doc }, + }); } catch (err) { this.logError(`Error in updating status to complete! Report: ${jobDebugMessage(report)}`, err, report); // prettier-ignore throw err; @@ -387,16 +379,14 @@ export class ReportingStore { let body: UpdateResponse; try { const client = await this.getClient(); - body = ( - await client.update({ - id: report._id, - index: report._index, - if_seq_no: report._seq_no, - if_primary_term: report._primary_term, - refresh: true, - body: { doc }, - }) - ).body; + body = await client.update({ + id: report._id, + index: report._index, + if_seq_no: report._seq_no, + if_primary_term: report._primary_term, + refresh: true, + body: { doc }, + }); } catch (err) { this.logError(`Error in clearing expiration and status for retry! Report: ${jobDebugMessage(report)}`, err, report); // prettier-ignore throw err; @@ -430,7 +420,7 @@ export class ReportingStore { }, }; - const { body } = await client.search({ + const body = await client.search({ size: 1, index: this.indexPrefix + '-*', seq_no_primary_term: true, diff --git a/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts b/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts index d283dd2a5e800..b369a5758fcb5 100644 --- a/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts +++ b/x-pack/plugins/reporting/server/routes/deprecations/deprecations.ts @@ -34,7 +34,7 @@ export const registerDeprecationsRoutes = (reporting: ReportingCore, logger: Log const store = await reporting.getStore(); try { - const { body } = await elasticsearch.client.asCurrentUser.security.hasPrivileges({ + const body = await elasticsearch.client.asCurrentUser.security.hasPrivileges({ body: { index: [ { diff --git a/x-pack/plugins/reporting/server/routes/lib/jobs_query.test.ts b/x-pack/plugins/reporting/server/routes/lib/jobs_query.test.ts index f2496189285eb..cc0df8c80fabc 100644 --- a/x-pack/plugins/reporting/server/routes/lib/jobs_query.test.ts +++ b/x-pack/plugins/reporting/server/routes/lib/jobs_query.test.ts @@ -7,13 +7,14 @@ import { set } from 'lodash'; import { ElasticsearchClient } from 'src/core/server'; +import { elasticsearchServiceMock } from '../../../../../../src/core/server/mocks'; import { statuses } from '../../lib'; import { createMockConfigSchema, createMockReportingCore } from '../../test_helpers'; import { jobsQueryFactory } from './jobs_query'; describe('jobsQuery', () => { - let client: jest.Mocked; + let client: ReturnType; let jobsQuery: ReturnType; beforeEach(async () => { @@ -26,8 +27,8 @@ describe('jobsQuery', () => { describe('list', () => { beforeEach(() => { - client.search.mockResolvedValue( - set>>({}, 'body.hits.hits', [ + client.search.mockResponse( + set>>({}, 'hits.hits', [ { _source: { _id: 'id1', jobtype: 'pdf', payload: {} } }, { _source: { _id: 'id2', jobtype: 'csv', payload: {} } }, ]) @@ -82,9 +83,7 @@ describe('jobsQuery', () => { }); it('should return an empty array when there are no hits', async () => { - client.search.mockResolvedValue({ body: {} } as Awaited< - ReturnType - >); + client.search.mockResponse({} as Awaited>); await expect( jobsQuery.list(['pdf'], { username: 'somebody' }, 0, 10, []) @@ -92,8 +91,8 @@ describe('jobsQuery', () => { }); it('should reject if the report source is missing', async () => { - client.search.mockResolvedValue( - set>>({}, 'body.hits.hits', [{}]) + client.search.mockResponse( + set>>({}, 'hits.hits', [{}]) ); await expect( @@ -104,9 +103,7 @@ describe('jobsQuery', () => { describe('count', () => { beforeEach(() => { - client.count.mockResolvedValue({ body: { count: 10 } } as Awaited< - ReturnType - >); + client.count.mockResponse({ count: 10 } as Awaited>); }); it('should pass parameters in the request body', async () => { @@ -135,8 +132,8 @@ describe('jobsQuery', () => { describe('get', () => { beforeEach(() => { - client.search.mockResolvedValue( - set>>({}, 'body.hits.hits', [ + client.search.mockResponse( + set>>({}, 'hits.hits', [ { _source: { _id: 'id1', jobtype: 'pdf', payload: {} } }, ]) ); @@ -168,9 +165,7 @@ describe('jobsQuery', () => { }); it('should return undefined when there is no report', async () => { - client.search.mockResolvedValue({ body: {} } as Awaited< - ReturnType - >); + client.search.mockResponse({} as Awaited>); await expect(jobsQuery.get({ username: 'somebody' }, 'id1')).resolves.toBeUndefined(); }); @@ -183,8 +178,8 @@ describe('jobsQuery', () => { describe('getError', () => { beforeEach(() => { - client.search.mockResolvedValue( - set>>({}, 'body.hits.hits', [ + client.search.mockResponse( + set>>({}, 'hits.hits', [ { _source: { _id: 'id1', @@ -218,8 +213,8 @@ describe('jobsQuery', () => { }); it('should reject when the job is not failed', async () => { - client.search.mockResolvedValue( - set>>({}, 'body.hits.hits', [ + client.search.mockResponse( + set>>({}, 'hits.hits', [ { _source: { _id: 'id1', @@ -236,9 +231,7 @@ describe('jobsQuery', () => { describe('delete', () => { beforeEach(() => { - client.delete.mockResolvedValue({ body: {} } as Awaited< - ReturnType - >); + client.delete.mockResponse({} as Awaited>); }); it('should pass parameters in the request body', async () => { @@ -248,7 +241,8 @@ describe('jobsQuery', () => { expect.objectContaining({ id: 'id1', index: '.reporting-12345', - }) + }), + { meta: true } ); }); }); diff --git a/x-pack/plugins/reporting/server/routes/lib/jobs_query.ts b/x-pack/plugins/reporting/server/routes/lib/jobs_query.ts index 1d41a66b71656..7f4d85ff14156 100644 --- a/x-pack/plugins/reporting/server/routes/lib/jobs_query.ts +++ b/x-pack/plugins/reporting/server/routes/lib/jobs_query.ts @@ -99,10 +99,10 @@ export function jobsQueryFactory(reportingCore: ReportingCore): JobsQueryFactory const response = (await execQuery((elasticsearchClient) => elasticsearchClient.search({ body, index: getIndex() }) - )) as TransportResult>; + )) as SearchResponse; return ( - response?.body.hits?.hits.map((report: SearchHit) => { + response?.hits?.hits.map((report: SearchHit) => { const { _source: reportSource, ...reportHead } = report; if (!reportSource) { throw new Error(`Search hit did not include _source!`); @@ -132,7 +132,7 @@ export function jobsQueryFactory(reportingCore: ReportingCore): JobsQueryFactory elasticsearchClient.count({ body, index: getIndex() }) ); - return response?.body.count ?? 0; + return response?.count ?? 0; }, async get(user, id) { @@ -161,7 +161,7 @@ export function jobsQueryFactory(reportingCore: ReportingCore): JobsQueryFactory elasticsearchClient.search({ body, index: getIndex() }) ); - const result = response?.body.hits?.hits?.[0]; + const result = response?.hits?.hits?.[0]; if (!result?._source) { logger.warning(`No hits resulted in search`); return; @@ -191,7 +191,7 @@ export function jobsQueryFactory(reportingCore: ReportingCore): JobsQueryFactory const response = await execQuery((elasticsearchClient) => elasticsearchClient.search({ body, index: getIndex() }) ); - const hits = response?.body.hits?.hits?.[0]; + const hits = response?.hits?.hits?.[0]; const status = hits?._source?.status; if (status !== statuses.JOB_STATUS_FAILED) { @@ -206,7 +206,7 @@ export function jobsQueryFactory(reportingCore: ReportingCore): JobsQueryFactory const { asInternalUser: elasticsearchClient } = await reportingCore.getEsClient(); const query = { id, index: deleteIndex, refresh: true }; - return await elasticsearchClient.delete(query); + return await elasticsearchClient.delete(query, { meta: true }); } catch (error) { throw new Error( i18n.translate('xpack.reporting.jobsQuery.deleteError', { diff --git a/x-pack/plugins/reporting/server/routes/management/integration_tests/jobs.test.ts b/x-pack/plugins/reporting/server/routes/management/integration_tests/jobs.test.ts index 9551f60f8c8e0..41165894464f1 100644 --- a/x-pack/plugins/reporting/server/routes/management/integration_tests/jobs.test.ts +++ b/x-pack/plugins/reporting/server/routes/management/integration_tests/jobs.test.ts @@ -8,8 +8,7 @@ jest.mock('../../../lib/content_stream', () => ({ getContentStream: jest.fn(), })); -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import { ElasticsearchClient } from 'kibana/server'; +import type { ElasticsearchClientMock } from '../../../../../../../src/core/server/mocks'; import { BehaviorSubject } from 'rxjs'; import { setupServer } from 'src/core/server/test_utils'; import { Readable } from 'stream'; @@ -37,7 +36,7 @@ describe('GET /api/reporting/jobs/download', () => { let core: ReportingCore; let mockSetupDeps: ReportingInternalSetup; let mockStartDeps: ReportingInternalStart; - let mockEsClient: DeeplyMockedKeys; + let mockEsClient: ElasticsearchClientMock; let stream: jest.Mocked; const getHits = (...sources: any) => { @@ -114,7 +113,7 @@ describe('GET /api/reporting/jobs/download', () => { }); it('fails on malformed download IDs', async () => { - mockEsClient.search.mockResolvedValueOnce({ body: getHits() } as any); + mockEsClient.search.mockResponseOnce(getHits() as any); registerJobInfoRoutes(core); await server.start(); @@ -154,7 +153,7 @@ describe('GET /api/reporting/jobs/download', () => { }); it('returns 404 if job not found', async () => { - mockEsClient.search.mockResolvedValueOnce({ body: getHits() } as any); + mockEsClient.search.mockResponseOnce(getHits() as any); registerJobInfoRoutes(core); await server.start(); @@ -163,12 +162,12 @@ describe('GET /api/reporting/jobs/download', () => { }); it('returns a 401 if not a valid job type', async () => { - mockEsClient.search.mockResolvedValueOnce({ - body: getHits({ + mockEsClient.search.mockResponseOnce( + getHits({ jobtype: 'invalidJobType', payload: { title: 'invalid!' }, - }), - } as any); + }) as any + ); registerJobInfoRoutes(core); await server.start(); @@ -177,12 +176,12 @@ describe('GET /api/reporting/jobs/download', () => { }); it(`returns job's info`, async () => { - mockEsClient.search.mockResolvedValueOnce({ - body: getHits({ + mockEsClient.search.mockResponseOnce( + getHits({ jobtype: 'base64EncodedJobType', payload: {}, // payload is irrelevant - }), - } as any); + }) as any + ); registerJobInfoRoutes(core); @@ -192,12 +191,12 @@ describe('GET /api/reporting/jobs/download', () => { }); it(`returns 403 if a user cannot view a job's info`, async () => { - mockEsClient.search.mockResolvedValueOnce({ - body: getHits({ + mockEsClient.search.mockResponseOnce( + getHits({ jobtype: 'customForbiddenJobType', payload: {}, // payload is irrelevant - }), - } as any); + }) as any + ); registerJobInfoRoutes(core); @@ -207,13 +206,13 @@ describe('GET /api/reporting/jobs/download', () => { }); it('when a job is incomplete', async () => { - mockEsClient.search.mockResolvedValueOnce({ - body: getHits({ + mockEsClient.search.mockResponseOnce( + getHits({ jobtype: 'unencodedJobType', status: 'pending', payload: { title: 'incomplete!' }, - }), - } as any); + }) as any + ); registerJobInfoRoutes(core); await server.start(); @@ -226,14 +225,14 @@ describe('GET /api/reporting/jobs/download', () => { }); it('when a job fails', async () => { - mockEsClient.search.mockResolvedValue({ - body: getHits({ + mockEsClient.search.mockResponse( + getHits({ jobtype: 'unencodedJobType', status: 'failed', output: { content: 'job failure message' }, payload: { title: 'failing job!' }, - }), - } as any); + }) as any + ); registerJobInfoRoutes(core); await server.start(); @@ -261,7 +260,7 @@ describe('GET /api/reporting/jobs/download', () => { }; it('when a known job-type is complete', async () => { - mockEsClient.search.mockResolvedValueOnce({ body: getCompleteHits() } as any); + mockEsClient.search.mockResponseOnce(getCompleteHits() as any); registerJobInfoRoutes(core); await server.start(); @@ -273,7 +272,7 @@ describe('GET /api/reporting/jobs/download', () => { }); it('succeeds when security is not there or disabled', async () => { - mockEsClient.search.mockResolvedValueOnce({ body: getCompleteHits() } as any); + mockEsClient.search.mockResponseOnce(getCompleteHits() as any); // @ts-ignore core.pluginSetupDeps.security = null; @@ -290,11 +289,11 @@ describe('GET /api/reporting/jobs/download', () => { }); it('forwards job content stream', async () => { - mockEsClient.search.mockResolvedValueOnce({ - body: getCompleteHits({ + mockEsClient.search.mockResponseOnce( + getCompleteHits({ jobType: 'unencodedJobType', - }), - } as any); + }) as any + ); registerJobInfoRoutes(core); await server.start(); @@ -306,12 +305,12 @@ describe('GET /api/reporting/jobs/download', () => { }); it('refuses to return unknown content-types', async () => { - mockEsClient.search.mockResolvedValueOnce({ - body: getCompleteHits({ + mockEsClient.search.mockResponseOnce( + getCompleteHits({ jobType: 'unencodedJobType', outputContentType: 'application/html', - }), - } as any); + }) as any + ); registerJobInfoRoutes(core); await server.start(); diff --git a/x-pack/plugins/reporting/server/usage/get_reporting_usage.ts b/x-pack/plugins/reporting/server/usage/get_reporting_usage.ts index 59387923e3755..a6bd65a136bf6 100644 --- a/x-pack/plugins/reporting/server/usage/get_reporting_usage.ts +++ b/x-pack/plugins/reporting/server/usage/get_reporting_usage.ts @@ -204,7 +204,7 @@ export async function getReportingUsage( const featureAvailability = await getLicense(); return esClient .search(params) - .then(({ body: response }) => handleResponse(response)) + .then((response) => handleResponse(response)) .then((usage: Partial): ReportingUsageType => { const exportTypesHandler = getExportTypesHandler(exportTypesRegistry); const availability = exportTypesHandler.getAvailability( diff --git a/x-pack/plugins/reporting/server/usage/reporting_usage_collector.test.ts b/x-pack/plugins/reporting/server/usage/reporting_usage_collector.test.ts index ad7a947273a23..cb6068f1efe67 100644 --- a/x-pack/plugins/reporting/server/usage/reporting_usage_collector.test.ts +++ b/x-pack/plugins/reporting/server/usage/reporting_usage_collector.test.ts @@ -6,6 +6,7 @@ */ import { loggerMock } from '@kbn/logging-mocks'; +import type { ElasticsearchClientMock } from '../../../../../src/core/server/mocks'; import { CollectorFetchContext } from 'src/plugins/usage_collection/server'; import { Collector, @@ -36,7 +37,7 @@ const getResponseMock = (base = {}) => base; const getMockFetchClients = (resp: any) => { const fetchParamsMock = createCollectorFetchContextMock(); - fetchParamsMock.esClient.search = jest.fn().mockResolvedValue({ body: resp }); + (fetchParamsMock.esClient as unknown as ElasticsearchClientMock).search.mockResponse(resp); return fetchParamsMock; }; @@ -181,20 +182,172 @@ describe('data modeling', () => { buckets: { all: { doc_count: 11, - layoutTypes: { doc_count: 6, pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'preserve_layout', doc_count: 5 }, { key: 'print', doc_count: 1 }, ] } }, - statusByApp: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'completed', doc_count: 6, jobTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'csv_searchsource', doc_count: 3, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'search', doc_count: 3 }, ] } }, { key: 'printable_pdf', doc_count: 2, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'dashboard', doc_count: 2 }, ] } }, { key: 'csv_searchsource', doc_count: 1, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'search', doc_count: 1 }, ] } }, ] } }, { key: 'completed_with_warnings', doc_count: 2, jobTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'PNG', doc_count: 1, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'dashboard', doc_count: 1 }, ] } }, { key: 'printable_pdf', doc_count: 1, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'dashboard', doc_count: 1 }, ] } }, ] } }, { key: 'failed', doc_count: 2, jobTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'printable_pdf', doc_count: 2, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'dashboard', doc_count: 2 }, ] } }, ] } }, { key: 'pending', doc_count: 1, jobTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'printable_pdf', doc_count: 1, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'dashboard', doc_count: 1 }, ] } }, ] } }, ] }, - objectTypes: { doc_count: 6, pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'dashboard', doc_count: 6 }, ] } }, - statusTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'completed', doc_count: 6 }, { key: 'completed_with_warnings', doc_count: 2 }, { key: 'failed', doc_count: 2 }, { key: 'pending', doc_count: 1 }, ] }, - jobTypes: { meta: {}, doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'printable_pdf', doc_count: 6, isDeprecated: { meta: {}, doc_count: 0 }, sizeMax: { value: 1713303.0 }, sizeAvg: { value: 957215.0 }, sizeMin: { value: 43226.0 } }, { key: 'csv_searchsource', doc_count: 3, isDeprecated: { meta: {}, doc_count: 0 }, sizeMax: { value: 7557.0 }, sizeAvg: { value: 3684.6666666666665 }, sizeMin: { value: 204.0 } }, { key: 'PNG', doc_count: 1, isDeprecated: { meta: {}, doc_count: 0 }, sizeMax: { value: 37748.0 }, sizeAvg: { value: 37748.0 }, sizeMin: { value: 37748.0 } }, { key: 'csv_searchsource', doc_count: 1, isDeprecated: { meta: {}, doc_count: 0 }, sizeMax: { value: 231.0 }, sizeAvg: { value: 231.0 }, sizeMin: { value: 231.0 } }, ] }, + layoutTypes: { + doc_count: 6, + pdf: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'preserve_layout', doc_count: 5 }, { key: 'print', doc_count: 1 },] + } + }, + statusByApp: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'completed', + doc_count: 6, + jobTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'csv_searchsource', + doc_count: 3, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'search', doc_count: 3 },] + } + }, { + key: 'printable_pdf', + doc_count: 2, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'dashboard', doc_count: 2 },] + } + }, { + key: 'csv_searchsource', + doc_count: 1, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'search', doc_count: 1 },] + } + },] + } + }, { + key: 'completed_with_warnings', + doc_count: 2, + jobTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'PNG', + doc_count: 1, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'dashboard', doc_count: 1 },] + } + }, { + key: 'printable_pdf', + doc_count: 1, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'dashboard', doc_count: 1 },] + } + },] + } + }, { + key: 'failed', + doc_count: 2, + jobTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'printable_pdf', + doc_count: 2, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'dashboard', doc_count: 2 },] + } + },] + } + }, { + key: 'pending', + doc_count: 1, + jobTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'printable_pdf', + doc_count: 1, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'dashboard', doc_count: 1 },] + } + },] + } + },] + }, + objectTypes: { + doc_count: 6, + pdf: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'dashboard', doc_count: 6 },] + } + }, + statusTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'completed', doc_count: 6 }, { + key: 'completed_with_warnings', + doc_count: 2 + }, { key: 'failed', doc_count: 2 }, { key: 'pending', doc_count: 1 },] + }, + jobTypes: { + meta: {}, + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'printable_pdf', + doc_count: 6, + isDeprecated: { meta: {}, doc_count: 0 }, + sizeMax: { value: 1713303.0 }, + sizeAvg: { value: 957215.0 }, + sizeMin: { value: 43226.0 } + }, { + key: 'csv_searchsource', + doc_count: 3, + isDeprecated: { meta: {}, doc_count: 0 }, + sizeMax: { value: 7557.0 }, + sizeAvg: { value: 3684.6666666666665 }, + sizeMin: { value: 204.0 } + }, { + key: 'PNG', + doc_count: 1, + isDeprecated: { meta: {}, doc_count: 0 }, + sizeMax: { value: 37748.0 }, + sizeAvg: { value: 37748.0 }, + sizeMin: { value: 37748.0 } + }, { + key: 'csv_searchsource', + doc_count: 1, + isDeprecated: { meta: {}, doc_count: 0 }, + sizeMax: { value: 231.0 }, + sizeAvg: { value: 231.0 }, + sizeMin: { value: 231.0 } + },] + }, sizeMax: { value: 1713303.0 }, sizeMin: { value: 204.0 }, sizeAvg: { value: 365084.75 }, }, last7Days: { doc_count: 0, - layoutTypes: { doc_count: 0, pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } }, + layoutTypes: { + doc_count: 0, + pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } + }, statusByApp: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, - objectTypes: { doc_count: 0, pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } }, + objectTypes: { + doc_count: 0, + pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } + }, statusTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, jobTypes: { meta: {}, doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] }, sizeMax: { value: null }, @@ -227,19 +380,111 @@ describe('data modeling', () => { buckets: { all: { doc_count: 9, - layoutTypes: { doc_count: 0, pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } }, - statusByApp: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'completed', doc_count: 9, jobTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'csv_searchsource', doc_count: 5, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [{ key: 'search', doc_count: 5 }] } }, { key: 'csv_searchsource', doc_count: 4, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [{ key: 'search', doc_count: 4 }] } }, ] } }, ] }, - objectTypes: { doc_count: 0, pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } }, - statusTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [{ key: 'completed', doc_count: 9 }] }, - jobTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'csv_searchsource', doc_count: 5, isDeprecated: { doc_count: 0 } }, { key: 'csv_searchsource', doc_count: 4, isDeprecated: { doc_count: 4 } }, ] }, + layoutTypes: { + doc_count: 0, + pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } + }, + statusByApp: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'completed', + doc_count: 9, + jobTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'csv_searchsource', + doc_count: 5, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'search', doc_count: 5 }] + } + }, { + key: 'csv_searchsource', + doc_count: 4, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'search', doc_count: 4 }] + } + },] + } + },] + }, + objectTypes: { + doc_count: 0, + pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } + }, + statusTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'completed', doc_count: 9 }] + }, + jobTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'csv_searchsource', + doc_count: 5, + isDeprecated: { doc_count: 0 } + }, { key: 'csv_searchsource', doc_count: 4, isDeprecated: { doc_count: 4 } },] + }, }, last7Days: { doc_count: 9, - layoutTypes: { doc_count: 0, pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } }, - statusByApp: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'completed', doc_count: 9, jobTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'csv_searchsource', doc_count: 5, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [{ key: 'search', doc_count: 5 }] } }, { key: 'csv_searchsource', doc_count: 4, appNames: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [{ key: 'search', doc_count: 4 }] } }, ] } }, ] }, - objectTypes: { doc_count: 0, pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } }, - statusTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [{ key: 'completed', doc_count: 9 }] }, - jobTypes: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'csv_searchsource', doc_count: 5, isDeprecated: { doc_count: 0 } }, { key: 'csv_searchsource', doc_count: 4, isDeprecated: { doc_count: 4 } }, ] }, + layoutTypes: { + doc_count: 0, + pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } + }, + statusByApp: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'completed', + doc_count: 9, + jobTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'csv_searchsource', + doc_count: 5, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'search', doc_count: 5 }] + } + }, { + key: 'csv_searchsource', + doc_count: 4, + appNames: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'search', doc_count: 4 }] + } + },] + } + },] + }, + objectTypes: { + doc_count: 0, + pdf: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [] } + }, + statusTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ key: 'completed', doc_count: 9 }] + }, + jobTypes: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [{ + key: 'csv_searchsource', + doc_count: 5, + isDeprecated: { doc_count: 0 } + }, { key: 'csv_searchsource', doc_count: 4, isDeprecated: { doc_count: 4 } },] + }, }, }, // prettier-ignore }, @@ -268,18 +513,76 @@ describe('data modeling', () => { all: { doc_count: 4, layoutTypes: { doc_count: 2, pdf: { buckets: [{ key: 'preserve_layout', doc_count: 2 }] } }, - statusByApp: { buckets: [ { key: 'completed', doc_count: 4, jobTypes: { buckets: [ { key: 'printable_pdf', doc_count: 2, appNames: { buckets: [ { key: 'canvas workpad', doc_count: 1 }, { key: 'dashboard', doc_count: 1 }, ] } }, { key: 'PNG', doc_count: 1, appNames: { buckets: [{ key: 'dashboard', doc_count: 1 }] } }, { key: 'csv_searchsource', doc_count: 1, appNames: { buckets: [] } }, ] } }, ] }, - objectTypes: { doc_count: 2, pdf: { buckets: [ { key: 'canvas workpad', doc_count: 1 }, { key: 'dashboard', doc_count: 1 }, ] } }, + statusByApp: { + buckets: [{ + key: 'completed', + doc_count: 4, + jobTypes: { + buckets: [{ + key: 'printable_pdf', + doc_count: 2, + appNames: { + buckets: [{ key: 'canvas workpad', doc_count: 1 }, { + key: 'dashboard', + doc_count: 1 + },] + } + }, { + key: 'PNG', + doc_count: 1, + appNames: { buckets: [{ key: 'dashboard', doc_count: 1 }] } + }, { key: 'csv_searchsource', doc_count: 1, appNames: { buckets: [] } },] + } + },] + }, + objectTypes: { + doc_count: 2, + pdf: { buckets: [{ key: 'canvas workpad', doc_count: 1 }, { key: 'dashboard', doc_count: 1 },] } + }, statusTypes: { buckets: [{ key: 'completed', doc_count: 4 }] }, - jobTypes: { buckets: [ { key: 'printable_pdf', doc_count: 2 }, { key: 'PNG', doc_count: 1 }, { key: 'csv_searchsource', doc_count: 1 }, ] }, + jobTypes: { + buckets: [{ key: 'printable_pdf', doc_count: 2 }, { + key: 'PNG', + doc_count: 1 + }, { key: 'csv_searchsource', doc_count: 1 },] + }, }, last7Days: { doc_count: 4, layoutTypes: { doc_count: 2, pdf: { buckets: [{ key: 'preserve_layout', doc_count: 2 }] } }, - statusByApp: { buckets: [ { key: 'completed', doc_count: 4, jobTypes: { buckets: [ { key: 'printable_pdf', doc_count: 2, appNames: { buckets: [ { key: 'canvas workpad', doc_count: 1 }, { key: 'dashboard', doc_count: 1 }, ] } }, { key: 'PNG', doc_count: 1, appNames: { buckets: [{ key: 'dashboard', doc_count: 1 }] } }, { key: 'csv_searchsource', doc_count: 1, appNames: { buckets: [] } }, ] } }, ] }, - objectTypes: { doc_count: 2, pdf: { buckets: [ { key: 'canvas workpad', doc_count: 1 }, { key: 'dashboard', doc_count: 1 }, ] } }, + statusByApp: { + buckets: [{ + key: 'completed', + doc_count: 4, + jobTypes: { + buckets: [{ + key: 'printable_pdf', + doc_count: 2, + appNames: { + buckets: [{ key: 'canvas workpad', doc_count: 1 }, { + key: 'dashboard', + doc_count: 1 + },] + } + }, { + key: 'PNG', + doc_count: 1, + appNames: { buckets: [{ key: 'dashboard', doc_count: 1 }] } + }, { key: 'csv_searchsource', doc_count: 1, appNames: { buckets: [] } },] + } + },] + }, + objectTypes: { + doc_count: 2, + pdf: { buckets: [{ key: 'canvas workpad', doc_count: 1 }, { key: 'dashboard', doc_count: 1 },] } + }, statusTypes: { buckets: [{ key: 'completed', doc_count: 4 }] }, - jobTypes: { buckets: [ { key: 'printable_pdf', doc_count: 2 }, { key: 'PNG', doc_count: 1 }, { key: 'csv_searchsource', doc_count: 1 }, ] }, + jobTypes: { + buckets: [{ key: 'printable_pdf', doc_count: 2 }, { + key: 'PNG', + doc_count: 1 + }, { key: 'csv_searchsource', doc_count: 1 },] + }, }, }, // prettier-ignore }, @@ -306,30 +609,30 @@ describe('data modeling', () => { aggregations: { ranges: { buckets: { - all: { - doc_count: 0, - jobTypes: { buckets: [] }, - layoutTypes: { doc_count: 0, pdf: { buckets: [] } }, - objectTypes: { doc_count: 0, pdf: { buckets: [] } }, - statusByApp: { buckets: [] }, - statusTypes: { buckets: [] }, - sizeMax: { value: null}, - sizeMin: { value: null }, - sizeAvg: { value: null}, - }, - last7Days: { - doc_count: 0, - jobTypes: { buckets: [] }, - layoutTypes: { doc_count: 0, pdf: { buckets: [] } }, - objectTypes: { doc_count: 0, pdf: { buckets: [] } }, - statusByApp: { buckets: [] }, - statusTypes: { buckets: [] }, - sizeMax: { value: null}, - sizeMin: { value: null }, - sizeAvg: { value: null}, + all: { + doc_count: 0, + jobTypes: { buckets: [] }, + layoutTypes: { doc_count: 0, pdf: { buckets: [] } }, + objectTypes: { doc_count: 0, pdf: { buckets: [] } }, + statusByApp: { buckets: [] }, + statusTypes: { buckets: [] }, + sizeMax: { value: null }, + sizeMin: { value: null }, + sizeAvg: { value: null }, + }, + last7Days: { + doc_count: 0, + jobTypes: { buckets: [] }, + layoutTypes: { doc_count: 0, pdf: { buckets: [] } }, + objectTypes: { doc_count: 0, pdf: { buckets: [] } }, + statusByApp: { buckets: [] }, + statusTypes: { buckets: [] }, + sizeMax: { value: null }, + sizeMin: { value: null }, + sizeAvg: { value: null }, - }, - }, // prettier-ignore + }, + }, // prettier-ignore }, }, }) diff --git a/x-pack/plugins/rollup/server/collectors/helpers.test.ts b/x-pack/plugins/rollup/server/collectors/helpers.test.ts index e0056b1759a94..68fd1c24ea91b 100644 --- a/x-pack/plugins/rollup/server/collectors/helpers.test.ts +++ b/x-pack/plugins/rollup/server/collectors/helpers.test.ts @@ -107,7 +107,7 @@ describe('rollupUsageCollectorHelpers', () => { const mockIndex = 'mock_index'; const getMockCallCluster = (hits: unknown[]) => ({ - search: () => Promise.resolve({ body: { hits: { hits } } }) as unknown, + search: () => Promise.resolve({ hits: { hits } }) as unknown, } as ElasticsearchClient); describe('fetchRollupIndexPatterns', () => { diff --git a/x-pack/plugins/rollup/server/collectors/helpers.ts b/x-pack/plugins/rollup/server/collectors/helpers.ts index b007bbbff7e4a..a00ad10237ee9 100644 --- a/x-pack/plugins/rollup/server/collectors/helpers.ts +++ b/x-pack/plugins/rollup/server/collectors/helpers.ts @@ -47,7 +47,7 @@ export async function fetchRollupIndexPatterns(kibanaIndex: string, esClient: El }, }; - const { body: esResponse } = await esClient.search(searchParams); + const esResponse = await esClient.search(searchParams); return get(esResponse, 'hits.hits', []).map((indexPattern: any) => { const { _id: savedObjectId } = indexPattern; @@ -68,7 +68,7 @@ const getSavedObjectsList = async ({ filterPath: string[]; filter: ESFilterProps; }) => { - const { body: esResponse } = await esClient.search({ + const esResponse = await esClient.search({ body: { search_after: searchAfter, sort: [{ updated_at: 'asc' }], diff --git a/x-pack/plugins/rollup/server/rollup_data_enricher.ts b/x-pack/plugins/rollup/server/rollup_data_enricher.ts index 2c334780720fa..599a53734605f 100644 --- a/x-pack/plugins/rollup/server/rollup_data_enricher.ts +++ b/x-pack/plugins/rollup/server/rollup_data_enricher.ts @@ -14,7 +14,7 @@ export const rollupDataEnricher = async (indicesList: Index[], client: IScopedCl } try { - const { body: rollupJobData } = await client.asCurrentUser.rollup.getRollupIndexCaps({ + const rollupJobData = await client.asCurrentUser.rollup.getRollupIndexCaps({ index: '_all', }); 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 1d3be4b8e1fbb..485c1301b4d9b 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 @@ -24,7 +24,7 @@ export const registerGetRoute = ({ license.guardApiRoute(async (context, request, response) => { try { const { client: clusterClient } = context.core.elasticsearch; - const { body: data } = await clusterClient.asCurrentUser.rollup.getRollupIndexCaps({ + const data = await clusterClient.asCurrentUser.rollup.getRollupIndexCaps({ index: '_all', }); return response.ok({ body: getCapabilitiesForRollupIndices(data) }); 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 b2431c3838234..dec51870f2f57 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 @@ -70,7 +70,7 @@ export const registerValidateIndexPatternRoute = ({ const { client: clusterClient } = context.core.elasticsearch; try { const { indexPattern } = request.params; - const [{ body: fieldCapabilities }, { body: rollupIndexCapabilities }] = await Promise.all([ + const [fieldCapabilities, rollupIndexCapabilities] = await Promise.all([ clusterClient.asCurrentUser.fieldCaps({ index: indexPattern, fields: '*' }), clusterClient.asCurrentUser.rollup.getRollupIndexCaps({ index: indexPattern }), ]); 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 11cfaf8851d45..a13bf4936a77f 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 @@ -38,7 +38,7 @@ export const registerCreateRoute = ({ body: rest, }); // Then request the newly created job. - const { body: results } = await clusterClient.asCurrentUser.rollup.getJobs({ id }); + const results = await clusterClient.asCurrentUser.rollup.getJobs({ id }); return response.ok({ body: results.jobs[0] }); } catch (err) { return handleEsError({ error: err, response }); 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 9944df2e55919..cc0b138aeb835 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 @@ -21,7 +21,7 @@ export const registerGetRoute = ({ license.guardApiRoute(async (context, request, response) => { const { client: clusterClient } = context.core.elasticsearch; try { - const { body: data } = await clusterClient.asCurrentUser.rollup.getJobs({ id: '_all' }); + const data = await clusterClient.asCurrentUser.rollup.getJobs({ id: '_all' }); return response.ok({ body: data }); } catch (err) { return handleEsError({ error: err, response }); 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 62aec4e01eaa0..ab144c1f42440 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 @@ -30,13 +30,11 @@ export const registerSearchRoute = ({ const { client: clusterClient } = context.core.elasticsearch; try { const requests = request.body.map(({ index, query }: { index: string; query?: any }) => - clusterClient.asCurrentUser.rollup - .rollupSearch({ - index, - rest_total_hits_as_int: true, - body: query, - }) - .then(({ body }) => body) + clusterClient.asCurrentUser.rollup.rollupSearch({ + index, + rest_total_hits_as_int: true, + body: query, + }) ); const data = await Promise.all(requests); return response.ok({ body: data }); diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts index 0557d2f65ee1c..1f8cfb4b78c85 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts @@ -59,6 +59,7 @@ const isValidAlert = (source?: estypes.SearchHit): source source?.fields?.[SPACE_IDS][0] != null) ); }; + export interface ConstructorOptions { logger: Logger; authorization: PublicMethodsOf; @@ -267,16 +268,16 @@ export class AlertsClient { seq_no_primary_term: true, }); - if (!result?.body.hits.hits.every((hit) => isValidAlert(hit))) { + if (!result?.hits.hits.every((hit) => isValidAlert(hit))) { const errorMessage = `Invalid alert found with id of "${id}" or with query "${query}" and operation ${operation}`; this.logger.error(errorMessage); throw Boom.badData(errorMessage); } - if (result?.body?.hits?.hits != null && result?.body.hits.hits.length > 0) { - await this.ensureAllAuthorized(result.body.hits.hits, operation); + if (result?.hits?.hits != null && result?.hits.hits.length > 0) { + await this.ensureAllAuthorized(result.hits.hits, operation); - result?.body.hits.hits.map((item) => + result?.hits.hits.map((item) => this.auditLogger?.log( alertAuditEvent({ action: operationAlertAuditActionMap[operation], @@ -287,7 +288,7 @@ export class AlertsClient { ); } - return result.body; + return result; } catch (error) { const errorMessage = `Unable to retrieve alert details for alert with id of "${id}" or with query "${query}" and operation ${operation} \nError: ${error}`; this.logger.error(errorMessage); @@ -319,7 +320,7 @@ export class AlertsClient { }, }); - await this.ensureAllAuthorized(mgetRes.body.docs, operation); + await this.ensureAllAuthorized(mgetRes.docs, operation); for (const id of ids) { this.auditLogger?.log( @@ -331,7 +332,7 @@ export class AlertsClient { ); } - const bulkUpdateRequest = mgetRes.body.docs.flatMap((item) => { + const bulkUpdateRequest = mgetRes.docs.flatMap((item) => { // @ts-expect-error doesn't handle error branch in MGetResponse const fieldToUpdate = this.getAlertStatusFieldUpdate(item?._source, status); return [ @@ -525,7 +526,7 @@ export class AlertsClient { alert?.hits.hits[0]._source, status as STATUS_VALUES ); - const { body: response } = await this.esClient.update({ + const response = await this.esClient.update({ ...decodeVersion(_version), id, index, diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts index 3f89506c0a1f4..3c57d8269f42b 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts @@ -81,43 +81,35 @@ describe('bulkUpdate()', () => { test('logs successful event in audit logger', async () => { const indexName = '.alerts-observability.apm.alerts'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.mget.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - docs: [ - { - found: true, - _id: fakeAlertId, - _index: indexName, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.mget.mockResponseOnce({ + docs: [ + { + found: true, + _id: fakeAlertId, + _index: indexName, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }) - ); - esClientMock.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - errors: false, - took: 1, - items: [ - { - update: { - _id: fakeAlertId, - _index: '.alerts-observability.apm.alerts', - result: 'updated', - status: 200, - }, - }, - ], + ], + }); + esClientMock.bulk.mockResponseOnce({ + errors: false, + took: 1, + items: [ + { + update: { + _id: fakeAlertId, + _index: '.alerts-observability.apm.alerts', + result: 'updated', + status: 200, + }, }, - }) - ); + ], + }); await alertsClient.bulkUpdate({ ids: [fakeAlertId], query: undefined, @@ -139,25 +131,21 @@ describe('bulkUpdate()', () => { test('audit error access if user is unauthorized for given alert', async () => { const indexName = '.alerts-observability.apm.alerts'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.mget.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - docs: [ - { - found: true, - _id: fakeAlertId, - _index: indexName, - _source: { - [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.mget.mockResponseOnce({ + docs: [ + { + found: true, + _id: fakeAlertId, + _index: indexName, + _source: { + [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }) - ); + ], + }); await expect( alertsClient.bulkUpdate({ @@ -186,36 +174,32 @@ describe('bulkUpdate()', () => { test('logs multiple error events in audit logger', async () => { const indexName = '.alerts-observability.apm.alerts'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.mget.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - docs: [ - { - found: true, - _id: successfulAuthzHit, - _index: indexName, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - { - found: true, - _id: unsuccessfulAuthzHit, - _index: indexName, - _source: { - [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.mget.mockResponseOnce({ + docs: [ + { + found: true, + _id: successfulAuthzHit, + _index: indexName, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }) - ); + { + found: true, + _id: unsuccessfulAuthzHit, + _index: indexName, + _source: { + [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, + }, + ], + }); await expect( alertsClient.bulkUpdate({ @@ -264,44 +248,36 @@ describe('bulkUpdate()', () => { test('logs successful event in audit logger', async () => { const indexName = '.alerts-observability.apm.alerts'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - _id: fakeAlertId, - _index: '.alerts-observability.apm.alerts', - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + _id: fakeAlertId, + _index: '.alerts-observability.apm.alerts', + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); + ], + }, + }); - esClientMock.updateByQuery.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - updated: 1, - }, - }) - ); + esClientMock.updateByQuery.mockResponseOnce({ + updated: 1, + }); await alertsClient.bulkUpdate({ ids: undefined, @@ -324,36 +300,32 @@ describe('bulkUpdate()', () => { test('audit error access if user is unauthorized for given alert', async () => { const indexName = '.alerts-observability.apm.alerts'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - _id: fakeAlertId, - _index: '.alerts-observability.apm.alerts', - _source: { - [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + _id: fakeAlertId, + _index: '.alerts-observability.apm.alerts', + _source: { + [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); + ], + }, + }); await expect( alertsClient.bulkUpdate({ ids: undefined, @@ -385,46 +357,42 @@ describe('bulkUpdate()', () => { test('logs multiple error events in audit logger', async () => { const indexName = '.alerts-observability.apm.alerts'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 2, + max_score: 999, + hits: [ + { + _id: successfulAuthzHit, + _index: '.alerts-observability.apm.alerts', + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - hits: { - total: 2, - max_score: 999, - hits: [ - { - _id: successfulAuthzHit, - _index: '.alerts-observability.apm.alerts', - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - { - _id: unsuccessfulAuthzHit, - _index: '.alerts-observability.apm.alerts', - _source: { - [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + { + _id: unsuccessfulAuthzHit, + _index: '.alerts-observability.apm.alerts', + _source: { + [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); + ], + }, + }); await expect( alertsClient.bulkUpdate({ ids: undefined, diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/find_alerts.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/find_alerts.test.ts index 285d318749786..7c4085cb5837f 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/find_alerts.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/find_alerts.test.ts @@ -72,42 +72,39 @@ beforeEach(() => { describe('find()', () => { test('calls ES client with given params', async () => { const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_WORKFLOW_STATUS]: 'open', - [SPACE_IDS]: ['test_default_space_id'], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['test_default_space_id'], + }, }, - }, - }) - ); + ], + }, + }); const result = await alertsClient.find({ query: { match: { [ALERT_WORKFLOW_STATUS]: 'open' } }, index: '.alerts-observability.apm.alerts', @@ -203,42 +200,39 @@ describe('find()', () => { test('logs successful event in audit logger', async () => { const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_WORKFLOW_STATUS]: 'open', - [SPACE_IDS]: ['test_default_space_id'], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['test_default_space_id'], + }, }, - }, - }) - ); + ], + }, + }); await alertsClient.find({ query: { match: { [ALERT_WORKFLOW_STATUS]: 'open' } }, index: '.alerts-observability.apm.alerts', @@ -257,41 +251,38 @@ describe('find()', () => { // fakeRuleTypeId will cause authz to fail const fakeRuleTypeId = 'fake.rule'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _id: fakeAlertId, - _index: indexName, - _source: { - [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_WORKFLOW_STATUS]: 'open', - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _id: fakeAlertId, + _index: indexName, + _source: { + [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); + ], + }, + }); await expect( alertsClient.find({ @@ -336,42 +327,39 @@ describe('find()', () => { describe('authorization', () => { beforeEach(() => { - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_WORKFLOW_STATUS]: 'open', - [SPACE_IDS]: ['test_default_space_id'], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: ['test_default_space_id'], + }, }, - }, - }) - ); + ], + }, + }); }); test('returns alert if user is authorized to read alert under the consumer', async () => { diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts index acc6e37099fdd..e3f186ce8c0c8 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts @@ -74,42 +74,39 @@ beforeEach(() => { describe('get()', () => { test('calls ES client with given params', async () => { const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: ['test_default_space_id'], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: ['test_default_space_id'], + }, }, - }, - }) - ); + ], + }, + }); const result = await alertsClient.get({ id: '1', index: '.alerts-observability.apm.alerts' }); expect(result).toMatchInlineSnapshot(` Object { @@ -183,42 +180,39 @@ describe('get()', () => { test('logs successful event in audit logger', async () => { const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: ['test_default_space_id'], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: ['test_default_space_id'], + }, }, - }, - }) - ); + ], + }, + }); await alertsClient.get({ id: 'NoxgpHkBqbdrfX07MqXV', index: '.alerts-observability.apm.alerts', @@ -237,41 +231,38 @@ describe('get()', () => { // fakeRuleTypeId will cause authz to fail const fakeRuleTypeId = 'fake.rule'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _id: fakeAlertId, - _index: indexName, - _source: { - [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _id: fakeAlertId, + _index: indexName, + _source: { + [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); + ], + }, + }); await expect(alertsClient.get({ id: fakeAlertId, index: '.alerts-observability.apm.alerts' })) .rejects.toThrowErrorMatchingInlineSnapshot(` @@ -309,42 +300,39 @@ describe('get()', () => { describe('authorization', () => { beforeEach(() => { - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_STATUS]: ALERT_STATUS_ACTIVE, - [SPACE_IDS]: ['test_default_space_id'], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_STATUS]: ALERT_STATUS_ACTIVE, + [SPACE_IDS]: ['test_default_space_id'], + }, }, - }, - }) - ); + ], + }, + }); }); test('returns alert if user is authorized to read alert under the consumer', async () => { diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts index 2778d4da0f089..8c540fc19f537 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts @@ -73,52 +73,45 @@ beforeEach(() => { describe('update()', () => { test('calls ES client with given params', async () => { const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_WORKFLOW_STATUS]: 'open', - [ALERT_RULE_CONSUMER]: 'apm', - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_RULE_CONSUMER]: 'apm', + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); - esClientMock.update.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 2, - result: 'updated', - _shards: { total: 2, successful: 1, failed: 0 }, - _seq_no: 1, - _primary_term: 1, - }, - }) - ); + ], + }, + }); + esClientMock.update.mockResponseOnce({ + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 2, + result: 'updated', + _shards: { total: 2, successful: 1, failed: 0 }, + _seq_no: 1, + _primary_term: 1, + }); const result = await alertsClient.update({ id: '1', status: 'closed', @@ -159,52 +152,45 @@ describe('update()', () => { test('logs successful event in audit logger', async () => { const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_WORKFLOW_STATUS]: 'open', - [ALERT_RULE_CONSUMER]: 'apm', - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_RULE_CONSUMER]: 'apm', + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); - esClientMock.update.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 2, - result: 'updated', - _shards: { total: 2, successful: 1, failed: 0 }, - _seq_no: 1, - _primary_term: 1, - }, - }) - ); + ], + }, + }); + esClientMock.update.mockResponseOnce({ + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 2, + result: 'updated', + _shards: { total: 2, successful: 1, failed: 0 }, + _seq_no: 1, + _primary_term: 1, + }); await alertsClient.update({ id: 'NoxgpHkBqbdrfX07MqXV', status: 'closed', @@ -230,41 +216,38 @@ describe('update()', () => { // fakeRuleTypeId will cause authz to fail const fakeRuleTypeId = 'fake.rule'; const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _version: 1, - _seq_no: 362, - _primary_term: 2, - _id: fakeAlertId, - _index: indexName, - _source: { - [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_WORKFLOW_STATUS]: 'open', - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _version: 1, + _seq_no: 362, + _primary_term: 2, + _id: fakeAlertId, + _index: indexName, + _source: { + [ALERT_RULE_TYPE_ID]: fakeRuleTypeId, + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); + ], + }, + }); await expect( alertsClient.update({ @@ -314,39 +297,36 @@ describe('update()', () => { test(`throws an error if ES client update fails`, async () => { const error = new Error('something went wrong on update'); const alertsClient = new AlertsClient(alertsClientParams); - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_WORKFLOW_STATUS]: 'open', - [ALERT_RULE_CONSUMER]: 'apm', - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_WORKFLOW_STATUS]: 'open', + [ALERT_RULE_CONSUMER]: 'apm', + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); + ], + }, + }); esClientMock.update.mockRejectedValue(error); await expect( @@ -371,56 +351,49 @@ describe('update()', () => { describe('authorization', () => { beforeEach(() => { - esClientMock.search.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - took: 5, - timed_out: false, - _shards: { - total: 1, - successful: 1, - failed: 0, - skipped: 0, - }, - hits: { - total: 1, - max_score: 999, - hits: [ - { - found: true, - _type: 'alert', - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 2, - _seq_no: 362, - _primary_term: 2, - _source: { - [ALERT_RULE_TYPE_ID]: 'apm.error_rate', - message: 'hello world 1', - [ALERT_RULE_CONSUMER]: 'apm', - [ALERT_WORKFLOW_STATUS]: 'open', - [SPACE_IDS]: [DEFAULT_SPACE], - }, - }, - ], + esClientMock.search.mockResponseOnce({ + took: 5, + timed_out: false, + _shards: { + total: 1, + successful: 1, + failed: 0, + skipped: 0, + }, + hits: { + total: 1, + max_score: 999, + hits: [ + { + // @ts-expect-error incorrect fields + found: true, + _type: 'alert', + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 2, + _seq_no: 362, + _primary_term: 2, + _source: { + [ALERT_RULE_TYPE_ID]: 'apm.error_rate', + message: 'hello world 1', + [ALERT_RULE_CONSUMER]: 'apm', + [ALERT_WORKFLOW_STATUS]: 'open', + [SPACE_IDS]: [DEFAULT_SPACE], + }, }, - }, - }) - ); + ], + }, + }); - esClientMock.update.mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: { - _index: '.alerts-observability.apm.alerts', - _id: 'NoxgpHkBqbdrfX07MqXV', - _version: 2, - result: 'updated', - _shards: { total: 2, successful: 1, failed: 0 }, - _seq_no: 1, - _primary_term: 1, - }, - }) - ); + esClientMock.update.mockResponseOnce({ + _index: '.alerts-observability.apm.alerts', + _id: 'NoxgpHkBqbdrfX07MqXV', + _version: 2, + result: 'updated', + _shards: { total: 2, successful: 1, failed: 0 }, + _seq_no: 1, + _primary_term: 1, + }); }); test('returns alert if user is authorized to update alert under the consumer', async () => { diff --git a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts index 4aa0126cdabf8..491c9ff22d21f 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts @@ -95,12 +95,12 @@ export class RuleDataClient implements IRuleDataClient { search: async (request) => { const clusterClient = await waitUntilReady(); - const { body } = (await clusterClient.search({ + const body = await clusterClient.search({ ...request, index: indexPattern, - })) as { body: any }; + }); - return body; + return body as any; }, getDynamicIndexPattern: async () => { @@ -193,13 +193,15 @@ export class RuleDataClient implements IRuleDataClient { index: alias, }; - return clusterClient.bulk(requestWithDefaultParameters).then((response) => { - if (response.body.errors) { - const error = new errors.ResponseError(response); - this.options.logger.error(error); - } - return response; - }); + return clusterClient + .bulk(requestWithDefaultParameters, { meta: true }) + .then((response) => { + if (response.body.errors) { + const error = new errors.ResponseError(response); + this.options.logger.error(error); + } + return response; + }); }) .catch((error) => { if (error instanceof RuleDataWriterInitializationError) { diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts index c49e9d1e111bf..2bda23ca3c46f 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/resource_installer.ts @@ -161,7 +161,7 @@ export class ResourceInstaller { const simulatedIndexMapping = await clusterClient.indices.simulateIndexTemplate({ name: index, }); - const simulatedMapping = get(simulatedIndexMapping, ['body', 'template', 'mappings']); + const simulatedMapping = get(simulatedIndexMapping, ['template', 'mappings']); try { await clusterClient.indices.putMapping({ @@ -365,7 +365,7 @@ export class ResourceInstaller { // something else created it so suppress the error. If it's not the write // index, that's bad, throw an error. if (err?.meta?.body?.error?.type === 'resource_already_exists_exception') { - const { body: existingIndices } = await clusterClient.indices.get({ + const existingIndices = await clusterClient.indices.get({ index: initialIndexName, }); if (!existingIndices[initialIndexName]?.aliases?.[primaryNamespacedAlias]?.is_write_index) { @@ -406,7 +406,7 @@ export class ResourceInstaller { logger.debug(`Installing index template ${template.name}`); - const { body: simulateResponse } = await clusterClient.indices.simulateTemplate(template); + const simulateResponse = await clusterClient.indices.simulateTemplate(template); const mappings: estypes.MappingTypeMapping = simulateResponse.template.mappings; if (isEmpty(mappings)) { @@ -434,7 +434,7 @@ export class ResourceInstaller { // finding legacy .siem-signals indices that we add the alias to for backwards compatibility reasons. Together, // the index pattern and alias should ensure that we retrieve only the "new" backing indices for this // particular alias. - const { body: response } = await clusterClient.indices.getAlias({ + const response = await clusterClient.indices.getAlias({ index: indexPatternForBackingIndices, name: aliasOrPatternForAliases, }); diff --git a/x-pack/plugins/saved_objects_tagging/server/usage/fetch_tag_usage_data.ts b/x-pack/plugins/saved_objects_tagging/server/usage/fetch_tag_usage_data.ts index 06230172d52bd..a234fd20f529c 100644 --- a/x-pack/plugins/saved_objects_tagging/server/usage/fetch_tag_usage_data.ts +++ b/x-pack/plugins/saved_objects_tagging/server/usage/fetch_tag_usage_data.ts @@ -36,7 +36,7 @@ export const fetchTagUsageData = async ({ esClient: ElasticsearchClient; kibanaIndex: string; }): Promise => { - const { body } = await esClient.search({ + const body = await esClient.search({ index: [kibanaIndex], ignore_unavailable: true, filter_path: 'aggregations', diff --git a/x-pack/plugins/searchprofiler/server/routes/profile.ts b/x-pack/plugins/searchprofiler/server/routes/profile.ts index cbe0b75bc9eda..22c97e240a3b9 100644 --- a/x-pack/plugins/searchprofiler/server/routes/profile.ts +++ b/x-pack/plugins/searchprofiler/server/routes/profile.ts @@ -49,7 +49,7 @@ export const register = ({ router, getLicenseStatus, log }: RouteDependencies) = return response.ok({ body: { ok: true, - resp: resp.body, + resp, }, }); } catch (err) { diff --git a/x-pack/plugins/security/server/authentication/api_keys/api_keys.test.ts b/x-pack/plugins/security/server/authentication/api_keys/api_keys.test.ts index a1b9671ab6bd7..8b29d5ed17c1c 100644 --- a/x-pack/plugins/security/server/authentication/api_keys/api_keys.test.ts +++ b/x-pack/plugins/security/server/authentication/api_keys/api_keys.test.ts @@ -9,7 +9,6 @@ import { elasticsearchServiceMock, httpServerMock, loggingSystemMock } from 'src import type { SecurityLicense } from '../../../common/licensing'; import { licenseMock } from '../../../common/licensing/index.mock'; -import { securityMock } from '../../mocks'; import { APIKeys } from './api_keys'; const encodeToBase64 = (str: string) => Buffer.from(str).toString('base64'); @@ -63,16 +62,12 @@ describe('API Keys', () => { it('returns true when the operation completes without error', async () => { mockLicense.isEnabled.mockReturnValue(true); - mockClusterClient.asInternalUser.security.invalidateApiKey.mockResolvedValue( - securityMock.createApiResponse({ - body: { - invalidated_api_keys: [], - previously_invalidated_api_keys: [], - error_count: 0, - error_details: [], - }, - }) - ); + mockClusterClient.asInternalUser.security.invalidateApiKey.mockResponse({ + invalidated_api_keys: [], + previously_invalidated_api_keys: [], + error_count: 0, + error_details: [], + }); const result = await apiKeys.areAPIKeysEnabled(); expect(mockClusterClient.asInternalUser.security.invalidateApiKey).toHaveBeenCalledTimes(1); expect(result).toEqual(true); @@ -111,16 +106,12 @@ describe('API Keys', () => { it('calls `invalidateApiKey` with proper parameters', async () => { mockLicense.isEnabled.mockReturnValue(true); - mockClusterClient.asInternalUser.security.invalidateApiKey.mockResolvedValueOnce( - securityMock.createApiResponse({ - body: { - invalidated_api_keys: [], - previously_invalidated_api_keys: [], - error_count: 0, - error_details: [], - }, - }) - ); + mockClusterClient.asInternalUser.security.invalidateApiKey.mockResponseOnce({ + invalidated_api_keys: [], + previously_invalidated_api_keys: [], + error_count: 0, + error_details: [], + }); const result = await apiKeys.areAPIKeysEnabled(); expect(result).toEqual(true); @@ -146,17 +137,13 @@ describe('API Keys', () => { it('calls `createApiKey` with proper parameters', async () => { mockLicense.isEnabled.mockReturnValue(true); - mockScopedClusterClient.asCurrentUser.security.createApiKey.mockResolvedValueOnce( + mockScopedClusterClient.asCurrentUser.security.createApiKey.mockResponseOnce({ + id: '123', + name: 'key-name', // @ts-expect-error @elastic/elsticsearch CreateApiKeyResponse.expiration: number - securityMock.createApiResponse({ - body: { - id: '123', - name: 'key-name', - expiration: '1d', - api_key: 'abc123', - }, - }) - ); + expiration: '1d', + api_key: 'abc123', + }); const result = await apiKeys.create(httpServerMock.createKibanaRequest(), { name: 'key-name', role_descriptors: { foo: true }, @@ -192,16 +179,13 @@ describe('API Keys', () => { it('calls `grantApiKey` with proper parameters for the Basic scheme', async () => { mockLicense.isEnabled.mockReturnValue(true); - mockClusterClient.asInternalUser.security.grantApiKey.mockResolvedValueOnce( - securityMock.createApiResponse({ - body: { - id: '123', - name: 'key-name', - api_key: 'abc123', - expires: '1d', - }, - }) - ); + mockClusterClient.asInternalUser.security.grantApiKey.mockResponseOnce({ + id: '123', + name: 'key-name', + api_key: 'abc123', + // @ts-expect-error invalid definition + expires: '1d', + }); const result = await apiKeys.grantAsInternalUser( httpServerMock.createKibanaRequest({ headers: { @@ -236,15 +220,11 @@ describe('API Keys', () => { it('calls `grantApiKey` with proper parameters for the Bearer scheme', async () => { mockLicense.isEnabled.mockReturnValue(true); - mockClusterClient.asInternalUser.security.grantApiKey.mockResolvedValueOnce( - securityMock.createApiResponse({ - body: { - id: '123', - name: 'key-name', - api_key: 'abc123', - }, - }) - ); + mockClusterClient.asInternalUser.security.grantApiKey.mockResponseOnce({ + id: '123', + name: 'key-name', + api_key: 'abc123', + }); const result = await apiKeys.grantAsInternalUser( httpServerMock.createKibanaRequest({ headers: { @@ -311,16 +291,12 @@ describe('API Keys', () => { it('calls callCluster with proper parameters', async () => { mockLicense.isEnabled.mockReturnValue(true); - mockScopedClusterClient.asCurrentUser.security.invalidateApiKey.mockResolvedValueOnce( - securityMock.createApiResponse({ - body: { - invalidated_api_keys: ['api-key-id-1'], - previously_invalidated_api_keys: [], - error_count: 0, - error_details: [], - }, - }) - ); + mockScopedClusterClient.asCurrentUser.security.invalidateApiKey.mockResponseOnce({ + invalidated_api_keys: ['api-key-id-1'], + previously_invalidated_api_keys: [], + error_count: 0, + error_details: [], + }); const result = await apiKeys.invalidate(httpServerMock.createKibanaRequest(), { ids: ['123'], }); @@ -339,16 +315,12 @@ describe('API Keys', () => { it(`Only passes ids as a parameter`, async () => { mockLicense.isEnabled.mockReturnValue(true); - mockScopedClusterClient.asCurrentUser.security.invalidateApiKey.mockResolvedValueOnce( - securityMock.createApiResponse({ - body: { - invalidated_api_keys: ['api-key-id-1'], - previously_invalidated_api_keys: [], - error_count: 0, - error_details: [], - }, - }) - ); + mockScopedClusterClient.asCurrentUser.security.invalidateApiKey.mockResponseOnce({ + invalidated_api_keys: ['api-key-id-1'], + previously_invalidated_api_keys: [], + error_count: 0, + error_details: [], + }); const result = await apiKeys.invalidate(httpServerMock.createKibanaRequest(), { ids: ['123'], name: 'abc', @@ -377,16 +349,12 @@ describe('API Keys', () => { it('calls callCluster with proper parameters', async () => { mockLicense.isEnabled.mockReturnValue(true); - mockClusterClient.asInternalUser.security.invalidateApiKey.mockResolvedValueOnce( - securityMock.createApiResponse({ - body: { - invalidated_api_keys: ['api-key-id-1'], - previously_invalidated_api_keys: [], - error_count: 0, - error_details: [], - }, - }) - ); + mockClusterClient.asInternalUser.security.invalidateApiKey.mockResponseOnce({ + invalidated_api_keys: ['api-key-id-1'], + previously_invalidated_api_keys: [], + error_count: 0, + error_details: [], + }); const result = await apiKeys.invalidateAsInternalUser({ ids: ['123'] }); expect(result).toEqual({ invalidated_api_keys: ['api-key-id-1'], @@ -403,16 +371,12 @@ describe('API Keys', () => { it('Only passes ids as a parameter', async () => { mockLicense.isEnabled.mockReturnValue(true); - mockClusterClient.asInternalUser.security.invalidateApiKey.mockResolvedValueOnce( - securityMock.createApiResponse({ - body: { - invalidated_api_keys: ['api-key-id-1'], - previously_invalidated_api_keys: [], - error_count: 0, - error_details: [], - }, - }) - ); + mockClusterClient.asInternalUser.security.invalidateApiKey.mockResponseOnce({ + invalidated_api_keys: ['api-key-id-1'], + previously_invalidated_api_keys: [], + error_count: 0, + error_details: [], + }); const result = await apiKeys.invalidateAsInternalUser({ ids: ['123'], name: 'abc', diff --git a/x-pack/plugins/security/server/authentication/api_keys/api_keys.ts b/x-pack/plugins/security/server/authentication/api_keys/api_keys.ts index 65a7972084cb8..6ad05dcf67b77 100644 --- a/x-pack/plugins/security/server/authentication/api_keys/api_keys.ts +++ b/x-pack/plugins/security/server/authentication/api_keys/api_keys.ts @@ -186,11 +186,9 @@ export class APIKeys { // User needs `manage_api_key` privilege to use this API let result: CreateAPIKeyResult; try { - result = ( - await this.clusterClient - .asScoped(request) - .asCurrentUser.security.createApiKey({ body: params }) - ).body; + result = await this.clusterClient + .asScoped(request) + .asCurrentUser.security.createApiKey({ body: params }); this.logger.debug('API key was created successfully'); } catch (e) { this.logger.error(`Failed to create API key: ${e.message}`); @@ -222,12 +220,10 @@ export class APIKeys { // User needs `manage_api_key` or `grant_api_key` privilege to use this API let result: GrantAPIKeyResult; try { - result = ( - await this.clusterClient.asInternalUser.security.grantApiKey({ - // @ts-expect-error @elastic/elasticsearch api_key.role_descriptors doesn't support `Record` - body: params, - }) - ).body; + result = await this.clusterClient.asInternalUser.security.grantApiKey({ + // @ts-expect-error @elastic/elasticsearch api_key.role_descriptors doesn't support `Record` + body: params, + }); this.logger.debug('API key was granted successfully'); } catch (e) { this.logger.error(`Failed to grant API key: ${e.message}`); @@ -252,13 +248,11 @@ export class APIKeys { let result: InvalidateAPIKeyResult; try { // User needs `manage_api_key` privilege to use this API - result = ( - await this.clusterClient.asScoped(request).asCurrentUser.security.invalidateApiKey({ - body: { - ids: params.ids, - }, - }) - ).body; + result = await this.clusterClient.asScoped(request).asCurrentUser.security.invalidateApiKey({ + body: { + ids: params.ids, + }, + }); this.logger.debug( `API keys by ids=[${params.ids.join(', ')}] was invalidated successfully as current user` ); @@ -288,13 +282,11 @@ export class APIKeys { let result: InvalidateAPIKeyResult; try { // Internal user needs `cluster:admin/xpack/security/api_key/invalidate` privilege to use this API - result = ( - await this.clusterClient.asInternalUser.security.invalidateApiKey({ - body: { - ids: params.ids, - }, - }) - ).body; + result = await this.clusterClient.asInternalUser.security.invalidateApiKey({ + body: { + ids: params.ids, + }, + }); this.logger.debug(`API keys by ids=[${params.ids.join(', ')}] was invalidated successfully`); } catch (e) { this.logger.error( diff --git a/x-pack/plugins/security/server/authentication/providers/anonymous.test.ts b/x-pack/plugins/security/server/authentication/providers/anonymous.test.ts index 124cdb0426518..0ed18b1cf5b0a 100644 --- a/x-pack/plugins/security/server/authentication/providers/anonymous.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/anonymous.test.ts @@ -79,9 +79,7 @@ describe('AnonymousAuthenticationProvider', () => { describe('`login` method', () => { it('succeeds if credentials are valid, and creates session and authHeaders', async () => { const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect( @@ -164,9 +162,7 @@ describe('AnonymousAuthenticationProvider', () => { const request = httpServerMock.createKibanaRequest({ headers: {} }); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect(provider.authenticate(request, {})).resolves.toEqual( @@ -180,9 +176,7 @@ describe('AnonymousAuthenticationProvider', () => { const request = httpServerMock.createKibanaRequest({ headers: { 'kbn-xsrf': 'xsrf' } }); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect(provider.authenticate(request, {})).resolves.toEqual( @@ -198,9 +192,7 @@ describe('AnonymousAuthenticationProvider', () => { const request = httpServerMock.createKibanaRequest({ headers: {} }); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect(provider.authenticate(request)).resolves.toEqual( @@ -244,9 +236,7 @@ describe('AnonymousAuthenticationProvider', () => { const request = httpServerMock.createKibanaRequest({ headers: {} }); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect(provider.authenticate(request, {})).resolves.toEqual( diff --git a/x-pack/plugins/security/server/authentication/providers/base.ts b/x-pack/plugins/security/server/authentication/providers/base.ts index d5b173fcfad8c..a6e5e19939c13 100644 --- a/x-pack/plugins/security/server/authentication/providers/base.ts +++ b/x-pack/plugins/security/server/authentication/providers/base.ts @@ -119,11 +119,9 @@ export abstract class BaseAuthenticationProvider { protected async getUser(request: KibanaRequest, authHeaders: Headers = {}) { return this.authenticationInfoToAuthenticatedUser( // @ts-expect-error Metadata is defined as Record - ( - await this.options.client - .asScoped({ headers: { ...request.headers, ...authHeaders } }) - .asCurrentUser.security.authenticate() - ).body + await this.options.client + .asScoped({ headers: { ...request.headers, ...authHeaders } }) + .asCurrentUser.security.authenticate() ); } diff --git a/x-pack/plugins/security/server/authentication/providers/basic.test.ts b/x-pack/plugins/security/server/authentication/providers/basic.test.ts index 025589bd25b40..1a4998bf27cbf 100644 --- a/x-pack/plugins/security/server/authentication/providers/basic.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/basic.test.ts @@ -49,9 +49,7 @@ describe('BasicAuthenticationProvider', () => { const authorization = generateAuthorizationHeader(credentials.username, credentials.password); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect( @@ -159,9 +157,7 @@ describe('BasicAuthenticationProvider', () => { const authorization = generateAuthorizationHeader('user', 'password'); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect(provider.authenticate(request, { authorization })).resolves.toEqual( diff --git a/x-pack/plugins/security/server/authentication/providers/http.test.ts b/x-pack/plugins/security/server/authentication/providers/http.test.ts index 451be10685558..c67ca0cb31160 100644 --- a/x-pack/plugins/security/server/authentication/providers/http.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/http.test.ts @@ -123,9 +123,7 @@ describe('HTTPAuthenticationProvider', () => { const request = httpServerMock.createKibanaRequest({ headers: { authorization: header } }); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); mockOptions.client.asScoped.mockClear(); diff --git a/x-pack/plugins/security/server/authentication/providers/kerberos.test.ts b/x-pack/plugins/security/server/authentication/providers/kerberos.test.ts index f5c02953cebd3..91475a845d8b0 100644 --- a/x-pack/plugins/security/server/authentication/providers/kerberos.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/kerberos.test.ts @@ -45,8 +45,8 @@ describe('KerberosAuthenticationProvider', () => { const request = httpServerMock.createKibanaRequest({ headers: {} }); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: mockAuthenticatedUser() }) + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse( + mockAuthenticatedUser() ); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); @@ -121,15 +121,13 @@ describe('KerberosAuthenticationProvider', () => { headers: { authorization: 'negotiate spnego' }, }); - mockOptions.client.asInternalUser.security.getToken.mockResolvedValue( + mockOptions.client.asInternalUser.security.getToken.mockResponse( // @ts-expect-error not full interface - securityMock.createApiResponse({ - body: { - access_token: 'some-token', - refresh_token: 'some-refresh-token', - authentication: user, - }, - }) + { + access_token: 'some-token', + refresh_token: 'some-refresh-token', + authentication: user, + } ); await expect(operation(request)).resolves.toEqual( @@ -156,16 +154,14 @@ describe('KerberosAuthenticationProvider', () => { headers: { authorization: 'negotiate spnego' }, }); - mockOptions.client.asInternalUser.security.getToken.mockResolvedValue( + mockOptions.client.asInternalUser.security.getToken.mockResponse( // @ts-expect-error not full interface - securityMock.createApiResponse({ - body: { - access_token: 'some-token', - refresh_token: 'some-refresh-token', - kerberos_authentication_response_token: 'response-token', - authentication: user, - }, - }) + { + access_token: 'some-token', + refresh_token: 'some-refresh-token', + kerberos_authentication_response_token: 'response-token', + authentication: user, + } ); await expect(operation(request)).resolves.toEqual( @@ -347,9 +343,7 @@ describe('KerberosAuthenticationProvider', () => { const authorization = `Bearer ${tokenPair.accessToken}`; const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect(provider.authenticate(request, tokenPair)).resolves.toEqual( diff --git a/x-pack/plugins/security/server/authentication/providers/kerberos.ts b/x-pack/plugins/security/server/authentication/providers/kerberos.ts index 75dc2a8f47969..5cb1b01dddf9a 100644 --- a/x-pack/plugins/security/server/authentication/providers/kerberos.ts +++ b/x-pack/plugins/security/server/authentication/providers/kerberos.ts @@ -156,14 +156,12 @@ export class KerberosAuthenticationProvider extends BaseAuthenticationProvider { }; try { // @ts-expect-error authentication.email can be optional - tokens = ( - await this.options.client.asInternalUser.security.getToken({ - body: { - grant_type: '_kerberos', - kerberos_ticket: kerberosTicket, - }, - }) - ).body; + tokens = await this.options.client.asInternalUser.security.getToken({ + body: { + grant_type: '_kerberos', + kerberos_ticket: kerberosTicket, + }, + }); } catch (err) { this.logger.debug( `Failed to exchange SPNEGO token for an access token: ${getDetailedErrorMessage(err)}` diff --git a/x-pack/plugins/security/server/authentication/providers/oidc.test.ts b/x-pack/plugins/security/server/authentication/providers/oidc.test.ts index 66af74f86c7c2..c21327fe0674a 100644 --- a/x-pack/plugins/security/server/authentication/providers/oidc.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/oidc.test.ts @@ -37,9 +37,7 @@ describe('OIDCAuthenticationProvider', () => { mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); mockUser = mockAuthenticatedUser({ authentication_provider: { type: 'oidc', name: 'oidc' } }); mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: mockUser }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(mockUser); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); provider = new OIDCAuthenticationProvider(mockOptions, { realm: 'oidc1' }); @@ -63,21 +61,17 @@ describe('OIDCAuthenticationProvider', () => { it('redirects third party initiated login attempts to the OpenId Connect Provider.', async () => { const request = httpServerMock.createKibanaRequest({ path: '/api/security/oidc/callback' }); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - state: 'statevalue', - nonce: 'noncevalue', - redirect: - 'https://op-host/path/login?response_type=code' + - '&scope=openid%20profile%20email' + - '&client_id=s6BhdRkqt3' + - '&state=statevalue' + - '&redirect_uri=https%3A%2F%2Ftest-hostname:1234%2Ftest-base-path%2Fapi%2Fsecurity%2Fv1%2F/oidc' + - '&login_hint=loginhint', - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + state: 'statevalue', + nonce: 'noncevalue', + redirect: + 'https://op-host/path/login?response_type=code' + + '&scope=openid%20profile%20email' + + '&client_id=s6BhdRkqt3' + + '&state=statevalue' + + '&redirect_uri=https%3A%2F%2Ftest-hostname:1234%2Ftest-base-path%2Fapi%2Fsecurity%2Fv1%2F/oidc' + + '&login_hint=loginhint', + }); await expect( provider.login(request, { @@ -115,21 +109,17 @@ describe('OIDCAuthenticationProvider', () => { it('redirects user initiated login attempts to the OpenId Connect Provider.', async () => { const request = httpServerMock.createKibanaRequest(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - state: 'statevalue', - nonce: 'noncevalue', - redirect: - 'https://op-host/path/login?response_type=code' + - '&scope=openid%20profile%20email' + - '&client_id=s6BhdRkqt3' + - '&state=statevalue' + - '&redirect_uri=https%3A%2F%2Ftest-hostname:1234%2Ftest-base-path%2Fapi%2Fsecurity%2Fv1%2F/oidc' + - '&login_hint=loginhint', - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + state: 'statevalue', + nonce: 'noncevalue', + redirect: + 'https://op-host/path/login?response_type=code' + + '&scope=openid%20profile%20email' + + '&client_id=s6BhdRkqt3' + + '&state=statevalue' + + '&redirect_uri=https%3A%2F%2Ftest-hostname:1234%2Ftest-base-path%2Fapi%2Fsecurity%2Fv1%2F/oidc' + + '&login_hint=loginhint', + }); await expect( provider.login(request, { @@ -196,15 +186,11 @@ describe('OIDCAuthenticationProvider', () => { it('gets token and redirects user to requested URL if OIDC authentication response is valid.', async () => { const { request, attempt, expectedRedirectURI } = getMocks(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - authentication: mockUser, - access_token: 'some-token', - refresh_token: 'some-refresh-token', - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + authentication: mockUser, + access_token: 'some-token', + refresh_token: 'some-refresh-token', + }); await expect( provider.login(request, attempt, { @@ -401,21 +387,17 @@ describe('OIDCAuthenticationProvider', () => { it('initiates OIDC handshake for non-AJAX request that can not be authenticated, but includes URL hash fragment.', async () => { mockOptions.getRequestOriginalURL.mockReturnValue('/mock-server-basepath/s/foo/some-path'); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - state: 'statevalue', - nonce: 'noncevalue', - redirect: - 'https://op-host/path/login?response_type=code' + - '&scope=openid%20profile%20email' + - '&client_id=s6BhdRkqt3' + - '&state=statevalue' + - '&redirect_uri=https%3A%2F%2Ftest-hostname:1234%2Ftest-base-path%2Fapi%2Fsecurity%2Fv1%2F/oidc' + - '&login_hint=loginhint', - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + state: 'statevalue', + nonce: 'noncevalue', + redirect: + 'https://op-host/path/login?response_type=code' + + '&scope=openid%20profile%20email' + + '&client_id=s6BhdRkqt3' + + '&state=statevalue' + + '&redirect_uri=https%3A%2F%2Ftest-hostname:1234%2Ftest-base-path%2Fapi%2Fsecurity%2Fv1%2F/oidc' + + '&login_hint=loginhint', + }); const request = httpServerMock.createKibanaRequest({ path: '/s/foo/some-path', @@ -742,9 +724,7 @@ describe('OIDCAuthenticationProvider', () => { const accessToken = 'x-oidc-token'; const refreshToken = 'x-oidc-refresh-token'; - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ body: { redirect: null } }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ redirect: null }); await expect( provider.logout(request, { accessToken, refreshToken, realm: 'oidc1' }) @@ -763,11 +743,9 @@ describe('OIDCAuthenticationProvider', () => { const accessToken = 'x-oidc-token'; const refreshToken = 'x-oidc-refresh-token'; - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { redirect: 'http://fake-idp/logout&id_token_hint=thehint' }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + redirect: 'http://fake-idp/logout&id_token_hint=thehint', + }); await expect( provider.logout(request, { accessToken, refreshToken, realm: 'oidc1' }) diff --git a/x-pack/plugins/security/server/authentication/providers/oidc.ts b/x-pack/plugins/security/server/authentication/providers/oidc.ts index 83f0ec50abb0d..cad10be6b4aa2 100644 --- a/x-pack/plugins/security/server/authentication/providers/oidc.ts +++ b/x-pack/plugins/security/server/authentication/providers/oidc.ts @@ -256,18 +256,16 @@ export class OIDCAuthenticationProvider extends BaseAuthenticationProvider { // user usually doesn't have `cluster:admin/xpack/security/oidc/authenticate`. // We can replace generic `transport.request` with a dedicated API method call once // https://github.com/elastic/elasticsearch/issues/67189 is resolved. - result = ( - await this.options.client.asInternalUser.transport.request({ - method: 'POST', - path: '/_security/oidc/authenticate', - body: { - state: stateOIDCState, - nonce: stateNonce, - redirect_uri: authenticationResponseURI, - realm: this.realm, - }, - }) - ).body as any; + result = (await this.options.client.asInternalUser.transport.request({ + method: 'POST', + path: '/_security/oidc/authenticate', + body: { + state: stateOIDCState, + nonce: stateNonce, + redirect_uri: authenticationResponseURI, + realm: this.realm, + }, + })) as any; } catch (err) { this.logger.debug( `Failed to authenticate request via OpenID Connect: ${getDetailedErrorMessage(err)}` @@ -305,13 +303,12 @@ export class OIDCAuthenticationProvider extends BaseAuthenticationProvider { // user usually doesn't have `cluster:admin/xpack/security/oidc/prepare`. // We can replace generic `transport.request` with a dedicated API method call once // https://github.com/elastic/elasticsearch/issues/67189 is resolved. - const { state, nonce, redirect } = ( - await this.options.client.asInternalUser.transport.request({ + const { state, nonce, redirect } = + (await this.options.client.asInternalUser.transport.request({ method: 'POST', path: '/_security/oidc/prepare', body: params, - }) - ).body as any; + })) as any; this.logger.debug('Redirecting to OpenID Connect Provider with authentication request.'); return AuthenticationResult.redirectTo( @@ -433,13 +430,11 @@ export class OIDCAuthenticationProvider extends BaseAuthenticationProvider { // user usually doesn't have `cluster:admin/xpack/security/oidc/logout`. // We can replace generic `transport.request` with a dedicated API method call once // https://github.com/elastic/elasticsearch/issues/67189 is resolved. - const { redirect } = ( - await this.options.client.asInternalUser.transport.request({ - method: 'POST', - path: '/_security/oidc/logout', - body: { token: state.accessToken, refresh_token: state.refreshToken }, - }) - ).body as any; + const { redirect } = (await this.options.client.asInternalUser.transport.request({ + method: 'POST', + path: '/_security/oidc/logout', + body: { token: state.accessToken, refresh_token: state.refreshToken }, + })) as any; this.logger.debug('User session has been successfully invalidated.'); diff --git a/x-pack/plugins/security/server/authentication/providers/pki.test.ts b/x-pack/plugins/security/server/authentication/providers/pki.test.ts index 4ad6fe61e259c..04d7013e496b7 100644 --- a/x-pack/plugins/security/server/authentication/providers/pki.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/pki.test.ts @@ -251,11 +251,10 @@ describe('PKIAuthenticationProvider', () => { mockGetPeerCertificate.mockReturnValueOnce(peerCertificate1); const request = httpServerMock.createKibanaRequest({ socket }); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { authentication: user, access_token: 'access-token' }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + authentication: user, + access_token: 'access-token', + }); await expect(operation(request)).resolves.toEqual( AuthenticationResult.succeeded( @@ -296,11 +295,10 @@ describe('PKIAuthenticationProvider', () => { const { socket } = getMockSocket({ authorized: true, peerCertificate }); const request = httpServerMock.createKibanaRequest({ socket, headers: {} }); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { authentication: user, access_token: 'access-token' }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + authentication: user, + access_token: 'access-token', + }); await expect(operation(request)).resolves.toEqual( AuthenticationResult.succeeded( @@ -334,11 +332,10 @@ describe('PKIAuthenticationProvider', () => { const { socket } = getMockSocket({ authorized: true, peerCertificate }); const request = httpServerMock.createKibanaRequest({ socket, headers: {} }); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { authentication: user, access_token: 'access-token' }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + authentication: user, + access_token: 'access-token', + }); await expect(operation(request)).resolves.toEqual( AuthenticationResult.succeeded( @@ -501,11 +498,10 @@ describe('PKIAuthenticationProvider', () => { const request = httpServerMock.createKibanaRequest({ socket }); const state = { accessToken: 'existing-token', peerCertificateFingerprint256: '3A:9A:C5:DD' }; - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { authentication: user, access_token: 'access-token' }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + authentication: user, + access_token: 'access-token', + }); await expect(provider.authenticate(request, state)).resolves.toEqual( AuthenticationResult.succeeded( @@ -545,11 +541,10 @@ describe('PKIAuthenticationProvider', () => { new errors.ResponseError(securityMock.createApiResponse({ statusCode: 401, body: {} })) ); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { authentication: user, access_token: 'access-token' }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + authentication: user, + access_token: 'access-token', + }); const nonAjaxRequest = httpServerMock.createKibanaRequest({ socket: getMockSocket({ @@ -669,9 +664,7 @@ describe('PKIAuthenticationProvider', () => { const request = httpServerMock.createKibanaRequest({ socket, headers: {} }); const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect(provider.authenticate(request, state)).resolves.toEqual( diff --git a/x-pack/plugins/security/server/authentication/providers/pki.ts b/x-pack/plugins/security/server/authentication/providers/pki.ts index 0c002f005bce3..1bb02671b97be 100644 --- a/x-pack/plugins/security/server/authentication/providers/pki.ts +++ b/x-pack/plugins/security/server/authentication/providers/pki.ts @@ -277,13 +277,11 @@ export class PKIAuthenticationProvider extends BaseAuthenticationProvider { try { // We can replace generic `transport.request` with a dedicated API method call once // https://github.com/elastic/elasticsearch/issues/67189 is resolved. - result = ( - await this.options.client.asInternalUser.transport.request({ - method: 'POST', - path: '/_security/delegate_pki', - body: { x509_certificate_chain: certificateChain }, - }) - ).body as any; + result = (await this.options.client.asInternalUser.transport.request({ + method: 'POST', + path: '/_security/delegate_pki', + body: { x509_certificate_chain: certificateChain }, + })) as any; } catch (err) { this.logger.debug( `Failed to exchange peer certificate chain to an access token: ${err.message}` diff --git a/x-pack/plugins/security/server/authentication/providers/saml.test.ts b/x-pack/plugins/security/server/authentication/providers/saml.test.ts index 251a59228fb03..046ae16c7e318 100644 --- a/x-pack/plugins/security/server/authentication/providers/saml.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/saml.test.ts @@ -34,9 +34,7 @@ describe('SAMLAuthenticationProvider', () => { mockUser = mockAuthenticatedUser({ authentication_provider: { type: 'saml', name: 'saml' } }); mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: mockUser }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(mockUser); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); provider = new SAMLAuthenticationProvider(mockOptions); @@ -46,16 +44,12 @@ describe('SAMLAuthenticationProvider', () => { it('gets token and redirects user to requested URL if SAML Response is valid.', async () => { const request = httpServerMock.createKibanaRequest(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - access_token: 'some-token', - refresh_token: 'some-refresh-token', - realm: 'test-realm', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + access_token: 'some-token', + refresh_token: 'some-refresh-token', + realm: 'test-realm', + authentication: mockUser, + }); await expect( provider.login( @@ -88,16 +82,12 @@ describe('SAMLAuthenticationProvider', () => { it('gets token and redirects user to the requested URL if SAML Response is valid ignoring Relay State.', async () => { const request = httpServerMock.createKibanaRequest(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - access_token: 'some-token', - refresh_token: 'some-refresh-token', - realm: 'test-realm', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + access_token: 'some-token', + refresh_token: 'some-refresh-token', + realm: 'test-realm', + authentication: mockUser, + }); provider = new SAMLAuthenticationProvider(mockOptions, { useRelayStateDeepLink: true, @@ -179,16 +169,12 @@ describe('SAMLAuthenticationProvider', () => { it('redirects to the default location if state contains empty redirect URL.', async () => { const request = httpServerMock.createKibanaRequest(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - access_token: 'user-initiated-login-token', - refresh_token: 'user-initiated-login-refresh-token', - realm: 'test-realm', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + access_token: 'user-initiated-login-token', + refresh_token: 'user-initiated-login-refresh-token', + realm: 'test-realm', + authentication: mockUser, + }); await expect( provider.login( @@ -217,16 +203,12 @@ describe('SAMLAuthenticationProvider', () => { it('redirects to the default location if state contains empty redirect URL ignoring Relay State.', async () => { const request = httpServerMock.createKibanaRequest(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - access_token: 'user-initiated-login-token', - refresh_token: 'user-initiated-login-refresh-token', - realm: 'test-realm', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + access_token: 'user-initiated-login-token', + refresh_token: 'user-initiated-login-refresh-token', + realm: 'test-realm', + authentication: mockUser, + }); provider = new SAMLAuthenticationProvider(mockOptions, { useRelayStateDeepLink: true, @@ -262,16 +244,12 @@ describe('SAMLAuthenticationProvider', () => { it('redirects to the default location if state is not presented.', async () => { const request = httpServerMock.createKibanaRequest(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - realm: 'test-realm', - access_token: 'idp-initiated-login-token', - refresh_token: 'idp-initiated-login-refresh-token', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + realm: 'test-realm', + access_token: 'idp-initiated-login-token', + refresh_token: 'idp-initiated-login-refresh-token', + authentication: mockUser, + }); await expect( provider.login(request, { @@ -327,17 +305,13 @@ describe('SAMLAuthenticationProvider', () => { beforeEach(() => { mockOptions.basePath.get.mockReturnValue(mockOptions.basePath.serverBasePath); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - username: 'user', - access_token: 'valid-token', - refresh_token: 'valid-refresh-token', - realm: 'test-realm', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + username: 'user', + access_token: 'valid-token', + refresh_token: 'valid-refresh-token', + realm: 'test-realm', + authentication: mockUser, + }); provider = new SAMLAuthenticationProvider(mockOptions, { useRelayStateDeepLink: true, @@ -547,16 +521,12 @@ describe('SAMLAuthenticationProvider', () => { }; const authorization = `Bearer ${state.accessToken}`; - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - username: 'user', - access_token: 'new-valid-token', - refresh_token: 'new-valid-refresh-token', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + username: 'user', + access_token: 'new-valid-token', + refresh_token: 'new-valid-refresh-token', + authentication: mockUser, + }); const failureReason = new Error('Failed to invalidate token!'); mockOptions.tokens.invalidate.mockRejectedValue(failureReason); @@ -614,17 +584,13 @@ describe('SAMLAuthenticationProvider', () => { mockScopedClusterClient.asCurrentUser.security.authenticate.mockImplementationOnce( () => response ); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - username: 'user', - access_token: 'new-valid-token', - refresh_token: 'new-valid-refresh-token', - realm: 'test-realm', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + username: 'user', + access_token: 'new-valid-token', + refresh_token: 'new-valid-refresh-token', + realm: 'test-realm', + authentication: mockUser, + }); mockOptions.tokens.invalidate.mockResolvedValue(undefined); await expect( @@ -671,17 +637,13 @@ describe('SAMLAuthenticationProvider', () => { mockScopedClusterClient.asCurrentUser.security.authenticate.mockImplementationOnce( () => response ); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - username: 'user', - access_token: 'new-valid-token', - refresh_token: 'new-valid-refresh-token', - realm: 'test-realm', - authentication: mockUser, - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + username: 'user', + access_token: 'new-valid-token', + refresh_token: 'new-valid-refresh-token', + realm: 'test-realm', + authentication: mockUser, + }); mockOptions.tokens.invalidate.mockResolvedValue(undefined); @@ -747,15 +709,11 @@ describe('SAMLAuthenticationProvider', () => { it('redirects requests to the IdP remembering redirect URL with existing state.', async () => { const request = httpServerMock.createKibanaRequest(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - id: 'some-request-id', - redirect: 'https://idp-host/path/login?SAMLRequest=some%20request%20', - realm: 'test-realm', - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + id: 'some-request-id', + redirect: 'https://idp-host/path/login?SAMLRequest=some%20request%20', + realm: 'test-realm', + }); await expect( provider.login(request, { @@ -789,15 +747,11 @@ describe('SAMLAuthenticationProvider', () => { it('redirects requests to the IdP remembering redirect URL without state.', async () => { const request = httpServerMock.createKibanaRequest(); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - id: 'some-request-id', - redirect: 'https://idp-host/path/login?SAMLRequest=some%20request%20', - realm: 'test-realm', - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + id: 'some-request-id', + redirect: 'https://idp-host/path/login?SAMLRequest=some%20request%20', + realm: 'test-realm', + }); await expect( provider.login( @@ -841,15 +795,11 @@ describe('SAMLAuthenticationProvider', () => { realm: 'test-realm', }); - customMockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - id: 'some-request-id', - redirect: 'https://idp-host/path/login?SAMLRequest=some%20request%20', - realm: 'test-realm', - }, - }) - ); + customMockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + id: 'some-request-id', + redirect: 'https://idp-host/path/login?SAMLRequest=some%20request%20', + realm: 'test-realm', + }); await expect( provider.login( @@ -974,14 +924,10 @@ describe('SAMLAuthenticationProvider', () => { it('initiates SAML handshake for non-AJAX request that can not be authenticated, but includes URL hash fragment.', async () => { mockOptions.getRequestOriginalURL.mockReturnValue('/mock-server-basepath/s/foo/some-path'); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { - id: 'some-request-id', - redirect: 'https://idp-host/path/login?SAMLRequest=some%20request%20', - }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + id: 'some-request-id', + redirect: 'https://idp-host/path/login?SAMLRequest=some%20request%20', + }); const request = httpServerMock.createKibanaRequest({ path: '/s/foo/some-path', @@ -1307,9 +1253,7 @@ describe('SAMLAuthenticationProvider', () => { const accessToken = 'x-saml-token'; const refreshToken = 'x-saml-refresh-token'; - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ body: { redirect: null } }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ redirect: null }); await expect( provider.logout(request, { @@ -1332,9 +1276,9 @@ describe('SAMLAuthenticationProvider', () => { const accessToken = 'x-saml-token'; const refreshToken = 'x-saml-refresh-token'; - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ body: { redirect: undefined } }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + redirect: undefined, + }); await expect( provider.logout(request, { @@ -1359,9 +1303,7 @@ describe('SAMLAuthenticationProvider', () => { const accessToken = 'x-saml-token'; const refreshToken = 'x-saml-refresh-token'; - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ body: { redirect: null } }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ redirect: null }); await expect( provider.logout(request, { @@ -1382,9 +1324,7 @@ describe('SAMLAuthenticationProvider', () => { it('relies on SAML invalidate call even if access token is presented.', async () => { const request = httpServerMock.createKibanaRequest({ query: { SAMLRequest: 'xxx yyy' } }); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ body: { redirect: null } }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ redirect: null }); await expect( provider.logout(request, { @@ -1405,9 +1345,7 @@ describe('SAMLAuthenticationProvider', () => { it('redirects to `loggedOut` URL if `redirect` field in SAML invalidate response is null.', async () => { const request = httpServerMock.createKibanaRequest({ query: { SAMLRequest: 'xxx yyy' } }); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ body: { redirect: null } }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ redirect: null }); await expect(provider.logout(request)).resolves.toEqual( DeauthenticationResult.redirectTo(mockOptions.urls.loggedOut(request)) @@ -1427,9 +1365,9 @@ describe('SAMLAuthenticationProvider', () => { it('redirects to `loggedOut` URL if `redirect` field in SAML invalidate response is not defined.', async () => { const request = httpServerMock.createKibanaRequest({ query: { SAMLRequest: 'xxx yyy' } }); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ body: { redirect: undefined } }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + redirect: undefined, + }); await expect(provider.logout(request)).resolves.toEqual( DeauthenticationResult.redirectTo(mockOptions.urls.loggedOut(request)) @@ -1461,11 +1399,9 @@ describe('SAMLAuthenticationProvider', () => { const accessToken = 'x-saml-token'; const refreshToken = 'x-saml-refresh-token'; - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { redirect: 'http://fake-idp/SLO?SAMLRequest=7zlH37H' }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + redirect: 'http://fake-idp/SLO?SAMLRequest=7zlH37H', + }); await expect( provider.logout(request, { @@ -1483,11 +1419,9 @@ describe('SAMLAuthenticationProvider', () => { it('redirects user to the IdP if SLO is supported by IdP in case of IdP initiated logout.', async () => { const request = httpServerMock.createKibanaRequest({ query: { SAMLRequest: 'xxx yyy' } }); - mockOptions.client.asInternalUser.transport.request.mockResolvedValue( - securityMock.createApiResponse({ - body: { redirect: 'http://fake-idp/SLO?SAMLRequest=7zlH37H' }, - }) - ); + mockOptions.client.asInternalUser.transport.request.mockResolvedValue({ + redirect: 'http://fake-idp/SLO?SAMLRequest=7zlH37H', + }); await expect( provider.logout(request, { diff --git a/x-pack/plugins/security/server/authentication/providers/saml.ts b/x-pack/plugins/security/server/authentication/providers/saml.ts index 4b8d30d8a2f18..fc9704747cf95 100644 --- a/x-pack/plugins/security/server/authentication/providers/saml.ts +++ b/x-pack/plugins/security/server/authentication/providers/saml.ts @@ -365,17 +365,15 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { // user usually doesn't have `cluster:admin/xpack/security/saml/authenticate`. // We can replace generic `transport.request` with a dedicated API method call once // https://github.com/elastic/elasticsearch/issues/67189 is resolved. - result = ( - await this.options.client.asInternalUser.transport.request({ - method: 'POST', - path: '/_security/saml/authenticate', - body: { - ids: !isIdPInitiatedLogin ? [stateRequestId] : [], - content: samlResponse, - ...(providerRealm ? { realm: providerRealm } : {}), - }, - }) - ).body as any; + result = (await this.options.client.asInternalUser.transport.request({ + method: 'POST', + path: '/_security/saml/authenticate', + body: { + ids: !isIdPInitiatedLogin ? [stateRequestId] : [], + content: samlResponse, + ...(providerRealm ? { realm: providerRealm } : {}), + }, + })) as any; } catch (err) { this.logger.debug(`Failed to log in with SAML response: ${getDetailedErrorMessage(err)}`); @@ -580,13 +578,11 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { id: requestId, redirect, realm, - } = ( - await this.options.client.asInternalUser.transport.request({ - method: 'POST', - path: '/_security/saml/prepare', - body: preparePayload, - }) - ).body as any; + } = (await this.options.client.asInternalUser.transport.request({ + method: 'POST', + path: '/_security/saml/prepare', + body: preparePayload, + })) as any; this.logger.debug('Redirecting to Identity Provider with SAML request.'); @@ -612,13 +608,11 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { // user usually doesn't have `cluster:admin/xpack/security/saml/logout`. // We can replace generic `transport.request` with a dedicated API method call once // https://github.com/elastic/elasticsearch/issues/67189 is resolved. - const { redirect } = ( - await this.options.client.asInternalUser.transport.request({ - method: 'POST', - path: '/_security/saml/logout', - body: { token: accessToken, refresh_token: refreshToken }, - }) - ).body as any; + const { redirect } = (await this.options.client.asInternalUser.transport.request({ + method: 'POST', + path: '/_security/saml/logout', + body: { token: accessToken, refresh_token: refreshToken }, + })) as any; this.logger.debug('User session has been successfully invalidated.'); @@ -641,17 +635,15 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { // user usually doesn't have `cluster:admin/xpack/security/saml/invalidate`. // We can replace generic `transport.request` with a dedicated API method call once // https://github.com/elastic/elasticsearch/issues/67189 is resolved. - const { redirect } = ( - await this.options.client.asInternalUser.transport.request({ - method: 'POST', - path: '/_security/saml/invalidate', - // Elasticsearch expects `query_string` without leading `?`, so we should strip it with `slice`. - body: { - query_string: request.url.search ? request.url.search.slice(1) : '', - ...invalidatePayload, - }, - }) - ).body as any; + const { redirect } = (await this.options.client.asInternalUser.transport.request({ + method: 'POST', + path: '/_security/saml/invalidate', + // Elasticsearch expects `query_string` without leading `?`, so we should strip it with `slice`. + body: { + query_string: request.url.search ? request.url.search.slice(1) : '', + ...invalidatePayload, + }, + })) as any; this.logger.debug('User session has been successfully invalidated.'); diff --git a/x-pack/plugins/security/server/authentication/providers/token.test.ts b/x-pack/plugins/security/server/authentication/providers/token.test.ts index 84a1649540267..989fc717d003d 100644 --- a/x-pack/plugins/security/server/authentication/providers/token.test.ts +++ b/x-pack/plugins/security/server/authentication/providers/token.test.ts @@ -49,15 +49,13 @@ describe('TokenAuthenticationProvider', () => { const tokenPair = { accessToken: 'foo', refreshToken: 'bar' }; const authorization = `Bearer ${tokenPair.accessToken}`; - mockOptions.client.asInternalUser.security.getToken.mockResolvedValue( + mockOptions.client.asInternalUser.security.getToken.mockResponse( // @ts-expect-error not full interface - securityMock.createApiResponse({ - body: { - access_token: tokenPair.accessToken, - refresh_token: tokenPair.refreshToken, - authentication: user, - }, - }) + { + access_token: tokenPair.accessToken, + refresh_token: tokenPair.refreshToken, + authentication: user, + } ); await expect(provider.login(request, credentials)).resolves.toEqual( @@ -163,9 +161,7 @@ describe('TokenAuthenticationProvider', () => { const authorization = `Bearer ${tokenPair.accessToken}`; const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.authenticate.mockResolvedValue( - securityMock.createApiResponse({ body: user }) - ); + mockScopedClusterClient.asCurrentUser.security.authenticate.mockResponse(user); mockOptions.client.asScoped.mockReturnValue(mockScopedClusterClient); await expect(provider.authenticate(request, tokenPair)).resolves.toEqual( diff --git a/x-pack/plugins/security/server/authentication/providers/token.ts b/x-pack/plugins/security/server/authentication/providers/token.ts index fae0d7ca69038..c66ab7e80332d 100644 --- a/x-pack/plugins/security/server/authentication/providers/token.ts +++ b/x-pack/plugins/security/server/authentication/providers/token.ts @@ -71,15 +71,13 @@ export class TokenAuthenticationProvider extends BaseAuthenticationProvider { access_token: accessToken, refresh_token: refreshToken, authentication: authenticationInfo, - } = ( - await this.options.client.asInternalUser.security.getToken({ - body: { - grant_type: 'password', - username, - password, - }, - }) - ).body; + } = await this.options.client.asInternalUser.security.getToken({ + body: { + grant_type: 'password', + username, + password, + }, + }); this.logger.debug('Get token API request to Elasticsearch successful'); return AuthenticationResult.succeeded( diff --git a/x-pack/plugins/security/server/authentication/tokens.test.ts b/x-pack/plugins/security/server/authentication/tokens.test.ts index d02b368635e6f..e86b441826e54 100644 --- a/x-pack/plugins/security/server/authentication/tokens.test.ts +++ b/x-pack/plugins/security/server/authentication/tokens.test.ts @@ -7,8 +7,6 @@ import { errors } from '@elastic/elasticsearch'; -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import type { ElasticsearchClient } from 'src/core/server'; import { elasticsearchServiceMock, loggingSystemMock } from 'src/core/server/mocks'; import { mockAuthenticatedUser } from '../../common/model/authenticated_user.mock'; @@ -17,7 +15,9 @@ import { Tokens } from './tokens'; describe('Tokens', () => { let tokens: Tokens; - let mockElasticsearchClient: DeeplyMockedKeys; + let mockElasticsearchClient: ReturnType< + typeof elasticsearchServiceMock.createElasticsearchClient + >; beforeEach(() => { mockElasticsearchClient = elasticsearchServiceMock.createElasticsearchClient(); @@ -103,18 +103,14 @@ describe('Tokens', () => { it('returns token pair if refresh API call succeeds', async () => { const authenticationInfo = mockAuthenticatedUser(); const tokenPair = { accessToken: 'access-token', refreshToken: 'refresh-token' }; - mockElasticsearchClient.security.getToken.mockResolvedValue( - securityMock.createApiResponse({ - body: { - access_token: tokenPair.accessToken, - refresh_token: tokenPair.refreshToken, - authentication: authenticationInfo, - type: 'Bearer', - expires_in: 1200, - scope: 'FULL', - }, - }) - ); + mockElasticsearchClient.security.getToken.mockResponse({ + access_token: tokenPair.accessToken, + refresh_token: tokenPair.refreshToken, + authentication: authenticationInfo, + type: 'Bearer', + expires_in: 1200, + scope: 'FULL', + }); await expect(tokens.refresh(refreshToken)).resolves.toEqual({ authenticationInfo, @@ -199,16 +195,12 @@ describe('Tokens', () => { it('invalidates all provided tokens', async () => { const tokenPair = { accessToken: 'foo', refreshToken: 'bar' }; - mockElasticsearchClient.security.invalidateToken.mockResolvedValue( - securityMock.createApiResponse({ - body: { - invalidated_tokens: 1, - previously_invalidated_tokens: 0, - error_count: 0, - error_details: [], - }, - }) - ); + mockElasticsearchClient.security.invalidateToken.mockResponse({ + invalidated_tokens: 1, + previously_invalidated_tokens: 0, + error_count: 0, + error_details: [], + }); await expect(tokens.invalidate(tokenPair)).resolves.toBe(undefined); @@ -224,16 +216,12 @@ describe('Tokens', () => { it('invalidates only access token if only access token is provided', async () => { const tokenPair = { accessToken: 'foo' }; - mockElasticsearchClient.security.invalidateToken.mockResolvedValue( - securityMock.createApiResponse({ - body: { - invalidated_tokens: 1, - previously_invalidated_tokens: 0, - error_count: 0, - error_details: [], - }, - }) - ); + mockElasticsearchClient.security.invalidateToken.mockResponse({ + invalidated_tokens: 1, + previously_invalidated_tokens: 0, + error_count: 0, + error_details: [], + }); await expect(tokens.invalidate(tokenPair)).resolves.toBe(undefined); @@ -246,16 +234,12 @@ describe('Tokens', () => { it('invalidates only refresh token if only refresh token is provided', async () => { const tokenPair = { refreshToken: 'foo' }; - mockElasticsearchClient.security.invalidateToken.mockResolvedValue( - securityMock.createApiResponse({ - body: { - invalidated_tokens: 1, - previously_invalidated_tokens: 0, - error_count: 0, - error_details: [], - }, - }) - ); + mockElasticsearchClient.security.invalidateToken.mockResponse({ + invalidated_tokens: 1, + previously_invalidated_tokens: 0, + error_count: 0, + error_details: [], + }); await expect(tokens.invalidate(tokenPair)).resolves.toBe(undefined); @@ -297,16 +281,12 @@ describe('Tokens', () => { it('does not fail if more than one token per access or refresh token were invalidated', async () => { const tokenPair = { accessToken: 'foo', refreshToken: 'bar' }; - mockElasticsearchClient.security.invalidateToken.mockResolvedValue( - securityMock.createApiResponse({ - body: { - invalidated_tokens: 5, - previously_invalidated_tokens: 0, - error_count: 0, - error_details: [], - }, - }) - ); + mockElasticsearchClient.security.invalidateToken.mockResponse({ + invalidated_tokens: 5, + previously_invalidated_tokens: 0, + error_count: 0, + error_details: [], + }); await expect(tokens.invalidate(tokenPair)).resolves.toBe(undefined); diff --git a/x-pack/plugins/security/server/authentication/tokens.ts b/x-pack/plugins/security/server/authentication/tokens.ts index 47051cc08da23..2629807e8d3ab 100644 --- a/x-pack/plugins/security/server/authentication/tokens.ts +++ b/x-pack/plugins/security/server/authentication/tokens.ts @@ -59,14 +59,12 @@ export class Tokens { access_token: accessToken, refresh_token: refreshToken, authentication: authenticationInfo, - } = ( - await this.options.client.security.getToken({ - body: { - grant_type: 'refresh_token', - refresh_token: existingRefreshToken, - }, - }) - ).body; + } = await this.options.client.security.getToken({ + body: { + grant_type: 'refresh_token', + refresh_token: existingRefreshToken, + }, + }); this.logger.debug('Access token has been successfully refreshed.'); @@ -118,10 +116,10 @@ export class Tokens { let invalidatedTokensCount; try { invalidatedTokensCount = ( - await this.options.client.security.invalidateToken<{ invalidated_tokens: number }>({ + await this.options.client.security.invalidateToken({ body: { refresh_token: refreshToken }, }) - ).body.invalidated_tokens; + ).invalidated_tokens; } catch (err) { this.logger.debug(`Failed to invalidate refresh token: ${getDetailedErrorMessage(err)}`); @@ -150,10 +148,10 @@ export class Tokens { let invalidatedTokensCount; try { invalidatedTokensCount = ( - await this.options.client.security.invalidateToken<{ invalidated_tokens: number }>({ + await this.options.client.security.invalidateToken({ body: { token: accessToken }, }) - ).body.invalidated_tokens; + ).invalidated_tokens; } catch (err) { this.logger.debug(`Failed to invalidate access token: ${getDetailedErrorMessage(err)}`); diff --git a/x-pack/plugins/security/server/authorization/check_privileges.test.ts b/x-pack/plugins/security/server/authorization/check_privileges.test.ts index d8906d91f152b..79ae84562cd8e 100644 --- a/x-pack/plugins/security/server/authorization/check_privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/check_privileges.test.ts @@ -24,9 +24,7 @@ const savedObjectTypes = ['foo-type', 'bar-type']; const createMockClusterClient = (response: any) => { const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.hasPrivileges.mockResolvedValue({ - body: response, - } as any); + mockScopedClusterClient.asCurrentUser.security.hasPrivileges.mockResponse(response as any); const mockClusterClient = elasticsearchServiceMock.createClusterClient(); mockClusterClient.asScoped.mockReturnValue(mockScopedClusterClient); diff --git a/x-pack/plugins/security/server/authorization/check_privileges.ts b/x-pack/plugins/security/server/authorization/check_privileges.ts index 81cf3ebc29f43..0459d8ccde293 100644 --- a/x-pack/plugins/security/server/authorization/check_privileges.ts +++ b/x-pack/plugins/security/server/authorization/check_privileges.ts @@ -59,7 +59,7 @@ export function checkPrivilegesWithRequestFactory( ]); const clusterClient = await getClusterClient(); - const { body } = await clusterClient.asScoped(request).asCurrentUser.security.hasPrivileges({ + const body = await clusterClient.asScoped(request).asCurrentUser.security.hasPrivileges({ body: { cluster: privileges.elasticsearch?.cluster as estypes.SecurityClusterPrivilege[], index: Object.entries(privileges.elasticsearch?.index ?? {}).map( diff --git a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts index ee5d3373ffcdb..17ed6b11630e3 100644 --- a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts +++ b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts @@ -115,10 +115,10 @@ const registerPrivilegesWithClusterTest = ( // ES returns an empty object if we don't have any privileges if (!existingPrivileges) { - return { body: {} }; + return {}; } - return { body: existingPrivileges }; + return existingPrivileges; }) as any); mockClusterClient.asInternalUser.security.putPrivileges.mockImplementation((async () => { if (throwErrorWhenPuttingPrivileges) { diff --git a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts index f32835e7727fc..2fcdc0b8dbcc9 100644 --- a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts +++ b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts @@ -59,9 +59,9 @@ export async function registerPrivilegesWithCluster( try { // we only want to post the privileges when they're going to change as Elasticsearch has // to clear the role cache to get these changes reflected in the _has_privileges API - const { body: existingPrivileges } = await clusterClient.asInternalUser.security.getPrivileges< - Record - >({ application }); + const existingPrivileges = await clusterClient.asInternalUser.security.getPrivileges({ + application, + }); if (arePrivilegesEqual(existingPrivileges, expectedPrivileges)) { logger.debug(`Kibana Privileges already registered with Elasticsearch for ${application}`); return; diff --git a/x-pack/plugins/security/server/deprecations/kibana_user_role.test.ts b/x-pack/plugins/security/server/deprecations/kibana_user_role.test.ts index d971769160df5..6f9a8e8763528 100644 --- a/x-pack/plugins/security/server/deprecations/kibana_user_role.test.ts +++ b/x-pack/plugins/security/server/deprecations/kibana_user_role.test.ts @@ -72,17 +72,11 @@ describe('Kibana Dashboard Only User role deprecations', () => { }); it('does not return any deprecations if none of the users and role mappings has a kibana user role', async () => { - mockContext.esClient.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ body: { userA: createMockUser() } }) - ); + mockContext.esClient.asCurrentUser.security.getUser.mockResponse({ userA: createMockUser() }); - mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ - body: { - mappingA: { enabled: true, roles: ['roleA'], rules: {}, metadata: {} }, - }, - }) - ); + mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: { enabled: true, roles: ['roleA'], rules: {}, metadata: {} }, + }); await expect(deprecationHandler.getDeprecations(mockContext)).resolves.toEqual([]); }); @@ -91,9 +85,9 @@ describe('Kibana Dashboard Only User role deprecations', () => { mockContext.esClient.asCurrentUser.security.getUser.mockRejectedValue( new errors.ResponseError(securityMock.createApiResponse({ statusCode: 403, body: {} })) ); - mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ body: { mappingA: createMockRoleMapping() } }) - ); + mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: createMockRoleMapping(), + }); await expect(deprecationHandler.getDeprecations(mockContext)).resolves.toMatchInlineSnapshot(` Array [ @@ -117,9 +111,9 @@ describe('Kibana Dashboard Only User role deprecations', () => { mockContext.esClient.asCurrentUser.security.getUser.mockRejectedValue( new errors.ResponseError(securityMock.createApiResponse({ statusCode: 500, body: {} })) ); - mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ body: { mappingA: createMockRoleMapping() } }) - ); + mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: createMockRoleMapping(), + }); await expect(deprecationHandler.getDeprecations(mockContext)).resolves.toMatchInlineSnapshot(` Array [ @@ -139,9 +133,7 @@ describe('Kibana Dashboard Only User role deprecations', () => { }); it('returns deprecations even if cannot retrieve role mappings due to permission error', async () => { - mockContext.esClient.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ body: { userA: createMockUser() } }) - ); + mockContext.esClient.asCurrentUser.security.getUser.mockResponse({ userA: createMockUser() }); mockContext.esClient.asCurrentUser.security.getRoleMapping.mockRejectedValue( new errors.ResponseError(securityMock.createApiResponse({ statusCode: 403, body: {} })) ); @@ -165,9 +157,7 @@ describe('Kibana Dashboard Only User role deprecations', () => { }); it('returns deprecations even if cannot retrieve role mappings due to unknown error', async () => { - mockContext.esClient.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ body: { userA: createMockUser() } }) - ); + mockContext.esClient.asCurrentUser.security.getUser.mockResponse({ userA: createMockUser() }); mockContext.esClient.asCurrentUser.security.getRoleMapping.mockRejectedValue( new errors.ResponseError(securityMock.createApiResponse({ statusCode: 500, body: {} })) ); @@ -190,20 +180,16 @@ describe('Kibana Dashboard Only User role deprecations', () => { }); it('returns only user-related deprecations', async () => { - mockContext.esClient.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ - body: { - userA: createMockUser({ username: 'userA', roles: ['roleA'] }), - userB: createMockUser({ username: 'userB', roles: ['roleB', 'kibana_user'] }), - userC: createMockUser({ username: 'userC', roles: ['roleC'] }), - userD: createMockUser({ username: 'userD', roles: ['kibana_user'] }), - }, - }) - ); + mockContext.esClient.asCurrentUser.security.getUser.mockResponse({ + userA: createMockUser({ username: 'userA', roles: ['roleA'] }), + userB: createMockUser({ username: 'userB', roles: ['roleB', 'kibana_user'] }), + userC: createMockUser({ username: 'userC', roles: ['roleC'] }), + userD: createMockUser({ username: 'userD', roles: ['kibana_user'] }), + }); - mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ body: { mappingA: createMockRoleMapping() } }) - ); + mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: createMockRoleMapping(), + }); await expect(deprecationHandler.getDeprecations(mockContext)).resolves.toMatchInlineSnapshot(` Array [ @@ -228,20 +214,14 @@ describe('Kibana Dashboard Only User role deprecations', () => { }); it('returns only role-mapping-related deprecations', async () => { - mockContext.esClient.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ body: { userA: createMockUser() } }) - ); + mockContext.esClient.asCurrentUser.security.getUser.mockResponse({ userA: createMockUser() }); - mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ - body: { - mappingA: createMockRoleMapping({ roles: ['roleA'] }), - mappingB: createMockRoleMapping({ roles: ['roleB', 'kibana_user'] }), - mappingC: createMockRoleMapping({ roles: ['roleC'] }), - mappingD: createMockRoleMapping({ roles: ['kibana_user'] }), - }, - }) - ); + mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: createMockRoleMapping({ roles: ['roleA'] }), + mappingB: createMockRoleMapping({ roles: ['roleB', 'kibana_user'] }), + mappingC: createMockRoleMapping({ roles: ['roleC'] }), + mappingD: createMockRoleMapping({ roles: ['kibana_user'] }), + }); await expect(deprecationHandler.getDeprecations(mockContext)).resolves.toMatchInlineSnapshot(` Array [ @@ -266,27 +246,19 @@ describe('Kibana Dashboard Only User role deprecations', () => { }); it('returns both user-related and role-mapping-related deprecations', async () => { - mockContext.esClient.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ - body: { - userA: createMockUser({ username: 'userA', roles: ['roleA'] }), - userB: createMockUser({ username: 'userB', roles: ['roleB', 'kibana_user'] }), - userC: createMockUser({ username: 'userC', roles: ['roleC'] }), - userD: createMockUser({ username: 'userD', roles: ['kibana_user'] }), - }, - }) - ); + mockContext.esClient.asCurrentUser.security.getUser.mockResponse({ + userA: createMockUser({ username: 'userA', roles: ['roleA'] }), + userB: createMockUser({ username: 'userB', roles: ['roleB', 'kibana_user'] }), + userC: createMockUser({ username: 'userC', roles: ['roleC'] }), + userD: createMockUser({ username: 'userD', roles: ['kibana_user'] }), + }); - mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ - body: { - mappingA: createMockRoleMapping({ roles: ['roleA'] }), - mappingB: createMockRoleMapping({ roles: ['roleB', 'kibana_user'] }), - mappingC: createMockRoleMapping({ roles: ['roleC'] }), - mappingD: createMockRoleMapping({ roles: ['kibana_user'] }), - }, - }) - ); + mockContext.esClient.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: createMockRoleMapping({ roles: ['roleA'] }), + mappingB: createMockRoleMapping({ roles: ['roleB', 'kibana_user'] }), + mappingC: createMockRoleMapping({ roles: ['roleC'] }), + mappingD: createMockRoleMapping({ roles: ['kibana_user'] }), + }); await expect(deprecationHandler.getDeprecations(mockContext)).resolves.toMatchInlineSnapshot(` Array [ diff --git a/x-pack/plugins/security/server/deprecations/kibana_user_role.ts b/x-pack/plugins/security/server/deprecations/kibana_user_role.ts index 9746597aa95b8..12961f223c243 100644 --- a/x-pack/plugins/security/server/deprecations/kibana_user_role.ts +++ b/x-pack/plugins/security/server/deprecations/kibana_user_role.ts @@ -75,7 +75,7 @@ async function getUsersDeprecations( ): Promise { let users: SecurityGetUserResponse; try { - users = (await client.security.getUser()).body; + users = await client.security.getUser(); } catch (err) { if (getErrorStatusCode(err) === 403) { logger.warn( @@ -139,7 +139,7 @@ async function getRoleMappingsDeprecations( ): Promise { let roleMappings: SecurityGetRoleMappingResponse; try { - roleMappings = (await client.security.getRoleMapping()).body; + roleMappings = await client.security.getRoleMapping(); } catch (err) { if (getErrorStatusCode(err) === 403) { logger.warn( diff --git a/x-pack/plugins/security/server/deprecations/privilege_deprecations.test.ts b/x-pack/plugins/security/server/deprecations/privilege_deprecations.test.ts index eb229bfe2dc22..cf0ab329b7686 100644 --- a/x-pack/plugins/security/server/deprecations/privilege_deprecations.test.ts +++ b/x-pack/plugins/security/server/deprecations/privilege_deprecations.test.ts @@ -30,28 +30,26 @@ describe('#getPrivilegeDeprecationsService', () => { }); it('happy path to find siem roles with feature_siem privileges', async () => { - mockAsCurrentUser.asCurrentUser.security.getRole.mockResolvedValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: ['feature_siem.all', 'feature_siem.cases_read'], - resources: ['space:securitySolutions'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, + mockAsCurrentUser.asCurrentUser.security.getRole.mockResponse({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: ['feature_siem.all', 'feature_siem.cases_read'], + resources: ['space:securitySolutions'], }, + ], + run_as: [], + metadata: { + _reserved: true, }, - }) - ); + transient_metadata: { + enabled: true, + }, + }, + }); const mockContext = { esClient: mockAsCurrentUser, @@ -98,34 +96,32 @@ describe('#getPrivilegeDeprecationsService', () => { }); it('happy path to find siem roles with feature_siem and feature_foo and feature_bar privileges', async () => { - mockAsCurrentUser.asCurrentUser.security.getRole.mockResolvedValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: [ - 'feature_foo.foo-privilege-1', - 'feature_foo.foo-privilege-2', - 'feature_bar.bar-privilege-1', - 'feature_siem.all', - 'feature_siem.cases_read', - ], - resources: ['space:securitySolutions'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, + mockAsCurrentUser.asCurrentUser.security.getRole.mockResponse({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: [ + 'feature_foo.foo-privilege-1', + 'feature_foo.foo-privilege-2', + 'feature_bar.bar-privilege-1', + 'feature_siem.all', + 'feature_siem.cases_read', + ], + resources: ['space:securitySolutions'], }, + ], + run_as: [], + metadata: { + _reserved: true, }, - }) - ); + transient_metadata: { + enabled: true, + }, + }, + }); const mockContext = { esClient: mockAsCurrentUser, @@ -179,32 +175,30 @@ describe('#getPrivilegeDeprecationsService', () => { }); it('happy path to NOT find siem roles with and feature_foo and feature_bar privileges', async () => { - mockAsCurrentUser.asCurrentUser.security.getRole.mockResolvedValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - first_role: { - cluster: [], - indices: [], - applications: [ - { - application, - privileges: [ - 'feature_foo.foo-privilege-1', - 'feature_foo.foo-privilege-2', - 'feature_bar.bar-privilege-1', - ], - resources: ['space:securitySolutions'], - }, - ], - run_as: [], - metadata: { - _reserved: true, - }, - transient_metadata: { - enabled: true, + mockAsCurrentUser.asCurrentUser.security.getRole.mockResponse({ + first_role: { + cluster: [], + indices: [], + applications: [ + { + application, + privileges: [ + 'feature_foo.foo-privilege-1', + 'feature_foo.foo-privilege-2', + 'feature_bar.bar-privilege-1', + ], + resources: ['space:securitySolutions'], }, + ], + run_as: [], + metadata: { + _reserved: true, }, - }) - ); + transient_metadata: { + enabled: true, + }, + }, + }); const mockContext = { esClient: mockAsCurrentUser, diff --git a/x-pack/plugins/security/server/deprecations/privilege_deprecations.ts b/x-pack/plugins/security/server/deprecations/privilege_deprecations.ts index 08413ccc74cf9..05a81936bfdff 100644 --- a/x-pack/plugins/security/server/deprecations/privilege_deprecations.ts +++ b/x-pack/plugins/security/server/deprecations/privilege_deprecations.ts @@ -15,7 +15,7 @@ import type { PrivilegeDeprecationsRolesByFeatureIdResponse, } from '../../common/model'; import { transformElasticsearchRoleToRole } from '../authorization'; -import type { AuthorizationServiceSetupInternal, ElasticsearchRole } from '../authorization'; +import type { AuthorizationServiceSetupInternal } from '../authorization'; import { getDetailedErrorMessage, getErrorStatusCode } from '../errors'; export const getPrivilegeDeprecationsService = ({ @@ -41,9 +41,9 @@ export const getPrivilegeDeprecationsService = ({ } let kibanaRoles; try { - const [features, { body: elasticsearchRoles }] = await Promise.all([ + const [features, elasticsearchRoles] = await Promise.all([ getFeatures(), - context.esClient.asCurrentUser.security.getRole>(), + context.esClient.asCurrentUser.security.getRole(), ]); kibanaRoles = Object.entries(elasticsearchRoles).map(([roleName, elasticsearchRole]) => transformElasticsearchRoleToRole( 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 e3a13eb6d1bda..cba705eccfcae 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 @@ -17,7 +17,7 @@ import { defineGetApiKeysRoutes } from './get'; interface TestOptions { isAdmin?: boolean; licenseCheckResult?: LicenseCheck; - apiResponse?: () => Promise; + apiResponse?: () => unknown; asserts: { statusCode: number; result?: Record }; } @@ -34,8 +34,9 @@ describe('Get API keys', () => { }; if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.getApiKey.mockImplementation( - (async () => ({ body: await apiResponse() })) as any + mockContext.core.elasticsearch.client.asCurrentUser.security.getApiKey.mockResponse( + // @ts-expect-error unknown type + apiResponse() ); } @@ -80,7 +81,7 @@ describe('Get API keys', () => { describe('success', () => { getApiKeysTest('returns API keys', { - apiResponse: async () => ({ + apiResponse: () => ({ api_keys: [ { id: 'YCLV7m0BJ3xI4hhWB648', @@ -111,7 +112,7 @@ describe('Get API keys', () => { }, }); getApiKeysTest('returns only valid API keys', { - apiResponse: async () => ({ + apiResponse: () => ({ api_keys: [ { id: 'YCLV7m0BJ3xI4hhWB648', 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 8982e4cf8c5d6..1b06dd00fc384 100644 --- a/x-pack/plugins/security/server/routes/api_keys/get.ts +++ b/x-pack/plugins/security/server/routes/api_keys/get.ts @@ -8,7 +8,6 @@ import { schema } from '@kbn/config-schema'; import type { RouteDefinitionParams } from '../'; -import type { ApiKey } from '../../../common/model'; import { wrapIntoCustomErrorResponse } from '../../errors'; import { createLicensedRouteHandler } from '../licensed_route_handler'; @@ -31,11 +30,11 @@ export function defineGetApiKeysRoutes({ router }: RouteDefinitionParams) { try { const isAdmin = request.query.isAdmin === 'true'; const apiResponse = - await context.core.elasticsearch.client.asCurrentUser.security.getApiKey<{ - api_keys: ApiKey[]; - }>({ owner: !isAdmin }); + await context.core.elasticsearch.client.asCurrentUser.security.getApiKey({ + owner: !isAdmin, + }); - const validKeys = apiResponse.body.api_keys.filter(({ invalidated }) => !invalidated); + const validKeys = apiResponse.api_keys.filter(({ invalidated }) => !invalidated); return response.ok({ body: { apiKeys: validKeys } }); } catch (error) { 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 019c61fd435be..dc8b7f4d9fc1e 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 @@ -18,7 +18,7 @@ import { defineCheckPrivilegesRoutes } from './privileges'; interface TestOptions { licenseCheckResult?: LicenseCheck; areAPIKeysEnabled?: boolean; - apiResponse?: () => Promise; + apiResponse?: () => unknown; asserts: { statusCode: number; result?: Record; apiArguments?: unknown }; } @@ -44,8 +44,13 @@ describe('Check API keys privileges', () => { mockRouteDefinitionParams.getAuthenticationService.mockReturnValue(authc); if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockImplementation( - (async () => ({ body: await apiResponse() })) as any + mockContext.core.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResponseImplementation( + // @ts-expect-error unknown return + () => { + return { + body: apiResponse(), + }; + } ); } @@ -81,7 +86,7 @@ describe('Check API keys privileges', () => { const error = Boom.notAcceptable('test not acceptable message'); getPrivilegesTest('returns error from cluster client', { - apiResponse: async () => { + apiResponse: () => { throw error; }, asserts: { @@ -96,7 +101,7 @@ describe('Check API keys privileges', () => { describe('success', () => { getPrivilegesTest('returns areApiKeysEnabled and isAdmin', { - apiResponse: async () => ({ + apiResponse: () => ({ username: 'elastic', has_all_requested: true, cluster: { manage_api_key: true, manage_security: true, manage_own_api_key: false }, @@ -115,7 +120,7 @@ describe('Check API keys privileges', () => { getPrivilegesTest( 'returns areApiKeysEnabled=false when API Keys are disabled in Elasticsearch', { - apiResponse: async () => ({ + apiResponse: () => ({ username: 'elastic', has_all_requested: true, cluster: { manage_api_key: true, manage_security: true, manage_own_api_key: true }, @@ -134,7 +139,7 @@ describe('Check API keys privileges', () => { ); getPrivilegesTest('returns isAdmin=false when user has insufficient privileges', { - apiResponse: async () => ({ + apiResponse: () => ({ username: 'elastic', has_all_requested: true, cluster: { manage_api_key: false, manage_security: false, manage_own_api_key: false }, @@ -151,7 +156,7 @@ describe('Check API keys privileges', () => { }); getPrivilegesTest('returns canManage=true when user can manage their own API Keys', { - apiResponse: async () => ({ + apiResponse: () => ({ username: 'elastic', has_all_requested: true, cluster: { manage_api_key: false, manage_security: false, manage_own_api_key: true }, 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 18de00ed79956..ffd7e9e805754 100644 --- a/x-pack/plugins/security/server/routes/api_keys/privileges.ts +++ b/x-pack/plugins/security/server/routes/api_keys/privileges.ts @@ -22,23 +22,15 @@ export function defineCheckPrivilegesRoutes({ try { const [ { - body: { - cluster: { - manage_security: manageSecurity, - manage_api_key: manageApiKey, - manage_own_api_key: manageOwnApiKey, - }, + cluster: { + manage_security: manageSecurity, + manage_api_key: manageApiKey, + manage_own_api_key: manageOwnApiKey, }, }, areApiKeysEnabled, ] = await Promise.all([ - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges<{ - cluster: { - manage_security: boolean; - manage_api_key: boolean; - manage_own_api_key: boolean; - }; - }>({ + context.core.elasticsearch.client.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_builtin.ts b/x-pack/plugins/security/server/routes/authorization/privileges/get_builtin.ts index a016a68d842ef..40b67aa08b073 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,7 +11,7 @@ export function defineGetBuiltinPrivilegesRoutes({ router }: RouteDefinitionPara router.get( { path: '/internal/security/esPrivileges/builtin', validate: false }, async (context, request, response) => { - const { body: privileges } = + const privileges = await context.core.elasticsearch.client.asCurrentUser.security.getBuiltinPrivileges(); // Exclude the `none` privilege, as it doesn't make sense as an option within the Kibana UI 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 a511d3aa52e21..1311897f5a564 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 @@ -20,7 +20,7 @@ const reservedPrivilegesApplicationWildcard = 'kibana-*'; interface TestOptions { name?: string; licenseCheckResult?: LicenseCheck; - apiResponse?: () => Promise; + apiResponse?: () => unknown; asserts: { statusCode: number; result?: Record }; } @@ -40,8 +40,8 @@ describe('GET role', () => { }; if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockImplementation( - (async () => ({ body: await apiResponse() })) as any + mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementation( + (() => ({ body: apiResponse() })) as any ); } @@ -79,7 +79,7 @@ describe('GET role', () => { const error = Boom.notAcceptable('test not acceptable message'); getRoleTest('returns error from cluster client', { name: 'first_role', - apiResponse: async () => { + apiResponse: () => { throw error; }, asserts: { statusCode: 406, result: error }, @@ -87,7 +87,7 @@ describe('GET role', () => { getRoleTest(`return error if we have empty resources`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -117,7 +117,7 @@ describe('GET role', () => { describe('success', () => { getRoleTest(`transforms elasticsearch privileges`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: ['manage_watcher'], indices: [ @@ -168,7 +168,7 @@ describe('GET role', () => { `transforms matching applications with * resource to kibana global base privileges`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -221,7 +221,7 @@ describe('GET role', () => { `transforms matching applications with * resource to kibana global feature privileges`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -281,7 +281,7 @@ describe('GET role', () => { `transforms matching applications with * resource to kibana _reserved privileges`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -335,7 +335,7 @@ describe('GET role', () => { `transforms applications with wildcard and * resource to kibana _reserved privileges`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -391,7 +391,7 @@ describe('GET role', () => { `transforms matching applications with space resources to kibana space base privileges`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -454,7 +454,7 @@ describe('GET role', () => { `transforms matching applications with space resources to kibana space feature privileges`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -527,7 +527,7 @@ describe('GET role', () => { `resource not * without space: prefix returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -574,7 +574,7 @@ describe('GET role', () => { `* and a space in the same entry returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -621,7 +621,7 @@ describe('GET role', () => { `* appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -673,7 +673,7 @@ describe('GET role', () => { `space privilege assigned globally returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -725,7 +725,7 @@ describe('GET role', () => { `space privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -772,7 +772,7 @@ describe('GET role', () => { `global base privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -824,7 +824,7 @@ describe('GET role', () => { `global base privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -871,7 +871,7 @@ describe('GET role', () => { `reserved privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -923,7 +923,7 @@ describe('GET role', () => { `reserved privilege assigned with a base privilege returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -970,7 +970,7 @@ describe('GET role', () => { `reserved privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -1017,7 +1017,7 @@ describe('GET role', () => { `global base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -1064,7 +1064,7 @@ describe('GET role', () => { `space base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -1109,7 +1109,7 @@ describe('GET role', () => { getRoleTest(`transforms unrecognized applications`, { name: 'first_role', - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], 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 4c54854d3279b..125966d887e04 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/get.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/get.ts @@ -22,7 +22,7 @@ export function defineGetRolesRoutes({ router, authz, getFeatures }: RouteDefini }, createLicensedRouteHandler(async (context, request, response) => { try { - const [features, { body: elasticsearchRoles }] = await Promise.all([ + const [features, elasticsearchRoles] = await Promise.all([ getFeatures(), await context.core.elasticsearch.client.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 8ecd5b7bd0913..39ea6fd715a8b 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 @@ -20,7 +20,7 @@ const reservedPrivilegesApplicationWildcard = 'kibana-*'; interface TestOptions { name?: string; licenseCheckResult?: LicenseCheck; - apiResponse?: () => Promise; + apiResponse?: () => unknown; asserts: { statusCode: number; result?: Record }; } @@ -40,8 +40,8 @@ describe('GET all roles', () => { }; if (apiResponse) { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockImplementation( - (async () => ({ body: await apiResponse() })) as any + mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementation( + (() => ({ body: apiResponse() })) as any ); } @@ -83,7 +83,7 @@ describe('GET all roles', () => { }); getRolesTest(`return error if we have empty resources`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -112,7 +112,7 @@ describe('GET all roles', () => { describe('success', () => { getRolesTest(`transforms elasticsearch privileges`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: ['manage_watcher'], indices: [ @@ -164,7 +164,7 @@ describe('GET all roles', () => { getRolesTest( `transforms matching applications with * resource to kibana global base privileges`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -218,7 +218,7 @@ describe('GET all roles', () => { getRolesTest( `transforms matching applications with * resource to kibana global feature privileges`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -279,7 +279,7 @@ describe('GET all roles', () => { getRolesTest( `transforms matching applications with * resource to kibana _reserved privileges`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -334,7 +334,7 @@ describe('GET all roles', () => { getRolesTest( `transforms applications with wildcard and * resource to kibana _reserved privileges`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -391,7 +391,7 @@ describe('GET all roles', () => { getRolesTest( `transforms matching applications with space resources to kibana space base privileges`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -455,7 +455,7 @@ describe('GET all roles', () => { getRolesTest( `transforms matching applications with space resources to kibana space feature privileges`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -529,7 +529,7 @@ describe('GET all roles', () => { getRolesTest( `resource not * without space: prefix returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -577,7 +577,7 @@ describe('GET all roles', () => { getRolesTest( `* and a space in the same entry returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -625,7 +625,7 @@ describe('GET all roles', () => { getRolesTest( `* appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -678,7 +678,7 @@ describe('GET all roles', () => { getRolesTest( `space appearing in multiple entries returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -731,7 +731,7 @@ describe('GET all roles', () => { getRolesTest( `space privilege assigned globally returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -784,7 +784,7 @@ describe('GET all roles', () => { getRolesTest( `space privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -832,7 +832,7 @@ describe('GET all roles', () => { getRolesTest( `global base privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -885,7 +885,7 @@ describe('GET all roles', () => { getRolesTest( `global base privilege with application wildcard returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -933,7 +933,7 @@ describe('GET all roles', () => { getRolesTest( `reserved privilege assigned at a space returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -986,7 +986,7 @@ describe('GET all roles', () => { getRolesTest( `reserved privilege assigned with a base privilege returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -1034,7 +1034,7 @@ describe('GET all roles', () => { getRolesTest( `reserved privilege assigned with a feature privilege returns populated kibana section`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -1101,7 +1101,7 @@ describe('GET all roles', () => { getRolesTest( `global base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -1149,7 +1149,7 @@ describe('GET all roles', () => { getRolesTest( `space base privilege assigned with a feature privilege returns empty kibana section with _transform_error set to ['kibana']`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -1195,7 +1195,7 @@ describe('GET all roles', () => { ); getRolesTest(`transforms unrecognized applications`, { - apiResponse: async () => ({ + apiResponse: () => ({ first_role: { cluster: [], indices: [], @@ -1240,7 +1240,7 @@ describe('GET all roles', () => { }); getRolesTest(`returns a sorted list of roles`, { - apiResponse: async () => ({ + apiResponse: () => ({ z_role: { cluster: [], indices: [], 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 89b39ddae0118..f34b6a0893660 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 @@ -8,7 +8,6 @@ import type { RouteDefinitionParams } from '../..'; import { wrapIntoCustomErrorResponse } from '../../../errors'; import { createLicensedRouteHandler } from '../../licensed_route_handler'; -import type { ElasticsearchRole } from './model'; import { transformElasticsearchRoleToRole } from './model'; export function defineGetAllRolesRoutes({ router, authz, getFeatures }: RouteDefinitionParams) { @@ -16,11 +15,9 @@ export function defineGetAllRolesRoutes({ router, authz, getFeatures }: RouteDef { path: '/api/security/role', validate: false }, createLicensedRouteHandler(async (context, request, response) => { try { - const [features, { body: elasticsearchRoles }] = await Promise.all([ + const [features, elasticsearchRoles] = await Promise.all([ getFeatures(), - await context.core.elasticsearch.client.asCurrentUser.security.getRole< - Record - >(), + await context.core.elasticsearch.client.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 72d78ba5aaca4..fac13a655892a 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 @@ -46,8 +46,8 @@ interface TestOptions { name: string; licenseCheckResult?: LicenseCheck; apiResponses?: { - get: () => Promise; - put: () => Promise; + get: () => unknown; + put: () => unknown; }; payload?: Record; asserts: { @@ -81,14 +81,14 @@ const putRoleTest = ( }; if (apiResponses?.get) { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockImplementationOnce( - (async () => ({ body: await apiResponses?.get() })) as any + mockContext.core.elasticsearch.client.asCurrentUser.security.getRole.mockResponseImplementationOnce( + (() => ({ body: apiResponses?.get() })) as any ); } if (apiResponses?.put) { - mockContext.core.elasticsearch.client.asCurrentUser.security.putRole.mockImplementationOnce( - (async () => ({ body: await apiResponses?.put() })) as any + mockContext.core.elasticsearch.client.asCurrentUser.security.putRole.mockResponseImplementationOnce( + (() => ({ body: apiResponses?.put() })) as any ); } @@ -273,7 +273,10 @@ describe('PUT role', () => { putRoleTest(`creates empty role`, { name: 'foo-role', payload: {}, - apiResponses: { get: async () => ({}), put: async () => {} }, + apiResponses: { + get: () => ({}), + put: () => {}, + }, asserts: { apiArguments: { get: [{ name: 'foo-role' }, { ignore: [404] }], @@ -303,7 +306,10 @@ describe('PUT role', () => { }, ], }, - apiResponses: { get: async () => ({}), put: async () => {} }, + apiResponses: { + get: () => ({}), + put: () => {}, + }, asserts: { apiArguments: { get: [{ name: 'foo-role' }, { ignore: [404] }], @@ -342,7 +348,10 @@ describe('PUT role', () => { }, ], }, - apiResponses: { get: async () => ({}), put: async () => {} }, + apiResponses: { + get: () => ({}), + put: () => {}, + }, asserts: { apiArguments: { get: [{ name: 'foo-role' }, { ignore: [404] }], @@ -379,7 +388,10 @@ describe('PUT role', () => { }, ], }, - apiResponses: { get: async () => ({}), put: async () => {} }, + apiResponses: { + get: () => ({}), + put: () => {}, + }, asserts: { apiArguments: { get: [{ name: 'foo-role' }, { ignore: [404] }], @@ -444,7 +456,10 @@ describe('PUT role', () => { }, ], }, - apiResponses: { get: async () => ({}), put: async () => {} }, + apiResponses: { + get: () => ({}), + put: () => {}, + }, asserts: { apiArguments: { get: [{ name: 'foo-role' }, { ignore: [404] }], @@ -534,7 +549,7 @@ describe('PUT role', () => { ], }, apiResponses: { - get: async () => ({ + get: () => ({ 'foo-role': { metadata: { bar: 'old-metadata', @@ -564,7 +579,7 @@ describe('PUT role', () => { ], }, }), - put: async () => {}, + put: () => {}, }, asserts: { apiArguments: { @@ -637,7 +652,7 @@ describe('PUT role', () => { ], }, apiResponses: { - get: async () => ({ + get: () => ({ 'foo-role': { metadata: { bar: 'old-metadata', @@ -672,7 +687,7 @@ describe('PUT role', () => { ], }, }), - put: async () => {}, + put: () => {}, }, asserts: { apiArguments: { @@ -728,7 +743,10 @@ describe('PUT role', () => { }, ], }, - apiResponses: { get: async () => ({}), put: async () => {} }, + apiResponses: { + get: () => ({}), + put: () => {}, + }, asserts: { recordSubFeaturePrivilegeUsage: true, apiArguments: { @@ -769,7 +787,10 @@ describe('PUT role', () => { }, ], }, - apiResponses: { get: async () => ({}), put: async () => {} }, + apiResponses: { + get: () => ({}), + put: () => {}, + }, asserts: { recordSubFeaturePrivilegeUsage: false, apiArguments: { @@ -810,7 +831,10 @@ describe('PUT role', () => { }, ], }, - apiResponses: { get: async () => ({}), put: async () => {} }, + apiResponses: { + get: () => ({}), + put: () => {}, + }, asserts: { recordSubFeaturePrivilegeUsage: false, apiArguments: { 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 c1b8cc56c32a4..06e731dc2d543 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/put.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/put.ts @@ -66,7 +66,7 @@ export function definePutRolesRoutes({ const { name } = request.params; try { - const [features, { body: rawRoles }] = await Promise.all([ + const [features, rawRoles] = await Promise.all([ getFeatures(), context.core.elasticsearch.client.asCurrentUser.security.getRole( { name: request.params.name }, diff --git a/x-pack/plugins/security/server/routes/deprecations/kibana_user_role.test.ts b/x-pack/plugins/security/server/routes/deprecations/kibana_user_role.test.ts index 3c9a775d7a054..8b8a10e917f1a 100644 --- a/x-pack/plugins/security/server/routes/deprecations/kibana_user_role.test.ts +++ b/x-pack/plugins/security/server/routes/deprecations/kibana_user_role.test.ts @@ -28,7 +28,9 @@ function createMockRoleMapping(mapping: Partial = { describe('Kibana user deprecation routes', () => { let router: jest.Mocked; - let mockContext: DeeplyMockedKeys; + let mockContext: DeeplyMockedKeys & { + core: ReturnType; + }; beforeEach(() => { const routeParamsMock = routeDefinitionParamsMock.create(); router = routeParamsMock.router; @@ -75,14 +77,10 @@ describe('Kibana user deprecation routes', () => { }); it('fails if fails to update user', async () => { - mockContext.core.elasticsearch.client.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ - body: { - userA: createMockUser({ username: 'userA', roles: ['roleA', 'kibana_user'] }), - userB: createMockUser({ username: 'userB', roles: ['kibana_user'] }), - }, - }) - ); + mockContext.core.elasticsearch.client.asCurrentUser.security.getUser.mockResponse({ + userA: createMockUser({ username: 'userA', roles: ['roleA', 'kibana_user'] }), + userB: createMockUser({ username: 'userB', roles: ['kibana_user'] }), + }); mockContext.core.elasticsearch.client.asCurrentUser.security.putUser.mockRejectedValue( new errors.ResponseError( securityMock.createApiResponse({ statusCode: 500, body: new Error('Oh no') }) @@ -105,9 +103,9 @@ describe('Kibana user deprecation routes', () => { }); it('does nothing if there are no users with Kibana user role', async () => { - mockContext.core.elasticsearch.client.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ body: { userA: createMockUser() } }) - ); + mockContext.core.elasticsearch.client.asCurrentUser.security.getUser.mockResponse({ + userA: createMockUser(), + }); await expect( routeHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory) @@ -119,20 +117,16 @@ describe('Kibana user deprecation routes', () => { }); it('updates users with Kibana user role', async () => { - mockContext.core.elasticsearch.client.asCurrentUser.security.getUser.mockResolvedValue( - securityMock.createApiResponse({ - body: { - userA: createMockUser({ username: 'userA', roles: ['roleA'] }), - userB: createMockUser({ username: 'userB', roles: ['roleB', 'kibana_user'] }), - userC: createMockUser({ username: 'userC', roles: ['roleC'] }), - userD: createMockUser({ username: 'userD', roles: ['kibana_user'] }), - userE: createMockUser({ - username: 'userE', - roles: ['kibana_user', 'kibana_admin', 'roleE'], - }), - }, - }) - ); + mockContext.core.elasticsearch.client.asCurrentUser.security.getUser.mockResponse({ + userA: createMockUser({ username: 'userA', roles: ['roleA'] }), + userB: createMockUser({ username: 'userB', roles: ['roleB', 'kibana_user'] }), + userC: createMockUser({ username: 'userC', roles: ['roleC'] }), + userD: createMockUser({ username: 'userD', roles: ['kibana_user'] }), + userE: createMockUser({ + username: 'userE', + roles: ['kibana_user', 'kibana_admin', 'roleE'], + }), + }); await expect( routeHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory) @@ -197,14 +191,10 @@ describe('Kibana user deprecation routes', () => { }); it('fails if fails to update role mapping', async () => { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ - body: { - mappingA: createMockRoleMapping({ roles: ['roleA', 'kibana_user'] }), - mappingB: createMockRoleMapping({ roles: ['kibana_user'] }), - }, - }) - ); + mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: createMockRoleMapping({ roles: ['roleA', 'kibana_user'] }), + mappingB: createMockRoleMapping({ roles: ['kibana_user'] }), + }); mockContext.core.elasticsearch.client.asCurrentUser.security.putRoleMapping.mockRejectedValue( new errors.ResponseError( securityMock.createApiResponse({ statusCode: 500, body: new Error('Oh no') }) @@ -227,9 +217,9 @@ describe('Kibana user deprecation routes', () => { }); it('does nothing if there are no role mappings with Kibana user role', async () => { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ body: { mappingA: createMockRoleMapping() } }) - ); + mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: createMockRoleMapping(), + }); await expect( routeHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory) @@ -241,17 +231,13 @@ describe('Kibana user deprecation routes', () => { }); it('updates role mappings with Kibana user role', async () => { - mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResolvedValue( - securityMock.createApiResponse({ - body: { - mappingA: createMockRoleMapping({ roles: ['roleA'] }), - mappingB: createMockRoleMapping({ roles: ['roleB', 'kibana_user'] }), - mappingC: createMockRoleMapping({ roles: ['roleC'] }), - mappingD: createMockRoleMapping({ roles: ['kibana_user'] }), - mappingE: createMockRoleMapping({ roles: ['kibana_user', 'kibana_admin', 'roleE'] }), - }, - }) - ); + mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResponse({ + mappingA: createMockRoleMapping({ roles: ['roleA'] }), + mappingB: createMockRoleMapping({ roles: ['roleB', 'kibana_user'] }), + mappingC: createMockRoleMapping({ roles: ['roleC'] }), + mappingD: createMockRoleMapping({ roles: ['kibana_user'] }), + mappingE: createMockRoleMapping({ roles: ['kibana_user', 'kibana_admin', 'roleE'] }), + }); await expect( routeHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory) 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 5d5e2a12f86a6..bb07ece2c75b9 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 @@ -28,7 +28,7 @@ export function defineKibanaUserRoleDeprecationRoutes({ router, logger }: RouteD createLicensedRouteHandler(async (context, request, response) => { let users: estypes.SecurityGetUserResponse; try { - users = (await context.core.elasticsearch.client.asCurrentUser.security.getUser()).body; + users = await context.core.elasticsearch.client.asCurrentUser.security.getUser(); } catch (err) { if (getErrorStatusCode(err) === 403) { logger.warn( @@ -91,9 +91,8 @@ export function defineKibanaUserRoleDeprecationRoutes({ router, logger }: RouteD createLicensedRouteHandler(async (context, request, response) => { let roleMappings: estypes.SecurityGetRoleMappingResponse; try { - roleMappings = ( - await context.core.elasticsearch.client.asCurrentUser.security.getRoleMapping() - ).body; + roleMappings = + await context.core.elasticsearch.client.asCurrentUser.security.getRoleMapping(); } catch (err) { logger.error(`Failed to retrieve role mappings: ${getDetailedErrorMessage(err)}.`); return response.customError(wrapIntoCustomErrorResponse(err)); diff --git a/x-pack/plugins/security/server/routes/indices/get_fields.test.ts b/x-pack/plugins/security/server/routes/indices/get_fields.test.ts index 20f9949f615cb..386d528080ab5 100644 --- a/x-pack/plugins/security/server/routes/indices/get_fields.test.ts +++ b/x-pack/plugins/security/server/routes/indices/get_fields.test.ts @@ -40,8 +40,8 @@ describe('GET /internal/security/fields/{query}', () => { const mockContext = { core: coreMock.createRequestHandlerContext(), }; - mockContext.core.elasticsearch.client.asCurrentUser.indices.getFieldMapping.mockImplementation( - (async () => ({ body: mockFieldMappingResponse })) as any + mockContext.core.elasticsearch.client.asCurrentUser.indices.getFieldMapping.mockResponse( + mockFieldMappingResponse as any ); defineGetFieldsRoutes(mockRouteDefinitionParams); 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 d6c7778d9ccbf..873ed0e1b4b92 100644 --- a/x-pack/plugins/security/server/routes/indices/get_fields.ts +++ b/x-pack/plugins/security/server/routes/indices/get_fields.ts @@ -18,7 +18,7 @@ export function defineGetFieldsRoutes({ router }: RouteDefinitionParams) { }, async (context, request, response) => { try { - const { body: indexMappings } = + const indexMappings = await context.core.elasticsearch.client.asCurrentUser.indices.getFieldMapping({ index: request.params.query, fields: '*', 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 64b1ae8af13c6..f652d370f3601 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 @@ -18,9 +18,9 @@ describe('DELETE role mappings', () => { core: coreMock.createRequestHandlerContext(), licensing: { license: { check: jest.fn().mockReturnValue({ state: 'valid' }) } } as any, }; - mockContext.core.elasticsearch.client.asCurrentUser.security.deleteRoleMapping.mockResolvedValue( - { body: { acknowledged: true } } as any - ); + mockContext.core.elasticsearch.client.asCurrentUser.security.deleteRoleMapping.mockResponse({ + acknowledged: true, + } as any); defineRoleMappingDeleteRoutes(mockRouteDefinitionParams); 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 9d23fbaf1e265..bf6353d5abd55 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/delete.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/delete.ts @@ -23,7 +23,7 @@ export function defineRoleMappingDeleteRoutes({ router }: RouteDefinitionParams) }, createLicensedRouteHandler(async (context, request, response) => { try { - const { body: deleteResponse } = + const deleteResponse = await context.core.elasticsearch.client.asCurrentUser.security.deleteRoleMapping({ name: request.params.name, }); 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 a015fcd293e35..06c6f02fad4fe 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 @@ -41,8 +41,8 @@ describe('GET role mappings feature check', () => { { licenseCheckResult = { state: 'valid' }, canManageRoleMappings = true, - nodeSettingsResponse = async () => ({}), - xpackUsageResponse = async () => defaultXpackUsageResponse, + nodeSettingsResponse = () => ({}), + xpackUsageResponse = () => defaultXpackUsageResponse, asserts, }: TestOptions ) => { @@ -54,14 +54,13 @@ describe('GET role mappings feature check', () => { }; mockContext.core.elasticsearch.client.asInternalUser.nodes.info.mockImplementation( - (async () => ({ body: await nodeSettingsResponse() })) as any + (async () => nodeSettingsResponse()) as any ); mockContext.core.elasticsearch.client.asInternalUser.transport.request.mockImplementation( - (async () => ({ body: await xpackUsageResponse() })) as any + (async () => xpackUsageResponse()) as any ); - mockContext.core.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResolvedValue({ - body: { has_all_requested: canManageRoleMappings }, + has_all_requested: canManageRoleMappings, } as any); defineRoleMappingFeatureCheckRoute(mockRouteDefinitionParams); @@ -95,7 +94,7 @@ describe('GET role mappings feature check', () => { }); getFeatureCheckTest('allows both script types when explicitly enabled', { - nodeSettingsResponse: async () => ({ + nodeSettingsResponse: () => ({ nodes: { someNodeId: { settings: { @@ -118,7 +117,7 @@ describe('GET role mappings feature check', () => { }); getFeatureCheckTest('disallows stored scripts when disabled', { - nodeSettingsResponse: async () => ({ + nodeSettingsResponse: () => ({ nodes: { someNodeId: { settings: { @@ -141,7 +140,7 @@ describe('GET role mappings feature check', () => { }); getFeatureCheckTest('disallows inline scripts when disabled', { - nodeSettingsResponse: async () => ({ + nodeSettingsResponse: () => ({ nodes: { someNodeId: { settings: { @@ -164,7 +163,7 @@ describe('GET role mappings feature check', () => { }); getFeatureCheckTest('indicates incompatible realms when only native and file are enabled', { - xpackUsageResponse: async () => ({ + xpackUsageResponse: () => ({ security: { realms: { native: { @@ -202,10 +201,10 @@ describe('GET role mappings feature check', () => { getFeatureCheckTest( 'falls back to allowing both script types if there is an error retrieving node settings', { - nodeSettingsResponse: async () => { + nodeSettingsResponse: () => { throw new Error('something bad happened'); }, - xpackUsageResponse: async () => { + xpackUsageResponse: () => { throw new Error('something bad happened'); }, asserts: { 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 95b5d56be9937..4976b7411008f 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,11 +43,10 @@ export function defineRoleMappingFeatureCheckRoute({ router, logger }: RouteDefi validate: false, }, createLicensedRouteHandler(async (context, request, response) => { - const { - body: { has_all_requested: canManageRoleMappings }, - } = await context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges<{ - has_all_requested: boolean; - }>({ body: { cluster: ['manage_security'] } }); + const { has_all_requested: canManageRoleMappings } = + await context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + body: { cluster: ['manage_security'] }, + }); if (!canManageRoleMappings) { return response.ok({ @@ -76,8 +75,7 @@ async function getEnabledRoleMappingsFeatures(esClient: ElasticsearchClient, log logger.debug(`Retrieving role mappings features`); const nodeScriptSettingsPromise = esClient.nodes - .info({ filter_path: 'nodes.*.settings.script' }) - .then(({ body }) => body) + .info({ filter_path: 'nodes.*.settings.script' }) .catch((error) => { // fall back to assuming that node settings are unset/at their default values. // this will allow the role mappings UI to permit both role template script types, @@ -90,7 +88,7 @@ async function getEnabledRoleMappingsFeatures(esClient: ElasticsearchClient, log // Do not augment with such input. const xpackUsagePromise = esClient.transport .request({ method: 'GET', path: '/_xpack/usage' }) - .then(({ body }) => body as XPackUsageResponse) + .then((body) => body as XPackUsageResponse) .catch((error) => { // fall back to no external realms configured. // this will cause a warning in the UI about no compatible realms being enabled, but will otherwise allow 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 b9511eac70af7..8aa9d60f8271e 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 @@ -65,9 +65,9 @@ describe('GET role mappings', () => { it('returns all role mappings', async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); const mockContext = getMockContext(); - mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResolvedValue({ - body: mockRoleMappingResponse, - } as any); + mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResponse( + mockRoleMappingResponse as any + ); defineRoleMappingGetRoutes(mockRouteDefinitionParams); @@ -133,15 +133,13 @@ describe('GET role mappings', () => { it('returns role mapping by name', async () => { const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); const mockContext = getMockContext(); - mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResolvedValue({ - body: { - mapping1: { - enabled: true, - roles: ['foo', 'bar'], - rules: { - field: { - dn: 'CN=bob,OU=example,O=com', - }, + mockContext.core.elasticsearch.client.asCurrentUser.security.getRoleMapping.mockResponse({ + mapping1: { + enabled: true, + roles: ['foo', 'bar'], + rules: { + field: { + dn: 'CN=bob,OU=example,O=com', }, }, }, 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 1039abdd8667a..dbe99fd804e25 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/get.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/get.ts @@ -33,7 +33,7 @@ export function defineRoleMappingGetRoutes(params: RouteDefinitionParams) { name: request.params.name, }); - const mappings = Object.entries(roleMappingsResponse.body).map(([name, mapping]) => { + const mappings = Object.entries(roleMappingsResponse).map(([name, mapping]) => { return { name, ...mapping, 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 727f3ba597336..e06d57b76098f 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 @@ -18,8 +18,8 @@ describe('POST role mappings', () => { core: coreMock.createRequestHandlerContext(), licensing: { license: { check: jest.fn().mockReturnValue({ state: 'valid' }) } } as any, }; - mockContext.core.elasticsearch.client.asCurrentUser.security.putRoleMapping.mockResolvedValue({ - body: { created: true }, + mockContext.core.elasticsearch.client.asCurrentUser.security.putRoleMapping.mockResponse({ + created: true, } as any); defineRoleMappingPostRoutes(mockRouteDefinitionParams); 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 5cc6c5ae48d3c..e7d55d93e541a 100644 --- a/x-pack/plugins/security/server/routes/role_mapping/post.ts +++ b/x-pack/plugins/security/server/routes/role_mapping/post.ts @@ -49,7 +49,7 @@ export function defineRoleMappingPostRoutes({ router }: RouteDefinitionParams) { name: request.params.name, body: request.body, }); - return response.ok({ body: saveResponse.body }); + return response.ok({ body: saveResponse }); } catch (error) { const wrappedError = wrapError(error); return response.customError({ diff --git a/x-pack/plugins/security/server/routes/users/get.ts b/x-pack/plugins/security/server/routes/users/get.ts index 78f8056164eec..8844ed0da4ea7 100644 --- a/x-pack/plugins/security/server/routes/users/get.ts +++ b/x-pack/plugins/security/server/routes/users/get.ts @@ -22,10 +22,9 @@ export function defineGetUserRoutes({ router }: RouteDefinitionParams) { createLicensedRouteHandler(async (context, request, response) => { try { const username = request.params.username; - const { body: users } = - await context.core.elasticsearch.client.asCurrentUser.security.getUser({ - username, - }); + const users = await context.core.elasticsearch.client.asCurrentUser.security.getUser({ + username, + }); if (!users[username]) { return response.notFound(); 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 5d28d98b684ec..4572d3929fed3 100644 --- a/x-pack/plugins/security/server/routes/users/get_all.ts +++ b/x-pack/plugins/security/server/routes/users/get_all.ts @@ -17,7 +17,7 @@ export function defineGetAllUsersRoutes({ router }: RouteDefinitionParams) { 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 + await context.core.elasticsearch.client.asCurrentUser.security.getUser() ), }); } catch (error) { diff --git a/x-pack/plugins/security/server/security_checkup/check_cluster_data.test.ts b/x-pack/plugins/security/server/security_checkup/check_cluster_data.test.ts index 396e06bd1d04e..95ad22c79c1fb 100644 --- a/x-pack/plugins/security/server/security_checkup/check_cluster_data.test.ts +++ b/x-pack/plugins/security/server/security_checkup/check_cluster_data.test.ts @@ -12,9 +12,7 @@ import { createClusterDataCheck } from './check_cluster_data'; describe('checkClusterForUserData', () => { it('returns false if no data is found', async () => { const esClient = elasticsearchServiceMock.createElasticsearchClient(); - esClient.cat.indices.mockResolvedValue( - elasticsearchServiceMock.createApiResponse({ body: [] }) - ); + esClient.cat.indices.mockResponse([]); const log = loggingSystemMock.createLogger(); @@ -25,24 +23,20 @@ describe('checkClusterForUserData', () => { it('returns false if data only exists in system indices', async () => { const esClient = elasticsearchServiceMock.createElasticsearchClient(); - esClient.cat.indices.mockResolvedValue( - elasticsearchServiceMock.createApiResponse({ - body: [ - { - index: '.kibana', - 'docs.count': '500', - }, - { - index: 'kibana_sample_ecommerce_data', - 'docs.count': '20', - }, - { - index: '.somethingElse', - 'docs.count': '20', - }, - ], - }) - ); + esClient.cat.indices.mockResponse([ + { + index: '.kibana', + 'docs.count': '500', + }, + { + index: 'kibana_sample_ecommerce_data', + 'docs.count': '20', + }, + { + index: '.somethingElse', + 'docs.count': '20', + }, + ]); const log = loggingSystemMock.createLogger(); @@ -53,20 +47,16 @@ describe('checkClusterForUserData', () => { it('returns true if data exists in non-system indices', async () => { const esClient = elasticsearchServiceMock.createElasticsearchClient(); - esClient.cat.indices.mockResolvedValue( - elasticsearchServiceMock.createApiResponse({ - body: [ - { - index: '.kibana', - 'docs.count': '500', - }, - { - index: 'some_real_index', - 'docs.count': '20', - }, - ], - }) - ); + esClient.cat.indices.mockResponse([ + { + index: '.kibana', + 'docs.count': '500', + }, + { + index: 'some_real_index', + 'docs.count': '20', + }, + ]); const log = loggingSystemMock.createLogger(); @@ -77,32 +67,20 @@ describe('checkClusterForUserData', () => { it('checks each time until the first true response is returned, then stops checking', async () => { const esClient = elasticsearchServiceMock.createElasticsearchClient(); esClient.cat.indices - .mockResolvedValueOnce( - elasticsearchServiceMock.createApiResponse({ - body: [], - }) - ) + .mockResponseOnce([]) .mockRejectedValueOnce(new Error('something terrible happened')) - .mockResolvedValueOnce( - elasticsearchServiceMock.createApiResponse({ - body: [ - { - index: '.kibana', - 'docs.count': '500', - }, - ], - }) - ) - .mockResolvedValueOnce( - elasticsearchServiceMock.createApiResponse({ - body: [ - { - index: 'some_real_index', - 'docs.count': '20', - }, - ], - }) - ); + .mockResponseOnce([ + { + index: '.kibana', + 'docs.count': '500', + }, + ]) + .mockResponseOnce([ + { + index: 'some_real_index', + 'docs.count': '20', + }, + ]); const log = loggingSystemMock.createLogger(); diff --git a/x-pack/plugins/security/server/security_checkup/check_cluster_data.ts b/x-pack/plugins/security/server/security_checkup/check_cluster_data.ts index bec8adfdc4f6b..03d2d89e70034 100644 --- a/x-pack/plugins/security/server/security_checkup/check_cluster_data.ts +++ b/x-pack/plugins/security/server/security_checkup/check_cluster_data.ts @@ -17,7 +17,7 @@ export const createClusterDataCheck = () => { format: 'json', h: ['index', 'docs.count'], }); - clusterHasUserData = indices.body.some((indexCount) => { + clusterHasUserData = indices.some((indexCount) => { const isInternalIndex = indexCount.index?.startsWith('.') || indexCount.index?.startsWith('kibana_sample_'); diff --git a/x-pack/plugins/security/server/session_management/session_index.test.ts b/x-pack/plugins/security/server/session_management/session_index.test.ts index 1667ae8b400be..94e92a2689fc3 100644 --- a/x-pack/plugins/security/server/session_management/session_index.test.ts +++ b/x-pack/plugins/security/server/session_management/session_index.test.ts @@ -13,8 +13,6 @@ import type { SearchResponse, } from '@elastic/elasticsearch/lib/api/types'; -import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; -import type { ElasticsearchClient } from 'src/core/server'; import { elasticsearchServiceMock, loggingSystemMock } from 'src/core/server/mocks'; import type { AuditLogger } from '../audit'; @@ -25,7 +23,9 @@ import { getSessionIndexTemplate, SessionIndex } from './session_index'; import { sessionIndexMock } from './session_index.mock'; describe('Session index', () => { - let mockElasticsearchClient: DeeplyMockedKeys; + let mockElasticsearchClient: ReturnType< + typeof elasticsearchServiceMock.createElasticsearchClient + >; let sessionIndex: SessionIndex; let auditLogger: AuditLogger; const indexName = '.kibana_some_tenant_security_session_1'; @@ -60,15 +60,9 @@ describe('Session index', () => { } it('debounces initialize calls', async () => { - mockElasticsearchClient.indices.existsTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.existsIndexTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: true }) - ); - mockElasticsearchClient.indices.exists.mockResolvedValue( - securityMock.createApiResponse({ body: true }) - ); + mockElasticsearchClient.indices.existsTemplate.mockResponse(false); + mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true); + mockElasticsearchClient.indices.exists.mockResponse(true); await Promise.all([ sessionIndex.initialize(), @@ -81,15 +75,9 @@ describe('Session index', () => { }); it('does not delete legacy index template if it does not exist and creates neither index template nor index if they exist', async () => { - mockElasticsearchClient.indices.existsTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.existsIndexTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: true }) - ); - mockElasticsearchClient.indices.exists.mockResolvedValue( - securityMock.createApiResponse({ body: true }) - ); + mockElasticsearchClient.indices.existsTemplate.mockResponse(false); + mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true); + mockElasticsearchClient.indices.exists.mockResponse(true); await sessionIndex.initialize(); @@ -101,15 +89,9 @@ describe('Session index', () => { }); it('deletes legacy index template if needed and creates both index template and index if they do not exist', async () => { - mockElasticsearchClient.indices.existsTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: true }) - ); - mockElasticsearchClient.indices.existsIndexTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.exists.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); + mockElasticsearchClient.indices.existsTemplate.mockResponse(true); + mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(false); + mockElasticsearchClient.indices.exists.mockResponse(false); await sessionIndex.initialize(); @@ -127,15 +109,9 @@ describe('Session index', () => { }); it('creates both index template and index if they do not exist', async () => { - mockElasticsearchClient.indices.existsTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.existsIndexTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.exists.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); + mockElasticsearchClient.indices.existsTemplate.mockResponse(false); + mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(false); + mockElasticsearchClient.indices.exists.mockResponse(false); await sessionIndex.initialize(); @@ -151,15 +127,9 @@ describe('Session index', () => { }); it('creates only index template if it does not exist even if index exists', async () => { - mockElasticsearchClient.indices.existsTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.existsIndexTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.exists.mockResolvedValue( - securityMock.createApiResponse({ body: true }) - ); + mockElasticsearchClient.indices.existsTemplate.mockResponse(false); + mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(false); + mockElasticsearchClient.indices.exists.mockResponse(true); await sessionIndex.initialize(); @@ -171,15 +141,9 @@ describe('Session index', () => { }); it('creates only index if it does not exist even if index template exists', async () => { - mockElasticsearchClient.indices.existsTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.existsIndexTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: true }) - ); - mockElasticsearchClient.indices.exists.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); + mockElasticsearchClient.indices.existsTemplate.mockResponse(false); + mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true); + mockElasticsearchClient.indices.exists.mockResponse(false); await sessionIndex.initialize(); @@ -192,15 +156,9 @@ describe('Session index', () => { }); it('does not fail if tries to create index when it exists already', async () => { - mockElasticsearchClient.indices.existsTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); - mockElasticsearchClient.indices.existsIndexTemplate.mockResolvedValue( - securityMock.createApiResponse({ body: true }) - ); - mockElasticsearchClient.indices.exists.mockResolvedValue( - securityMock.createApiResponse({ body: false }) - ); + mockElasticsearchClient.indices.existsTemplate.mockResponse(false); + mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true); + mockElasticsearchClient.indices.exists.mockResponse(false); mockElasticsearchClient.indices.create.mockRejectedValue( new errors.ResponseError( securityMock.createApiResponse({ @@ -217,9 +175,7 @@ describe('Session index', () => { securityMock.createApiResponse(securityMock.createApiResponse({ body: { type: 'Uh oh.' } })) ); mockElasticsearchClient.indices.existsIndexTemplate.mockRejectedValueOnce(unexpectedError); - mockElasticsearchClient.indices.existsIndexTemplate.mockResolvedValueOnce( - securityMock.createApiResponse({ body: true }) - ); + mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true); await expect(sessionIndex.initialize()).rejects.toBe(unexpectedError); await expect(sessionIndex.initialize()).resolves.toBe(undefined); @@ -234,28 +190,17 @@ describe('Session index', () => { sort: [0], }; beforeEach(() => { - mockElasticsearchClient.openPointInTime.mockResolvedValue( - securityMock.createApiResponse({ - body: { id: 'PIT_ID' } as OpenPointInTimeResponse, - }) - ); - mockElasticsearchClient.closePointInTime.mockResolvedValue( - securityMock.createApiResponse({ - body: { succeeded: true, num_freed: 1 } as ClosePointInTimeResponse, - }) - ); - mockElasticsearchClient.search.mockResolvedValue( - securityMock.createApiResponse({ - body: { - hits: { hits: [sessionValue] }, - } as SearchResponse, - }) - ); - mockElasticsearchClient.bulk.mockResolvedValue( - securityMock.createApiResponse({ - body: { items: [{}] } as BulkResponse, - }) - ); + mockElasticsearchClient.openPointInTime.mockResponse({ + id: 'PIT_ID', + } as OpenPointInTimeResponse); + mockElasticsearchClient.closePointInTime.mockResponse({ + succeeded: true, + num_freed: 1, + } as ClosePointInTimeResponse); + mockElasticsearchClient.search.mockResponse({ + hits: { hits: [sessionValue] }, + } as SearchResponse); + mockElasticsearchClient.bulk.mockResponse({ items: [{}] } as BulkResponse); jest.spyOn(Date, 'now').mockImplementation(() => now); }); @@ -773,13 +718,9 @@ describe('Session index', () => { it('should clean up sessions in batches of 10,000', async () => { for (const count of [10_000, 1]) { - mockElasticsearchClient.search.mockResolvedValueOnce( - securityMock.createApiResponse({ - body: { - hits: { hits: new Array(count).fill(sessionValue, 0) }, - } as SearchResponse, - }) - ); + mockElasticsearchClient.search.mockResponseOnce({ + hits: { hits: new Array(count).fill(sessionValue, 0) }, + } as SearchResponse); } await sessionIndex.cleanUp(); @@ -791,13 +732,9 @@ describe('Session index', () => { }); it('should limit number of batches to 10', async () => { - mockElasticsearchClient.search.mockResolvedValue( - securityMock.createApiResponse({ - body: { - hits: { hits: new Array(10_000).fill(sessionValue, 0) }, - } as SearchResponse, - }) - ); + mockElasticsearchClient.search.mockResponse({ + hits: { hits: new Array(10_000).fill(sessionValue, 0) }, + } as SearchResponse); await sessionIndex.cleanUp(); @@ -829,23 +766,25 @@ describe('Session index', () => { }); it('returns `null` if index is not found', async () => { - mockElasticsearchClient.get.mockResolvedValue( - securityMock.createApiResponse({ - statusCode: 404, - body: { _index: 'my-index', _type: '_doc', _id: '0', found: false }, - }) - ); + mockElasticsearchClient.get.mockResponse({ + _index: 'my-index', + // @ts-expect-error incomplete definition + _type: '_doc', + _id: '0', + found: false, + }); await expect(sessionIndex.get('some-sid')).resolves.toBeNull(); }); it('returns `null` if session index value document is not found', async () => { - mockElasticsearchClient.get.mockResolvedValue( - securityMock.createApiResponse({ - statusCode: 200, - body: { _index: 'my-index', _type: '_doc', _id: '0', found: false }, - }) - ); + mockElasticsearchClient.get.mockResponse({ + _index: 'my-index', + // @ts-expect-error incomplete definition + _type: '_doc', + _id: '0', + found: false, + }); await expect(sessionIndex.get('some-sid')).resolves.toBeNull(); }); @@ -859,20 +798,16 @@ describe('Session index', () => { content: 'some-encrypted-content', }; - mockElasticsearchClient.get.mockResolvedValue( - securityMock.createApiResponse({ - statusCode: 200, - body: { - found: true, - _index: 'my-index', - _type: '_doc', - _id: '0', - _source: indexDocumentSource, - _primary_term: 1, - _seq_no: 456, - }, - }) - ); + mockElasticsearchClient.get.mockResponse({ + found: true, + _index: 'my-index', + // @ts-expect-error incomplete definition + _type: '_doc', + _id: '0', + _source: indexDocumentSource, + _primary_term: 1, + _seq_no: 456, + }); await expect(sessionIndex.get('some-sid')).resolves.toEqual({ ...indexDocumentSource, @@ -883,7 +818,7 @@ describe('Session index', () => { expect(mockElasticsearchClient.get).toHaveBeenCalledTimes(1); expect(mockElasticsearchClient.get).toHaveBeenCalledWith( { id: 'some-sid', index: indexName }, - { ignore: [404] } + { ignore: [404], meta: true } ); }); }); @@ -908,19 +843,15 @@ describe('Session index', () => { }); it('properly stores session value in the index', async () => { - mockElasticsearchClient.create.mockResolvedValue( - securityMock.createApiResponse({ - body: { - _shards: { total: 1, failed: 0, successful: 1, skipped: 0 }, - _index: 'my-index', - _id: 'W0tpsmIBdwcYyG50zbta', - _version: 1, - _primary_term: 321, - _seq_no: 654, - result: 'created', - }, - }) - ); + mockElasticsearchClient.create.mockResponse({ + _shards: { total: 1, failed: 0, successful: 1, skipped: 0 }, + _index: 'my-index', + _id: 'W0tpsmIBdwcYyG50zbta', + _version: 1, + _primary_term: 321, + _seq_no: 654, + result: 'created', + }); const sid = 'some-long-sid'; const sessionValue = { @@ -966,33 +897,27 @@ describe('Session index', () => { content: 'some-updated-encrypted-content', }; - mockElasticsearchClient.get.mockResolvedValue( - securityMock.createApiResponse({ - statusCode: 200, - body: { - _index: 'my-index', - _type: '_doc', - _id: '0', - _source: latestSessionValue, - _primary_term: 321, - _seq_no: 654, - found: true, - }, - }) - ); - mockElasticsearchClient.index.mockResolvedValue( - securityMock.createApiResponse({ - statusCode: 409, - body: { - _shards: { total: 1, failed: 0, successful: 1, skipped: 0 }, - _index: 'my-index', - _id: 'W0tpsmIBdwcYyG50zbta', - _version: 1, - _primary_term: 321, - _seq_no: 654, - result: 'updated', - }, - }) + mockElasticsearchClient.get.mockResponse({ + _index: 'my-index', + // @ts-expect-error incomplete definition + _type: '_doc', + _id: '0', + _source: latestSessionValue, + _primary_term: 321, + _seq_no: 654, + found: true, + }); + mockElasticsearchClient.index.mockResponse( + { + _shards: { total: 1, failed: 0, successful: 1, skipped: 0 }, + _index: 'my-index', + _id: 'W0tpsmIBdwcYyG50zbta', + _version: 1, + _primary_term: 321, + _seq_no: 654, + result: 'updated', + }, + { statusCode: 409 } ); const sid = 'some-long-sid'; @@ -1020,25 +945,20 @@ describe('Session index', () => { if_primary_term: 123, refresh: 'wait_for', }, - { ignore: [409] } + { ignore: [409], meta: true } ); }); it('properly stores session value in the index', async () => { - mockElasticsearchClient.index.mockResolvedValue( - securityMock.createApiResponse({ - statusCode: 200, - body: { - _shards: { total: 1, failed: 0, successful: 1, skipped: 0 }, - _index: 'my-index', - _id: 'W0tpsmIBdwcYyG50zbta', - _version: 1, - _primary_term: 321, - _seq_no: 654, - result: 'created', - }, - }) - ); + mockElasticsearchClient.index.mockResponse({ + _shards: { total: 1, failed: 0, successful: 1, skipped: 0 }, + _index: 'my-index', + _id: 'W0tpsmIBdwcYyG50zbta', + _version: 1, + _primary_term: 321, + _seq_no: 654, + result: 'created', + }); const sid = 'some-long-sid'; const metadata = { primaryTerm: 123, sequenceNumber: 456 }; @@ -1066,16 +986,14 @@ describe('Session index', () => { if_primary_term: 123, refresh: 'wait_for', }, - { ignore: [409] } + { ignore: [409], meta: true } ); }); }); describe('#invalidate', () => { beforeEach(() => { - mockElasticsearchClient.deleteByQuery.mockResolvedValue( - securityMock.createApiResponse({ body: { deleted: 10 } }) - ); + mockElasticsearchClient.deleteByQuery.mockResponse({ deleted: 10 }); }); it('[match=sid] throws if call to Elasticsearch fails', async () => { @@ -1095,7 +1013,7 @@ describe('Session index', () => { expect(mockElasticsearchClient.delete).toHaveBeenCalledTimes(1); expect(mockElasticsearchClient.delete).toHaveBeenCalledWith( { id: 'some-long-sid', index: indexName, refresh: 'wait_for' }, - { ignore: [404] } + { ignore: [404], meta: true } ); }); diff --git a/x-pack/plugins/security/server/session_management/session_index.ts b/x-pack/plugins/security/server/session_management/session_index.ts index e064a735bc031..8a69b9b7f0043 100644 --- a/x-pack/plugins/security/server/session_management/session_index.ts +++ b/x-pack/plugins/security/server/session_management/session_index.ts @@ -182,7 +182,7 @@ export class SessionIndex { const { body: response, statusCode } = await this.options.elasticsearchClient.get( { id: sid, index: this.indexName }, - { ignore: [404] } + { ignore: [404], meta: true } ); const docNotFound = response.found === false; @@ -217,18 +217,17 @@ export class SessionIndex { const { sid, ...sessionValueToStore } = sessionValue; try { - const { - body: { _primary_term: primaryTerm, _seq_no: sequenceNumber }, - } = await this.options.elasticsearchClient.create({ - id: sid, - // We cannot control whether index is created automatically during this operation or not. - // But we can reduce probability of getting into a weird state when session is being created - // while session index is missing for some reason. This way we'll recreate index with a - // proper name and alias. But this will only work if we still have a proper index template. - index: this.indexName, - body: sessionValueToStore, - refresh: 'wait_for', - }); + const { _primary_term: primaryTerm, _seq_no: sequenceNumber } = + await this.options.elasticsearchClient.create({ + id: sid, + // We cannot control whether index is created automatically during this operation or not. + // But we can reduce probability of getting into a weird state when session is being created + // while session index is missing for some reason. This way we'll recreate index with a + // proper name and alias. But this will only work if we still have a proper index template. + index: this.indexName, + body: sessionValueToStore, + refresh: 'wait_for', + }); return { ...sessionValue, metadata: { primaryTerm, sequenceNumber } } as SessionIndexValue; } catch (err) { @@ -253,7 +252,7 @@ export class SessionIndex { if_primary_term: metadata.primaryTerm, refresh: 'wait_for', }, - { ignore: [409] } + { ignore: [409], meta: true } ); // We don't want to override changes that were made after we fetched session value or @@ -288,7 +287,7 @@ export class SessionIndex { // over any updates that could happen in the meantime. const { statusCode } = await this.options.elasticsearchClient.delete( { id: filter.sid, index: this.indexName, refresh: 'wait_for' }, - { ignore: [404] } + { ignore: [404], meta: true } ); // 404 means the session with such SID wasn't found and hence nothing was removed. @@ -321,7 +320,7 @@ export class SessionIndex { } try { - const { body: response } = await this.options.elasticsearchClient.deleteByQuery({ + const response = await this.options.elasticsearchClient.deleteByQuery({ index: this.indexName, refresh: true, body: { query: deleteQuery }, @@ -347,11 +346,11 @@ export class SessionIndex { // Check if legacy index template exists, and remove it if it does. let legacyIndexTemplateExists = false; try { - legacyIndexTemplateExists = ( - await this.options.elasticsearchClient.indices.existsTemplate({ + legacyIndexTemplateExists = await this.options.elasticsearchClient.indices.existsTemplate( + { name: sessionIndexTemplateName, - }) - ).body; + } + ); } catch (err) { this.options.logger.error( `Failed to check if session legacy index template exists: ${err.message}` @@ -376,11 +375,9 @@ export class SessionIndex { // Check if required index template exists. let indexTemplateExists = false; try { - indexTemplateExists = ( - await this.options.elasticsearchClient.indices.existsIndexTemplate({ - name: sessionIndexTemplateName, - }) - ).body; + indexTemplateExists = await this.options.elasticsearchClient.indices.existsIndexTemplate({ + name: sessionIndexTemplateName, + }); } catch (err) { this.options.logger.error( `Failed to check if session index template exists: ${err.message}` @@ -407,9 +404,9 @@ export class SessionIndex { // always enabled, so we create session index explicitly. let indexExists = false; try { - indexExists = ( - await this.options.elasticsearchClient.indices.exists({ index: this.indexName }) - ).body; + indexExists = await this.options.elasticsearchClient.indices.exists({ + index: this.indexName, + }); } catch (err) { this.options.logger.error(`Failed to check if session index exists: ${err.message}`); return reject(err); @@ -460,7 +457,7 @@ export class SessionIndex { operations.push({ delete: { _id } }); }); if (operations.length > 0) { - const { body: bulkResponse } = await this.options.elasticsearchClient.bulk( + const bulkResponse = await this.options.elasticsearchClient.bulk( { index: this.indexName, operations, @@ -558,7 +555,7 @@ export class SessionIndex { }); } - const { body: openPitResponse } = await this.options.elasticsearchClient.openPointInTime({ + const openPitResponse = await this.options.elasticsearchClient.openPointInTime({ index: this.indexName, keep_alive: SESSION_INDEX_CLEANUP_KEEP_ALIVE, }); @@ -566,16 +563,15 @@ export class SessionIndex { try { let searchAfter: SortResults | undefined; for (let i = 0; i < SESSION_INDEX_CLEANUP_BATCH_LIMIT; i++) { - const { body: searchResponse } = - await this.options.elasticsearchClient.search({ - pit: { id: openPitResponse.id, keep_alive: SESSION_INDEX_CLEANUP_KEEP_ALIVE }, - _source_includes: 'usernameHash,provider', - query: { bool: { should: deleteQueries } }, - search_after: searchAfter, - size: SESSION_INDEX_CLEANUP_BATCH_SIZE, - sort: '_shard_doc', - track_total_hits: false, // for performance - }); + const searchResponse = await this.options.elasticsearchClient.search({ + pit: { id: openPitResponse.id, keep_alive: SESSION_INDEX_CLEANUP_KEEP_ALIVE }, + _source_includes: 'usernameHash,provider', + query: { bool: { should: deleteQueries } }, + search_after: searchAfter, + size: SESSION_INDEX_CLEANUP_BATCH_SIZE, + sort: '_shard_doc', + track_total_hits: false, // for performance + }); const { hits } = searchResponse.hits; if (hits.length > 0) { yield hits; diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/metadata/check_metadata_transforms_task.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/metadata/check_metadata_transforms_task.test.ts index 5dcdacd0921a8..b15101bf3cdb3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/metadata/check_metadata_transforms_task.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/metadata/check_metadata_transforms_task.test.ts @@ -132,22 +132,28 @@ describe('check metadata transforms task', () => { it('should stop task if transform stats response fails', async () => { esClient.transform.getTransformStats.mockRejectedValue({}); await runTask(); - expect(esClient.transform.getTransformStats).toHaveBeenCalledWith({ - transform_id: METADATA_TRANSFORMS_PATTERN, - }); + expect(esClient.transform.getTransformStats).toHaveBeenCalledWith( + { + transform_id: METADATA_TRANSFORMS_PATTERN, + }, + { meta: true } + ); expect(esClient.transform.stopTransform).not.toHaveBeenCalled(); expect(esClient.transform.startTransform).not.toHaveBeenCalled(); }); it('should attempt transform restart if failing state', async () => { const transformStatsResponseMock = buildFailedStatsResponse(); - esClient.transform.getTransformStats.mockResolvedValue(transformStatsResponseMock); + esClient.transform.getTransformStats.mockResponse(transformStatsResponseMock.body); const taskResponse = (await runTask()) as RunResult; - expect(esClient.transform.getTransformStats).toHaveBeenCalledWith({ - transform_id: METADATA_TRANSFORMS_PATTERN, - }); + expect(esClient.transform.getTransformStats).toHaveBeenCalledWith( + { + transform_id: METADATA_TRANSFORMS_PATTERN, + }, + { meta: true } + ); expect(esClient.transform.stopTransform).toHaveBeenCalledWith({ transform_id: failedTransformId, allow_no_match: true, @@ -165,7 +171,7 @@ describe('check metadata transforms task', () => { it('should correctly track transform restart attempts', async () => { const transformStatsResponseMock = buildFailedStatsResponse(); - esClient.transform.getTransformStats.mockResolvedValue(transformStatsResponseMock); + esClient.transform.getTransformStats.mockResponse(transformStatsResponseMock.body); esClient.transform.stopTransform.mockRejectedValueOnce({}); let taskResponse = (await runTask()) as RunResult; @@ -196,7 +202,7 @@ describe('check metadata transforms task', () => { it('should correctly back off subsequent restart attempts', async () => { let transformStatsResponseMock = buildFailedStatsResponse(); - esClient.transform.getTransformStats.mockResolvedValue(transformStatsResponseMock); + esClient.transform.getTransformStats.mockResponse(transformStatsResponseMock.body); esClient.transform.stopTransform.mockRejectedValueOnce({}); let taskStartedAt = new Date(); @@ -263,7 +269,7 @@ describe('check metadata transforms task', () => { ], }, } as unknown as TransportResult; - esClient.transform.getTransformStats.mockResolvedValue(transformStatsResponseMock); + esClient.transform.getTransformStats.mockResponse(transformStatsResponseMock.body); taskResponse = (await runTask({ ...MOCK_TASK_INSTANCE, state: taskResponse.state, @@ -302,7 +308,7 @@ describe('check metadata transforms task', () => { count: 1, }, } as unknown as TransportResult; - esClient.transform.getTransformStats.mockResolvedValue(transformStatsResponseMock); + esClient.transform.getTransformStats.mockResponse(transformStatsResponseMock.body); }); it('should reinstall if missing transforms', async () => { @@ -417,7 +423,7 @@ describe('check metadata transforms task', () => { count: 2, }, } as unknown as TransportResult; - esClient.transform.getTransformStats.mockResolvedValue(goodTransformStatsResponseMock); + esClient.transform.getTransformStats.mockResponse(goodTransformStatsResponseMock.body); taskResponse = (await runTask({ ...MOCK_TASK_INSTANCE, state: taskResponse.state, diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/metadata/check_metadata_transforms_task.ts b/x-pack/plugins/security_solution/server/endpoint/lib/metadata/check_metadata_transforms_task.ts index 3d96cab82779a..39c93e748d75b 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/metadata/check_metadata_transforms_task.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/metadata/check_metadata_transforms_task.ts @@ -110,9 +110,12 @@ export class CheckMetadataTransformsTask { let transformStatsResponse: TransportResult; try { - transformStatsResponse = await esClient?.transform.getTransformStats({ - transform_id: METADATA_TRANSFORMS_PATTERN, - }); + transformStatsResponse = await esClient?.transform.getTransformStats( + { + transform_id: METADATA_TRANSFORMS_PATTERN, + }, + { meta: true } + ); } catch (e) { const err = wrapErrorIfNeeded(e); const errMessage = `failed to get transform stats with error: ${err}`; 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 f5ab180a14cee..fe35d4689b487 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 @@ -235,7 +235,8 @@ describe('Action Log API', () => { hasFleetResponses?: boolean; hasResponses?: boolean; }) => { - esClientMock.asInternalUser.search = jest.fn().mockImplementationOnce(() => { + // @ts-expect-error incomplete types + esClientMock.asInternalUser.search.mockResponseImplementationOnce(() => { let actions: Results[] = []; let fleetActions: Results[] = []; let responses: Results[] = []; @@ -276,12 +277,13 @@ describe('Action Log API', () => { ...fleetResponses, ]); - return Promise.resolve(results); + return results; }); }; havingErrors = () => { - esClientMock.asInternalUser.search = jest.fn().mockImplementationOnce(() => + esClientMock.asInternalUser.search.mockImplementationOnce(() => + // @ts-expect-error wrong definition Promise.resolve(() => { throw new Error(); }) 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 a5d0f85d713a4..859a0cc06348a 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 @@ -184,12 +184,15 @@ export const isolationRequestHandler = function ( // write the action request to the new endpoint index if (doesLogsEndpointActionsDsExist) { try { - logsEndpointActionsResult = await esClient.index({ - index: `${ENDPOINT_ACTIONS_DS}-default`, - body: { - ...doc, + logsEndpointActionsResult = await esClient.index( + { + index: `${ENDPOINT_ACTIONS_DS}-default`, + body: { + ...doc, + }, }, - }); + { meta: true } + ); if (logsEndpointActionsResult.statusCode !== 201) { return res.customError({ statusCode: 500, @@ -208,16 +211,19 @@ export const isolationRequestHandler = function ( // write actions to .fleet-actions index try { - fleetActionIndexResult = await esClient.index({ - index: AGENT_ACTIONS_INDEX, - body: { - ...doc.EndpointActions, - '@timestamp': doc['@timestamp'], - agents, - timeout: 300, // 5 minutes - user_id: doc.user.id, + fleetActionIndexResult = await esClient.index( + { + index: AGENT_ACTIONS_INDEX, + body: { + ...doc.EndpointActions, + '@timestamp': doc['@timestamp'], + agents, + timeout: 300, // 5 minutes + user_id: doc.user.id, + }, }, - }); + { meta: true } + ); if (fleetActionIndexResult.statusCode !== 201) { return res.customError({ diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.test.ts index 50bff936d488d..a239ae03ce135 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/status.test.ts @@ -114,7 +114,7 @@ describe('Endpoint Action Status', () => { responses: MockResponse[], endpointResponses?: MockEndpointResponse[] ) => { - esClientMock.asInternalUser.search = jest.fn().mockImplementation((req) => { + esClientMock.asInternalUser.search.mockResponseImplementation((req = {}) => { const size = req.size ? req.size : 10; const items: any[] = req.index === '.fleet-actions' @@ -124,9 +124,9 @@ describe('Endpoint Action Status', () => { : responses.splice(0, size); if (items.length > 0) { - return Promise.resolve(mockSearchResult(items.map((x) => x.build()))); + return mockSearchResult(items.map((x) => x.build())); } else { - return Promise.resolve(mockSearchResult()); + return mockSearchResult(); } }); }; @@ -505,7 +505,7 @@ describe('Endpoint Action Status', () => { responses: MockResponse[], endpointResponses?: MockEndpointResponse[] ) => { - esClientMock.asInternalUser.search = jest.fn().mockImplementation((req) => { + esClientMock.asInternalUser.search.mockResponseImplementation((req = {}) => { const size = req.size ? req.size : 10; const items: any[] = req.index === '.fleet-actions' @@ -515,9 +515,9 @@ describe('Endpoint Action Status', () => { : responses.splice(0, size); if (items.length > 0) { - return Promise.resolve(mockSearchResult(items.map((x) => x.build()))); + return mockSearchResult(items.map((x) => x.build())); } else { - return Promise.resolve(mockSearchResult()); + return mockSearchResult(); } }); }; 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 02d13c7c057d1..1d2c589cd15a2 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 @@ -192,7 +192,7 @@ export function getMetadataTransformStatsHandler( allow_no_match: true, }); return response.ok({ - body: transformStats.body, + body: transformStats, }); } catch (error) { return errorHandler(logger, response, error); @@ -366,6 +366,6 @@ async function legacyListMetadataQuery( }); const result = await esClient.search(queryParams); - const hostListQueryResult = queryResponseToHostListResult(result.body); + const hostListQueryResult = queryResponseToHostListResult(result); return mapToHostResultList(queryParams, hostListQueryResult, metadataRequestContext); } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts index ee5a79b1aefff..8998b88391f96 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts @@ -172,12 +172,12 @@ describe('test endpoint routes', () => { const response = legacyMetadataSearchResponseMock( new EndpointDocGenerator().generateHostMetadata() ); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; esSearchMock .mockImplementationOnce(() => { throw new IndexNotFoundException(); }) - .mockImplementationOnce(() => Promise.resolve({ body: response })); + .mockResponseImplementationOnce(() => ({ body: response })); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(HOST_METADATA_LIST_ROUTE) )!; @@ -219,11 +219,10 @@ describe('test endpoint routes', () => { mockAgentClient.listAgents.mockResolvedValue(noUnenrolledAgent); mockAgentPolicyService.getByIds = jest.fn().mockResolvedValueOnce([]); const metadata = new EndpointDocGenerator().generateHostMetadata(); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; - esSearchMock.mockResolvedValueOnce({}); - esSearchMock.mockResolvedValueOnce({ - body: unitedMetadataSearchResponseMock(metadata), - }); + const esSearchMock = mockScopedClient.asInternalUser.search; + // @ts-expect-error incorrect type + esSearchMock.mockResponseOnce(undefined); + esSearchMock.mockResponseOnce(unitedMetadataSearchResponseMock(metadata)); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(HOST_METADATA_LIST_ROUTE) )!; @@ -238,6 +237,7 @@ describe('test endpoint routes', () => { expect(esSearchMock.mock.calls[0][0]?.index).toEqual(METADATA_UNITED_INDEX); expect(esSearchMock.mock.calls[0][0]?.size).toEqual(1); expect(esSearchMock.mock.calls[1][0]?.index).toEqual(METADATA_UNITED_INDEX); + // @ts-expect-error partial definition expect(esSearchMock.mock.calls[1][0]?.body?.query).toEqual({ bool: { must: [ @@ -390,12 +390,12 @@ describe('test endpoint routes', () => { const response = legacyMetadataSearchResponseMock( new EndpointDocGenerator().generateHostMetadata() ); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; esSearchMock .mockImplementationOnce(() => { throw new IndexNotFoundException(); }) - .mockImplementationOnce(() => Promise.resolve({ body: response })); + .mockResponseOnce(response); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(HOST_METADATA_LIST_ROUTE) )!; @@ -427,7 +427,7 @@ describe('test endpoint routes', () => { pageSize: 10, }, }); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; mockAgentClient.getAgentStatusById.mockResolvedValue('error'); mockAgentClient.listAgents.mockResolvedValue(noUnenrolledAgent); @@ -435,12 +435,8 @@ describe('test endpoint routes', () => { .mockImplementationOnce(() => { throw new IndexNotFoundException(); }) - .mockImplementationOnce(() => - Promise.resolve({ - body: legacyMetadataSearchResponseMock( - new EndpointDocGenerator().generateHostMetadata() - ), - }) + .mockResponseOnce( + legacyMetadataSearchResponseMock(new EndpointDocGenerator().generateHostMetadata()) ); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(HOST_METADATA_LIST_ROUTE) @@ -452,6 +448,7 @@ describe('test endpoint routes', () => { mockResponse ); expect(esSearchMock).toHaveBeenCalledTimes(2); + // @ts-expect-error partial definition expect(esSearchMock.mock.calls[1][0]?.body?.query.bool.must_not).toContainEqual({ terms: { 'elastic.agent.id': [ @@ -480,7 +477,7 @@ describe('test endpoint routes', () => { kuery: 'not host.ip:10.140.73.246', }, }); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; mockAgentClient.getAgentStatusById.mockResolvedValue('error'); mockAgentClient.listAgents.mockResolvedValue(noUnenrolledAgent); @@ -488,12 +485,8 @@ describe('test endpoint routes', () => { .mockImplementationOnce(() => { throw new IndexNotFoundException(); }) - .mockImplementationOnce(() => - Promise.resolve({ - body: legacyMetadataSearchResponseMock( - new EndpointDocGenerator().generateHostMetadata() - ), - }) + .mockResponseOnce( + legacyMetadataSearchResponseMock(new EndpointDocGenerator().generateHostMetadata()) ); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(HOST_METADATA_LIST_ROUTE) @@ -508,6 +501,7 @@ describe('test endpoint routes', () => { expect(esSearchMock).toBeCalled(); expect( // KQL filter to be passed through + // @ts-expect-error partial definition esSearchMock.mock.calls[1][0]?.body?.query.bool.must ).toContainEqual({ bool: { @@ -525,6 +519,7 @@ describe('test endpoint routes', () => { }, }, }); + // @ts-expect-error partial definition expect(esSearchMock.mock.calls[1][0]?.body?.query.bool.must).toContainEqual({ bool: { must_not: [ @@ -566,11 +561,9 @@ describe('test endpoint routes', () => { describe('GET endpoint details route', () => { it('should return 404 on no results', async () => { const mockRequest = httpServerMock.createKibanaRequest({ params: { id: 'BADID' } }); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; - esSearchMock.mockImplementationOnce(() => - Promise.resolve({ body: legacyMetadataSearchResponseMock() }) - ); + esSearchMock.mockResponseOnce(legacyMetadataSearchResponseMock()); mockAgentClient.getAgentStatusById.mockResolvedValue('error'); mockAgentClient.getAgent.mockResolvedValue({ @@ -603,10 +596,10 @@ describe('test endpoint routes', () => { const mockRequest = httpServerMock.createKibanaRequest({ params: { id: response.hits.hits[0]._id }, }); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; mockAgentClient.getAgent.mockResolvedValue(agentGenerator.generate({ status: 'online' })); - esSearchMock.mockImplementationOnce(() => Promise.resolve({ body: response })); + esSearchMock.mockResponseOnce(response); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(HOST_METADATA_GET_ROUTE) @@ -637,11 +630,11 @@ describe('test endpoint routes', () => { const mockRequest = httpServerMock.createKibanaRequest({ params: { id: response.hits.hits[0]._id }, }); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; mockAgentClient.getAgent.mockRejectedValue(new AgentNotFoundError('not found')); - esSearchMock.mockImplementationOnce(() => Promise.resolve({ body: response })); + esSearchMock.mockResponseOnce(response); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(HOST_METADATA_GET_ROUTE) @@ -671,14 +664,14 @@ describe('test endpoint routes', () => { const mockRequest = httpServerMock.createKibanaRequest({ params: { id: response.hits.hits[0]._id }, }); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; mockAgentClient.getAgent.mockResolvedValue( agentGenerator.generate({ status: 'error', }) ); - esSearchMock.mockImplementationOnce(() => Promise.resolve({ body: response })); + esSearchMock.mockResponseOnce(response); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(HOST_METADATA_GET_ROUTE) @@ -708,9 +701,9 @@ describe('test endpoint routes', () => { const mockRequest = httpServerMock.createKibanaRequest({ params: { id: response.hits.hits[0]._id }, }); - const esSearchMock = mockScopedClient.asInternalUser.search as jest.Mock; + const esSearchMock = mockScopedClient.asInternalUser.search; - esSearchMock.mockImplementationOnce(() => Promise.resolve({ body: response })); + esSearchMock.mockResponseOnce(response); mockAgentClient.getAgent.mockResolvedValue({ active: false, } as unknown as Agent); @@ -762,9 +755,8 @@ describe('test endpoint routes', () => { ], }; const esClientMock = mockScopedClient.asInternalUser; - (esClientMock.transform.getTransformStats as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ body: expectedResponse }) - ); + // @ts-expect-error incomplete type + esClientMock.transform.getTransformStats.mockResponseOnce(expectedResponse); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => path.startsWith(METADATA_TRANSFORMS_STATUS_ROUTE) )!; 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 b8efa2636d8c7..ac4a1ee25ebbf 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 @@ -56,9 +56,7 @@ describe('test policy response handler', () => { const response = createSearchResponse(new EndpointDocGenerator().generatePolicyResponse()); const hostPolicyResponseHandler = getHostPolicyResponseHandler(); - (mockScopedClient.asCurrentUser.search as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ body: response }) - ); + mockScopedClient.asCurrentUser.search.mockResponseOnce(response); const mockRequest = httpServerMock.createKibanaRequest({ params: { agentId: 'id' }, }); @@ -79,9 +77,7 @@ describe('test policy response handler', () => { it('should return not found when there is no response policy for host', async () => { const hostPolicyResponseHandler = getHostPolicyResponseHandler(); - (mockScopedClient.asCurrentUser.search as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ body: createSearchResponse() }) - ); + mockScopedClient.asCurrentUser.search.mockResponseOnce(createSearchResponse()); const mockRequest = httpServerMock.createKibanaRequest({ params: { agentId: 'id' }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts index 64b2e614d91ee..258e1d8ba45b8 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/service.ts @@ -53,9 +53,9 @@ export async function getPolicyResponseByAgentId( const query = getESQueryPolicyResponseByAgentID(agentID, index); const response = await dataClient.asCurrentUser.search(query); - if (response.body.hits.hits.length > 0 && response.body.hits.hits[0]._source != null) { + if (response.hits.hits.length > 0 && response.hits.hits[0]._source != null) { return { - policy_response: response.body.hits.hits[0]._source, + policy_response: response.hits.hits[0]._source, }; } 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 6031ca9a6f5ae..f2b29897e2f26 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 @@ -109,7 +109,7 @@ export function handleEntities(): RequestHandler hit._source); + return response.hits.hits.map((hit) => hit._source); } } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/descendants.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/descendants.ts index 989d695de4d62..83deae716e12e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/descendants.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/descendants.ts @@ -6,7 +6,6 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { TransportResult } from '@elastic/elasticsearch'; import { IScopedClusterClient } from 'src/core/server'; import { JsonObject, JsonValue } from '@kbn/utility-types'; import { FieldsObject, ResolverSchema } from '../../../../../../common/endpoint/types'; @@ -26,6 +25,7 @@ export class DescendantsQuery { private readonly indexPatterns: string | string[]; private readonly timeRange: TimeRange; private readonly docValueFields: JsonValue[]; + constructor({ schema, indexPatterns, timeRange }: DescendantsParams) { this.docValueFields = docValueFields(schema); this.schema = schema; @@ -198,7 +198,7 @@ export class DescendantsQuery { return []; } - let response: TransportResult>; + let response: estypes.SearchResponse; if (this.schema.ancestry) { response = await client.asCurrentUser.search({ body: this.queryWithAncestryArray(validNodes, this.schema.ancestry, limit), @@ -220,6 +220,6 @@ export class DescendantsQuery { * So the schema fields are flattened ('process.parent.entity_id') */ // @ts-expect-error @elastic/elasticsearch _source is optional - return response.body.hits.hits.map((hit) => hit.fields); + return response.hits.hits.map((hit) => hit.fields); } } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/lifecycle.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/lifecycle.ts index 0ea8f672aad64..c8a850b49c756 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/lifecycle.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/lifecycle.ts @@ -91,7 +91,7 @@ export class LifecycleQuery { return []; } - const response = await client.asCurrentUser.search({ + const body = await client.asCurrentUser.search({ body: this.query(validNodes), index: this.indexPatterns, }); @@ -105,6 +105,6 @@ export class LifecycleQuery { * So the schema fields are flattened ('process.parent.entity_id') */ // @ts-expect-error @elastic/elasticsearch _source is optional - return response.body.hits.hits.map((hit) => hit.fields); + return body.hits.hits.map((hit) => hit.fields); } } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/stats.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/stats.ts index 5365fddbd436b..6459792147217 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/stats.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/tree/queries/stats.ts @@ -123,13 +123,13 @@ export class StatsQuery { } // leaving unknown here because we don't actually need the hits part of the body - const response = await client.asCurrentUser.search({ + const body = await client.asCurrentUser.search({ body: this.query(nodes), index: this.indexPatterns, }); // @ts-expect-error declare aggegations type explicitly - return response.body.aggregations?.ids?.buckets.reduce( + return body.aggregations?.ids?.buckets.reduce( (cummulative: Record, bucket: CategoriesAgg) => ({ ...cummulative, [bucket.key]: StatsQuery.getEventStats(bucket), diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions.ts index 93a3da27a7d5a..876949a7ac291 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions.ts @@ -212,7 +212,7 @@ export const getPendingActionCounts = async ( { ignore: [404] } ) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - .then((result) => result.body?.hits?.hits?.map((a) => a._source!) || []) + .then((result) => result?.hits?.hits?.map((a) => a._source!) || []) .catch(catchAndWrapError); // retrieve any responses to those action IDs from these agents @@ -305,9 +305,7 @@ const hasEndpointResponseDoc = async ({ }, { ignore: [404] } ) - .then( - (result) => result.body?.hits?.hits?.map((a) => a._source?.EndpointActions.action_id) || [] - ) + .then((result) => result?.hits?.hits?.map((a) => a._source?.EndpointActions.action_id) || []) .catch(catchAndWrapError); return response.filter((action): action is string => action !== undefined); }; @@ -354,7 +352,7 @@ const fetchActionResponses = async ( { ignore: [404] } ) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - .then((result) => result.body?.hits?.hits?.map((a) => a._source!) || []) + .then((result) => result?.hits?.hits?.map((a) => a._source!) || []) .catch(catchAndWrapError); if (actionResponses.length === 0) { diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.test.ts index bf920420d7a8b..24fdfd15ed105 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.test.ts @@ -46,11 +46,7 @@ describe('EndpointMetadataService', () => { beforeEach(() => { fleetAgentIds = ['one', 'two']; endpointMetadataDoc = endpointDocGenerator.generateHostMetadata(); - esClient.search.mockReturnValue( - elasticsearchServiceMock.createSuccessTransportRequestPromise( - legacyMetadataSearchResponseMock(endpointMetadataDoc) - ) - ); + esClient.search.mockResponse(legacyMetadataSearchResponseMock(endpointMetadataDoc)); }); it('should call elasticsearch with proper filter', async () => { @@ -79,28 +75,23 @@ describe('EndpointMetadataService', () => { describe('#doesUnitedIndexExist', () => { it('should return true if united index found', async () => { - const esMockResponse = elasticsearchServiceMock.createSuccessTransportRequestPromise( - unitedMetadataSearchResponseMock() - ); - esClient.search.mockResolvedValue(esMockResponse); + esClient.search.mockResponse(unitedMetadataSearchResponseMock()); const doesIndexExist = await metadataService.doesUnitedIndexExist(esClient); expect(doesIndexExist).toEqual(true); }); it('should return false if united index not found', async () => { - const esMockResponse = elasticsearchServiceMock.createErrorTransportRequestPromise({ + esClient.search.mockRejectedValue({ meta: { body: { error: { type: 'index_not_found_exception' } } }, }); - esClient.search.mockResolvedValue(esMockResponse); const doesIndexExist = await metadataService.doesUnitedIndexExist(esClient); expect(doesIndexExist).toEqual(false); }); it('should throw wrapped error if es error other than index not found', async () => { - const esMockResponse = elasticsearchServiceMock.createErrorTransportRequestPromise({}); - esClient.search.mockResolvedValue(esMockResponse); + esClient.search.mockRejectedValue({}); const response = metadataService.doesUnitedIndexExist(esClient); await expect(response).rejects.toThrow(EndpointError); }); @@ -115,8 +106,7 @@ describe('EndpointMetadataService', () => { }); it('should throw wrapped error if es error', async () => { - const esMockResponse = elasticsearchServiceMock.createErrorTransportRequestPromise({}); - esClient.search.mockResolvedValue(esMockResponse); + esClient.search.mockRejectedValue({}); const metadataListResponse = metadataService.getHostMetadataList( esClient, testMockedContext.fleetServices, @@ -154,11 +144,7 @@ describe('EndpointMetadataService', () => { policy_revision: agentPolicies[0].revision, } as unknown as Agent; const mockDoc = unitedMetadataSearchResponseMock(endpointMetadataDoc, mockAgent); - const esMockResponse = await elasticsearchServiceMock.createSuccessTransportRequestPromise( - mockDoc - ); - - esClient.search.mockResolvedValue(esMockResponse); + esClient.search.mockResponse(mockDoc); agentPolicyServiceMock.getByIds.mockResolvedValue(agentPolicies); testMockedContext.packagePolicyService.list.mockImplementation( async (_, { page, perPage }) => { diff --git a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts index 857b9ca18163c..7ddebf93bb025 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/metadata/endpoint_metadata_service.ts @@ -12,7 +12,6 @@ import { SavedObjectsServiceStart, } from 'kibana/server'; -import { TransportResult } from '@elastic/elasticsearch'; import { SearchTotalHits, SearchResponse } from '@elastic/elasticsearch/lib/api/types'; import { HostInfo, @@ -122,7 +121,7 @@ export class EndpointMetadataService { async getHostMetadata(esClient: ElasticsearchClient, endpointId: string): Promise { const query = getESQueryHostMetadataByID(endpointId); const queryResult = await esClient.search(query).catch(catchAndWrapError); - const endpointMetadata = queryResponseToHostResult(queryResult.body).result; + const endpointMetadata = queryResponseToHostResult(queryResult).result; if (endpointMetadata) { return endpointMetadata; @@ -148,7 +147,7 @@ export class EndpointMetadataService { .search(query, { ignore: [404] }) .catch(catchAndWrapError); - return queryResponseToHostListResult(searchResult.body).resultList; + return queryResponseToHostListResult(searchResult).resultList; } /** @@ -413,7 +412,7 @@ export class EndpointMetadataService { const endpointPolicyIds = endpointPolicies.map((policy) => policy.policy_id); const unitedIndexQuery = await buildUnitedIndexQuery(queryOptions, endpointPolicyIds); - let unitedMetadataQueryResponse: TransportResult, unknown>; + let unitedMetadataQueryResponse: SearchResponse; try { unitedMetadataQueryResponse = await esClient.search(unitedIndexQuery); @@ -423,7 +422,7 @@ export class EndpointMetadataService { throw err; } - const { hits: docs, total: docsCount } = unitedMetadataQueryResponse?.body?.hits || {}; + const { hits: docs, total: docsCount } = unitedMetadataQueryResponse?.hits || {}; const agentPolicyIds: string[] = docs.map((doc) => doc._source?.united?.agent?.policy_id ?? ''); const agentPolicies = 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 f82ce73491e57..bd2cdd7e45a3a 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 @@ -19,7 +19,9 @@ export async function getMetadataForEndpoints( ): Promise { const query = getESQueryHostMetadataByIDs(endpointIDs); const esClient = requestHandlerContext.core.elasticsearch.client.asCurrentUser; - const { body } = await esClient.search(query as estypes.SearchRequest); + const { body } = await esClient.search(query as estypes.SearchRequest, { + meta: true, + }); const hosts = queryResponseToHostListResult(body as estypes.SearchResponse); return hosts.resultList; } 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 4d548141e9819..15d6bb6f6aa28 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; - actionRequests = await esClient.search(actionsSearchQuery, queryOptions); + actionRequests = await esClient.search(actionsSearchQuery, { ...queryOptions, meta: true }); const actionIds = actionRequests?.body?.hits?.hits?.map((e) => { return logsEndpointActionsRegex.test(e._index) ? (e._source as LogsEndpointAction).EndpointActions.action_id @@ -251,7 +251,7 @@ export const getActionResponsesResult = async ({ let actionResponses: TransportResult, unknown>; try { const esClient = context.core.elasticsearch.client.asInternalUser; - actionResponses = await esClient.search(responsesSearchQuery, queryOptions); + actionResponses = await esClient.search(responsesSearchQuery, { ...queryOptions, meta: true }); } catch (error) { logger.error(error); throw error; 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 dea2e46c3c258..fae38da9a8985 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 @@ -19,9 +19,12 @@ export const doLogsEndpointActionDsExists = async ({ }): Promise => { try { const esClient = context.core.elasticsearch.client.asInternalUser; - const doesIndexTemplateExist = await esClient.indices.existsIndexTemplate({ - name: dataStreamName, - }); + const doesIndexTemplateExist = await esClient.indices.existsIndexTemplate( + { + name: dataStreamName, + }, + { meta: true } + ); return doesIndexTemplateExist.statusCode === 404 ? false : true; } catch (error) { const errorType = error?.type ?? ''; @@ -44,9 +47,12 @@ export const doesLogsEndpointActionsIndexExist = async ({ }): Promise => { try { const esClient = context.core.elasticsearch.client.asInternalUser; - const doesIndexExist = await esClient.indices.exists({ - index: indexName, - }); + const doesIndexExist = await esClient.indices.exists( + { + index: indexName, + }, + { meta: true } + ); return doesIndexExist.statusCode === 404 ? false : true; } catch (error) { const errorType = error?.type ?? ''; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.test.ts index 21eb65b075e3f..4fa91bdbfd06d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.test.ts @@ -47,8 +47,7 @@ describe('createMigration', () => { it('returns info about the created migration', async () => { (createMigrationIndex as jest.Mock).mockResolvedValueOnce('destinationIndex'); - // @ts-expect-error minimum stub for our reindex response - esClient.reindex.mockResolvedValueOnce({ body: { task: 'reindexTaskId' } }); + esClient.reindex.mockResponseOnce({ task: 'reindexTaskId' }); const migration = await createMigration({ esClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts index 5f429dc46152e..c17431c117d82 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration.ts @@ -48,7 +48,7 @@ export const createMigration = async ({ const { size, ...reindexQueryOptions } = reindexOptions; - const response = await esClient.reindex<{ task: string }>({ + const response = await esClient.reindex({ body: { dest: { index: migrationIndex }, source: { index, size }, @@ -97,7 +97,7 @@ export const createMigration = async ({ return { destinationIndex: migrationIndex, sourceIndex: index, - taskId: String(response.body.task), + taskId: String(response.task), version, }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration_index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration_index.ts index 2762f9e9dcd6d..0c3da2a114595 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration_index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/create_migration_index.ts @@ -32,7 +32,7 @@ export const createMigrationIndex = async ({ const paddedVersion = `${version}`.padStart(6, '0'); const destinationIndexName = `${index}-r${paddedVersion}`; - const response = await esClient.indices.create<{ index: string }>({ + const response = await esClient.indices.create({ index: destinationIndexName, body: { settings: { @@ -46,5 +46,5 @@ export const createMigrationIndex = async ({ }, }); - return response.body.index; + return response.index; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/finalize_migration.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/finalize_migration.test.ts index 46de2eb133bac..22f4384483715 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/finalize_migration.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/finalize_migration.test.ts @@ -24,7 +24,7 @@ describe('finalizeMigration', () => { // @ts-expect-error stubbing what we use of the task response // all our reindex tasks are completed - esClient.tasks.get.mockResolvedValueOnce({ body: { completed: true } }); + esClient.tasks.get.mockResponse({ completed: true }); // stub out our update call to just return the attributes we passed (updateMigrationSavedObject as jest.Mock).mockImplementation(({ attributes }) => ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/finalize_migration.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/finalize_migration.ts index ca8ae01ee2d1f..b1784d0b2ba1c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/finalize_migration.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/finalize_migration.ts @@ -48,7 +48,7 @@ export const finalizeMigration = async ({ const { destinationIndex, sourceIndex, taskId } = migration.attributes; - const { body: task } = await esClient.tasks.get<{ completed: boolean }>({ task_id: taskId }); + const task = await esClient.tasks.get({ task_id: taskId }); if (!task.completed) { return migration; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_index_versions_by_index.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_index_versions_by_index.test.ts index 32b3ccbf17b57..cd9d8cdb52a77 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_index_versions_by_index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_index_versions_by_index.test.ts @@ -16,8 +16,7 @@ describe('getIndexVersionsByIndex', () => { }); it('returns keys for each specified index', async () => { - // @ts-expect-error mocking only what we need - esClient.indices.getMapping.mockResolvedValue({ body: {} }); + esClient.indices.getMapping.mockResponse({}); const result = await getIndexVersionsByIndex({ esClient, @@ -28,8 +27,7 @@ describe('getIndexVersionsByIndex', () => { }); it('returns undefined values if no mappings are found', async () => { - // @ts-expect-error mocking only what we need - esClient.indices.getMapping.mockResolvedValue({ body: {} }); + esClient.indices.getMapping.mockResponse({}); const result = await getIndexVersionsByIndex({ esClient, @@ -43,11 +41,8 @@ describe('getIndexVersionsByIndex', () => { }); it('properly transforms the response', async () => { - // @ts-expect-error mocking only what we need - esClient.indices.getMapping.mockResolvedValue({ - body: { - index1: { mappings: { _meta: { version: 3 } } }, - }, + esClient.indices.getMapping.mockResponse({ + index1: { mappings: { _meta: { version: 3 } } }, }); const result = await getIndexVersionsByIndex({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_index_versions_by_index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_index_versions_by_index.ts index f912a47892461..2de176cebe6ae 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_index_versions_by_index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_index_versions_by_index.ts @@ -33,7 +33,7 @@ export const getIndexVersionsByIndex = async ({ esClient: ElasticsearchClient; index: string[]; }): Promise => { - const { body: indexVersions } = await esClient.indices.getMapping({ + const indexVersions = await esClient.indices.getMapping({ index, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signal_versions_by_index.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signal_versions_by_index.test.ts index 2cdfa2c13e7b5..2a063a7f7df0e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signal_versions_by_index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signal_versions_by_index.test.ts @@ -16,9 +16,9 @@ describe('getSignalVersionsByIndex', () => { }); it('properly transforms the elasticsearch aggregation', async () => { - esClient.search.mockResolvedValueOnce({ + esClient.search.mockResponseOnce( // @ts-expect-error mocking only what we need - body: { + { aggregations: { signals_indices: { buckets: [ @@ -34,8 +34,8 @@ describe('getSignalVersionsByIndex', () => { ], }, }, - }, - }); + } + ); const result = await getSignalVersionsByIndex({ esClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signal_versions_by_index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signal_versions_by_index.ts index decde16d77a38..a5fd7fbe3ce5a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signal_versions_by_index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signal_versions_by_index.ts @@ -72,7 +72,7 @@ export const getSignalVersionsByIndex = async ({ }, }); - const aggs = response.body.aggregations as SignalVersionsAggResponse['aggregations']; + const aggs = response.aggregations as SignalVersionsAggResponse['aggregations']; const indexBuckets = aggs.signals_indices.buckets; return index.reduce((agg, _index) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signals_indices_in_range.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signals_indices_in_range.ts index 2080289b8d586..a03f64c7b8f48 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signals_indices_in_range.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/migrations/get_signals_indices_in_range.ts @@ -71,6 +71,6 @@ export const getSignalsIndicesInRange = async ({ }, }); - const aggs = response.body.aggregations as IndexesResponse['aggregations']; + const aggs = response.aggregations as IndexesResponse['aggregations']; return aggs.indexes.buckets.map((bucket) => bucket.key); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/get_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/get_signals.ts index 398438234ed71..23a955423f413 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/get_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/get_signals.ts @@ -38,7 +38,7 @@ export const getSignals = async ({ size, }); - const { body: result } = await esClient.search(query); + const result = await esClient.search(query); return result; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts index ae253dfa3438c..20aac86a336e0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts @@ -19,9 +19,8 @@ import { sampleEmptyDocSearchResults, } from '../signals/__mocks__/es_results'; import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE } from '../../../../common/constants'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; + jest.mock('./build_signals_query'); /** @@ -101,10 +100,8 @@ describe('legacyRules_notification_alert_type', () => { references: [], attributes: ruleAlert, }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( - sampleDocSearchResultsWithSortId() - ) + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsWithSortId() ); await alert.executor(payload); @@ -129,10 +126,8 @@ describe('legacyRules_notification_alert_type', () => { references: [], attributes: ruleAlert, }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( - sampleDocSearchResultsWithSortId() - ) + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsWithSortId() ); await alert.executor(payload); @@ -157,10 +152,8 @@ describe('legacyRules_notification_alert_type', () => { references: [], attributes: ruleAlert, }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( - sampleDocSearchResultsWithSortId() - ) + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsWithSortId() ); await alert.executor(payload); expect(alertServices.alertFactory.create).toHaveBeenCalled(); @@ -186,10 +179,8 @@ describe('legacyRules_notification_alert_type', () => { references: [], attributes: ruleAlert, }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( - sampleDocSearchResultsWithSortId() - ) + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsWithSortId() ); await alert.executor(payload); expect(alertServices.alertFactory.create).toHaveBeenCalled(); @@ -212,8 +203,8 @@ describe('legacyRules_notification_alert_type', () => { references: [], attributes: ruleAlert, }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise(sampleEmptyDocSearchResults()) + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleEmptyDocSearchResults() ); await alert.executor(payload); @@ -229,10 +220,8 @@ describe('legacyRules_notification_alert_type', () => { references: [], attributes: ruleAlert, }); - alertServices.scopedClusterClient.asCurrentUser.search.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( - sampleDocSearchResultsNoSortIdNoVersion() - ) + alertServices.scopedClusterClient.asCurrentUser.search.mockResponse( + sampleDocSearchResultsNoSortIdNoVersion() ); await alert.executor(payload); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.test.ts index b5dffa7b34c14..a094a87acfbf6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.test.ts @@ -71,7 +71,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -100,7 +100,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [], total: 0, @@ -130,7 +130,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [], total: 0, @@ -155,7 +155,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -184,7 +184,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -224,7 +224,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -260,7 +260,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -291,7 +291,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -353,7 +353,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -420,7 +420,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -475,7 +475,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { @@ -537,7 +537,7 @@ describe('schedule_throttle_notification_actions', () => { outputIndex: 'output-123', ruleId: 'rule-123', esClient: elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [ { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/check_template_version.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/check_template_version.ts index 0040b5f30afb4..50ec789266aa0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/check_template_version.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/check_template_version.ts @@ -23,7 +23,7 @@ export const getTemplateVersion = async ({ }): Promise => { try { const response = await esClient.indices.getIndexTemplate({ name: alias }); - return response.body.index_templates[0].index_template.version ?? 0; + return response.index_templates[0].index_template.version ?? 0; } catch (e) { return 0; } @@ -42,7 +42,7 @@ export const templateNeedsUpdate = async ({ }; export const fieldAliasesOutdated = async (esClient: ElasticsearchClient, index: string) => { - const { body: indexMappings } = await esClient.indices.get({ index }); + const indexMappings = await esClient.indices.get({ index }); for (const [indexName, mapping] of Object.entries(indexMappings)) { if (indexName.startsWith(`${index}-`)) { const aliasesVersion = get(mapping.mappings?._meta, ALIAS_VERSION_FIELD) ?? 0; 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 f6e2926990556..9bb848b2f7d34 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 @@ -141,7 +141,7 @@ const addFieldAliasesToIndices = async ({ esClient: ElasticsearchClient; index: string; }) => { - const { body: indexMappings } = await esClient.indices.get({ index }); + const indexMappings = await esClient.indices.get({ index }); const indicesByVersion: Record = {}; const versions: Set = new Set(); for (const [indexName, mapping] of Object.entries(indexMappings)) { @@ -182,7 +182,7 @@ const addIndexAliases = async ({ index: string; aadIndexAliasName: string; }) => { - const { body: indices } = await esClient.indices.getAlias({ index: `${index}-*`, name: index }); + const indices = await esClient.indices.getAlias({ index: `${index}-*`, name: index }); const aliasActions = { actions: Object.keys(indices).map((concreteIndexName) => { return { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_index_version.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_index_version.ts index b6f711fc319fb..9d50de51c053c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_index_version.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/index/get_index_version.ts @@ -13,7 +13,7 @@ export const getIndexVersion = async ( esClient: ElasticsearchClient, index: string ): Promise => { - const { body: indexAlias } = await esClient.indices.getAlias({ + const indexAlias = await esClient.indices.getAlias({ index, }); const writeIndex = Object.keys(indexAlias).find( 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 8d89bc66b2041..e4626aaa93216 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 @@ -34,7 +34,7 @@ import { } from '../../../../../../alerting/common'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ExecutorType } from '../../../../../../alerting/server/types'; -import { Alert } from '../../../../../../alerting/server'; +import { Alert, createAbortableEsClientFactory } from '../../../../../../alerting/server'; import { ConfigType } from '../../../../config'; import { alertInstanceFactoryStub } from '../../signals/preview/alert_instance_factory_stub'; import { CreateRuleOptions, CreateSecurityRuleTypeWrapperProps } from '../../rule_types/types'; @@ -182,7 +182,10 @@ export const previewRulesRoute = async ( shouldStopExecution: () => false, alertFactory, // Just use es client always for preview - search: context.core.elasticsearch.client, + search: createAbortableEsClientFactory({ + scopedClusterClient: context.core.elasticsearch.client, + abortController: new AbortController(), + }), savedObjectsClient: context.core.savedObjects.client, scopedClusterClient: context.core.elasticsearch.client, }, 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 39ccf9f158422..54ecd5efcd67c 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 @@ -18,8 +18,6 @@ import { requestContextMock, serverMock, requestMock } from '../__mocks__'; import { SetupPlugins } from '../../../../plugin'; import { createMockTelemetryEventsSender } from '../../../telemetry/__mocks__'; import { setSignalsStatusRoute } from './open_close_signals_route'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { loggingSystemMock } from 'src/core/server/mocks'; describe('set signal status', () => { @@ -32,10 +30,8 @@ describe('set signal status', () => { logger = loggingSystemMock.createLogger(); ({ context } = requestContextMock.createTools()); - context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise( - getSuccessfulSignalUpdateResponse() - ) + context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockResponse( + getSuccessfulSignalUpdateResponse() ); const telemetrySenderMock = createMockTelemetryEventsSender(); const securityMock = { @@ -69,8 +65,8 @@ describe('set signal status', () => { }); test('catches error if asCurrentUser throws error', async () => { - context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockResolvedValue( - elasticsearchClientMock.createErrorTransportRequestPromise(new Error('Test error')) + context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockRejectedValue( + new Error('Test error') ); const response = await server.inject(getSetSignalStatusByQueryRequest(), context); expect(response.status).toEqual(500); 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 3e7a82a3fdbda..bf62d7602b2d9 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 @@ -99,7 +99,7 @@ export const setSignalsStatusRoute = ( }; } try { - const { body } = await esClient.updateByQuery({ + const body = await esClient.updateByQuery({ index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, conflicts: conflicts ?? 'abort', // https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html#_refreshing_shards_2 diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts index 00244832d0191..1096573f81cd3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts @@ -159,13 +159,16 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = if (!wroteWarningStatus) { const timestampFieldCaps = await withSecuritySpan('fieldCaps', () => - services.scopedClusterClient.asCurrentUser.fieldCaps({ - index, - fields: hasTimestampOverride - ? ['@timestamp', timestampOverride as string] - : ['@timestamp'], - include_unmapped: true, - }) + services.scopedClusterClient.asCurrentUser.fieldCaps( + { + index, + fields: hasTimestampOverride + ? ['@timestamp', timestampOverride as string] + : ['@timestamp'], + include_unmapped: true, + }, + { meta: true } + ) ); wroteWarningStatus = await hasTimestampFields({ timestampField: hasTimestampOverride diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_factory.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_factory.ts index 4bfb6149a1d29..a8334cf0a4396 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_factory.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_factory.ts @@ -53,7 +53,7 @@ export const bulkCreateFactory = ]); const start = performance.now(); - const { body: response } = await withSecuritySpan('writeAlertsBulk', () => + const response = await withSecuritySpan('writeAlertsBulk', () => esClient.bulk({ refresh: refreshForBulkCreate, body: bulkBody, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts index 2f5aaec5ea43f..0d7ac2cea493a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts @@ -14,8 +14,6 @@ import { getEntryListMock } from '../../../../../../lists/common/schemas/types/e import { getCompleteRuleMock, getEqlRuleParams } from '../../schemas/rule_schemas.mock'; import { getIndexVersion } from '../../routes/index/get_index_version'; import { SIGNALS_TEMPLATE_VERSION } from '../../routes/index/get_signals_template'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { allowedExperimentalValues } from '../../../../../common/experimental_features'; import { EqlRuleParams } from '../../schemas/rule_schemas'; @@ -38,14 +36,12 @@ describe('eql_executor', () => { beforeEach(() => { alertServices = alertsMock.createAlertServices(); logger = loggingSystemMock.createLogger(); - alertServices.scopedClusterClient.asCurrentUser.transport.request.mockResolvedValue( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - hits: { - total: { value: 10 }, - events: [], - }, - }) - ); + alertServices.scopedClusterClient.asCurrentUser.transport.request.mockResolvedValue({ + hits: { + total: { value: 10 }, + events: [], + }, + }); }); describe('eqlExecutor', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts index 7e83649d3e38b..ac44d1d6470a6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { TransportResult } from '@elastic/elasticsearch'; import { performance } from 'perf_hooks'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { Logger } from 'src/core/server'; @@ -118,9 +117,9 @@ export const eqlExecutor = async ({ ); // TODO: fix this later - const { body: response } = (await services.scopedClusterClient.asCurrentUser.transport.request( + const response = (await services.scopedClusterClient.asCurrentUser.transport.request( request - )) as TransportResult; + )) as EqlSignalSearchResponse; const eqlSignalSearchEnd = performance.now(); const eqlSearchDuration = makeFloatString(eqlSignalSearchEnd - eqlSignalSearchStart); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts index 01f8816bb9ce5..b44c4cbe1661f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts @@ -86,20 +86,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -107,20 +105,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -128,20 +124,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -149,20 +143,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -213,20 +205,18 @@ describe('searchAfterAndBulkCreate', () => { repeatedSearchResultsWithSortId(4, 1, someGuids.slice(0, 3)) ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -234,20 +224,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -255,20 +243,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -319,35 +305,36 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -452,42 +439,40 @@ describe('searchAfterAndBulkCreate', () => { }); test('should return success when empty string sortId present', async () => { - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - _id: someGuids[0], - _index: 'myfakeindex', - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + create: { + _id: someGuids[0], + _index: 'myfakeindex', + status: 201, }, - { - create: { - _id: someGuids[1], - _index: 'myfakeindex', - status: 201, - }, + }, + { + create: { + _id: someGuids[1], + _index: 'myfakeindex', + status: 201, }, - { - create: { - _id: someGuids[2], - _index: 'myfakeindex', - status: 201, - }, + }, + { + create: { + _id: someGuids[2], + _index: 'myfakeindex', + status: 201, }, - { - create: { - _id: someGuids[3], - _index: 'myfakeindex', - status: 201, - }, + }, + { + create: { + _id: someGuids[3], + _index: 'myfakeindex', + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search .mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -594,35 +579,36 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); const exceptionItem = getExceptionListItemSchemaMock(); exceptionItem.entries = [ @@ -667,35 +653,36 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - { - create: { - status: 201, - }, + }, + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -922,9 +909,7 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(bulkItem) - ); // adds the response with errors we are testing + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce(bulkItem); // adds the response with errors we are testing mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -932,20 +917,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -953,20 +936,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -974,20 +955,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -1027,20 +1006,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -1048,20 +1025,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( @@ -1069,20 +1044,18 @@ describe('searchAfterAndBulkCreate', () => { ) ); - mockService.scopedClusterClient.asCurrentUser.bulk.mockResolvedValueOnce( - // @ts-expect-error not full response interface - elasticsearchClientMock.createSuccessTransportRequestPromise({ - took: 100, - errors: false, - items: [ - { - create: { - status: 201, - }, + mockService.scopedClusterClient.asCurrentUser.bulk.mockResponseOnce({ + took: 100, + errors: false, + items: [ + { + // @ts-expect-error not full response interface + create: { + status: 201, }, - ], - }) - ); + }, + ], + }); mockService.search.asCurrentUser.search.mockResolvedValueOnce( elasticsearchClientMock.createSuccessTransportRequestPromise( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/get_event_count.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/get_event_count.ts index 1833491851831..28a994280abed 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/get_event_count.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/get_event_count.ts @@ -29,7 +29,7 @@ export const getEventCount = async ({ timestampOverride, searchAfterSortIds: undefined, }).body.query; - const { body: response } = await esClient.count({ + const response = await esClient.count({ body: { query: eventSearchQueryBodyQuery }, ignore_unavailable: true, index, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/get_threat_list.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/get_threat_list.ts index e51d606cdd52e..f31c1fbfdaec3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/get_threat_list.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/get_threat_list.ts @@ -45,7 +45,7 @@ export const getThreatList = async ({ ) ); - const { body: response } = await esClient.search< + const response = await esClient.search< ThreatListDoc, Record >({ @@ -80,7 +80,7 @@ export const getThreatListCount = async ({ index, exceptionItems ); - const { body: response } = await esClient.count({ + const response = await esClient.count({ body: { query: queryFilter, }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts index 24120277aef76..31e43c694084a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts @@ -193,21 +193,19 @@ export const checkPrivilegesFromEsClient = async ( withSecuritySpan( 'checkPrivilegesFromEsClient', async () => - ( - await esClient.transport.request({ - path: '/_security/user/_has_privileges', - method: 'POST', - body: { - index: [ - { - names: indices ?? [], - allow_restricted_indices: true, - privileges: ['read'], - }, - ], - }, - }) - ).body as Privilege + (await esClient.transport.request({ + path: '/_security/user/_has_privileges', + method: 'POST', + body: { + index: [ + { + names: indices ?? [], + allow_restricted_indices: true, + privileges: ['read'], + }, + ], + }, + })) as Privilege ); export const getNumCatchupIntervals = ({ diff --git a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/helpers.ts b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/helpers.ts index 47218f2731e78..9c920a29529ab 100644 --- a/x-pack/plugins/security_solution/server/lib/sourcerer/routes/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/sourcerer/routes/helpers.ts @@ -20,7 +20,7 @@ export const findExistingIndices = async ( ignore_unavailable: true, allow_no_indices: false, }); - return searchResponse.body.indices.length > 0; + return searchResponse.indices.length > 0; }) .map((p) => p.catch((e) => false)) ); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts b/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts index f96643663b48b..6e24cea41b718 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts @@ -125,6 +125,7 @@ export interface ITelemetryReceiver { type: string; }; } + export class TelemetryReceiver implements ITelemetryReceiver { private readonly logger: Logger; private agentClient?: AgentClient; @@ -219,7 +220,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { }, }; - return this.esClient.search(query); + return this.esClient.search(query, { meta: true }); } public async fetchEndpointMetrics(executeFrom: string, executeTo: string) { @@ -266,7 +267,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { }, }; - return this.esClient.search(query); + return this.esClient.search(query, { meta: true }); } public async fetchDiagnosticAlerts(executeFrom: string, executeTo: string) { @@ -298,7 +299,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { }, }; - return (await this.esClient.search(query)).body; + return this.esClient.search(query); } public async fetchPolicyConfigs(id: string) { @@ -412,7 +413,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { }, }, }; - return this.esClient.search(query); + return this.esClient.search(query, { meta: true }); } public async fetchDetectionExceptionList(listId: string, ruleVersion: number) { @@ -446,8 +447,7 @@ export class TelemetryReceiver implements ITelemetryReceiver { throw Error('elasticsearch client is unavailable: cannot retrieve cluster infomation'); } - const { body } = await this.esClient.info(); - return body; + return this.esClient.info(); } public async fetchLicenseInfo(): Promise { @@ -456,17 +456,15 @@ export class TelemetryReceiver implements ITelemetryReceiver { } try { - const ret = ( - await this.esClient.transport.request({ - method: 'GET', - path: '/_license', - querystring: { - local: true, - }, - }) - ).body as Promise<{ license: ESLicense }>; + const ret = (await this.esClient.transport.request({ + method: 'GET', + path: '/_license', + querystring: { + local: true, + }, + })) as { license: ESLicense }; - return (await ret).license; + return ret.license; } catch (err) { this.logger.debug(`failed retrieving license: ${err}`); return undefined; diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.test.ts index a88fa7d3c43aa..e1c380fc3fcac 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.test.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.test.ts @@ -82,20 +82,19 @@ describe('allHosts search strategy', () => { ); const mockedDeps = mockDeps(); - (mockedDeps.esClient.asCurrentUser.search as jest.Mock).mockResolvedValue({ - body: { - hits: { - hits: [ - { - _source: { - risk, - host: { - name: hostName, - }, + mockedDeps.esClient.asCurrentUser.search.mockResponse({ + hits: { + hits: [ + // @ts-expect-error incomplete type + { + _source: { + risk, + host: { + name: hostName, }, }, - ], - }, + }, + ], }, }); @@ -107,9 +106,8 @@ describe('allHosts search strategy', () => { test('should query host risk only for hostNames in the current page', async () => { const buildHostsRiskQuery = jest.spyOn(buildRiskQuery, 'buildHostsRiskScoreQuery'); const mockedDeps = mockDeps(); - (mockedDeps.esClient.asCurrentUser.search as jest.Mock).mockResolvedValue({ - body: { hits: { hits: [] } }, - }); + // @ts-expect-error incomplete type + mockedDeps.esClient.asCurrentUser.search.mockResponse({ hits: { hits: [] } }); const hostName: string = get( 'aggregations.host_data.buckets[1].key', @@ -135,20 +133,19 @@ describe('allHosts search strategy', () => { ); const mockedDeps = mockDeps(false); - (mockedDeps.esClient.asCurrentUser.search as jest.Mock).mockResolvedValue({ - body: { - hits: { - hits: [ - { - _source: { - risk, - host: { - name: hostName, - }, + mockedDeps.esClient.asCurrentUser.search.mockResponse({ + hits: { + hits: [ + // @ts-expect-error incomplete type + { + _source: { + risk, + host: { + name: hostName, }, }, - ], - }, + }, + ], }, }); @@ -159,7 +156,7 @@ describe('allHosts search strategy', () => { test("should not enhance data when index doesn't exist", async () => { const mockedDeps = mockDeps(); - (mockedDeps.esClient.asCurrentUser.search as jest.Mock).mockImplementation(() => { + mockedDeps.esClient.asCurrentUser.search.mockImplementation(() => { throw new IndexNotFoundException(); }); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts index 13769837dfe78..460dfdbb5cb95 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts @@ -122,7 +122,7 @@ async function getHostRiskData( hostNames, }) ); - return hostRiskResponse.body; + return hostRiskResponse; } catch (error) { if (error?.meta?.body?.error?.type !== 'index_not_found_exception') { throw error; diff --git a/x-pack/plugins/security_solution/server/usage/detections/detection_rule_helpers.ts b/x-pack/plugins/security_solution/server/usage/detections/detection_rule_helpers.ts index 446fc956c0c65..39c108931e2d7 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/detection_rule_helpers.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/detection_rule_helpers.ts @@ -374,8 +374,8 @@ export const getDetectionRuleMetrics = async ( }; try { - const { body: ruleResults } = await esClient.search(ruleSearchOptions); - const { body: detectionAlertsResp } = (await esClient.search({ + const ruleResults = await esClient.search(ruleSearchOptions); + const detectionAlertsResp = (await esClient.search({ index: `${signalsIndex}*`, size: MAX_RESULTS_WINDOW, body: { @@ -399,7 +399,7 @@ export const getDetectionRuleMetrics = async ( }, }, }, - })) as { body: AlertsAggregationResponse }; + })) as AlertsAggregationResponse; const cases = await savedObjectClient.find({ type: CASE_COMMENT_SAVED_OBJECT, diff --git a/x-pack/plugins/security_solution/server/usage/detections/detections.test.ts b/x-pack/plugins/security_solution/server/usage/detections/detections.test.ts index d08f915e4428f..866fa226e2ecf 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/detections.test.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/detections.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { ElasticsearchClient } from '../../../../../../src/core/server'; import { elasticsearchServiceMock, savedObjectsClientMock, @@ -24,11 +23,9 @@ import { } from './detections.mocks'; import { getInitialDetectionMetrics, initialDetectionRulesUsage } from './detection_rule_helpers'; import { DetectionMetrics } from './types'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; describe('Detections Usage and Metrics', () => { - let esClientMock: jest.Mocked; + let esClientMock: ReturnType; let mlMock: ReturnType; let savedObjectsClient: ReturnType; @@ -46,12 +43,8 @@ describe('Detections Usage and Metrics', () => { it('returns information with rule, alerts and cases', async () => { esClientMock.search - .mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ body: getMockRuleSearchResponse() }) - ) - .mockResolvedValue( - elasticsearchClientMock.createApiResponse({ body: getMockRuleAlertsResponse(3400) }) - ); + .mockResponseOnce(getMockRuleSearchResponse()) + .mockResponseOnce(getMockRuleAlertsResponse(3400)); savedObjectsClient.find.mockResolvedValue(getMockAlertCasesResponse()); const result = await fetchDetectionsMetrics('', '', esClientMock, savedObjectsClient, mlMock); @@ -103,14 +96,8 @@ describe('Detections Usage and Metrics', () => { it('returns information with on non elastic prebuilt rule', async () => { esClientMock.search - .mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ - body: getMockRuleSearchResponse('not_immutable'), - }) - ) - .mockResolvedValue( - elasticsearchClientMock.createApiResponse({ body: getMockRuleAlertsResponse(800) }) - ); + .mockResponseOnce(getMockRuleSearchResponse('not_immutable')) + .mockResponseOnce(getMockRuleAlertsResponse(800)); savedObjectsClient.find.mockResolvedValue(getMockAlertCasesResponse()); const result = await fetchDetectionsMetrics('', '', esClientMock, savedObjectsClient, mlMock); @@ -147,12 +134,8 @@ describe('Detections Usage and Metrics', () => { it('returns information with rule, no alerts and no cases', async () => { esClientMock.search - .mockResolvedValueOnce( - elasticsearchClientMock.createApiResponse({ body: getMockRuleSearchResponse() }) - ) - .mockResolvedValue( - elasticsearchClientMock.createApiResponse({ body: getMockRuleAlertsResponse(0) }) - ); + .mockResponseOnce(getMockRuleSearchResponse()) + .mockResponseOnce(getMockRuleAlertsResponse(0)); savedObjectsClient.find.mockResolvedValue(getMockAlertCasesResponse()); const result = await fetchDetectionsMetrics('', '', esClientMock, savedObjectsClient, mlMock); diff --git a/x-pack/plugins/snapshot_restore/server/lib/get_managed_policy_names.ts b/x-pack/plugins/snapshot_restore/server/lib/get_managed_policy_names.ts index 2c3ebf2e0176e..0e2f90fe50449 100644 --- a/x-pack/plugins/snapshot_restore/server/lib/get_managed_policy_names.ts +++ b/x-pack/plugins/snapshot_restore/server/lib/get_managed_policy_names.ts @@ -15,9 +15,7 @@ export const getManagedPolicyNames = async ( clusterClient: ElasticsearchClient ): Promise => { try { - const { - body: { persistent, transient, defaults }, - } = await clusterClient.cluster.getSettings({ + const { persistent, transient, defaults } = await clusterClient.cluster.getSettings({ filter_path: '*.*managed_policies', flat_settings: true, include_defaults: true, diff --git a/x-pack/plugins/snapshot_restore/server/lib/get_managed_repository_name.ts b/x-pack/plugins/snapshot_restore/server/lib/get_managed_repository_name.ts index 65dc4a750c57a..c9ea3cdfffe12 100644 --- a/x-pack/plugins/snapshot_restore/server/lib/get_managed_repository_name.ts +++ b/x-pack/plugins/snapshot_restore/server/lib/get_managed_repository_name.ts @@ -15,9 +15,7 @@ export const getManagedRepositoryName = async ( client: ElasticsearchClient ): Promise => { try { - const { - body: { persistent, transient, defaults }, - } = await client.cluster.getSettings({ + const { persistent, transient, defaults } = await client.cluster.getSettings({ filter_path: '*.*managed_repository', flat_settings: true, include_defaults: true, 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 5e6c937088848..7a91cb8dc6848 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/app.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/app.ts @@ -49,23 +49,20 @@ export function registerAppRoutes({ try { // Get cluster privileges - const { - body: { has_all_requested: hasAllPrivileges, cluster }, - } = await clusterClient.asCurrentUser.security.hasPrivileges({ - body: { - // @ts-expect-error @elastic/elasticsearch doesn't declare all possible values in SecurityClusterPrivilege - cluster: [...APP_REQUIRED_CLUSTER_PRIVILEGES, ...APP_SLM_CLUSTER_PRIVILEGES], - }, - }); + const { has_all_requested: hasAllPrivileges, cluster } = + await clusterClient.asCurrentUser.security.hasPrivileges({ + body: { + // @ts-expect-error @elastic/elasticsearch doesn't declare all possible values in SecurityClusterPrivilege + cluster: [...APP_REQUIRED_CLUSTER_PRIVILEGES, ...APP_SLM_CLUSTER_PRIVILEGES], + }, + }); // Find missing cluster privileges and set overall app privileges privilegesResult.missingPrivileges.cluster = extractMissingPrivileges(cluster); privilegesResult.hasAllPrivileges = hasAllPrivileges; // Get all index privileges the user has - const { - body: { indices }, - } = await clusterClient.asCurrentUser.security.getUserPrivileges(); + const { indices } = await clusterClient.asCurrentUser.security.getUserPrivileges(); // Check if they have all the required index privileges for at least one index const oneIndexWithAllPrivileges = indices.find(({ privileges }) => { diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/policy.test.ts b/x-pack/plugins/snapshot_restore/server/routes/api/policy.test.ts index 5ef5f2d01b96c..7401f126b3594 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/policy.test.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/policy.test.ts @@ -75,8 +75,8 @@ describe('[Snapshot and Restore API Routes] Policy', () => { fooPolicy: mockEsPolicy, barPolicy: mockEsPolicy, }; - getClusterSettingsFn.mockResolvedValue({ body: {} }); - getLifecycleFn.mockResolvedValue({ body: mockEsResponse }); + getClusterSettingsFn.mockResolvedValue({}); + getLifecycleFn.mockResolvedValue(mockEsResponse); const expectedResponse = { policies: [ { @@ -96,8 +96,8 @@ describe('[Snapshot and Restore API Routes] Policy', () => { it('should return empty array if no repositories returned from ES', async () => { const mockEsResponse = {}; - getClusterSettingsFn.mockResolvedValue({ body: {} }); - getLifecycleFn.mockResolvedValue({ body: mockEsResponse }); + getClusterSettingsFn.mockResolvedValue({}); + getLifecycleFn.mockResolvedValue(mockEsResponse); const expectedResponse = { policies: [] }; await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: expectedResponse, @@ -126,8 +126,8 @@ describe('[Snapshot and Restore API Routes] Policy', () => { [name]: mockEsPolicy, }; - getLifecycleFn.mockResolvedValue({ body: mockEsResponse }); - getClusterSettingsFn.mockResolvedValue({ body: {} }); + getLifecycleFn.mockResolvedValue(mockEsResponse); + getClusterSettingsFn.mockResolvedValue({}); const expectedResponse = { policy: { @@ -154,7 +154,7 @@ describe('[Snapshot and Restore API Routes] Policy', () => { it('should throw if ES error', async () => { getLifecycleFn.mockRejectedValueOnce(new Error('something unexpected')); - getClusterSettingsFn.mockResolvedValueOnce({ body: {} }); + getClusterSettingsFn.mockResolvedValueOnce({}); await expect(router.runRequest(mockRequest)).rejects.toThrowError(); }); @@ -175,7 +175,7 @@ describe('[Snapshot and Restore API Routes] Policy', () => { const mockEsResponse = { snapshot_name: 'foo-policy-snapshot', }; - executeLifecycleFn.mockResolvedValue({ body: mockEsResponse }); + executeLifecycleFn.mockResolvedValue(mockEsResponse); const expectedResponse = { snapshotName: 'foo-policy-snapshot', @@ -206,7 +206,7 @@ describe('[Snapshot and Restore API Routes] Policy', () => { it('should return successful ES responses', async () => { const mockEsResponse = { acknowledged: true }; - deleteLifecycleFn.mockResolvedValue({ body: mockEsResponse }); + deleteLifecycleFn.mockResolvedValue(mockEsResponse); const expectedResponse = { itemsDeleted: names, errors: [] }; await expect(router.runRequest(mockRequest)).resolves.toEqual({ @@ -243,7 +243,7 @@ describe('[Snapshot and Restore API Routes] Policy', () => { const mockEsResponse = { acknowledged: true }; deleteLifecycleFn.mockRejectedValueOnce(mockEsError); - deleteLifecycleFn.mockResolvedValueOnce({ body: mockEsResponse }); + deleteLifecycleFn.mockResolvedValueOnce(mockEsResponse); const expectedResponse = { itemsDeleted: [names[1]], @@ -277,8 +277,8 @@ describe('[Snapshot and Restore API Routes] Policy', () => { it('should return successful ES response', async () => { const mockEsResponse = { acknowledged: true }; - getLifecycleFn.mockResolvedValue({ body: {} }); - putLifecycleFn.mockResolvedValue({ body: mockEsResponse }); + getLifecycleFn.mockResolvedValue({}); + putLifecycleFn.mockResolvedValue(mockEsResponse); const expectedResponse = { ...mockEsResponse }; await expect(router.runRequest(mockRequest)).resolves.toEqual({ @@ -288,14 +288,14 @@ describe('[Snapshot and Restore API Routes] Policy', () => { it('should return error if policy with the same name already exists', async () => { const mockEsResponse = { [name]: {} }; - getLifecycleFn.mockResolvedValue({ body: mockEsResponse }); + getLifecycleFn.mockResolvedValue(mockEsResponse); const response = await router.runRequest(mockRequest); expect(response.status).toBe(409); }); it('should throw if ES error', async () => { - getLifecycleFn.mockResolvedValue({ body: {} }); + getLifecycleFn.mockResolvedValue({}); putLifecycleFn.mockRejectedValue(new Error()); await expect(router.runRequest(mockRequest)).rejects.toThrowError(); @@ -317,8 +317,8 @@ describe('[Snapshot and Restore API Routes] Policy', () => { it('should return successful ES response', async () => { const mockEsResponse = { acknowledged: true }; - getLifecycleFn.mockResolvedValue({ body: { [name]: {} } }); - putLifecycleFn.mockResolvedValue({ body: mockEsResponse }); + getLifecycleFn.mockResolvedValue({ [name]: {} }); + putLifecycleFn.mockResolvedValue(mockEsResponse); const expectedResponse = { ...mockEsResponse }; await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: expectedResponse }); @@ -360,7 +360,7 @@ describe('[Snapshot and Restore API Routes] Policy', () => { ], }; - resolveIndicesFn.mockResolvedValue({ body: mockEsResponse }); + resolveIndicesFn.mockResolvedValue(mockEsResponse); const expectedResponse = { indices: ['fooIndex'], @@ -375,7 +375,7 @@ describe('[Snapshot and Restore API Routes] Policy', () => { aliases: [], data_streams: [], }; - resolveIndicesFn.mockResolvedValue({ body: mockEsResponse }); + resolveIndicesFn.mockResolvedValue(mockEsResponse); const expectedResponse = { indices: [], dataStreams: [] }; await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: expectedResponse }); @@ -400,7 +400,7 @@ describe('[Snapshot and Restore API Routes] Policy', () => { it('should return successful ES response', async () => { const mockEsResponse = { acknowledged: true }; - putClusterSettingsFn.mockResolvedValue({ body: mockEsResponse }); + putClusterSettingsFn.mockResolvedValue(mockEsResponse); const expectedResponse = { ...mockEsResponse }; await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: expectedResponse }); 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 0458d78263270..57cb81ca13b9b 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/policy.ts @@ -29,7 +29,7 @@ export function registerPolicyRoutes({ try { // Get policies - const { body: policiesByName } = await clusterClient.asCurrentUser.slm.getLifecycle({ + const policiesByName = await clusterClient.asCurrentUser.slm.getLifecycle({ human: true, }); @@ -57,7 +57,7 @@ export function registerPolicyRoutes({ const { name } = req.params as TypeOf; try { - const { body: policiesByName } = await clusterClient.asCurrentUser.slm.getLifecycle({ + const policiesByName = await clusterClient.asCurrentUser.slm.getLifecycle({ policy_id: name, human: true, }); @@ -87,7 +87,7 @@ export function registerPolicyRoutes({ try { // Check that policy with the same name doesn't already exist - const { body: policyByName } = await clusterClient.asCurrentUser.slm.getLifecycle({ + const policyByName = await clusterClient.asCurrentUser.slm.getLifecycle({ policy_id: name, }); @@ -106,7 +106,7 @@ export function registerPolicyRoutes({ body: serializePolicy(policy) as unknown as estypes.SlmPutLifecycleRequest['body'], }); - return res.ok({ body: response.body }); + return res.ok({ body: response }); } catch (e) { return handleEsError({ error: e, response: res }); } @@ -136,7 +136,7 @@ export function registerPolicyRoutes({ body: serializePolicy(policy) as unknown as estypes.SlmPutLifecycleRequest['body'], }); - return res.ok({ body: response.body }); + return res.ok({ body: response }); } catch (e) { return handleEsError({ error: e, response: res }); } @@ -182,11 +182,10 @@ export function registerPolicyRoutes({ const { name } = req.params as TypeOf; try { - const { - body: { snapshot_name: snapshotName }, - } = await clusterClient.asCurrentUser.slm.executeLifecycle({ - policy_id: name, - }); + const { snapshot_name: snapshotName } = + await clusterClient.asCurrentUser.slm.executeLifecycle({ + policy_id: name, + }); return res.ok({ body: { snapshotName } }); } catch (e) { return handleEsError({ error: e, response: res }); @@ -206,7 +205,7 @@ export function registerPolicyRoutes({ expand_wildcards: 'all', }); // @ts-expect-error Type 'ResolveIndexAliasItem[]' is not comparable to type 'IndexAndAliasFromEs[]'. - const resolvedIndicesResponse = response.body as ResolveIndexResponseFromES; + const resolvedIndicesResponse = response as ResolveIndexResponseFromES; const body: PolicyIndicesResponse = { dataStreams: resolvedIndicesResponse.data_streams.map(({ name }) => name).sort(), @@ -229,12 +228,11 @@ export function registerPolicyRoutes({ { path: addBasePath('policies/retention_settings'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { const { client: clusterClient } = ctx.core.elasticsearch; - const { - body: { persistent, transient, defaults }, - } = await clusterClient.asCurrentUser.cluster.getSettings({ - filter_path: '**.slm.retention*', - include_defaults: true, - }); + const { persistent, transient, defaults } = + await clusterClient.asCurrentUser.cluster.getSettings({ + filter_path: '**.slm.retention*', + include_defaults: true, + }); const { slm: retentionSettings }: { slm?: { retention_schedule: string } } = { ...defaults, ...persistent, @@ -273,7 +271,7 @@ export function registerPolicyRoutes({ }, }); - return res.ok({ body: response.body }); + return res.ok({ body: response }); } catch (e) { return handleEsError({ error: e, response: res }); } @@ -286,7 +284,7 @@ export function registerPolicyRoutes({ license.guardApiRoute(async (ctx, req, res) => { const { client: clusterClient } = ctx.core.elasticsearch; const response = await clusterClient.asCurrentUser.slm.executeRetention(); - return res.ok({ body: response.body }); + return res.ok({ body: response }); }) ); } diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.test.ts b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.test.ts index 1ea7c36d41b59..844be90f9b842 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.test.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.test.ts @@ -61,9 +61,9 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { }, }; - clusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse }); - getRepoFn.mockResolvedValue({ body: mockRepositoryEsResponse }); - getLifecycleFn.mockResolvedValue({ body: mockPolicyEsResponse }); + clusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getRepoFn.mockResolvedValue(mockRepositoryEsResponse); + getLifecycleFn.mockResolvedValue(mockPolicyEsResponse); const expectedResponse = { repositories: [ @@ -96,9 +96,9 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { }, }; - clusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse }); - getRepoFn.mockResolvedValue({ body: mockRepositoryEsResponse }); - getLifecycleFn.mockResolvedValue({ body: mockPolicyEsResponse }); + clusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getRepoFn.mockResolvedValue(mockRepositoryEsResponse); + getLifecycleFn.mockResolvedValue(mockPolicyEsResponse); const expectedResponse = { repositories: [], @@ -112,7 +112,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { }); it('should throw if ES error', async () => { - clusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse }); + clusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); getRepoFn.mockRejectedValue(new Error()); await expect(router.runRequest(mockRequest)).rejects.toThrowError(); @@ -135,9 +135,9 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { [name]: { type: '', settings: {} }, }; - getClusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse }); - getRepoFn.mockResolvedValue({ body: mockEsResponse }); - getSnapshotFn.mockResolvedValue({ body: {} }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getRepoFn.mockResolvedValue(mockEsResponse); + getSnapshotFn.mockResolvedValue({}); const expectedResponse = { repository: { name, ...mockEsResponse[name] }, @@ -149,9 +149,9 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { }); it('should return empty repository object if not returned from ES', async () => { - getClusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse }); - getRepoFn.mockResolvedValue({ body: {} }); - getSnapshotFn.mockResolvedValue({ body: {} }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getRepoFn.mockResolvedValue({}); + getSnapshotFn.mockResolvedValue({}); const expectedResponse = { repository: {}, @@ -169,9 +169,9 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { snapshots: [{ repository: name }, { repository: name }], }; - getClusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse }); - getRepoFn.mockResolvedValue({ body: mockEsResponse }); - getSnapshotFn.mockResolvedValue({ body: mockEsSnapshotResponse }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getRepoFn.mockResolvedValue(mockEsResponse); + getSnapshotFn.mockResolvedValue(mockEsSnapshotResponse); const expectedResponse = { repository: { name, ...mockEsResponse[name] }, @@ -189,8 +189,8 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { [name]: { type: '', settings: {} }, }; - getClusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse }); - getRepoFn.mockResolvedValue({ body: mockEsResponse }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getRepoFn.mockResolvedValue(mockEsResponse); getSnapshotFn.mockRejectedValueOnce(new Error('snapshot error')); const expectedResponse = { @@ -205,7 +205,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { }); it('should throw if ES error', async () => { - getClusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); getRepoFn.mockRejectedValue(new Error()); @@ -226,7 +226,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { it('should return repository verification response if returned from ES', async () => { const mockEsResponse = { nodes: {} }; - verifyRepoFn.mockResolvedValue({ body: mockEsResponse }); + verifyRepoFn.mockResolvedValue(mockEsResponse); const expectedResponse = { verification: { valid: true, response: mockEsResponse }, @@ -254,7 +254,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { }; it('returns default types if no repository plugins returned from ES', async () => { - nodesInfoFn.mockResolvedValue({ body: { nodes: { testNodeId: { plugins: [] } } } }); + nodesInfoFn.mockResolvedValue({ nodes: { testNodeId: { plugins: [] } } }); const expectedResponse = [...DEFAULT_REPOSITORY_TYPES]; await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: expectedResponse }); @@ -267,7 +267,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { const mockEsResponse = { nodes: { testNodeId: { plugins: [...pluginNames.map((key) => ({ name: key }))] } }, }; - nodesInfoFn.mockResolvedValue({ body: mockEsResponse }); + nodesInfoFn.mockResolvedValue(mockEsResponse); const expectedResponse = [...DEFAULT_REPOSITORY_TYPES, ...pluginTypes]; await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: expectedResponse }); @@ -278,7 +278,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { const mockEsResponse = { nodes: { testNodeId: { plugins: [...pluginNames.map((key) => ({ name: key }))] } }, }; - nodesInfoFn.mockResolvedValue({ body: mockEsResponse }); + nodesInfoFn.mockResolvedValue(mockEsResponse); const expectedResponse = [...DEFAULT_REPOSITORY_TYPES]; @@ -294,7 +294,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { masterNode: { plugins: [...masterNodePlugins.map((key) => ({ name: key }))] }, }, }; - nodesInfoFn.mockResolvedValue({ body: mockEsResponse }); + nodesInfoFn.mockResolvedValue(mockEsResponse); const expectedResponse = [...DEFAULT_REPOSITORY_TYPES]; @@ -323,8 +323,8 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { it('should return successful ES response', async () => { const mockEsResponse = { acknowledged: true }; - getRepoFn.mockResolvedValue({ body: {} }); - createRepoFn.mockResolvedValue({ body: mockEsResponse }); + getRepoFn.mockResolvedValue({}); + createRepoFn.mockResolvedValue(mockEsResponse); const expectedResponse = { ...mockEsResponse }; @@ -332,14 +332,14 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { }); it('should return error if repository with the same name already exists', async () => { - getRepoFn.mockResolvedValue({ body: { [name]: {} } }); + getRepoFn.mockResolvedValue({ [name]: {} }); const response = await router.runRequest(mockRequest); expect(response.status).toBe(409); }); it('should throw if ES error', async () => { const error = new Error('Oh no!'); - getRepoFn.mockResolvedValue({ body: {} }); + getRepoFn.mockResolvedValue({}); createRepoFn.mockRejectedValue(error); await expect(router.runRequest(mockRequest)).rejects.toThrowError(error); @@ -361,8 +361,8 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { it('should return successful ES response', async () => { const mockEsResponse = { acknowledged: true }; - getRepoFn.mockResolvedValue({ body: { [name]: {} } }); - createRepoFn.mockResolvedValue({ body: mockEsResponse }); + getRepoFn.mockResolvedValue({ [name]: {} }); + createRepoFn.mockResolvedValue(mockEsResponse); const expectedResponse = mockEsResponse; @@ -387,8 +387,8 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { it('should return successful ES responses', async () => { const mockEsResponse = { acknowledged: true }; - deleteRepoFn.mockResolvedValueOnce({ body: mockEsResponse }); - deleteRepoFn.mockResolvedValueOnce({ body: mockEsResponse }); + deleteRepoFn.mockResolvedValueOnce(mockEsResponse); + deleteRepoFn.mockResolvedValueOnce(mockEsResponse); const expectedResponse = { itemsDeleted: names, errors: [] }; await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: expectedResponse }); @@ -419,7 +419,7 @@ describe('[Snapshot and Restore API Routes] Repositories', () => { mockEsError.response = '{}'; mockEsError.statusCode = 500; const mockEsResponse = { acknowledged: true }; - const responses = [Promise.reject(mockEsError), Promise.resolve({ body: mockEsResponse })]; + const responses = [Promise.reject(mockEsError), Promise.resolve(mockEsResponse)]; deleteRepoFn.mockImplementation(() => responses.shift()); 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 03a5ab26a65b0..22c4d4a2b3e91 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/repositories.ts @@ -47,10 +47,9 @@ export function registerRepositoriesRoutes({ let managedRepository: ManagedRepository; try { - const { body: repositoriesByName } = - await clusterClient.asCurrentUser.snapshot.getRepository({ - name: '_all', - }); + const repositoriesByName = await clusterClient.asCurrentUser.snapshot.getRepository({ + name: '_all', + }); repositoryNames = Object.keys(repositoriesByName); repositories = repositoryNames.map((name) => { const { type = '', settings = {} } = repositoriesByName[name]; @@ -71,7 +70,7 @@ export function registerRepositoriesRoutes({ // If a managed repository, we also need to check if a policy is associated to it if (managedRepositoryName) { try { - const { body: policiesByName } = await clusterClient.asCurrentUser.slm.getLifecycle({ + const policiesByName = await clusterClient.asCurrentUser.slm.getLifecycle({ human: true, }); @@ -107,24 +106,20 @@ export function registerRepositoriesRoutes({ let repositoryByName: SnapshotGetRepositoryResponse; try { - ({ body: repositoryByName } = await clusterClient.asCurrentUser.snapshot.getRepository({ + repositoryByName = await clusterClient.asCurrentUser.snapshot.getRepository({ name, - })); + }); } catch (e) { return handleEsError({ error: e, response: res }); } - const { - body: { snapshots: snapshotList }, - } = await clusterClient.asCurrentUser.snapshot + const { snapshots: snapshotList } = await clusterClient.asCurrentUser.snapshot .get({ repository: name, snapshot: '_all', }) .catch((e) => ({ - body: { - snapshots: null, - }, + snapshots: null, })); if (repositoryByName[name]) { @@ -163,9 +158,7 @@ export function registerRepositoriesRoutes({ const types: RepositoryType[] = isCloudEnabled ? [] : [...DEFAULT_REPOSITORY_TYPES]; try { - const { - body: { nodes }, - } = await clusterClient.asCurrentUser.nodes.info({ + const { nodes } = await clusterClient.asCurrentUser.nodes.info({ node_id: '_all', metric: 'plugins', }); @@ -202,13 +195,11 @@ export function registerRepositoriesRoutes({ const { name } = req.params as TypeOf; try { - const { body: verificationResults } = await clusterClient.asCurrentUser.snapshot + const verificationResults = await clusterClient.asCurrentUser.snapshot .verifyRepository({ name }) .catch((e) => ({ - body: { - valid: false, - error: e.response ? JSON.parse(e.response) : e, - }, + valid: false, + error: e.response ? JSON.parse(e.response) : e, })); return res.ok({ @@ -238,7 +229,7 @@ export function registerRepositoriesRoutes({ const { name } = req.params as TypeOf; try { - const { body: cleanupResults } = await clusterClient.asCurrentUser.snapshot + const cleanupResults = await clusterClient.asCurrentUser.snapshot .cleanupRepository({ name }) .catch((e) => { // This API returns errors in a non-standard format, which we'll need to @@ -281,9 +272,7 @@ export function registerRepositoriesRoutes({ // Check that repository with the same name doesn't already exist try { - const { body: repositoryByName } = await clusterClient.asCurrentUser.snapshot.getRepository( - { name } - ); + const repositoryByName = await clusterClient.asCurrentUser.snapshot.getRepository({ name }); if (repositoryByName[name]) { return res.conflict({ body: 'There is already a repository with that name.' }); } @@ -303,7 +292,7 @@ export function registerRepositoriesRoutes({ verify: false, }); - return res.ok({ body: response.body }); + return res.ok({ body: response }); } catch (e) { return handleEsError({ error: e, response: res }); } @@ -337,7 +326,7 @@ export function registerRepositoriesRoutes({ }); return res.ok({ - body: response.body, + body: response, }); } catch (e) { return handleEsError({ error: e, response: res }); diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/restore.test.ts b/x-pack/plugins/snapshot_restore/server/routes/api/restore.test.ts index a6f6924aaae31..69490a2c85649 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/restore.test.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/restore.test.ts @@ -45,7 +45,7 @@ describe('[Snapshot and Restore API Routes] Restore', () => { it('should return successful response from ES', async () => { const mockEsResponse = { acknowledged: true }; - restoreSnapshotFn.mockResolvedValue({ body: mockEsResponse }); + restoreSnapshotFn.mockResolvedValue(mockEsResponse); await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: mockEsResponse, @@ -82,7 +82,7 @@ describe('[Snapshot and Restore API Routes] Restore', () => { }, }; - indicesRecoveryFn.mockResolvedValue({ body: mockEsResponse }); + indicesRecoveryFn.mockResolvedValue(mockEsResponse); const expectedResponse = [ { @@ -106,7 +106,7 @@ describe('[Snapshot and Restore API Routes] Restore', () => { it('should return empty array if no repositories returned from ES', async () => { const mockEsResponse = {}; - indicesRecoveryFn.mockResolvedValue({ body: mockEsResponse }); + indicesRecoveryFn.mockResolvedValue(mockEsResponse); const expectedResponse: any[] = []; await expect(router.runRequest(mockRequest)).resolves.toEqual({ 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 f62256090eaaa..ea688273781ed 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/restore.ts @@ -28,7 +28,7 @@ export function registerRestoreRoutes({ try { const snapshotRestores: SnapshotRestore[] = []; - const { body: recoveryByIndexName } = await clusterClient.asCurrentUser.indices.recovery({ + const recoveryByIndexName = await clusterClient.asCurrentUser.indices.recovery({ human: true, }); @@ -111,7 +111,7 @@ export function registerRestoreRoutes({ body: serializeRestoreSettings(restoreSettings) as estypes.SnapshotRestoreRequest['body'], }); - return res.ok({ body: response.body }); + return res.ok({ body: response }); } catch (e) { return handleEsError({ error: e, response: res }); } diff --git a/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.test.ts b/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.test.ts index 4ecd34a43adb9..ba4b888c58773 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.test.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.test.ts @@ -82,12 +82,10 @@ describe('[Snapshot and Restore API Routes] Snapshots', () => { bazRepository: {}, }; - getClusterSettingsFn.mockResolvedValue({ - body: mockSnapshotGetManagedRepositoryEsResponse, - }); - getLifecycleFn.mockResolvedValue({ body: mockGetPolicyEsResponse }); - getRepoFn.mockResolvedValue({ body: mockGetRepositoryEsResponse }); - getSnapshotFn.mockResolvedValue({ body: mockGetSnapshotsResponse }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getLifecycleFn.mockResolvedValue(mockGetPolicyEsResponse); + getRepoFn.mockResolvedValue(mockGetRepositoryEsResponse); + getSnapshotFn.mockResolvedValue(mockGetSnapshotsResponse); const expectedResponse = { repositories: ['fooRepository', 'barRepository', 'bazRepository'], @@ -138,12 +136,10 @@ describe('[Snapshot and Restore API Routes] Snapshots', () => { fooRepository: {}, }; - getClusterSettingsFn.mockResolvedValue({ - body: mockSnapshotGetManagedRepositoryEsResponse, - }); - getLifecycleFn.mockResolvedValue({ body: mockGetPolicyEsResponse }); - getRepoFn.mockResolvedValue({ body: mockGetRepositoryEsResponse }); - getSnapshotFn.mockResolvedValue({ body: mockGetSnapshotsResponse }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getLifecycleFn.mockResolvedValue(mockGetPolicyEsResponse); + getRepoFn.mockResolvedValue(mockGetRepositoryEsResponse); + getSnapshotFn.mockResolvedValue(mockGetSnapshotsResponse); const expectedResponse = { repositories: ['fooRepository'], @@ -173,11 +169,9 @@ describe('[Snapshot and Restore API Routes] Snapshots', () => { }); test('returns empty arrays if no repositories returned from ES', async () => { - getClusterSettingsFn.mockResolvedValue({ - body: mockSnapshotGetManagedRepositoryEsResponse, - }); - getLifecycleFn.mockResolvedValue({ body: {} }); - getRepoFn.mockResolvedValue({ body: {} }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getLifecycleFn.mockResolvedValue({}); + getRepoFn.mockResolvedValue({}); const expectedResponse = { snapshots: [], @@ -197,9 +191,9 @@ describe('[Snapshot and Restore API Routes] Snapshots', () => { getClusterSettingsFn.mockResolvedValue({ body: mockSnapshotGetManagedRepositoryEsResponse, }); - getLifecycleFn.mockResolvedValue({ body: {} }); - getRepoFn.mockResolvedValue({ body: mockGetRepositoryEsResponse }); - getSnapshotFn.mockResolvedValue({ body: {} }); + getLifecycleFn.mockResolvedValue({}); + getRepoFn.mockResolvedValue(mockGetRepositoryEsResponse); + getSnapshotFn.mockResolvedValue({}); const expectedResponse = { snapshots: [], @@ -245,10 +239,8 @@ describe('[Snapshot and Restore API Routes] Snapshots', () => { snapshots: [{ snapshot, repository }], }; - getClusterSettingsFn.mockResolvedValue({ - body: mockSnapshotGetManagedRepositoryEsResponse, - }); - getSnapshotFn.mockResolvedValue({ body: mockGetSnapshotEsResponse }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getSnapshotFn.mockResolvedValue(mockGetSnapshotEsResponse); const expectedResponse = { ...defaultSnapshot, @@ -283,10 +275,8 @@ describe('[Snapshot and Restore API Routes] Snapshots', () => { ], }; - getClusterSettingsFn.mockResolvedValue({ - body: mockSnapshotGetManagedRepositoryEsResponse, - }); - getSnapshotFn.mockResolvedValue({ body: mockSnapshotGetEsResponse }); + getClusterSettingsFn.mockResolvedValue(mockSnapshotGetManagedRepositoryEsResponse); + getSnapshotFn.mockResolvedValue(mockSnapshotGetEsResponse); await expect(router.runRequest(mockRequest)).resolves.toEqual({ body: 'Snapshot not found', @@ -314,8 +304,8 @@ describe('[Snapshot and Restore API Routes] Snapshots', () => { it('should return successful ES responses', async () => { const mockEsResponse = { acknowledged: true }; - deleteSnapshotFn.mockResolvedValueOnce({ body: mockEsResponse }); - deleteSnapshotFn.mockResolvedValueOnce({ body: mockEsResponse }); + deleteSnapshotFn.mockResolvedValueOnce(mockEsResponse); + deleteSnapshotFn.mockResolvedValueOnce(mockEsResponse); const expectedResponse = { itemsDeleted: [ @@ -360,7 +350,7 @@ describe('[Snapshot and Restore API Routes] Snapshots', () => { const mockEsResponse = { acknowledged: true }; deleteSnapshotFn.mockRejectedValueOnce(mockEsError); - deleteSnapshotFn.mockResolvedValueOnce({ body: mockEsResponse }); + deleteSnapshotFn.mockResolvedValueOnce(mockEsResponse); const expectedResponse = { itemsDeleted: [{ snapshot: 'snapshot-2', repository: 'barRepository' }], 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 7ff68f7958bfc..f85c9c33756b7 100644 --- a/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts +++ b/x-pack/plugins/snapshot_restore/server/routes/api/snapshots.ts @@ -65,7 +65,7 @@ export function registerSnapshotsRoutes({ // Attempt to retrieve policies // This could fail if user doesn't have access to read SLM policies try { - const { body: policiesByName } = await clusterClient.asCurrentUser.slm.getLifecycle(); + const policiesByName = await clusterClient.asCurrentUser.slm.getLifecycle(); policies = Object.keys(policiesByName); } catch (e) { // Silently swallow error as policy names aren't required in UI @@ -74,10 +74,9 @@ export function registerSnapshotsRoutes({ let repositories: string[] = []; try { - const { body: repositoriesByName } = - await clusterClient.asCurrentUser.snapshot.getRepository({ - name: '_all', - }); + const repositoriesByName = await clusterClient.asCurrentUser.snapshot.getRepository({ + name: '_all', + }); repositories = Object.keys(repositoriesByName); if (repositories.length === 0) { @@ -108,7 +107,7 @@ export function registerSnapshotsRoutes({ } try { // If any of these repositories 504 they will cost the request significant time. - const { body: fetchedSnapshots } = await clusterClient.asCurrentUser.snapshot.get({ + const fetchedSnapshots = await clusterClient.asCurrentUser.snapshot.get({ repository: searchField === 'repository' ? getSnapshotSearchWildcard({ @@ -189,7 +188,7 @@ export function registerSnapshotsRoutes({ ignore_unavailable: true, }); - const { snapshots: snapshotsList } = response.body; + const { snapshots: snapshotsList } = response; if (!snapshotsList || snapshotsList.length === 0) { return res.notFound({ body: 'Snapshot not found' }); diff --git a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts index 6bf410e21dcb3..59c28034c321c 100644 --- a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts +++ b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts @@ -82,9 +82,18 @@ function setup({ }; } -const defaultEsClientSearchMock = jest.fn().mockResolvedValue({ - body: { +const getMockFetchContext = (mockedEsClient: any) => { + return { + ...createCollectorFetchContextMock(), + esClient: mockedEsClient, + }; +}; + +const getMockedEsClient = () => { + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + esClient.search.mockResponse({ hits: { + // @ts-expect-error incomplete definition total: { value: 2, }, @@ -99,19 +108,7 @@ const defaultEsClientSearchMock = jest.fn().mockResolvedValue({ ], }, }, - }, -}); - -const getMockFetchContext = (mockedEsClient: any) => { - return { - ...createCollectorFetchContextMock(), - esClient: mockedEsClient, - }; -}; - -const getMockedEsClient = (esClientMock: jest.Mock) => { - const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; - esClient.search = esClientMock; + }); return esClient; }; @@ -150,10 +147,10 @@ describe('with a basic license', () => { licensing, usageStatsServicePromise: Promise.resolve(usageStatsService), }); - const esClient = getMockedEsClient(defaultEsClientSearchMock); + const esClient = getMockedEsClient(); usageData = await collector.fetch(getMockFetchContext(esClient)); - expect(defaultEsClientSearchMock).toHaveBeenCalledWith({ + expect(esClient.search).toHaveBeenCalledWith({ body: { aggs: { disabledFeatures: { @@ -209,7 +206,7 @@ describe('with no license', () => { licensing, usageStatsServicePromise: Promise.resolve(usageStatsService), }); - const esClient = getMockedEsClient(defaultEsClientSearchMock); + const esClient = getMockedEsClient(); usageData = await collector.fetch(getMockFetchContext(esClient)); }); @@ -250,7 +247,7 @@ describe('with platinum license', () => { licensing, usageStatsServicePromise: Promise.resolve(usageStatsService), }); - const esClient = getMockedEsClient(defaultEsClientSearchMock); + const esClient = getMockedEsClient(); usageData = await collector.fetch(getMockFetchContext(esClient)); }); diff --git a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts index f2ca7a9ebb332..bac8bcabda3b1 100644 --- a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts +++ b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts @@ -46,7 +46,7 @@ async function getSpacesUsage( } const knownFeatureIds = features.getKibanaFeatures().map((feature) => feature.id); - const { body: resp } = (await esClient.search({ + const resp = (await esClient.search({ index: kibanaIndex, body: { track_total_hits: true, @@ -68,7 +68,7 @@ async function getSpacesUsage( }, size: 0, }, - })) as { body: SpacesAggregationResponse }; + })) as SpacesAggregationResponse; const { hits, aggregations } = resp; diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/es_query_builder.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/es_query_builder.ts index c523468674122..345c21d62c67a 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/es_query_builder.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/es_query_builder.ts @@ -8,7 +8,6 @@ import { ElasticsearchClient } from 'kibana/server'; import { Logger } from 'src/core/server'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { TransportResult } from '@elastic/elasticsearch'; import { fromKueryExpression, toElasticsearchQuery, @@ -50,7 +49,7 @@ export async function getShapesFilters( const shapesIdsNamesMap: Record = {}; // Get all shapes in index // eslint-disable-next-line @typescript-eslint/no-explicit-any - const { body: boundaryData }: TransportResult> = await esClient.search({ + const boundaryData = await esClient.search>({ index: boundaryIndexTitle, body: { size: MAX_SHAPES_QUERY_SIZE, @@ -72,11 +71,9 @@ export async function getShapesFilters( }; }); if (boundaryNameField) { - boundaryData.hits.hits.forEach( - ({ _source, _id }: { _source: Record; _id: string }) => { - shapesIdsNamesMap[_id] = _source[boundaryNameField]; - } - ); + boundaryData.hits.hits.forEach(({ _source, _id }) => { + shapesIdsNamesMap[_id] = _source![boundaryNameField]; + }); } return { shapesFilters: filters, @@ -203,7 +200,7 @@ export async function executeEsQueryFactory( let esResult: estypes.SearchResponse | undefined; try { - ({ body: esResult } = await esClient.search(esQuery)); + esResult = await esClient.search(esQuery); } catch (err) { log.warn(`${err.message}`); } diff --git a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts index dc633e298490c..185474b827eda 100644 --- a/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts +++ b/x-pack/plugins/stack_alerts/server/alert_types/geo_containment/tests/geo_containment.test.ts @@ -6,7 +6,7 @@ */ import _ from 'lodash'; -import { loggingSystemMock } from 'src/core/server/mocks'; +import { loggingSystemMock, elasticsearchServiceMock } from 'src/core/server/mocks'; import { AlertServicesMock, alertsMock } from '../../../../../alerting/server/mocks'; import sampleAggsJsonResponse from './es_sample_response.json'; import sampleShapesJsonResponse from './es_sample_response_shapes.json'; @@ -512,23 +512,25 @@ describe('geo_containment', () => { const boundaryCall = jest.fn(); const esAggCall = jest.fn(); const contextKeys = Object.keys(expectedAlertResults[0].context); + const esClient = elasticsearchServiceMock.createElasticsearchClient(); + // @ts-ignore incomplete return type + esClient.search.mockResponseImplementation(({ index }) => { + if (index === geoContainmentParams.boundaryIndexTitle) { + boundaryCall(); + return sampleShapesJsonResponse; + } else { + esAggCall(); + return sampleAggsJsonResponse; + } + }); + const alertServicesWithSearchMock: AlertServicesMock = { ...alertsMock.createAlertServices(), // @ts-ignore alertFactory: alertFactory(contextKeys, testAlertActionArr), + // @ts-ignore scopedClusterClient: { - asCurrentUser: { - // @ts-ignore - search: jest.fn(({ index }: { index: string }) => { - if (index === geoContainmentParams.boundaryIndexTitle) { - boundaryCall(); - return sampleShapesJsonResponse; - } else { - esAggCall(); - return sampleAggsJsonResponse; - } - }), - }, + asCurrentUser: esClient, }, }; diff --git a/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.test.ts b/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.test.ts index 928d993b03335..1c3309c9d53f1 100644 --- a/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.test.ts +++ b/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.test.ts @@ -18,9 +18,7 @@ describe('getOldestIdleActionTask', () => { it('returns a default of now-24h when no results', async () => { const client = elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - body: { hits: { hits: [], total: 0 } }, - }) + Promise.resolve({ hits: { hits: [], total: 0 } }) ); const ts = await getOldestIdleActionTask(client, '.index-name'); @@ -29,7 +27,7 @@ describe('getOldestIdleActionTask', () => { it('returns a default of Date.now-24h when a 404 is returned', async () => { const client = elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ error: { status: 404 }, }) ); @@ -40,7 +38,7 @@ describe('getOldestIdleActionTask', () => { it("returns the search result's task.runAt-24h field if it exists", async () => { const client = elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [{ _source: { task: { runAt: '2015-01-01T12:10:30Z' } } }], total: 1 }, }) ); @@ -51,7 +49,7 @@ describe('getOldestIdleActionTask', () => { it("fallsback to 0 if the search result's task.runAt field does not exist", async () => { const client1 = elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [{ _source: { task: { runAt: undefined } } }], total: 1 }, }) ); @@ -60,7 +58,7 @@ describe('getOldestIdleActionTask', () => { expect(ts1).toEqual('0'); const client2 = elasticsearchServiceMock.createElasticsearchClient( - elasticsearchServiceMock.createSuccessTransportRequestPromise({ + Promise.resolve({ hits: { hits: [{ _source: { task: undefined } }], total: 1 }, }) ); diff --git a/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.ts b/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.ts index 5a8d8e2c81dc9..a7fb5c1c8c893 100644 --- a/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.ts +++ b/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.ts @@ -18,7 +18,7 @@ export const getOldestIdleActionTask = async ( // Default is now - 24h const oneDayAgo = `now-24h`; - const response = await client.search<{ task: { runAt: string } }>( + const response = await (client as ElasticsearchClient).search<{ task: { runAt: string } }>( { size: 1, index: taskManagerIndex, @@ -63,14 +63,14 @@ export const getOldestIdleActionTask = async ( { ignore: [404] } ); - if ((response.body as { error?: { status: number } }).error?.status === 404) { + if ((response as { error?: { status: number } }).error?.status === 404) { // If the index doesn't exist, fallback to default return oneDayAgo; - } else if (response.body?.hits?.hits?.length > 0) { + } else if (response.hits?.hits?.length > 0) { // If there is a search result, return it's task.runAt field // If there is a search result but it has no task.runAt, assume something has gone very wrong and return 0 as a safe value // 0 should be safest since no docs should get filtered out - const runAt = response.body.hits.hits[0]._source?.task?.runAt; + const runAt = response.hits.hits[0]._source?.task?.runAt; return runAt ? `${runAt}||-24h` : `0`; } else { // If no results, fallback to default diff --git a/x-pack/plugins/task_manager/server/routes/health.test.ts b/x-pack/plugins/task_manager/server/routes/health.test.ts index b6fecdd02abb7..580cc9035b366 100644 --- a/x-pack/plugins/task_manager/server/routes/health.test.ts +++ b/x-pack/plugins/task_manager/server/routes/health.test.ts @@ -36,10 +36,8 @@ const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); // eslint-disable-next-line @typescript-eslint/no-explicit-any const createMockClusterClient = (response: any) => { const mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); - mockScopedClusterClient.asCurrentUser.security.hasPrivileges.mockResolvedValue({ - body: response, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + mockScopedClusterClient.asCurrentUser.security.hasPrivileges.mockResponse(response as any); const mockClusterClient = elasticsearchServiceMock.createClusterClient(); mockClusterClient.asScoped.mockReturnValue(mockScopedClusterClient); diff --git a/x-pack/plugins/task_manager/server/routes/health.ts b/x-pack/plugins/task_manager/server/routes/health.ts index f980cf82e76ca..2c0e082eb0991 100644 --- a/x-pack/plugins/task_manager/server/routes/health.ts +++ b/x-pack/plugins/task_manager/server/routes/health.ts @@ -128,7 +128,7 @@ export function healthRoute(params: HealthRouteParams): { // the `taskManager` feature, which is only available as part of the Global All privilege. if (usageCounter) { const clusterClient = await getClusterClient(); - const { body: hasPrivilegesResponse } = await clusterClient + const hasPrivilegesResponse = await clusterClient .asScoped(req) .asCurrentUser.security.hasPrivileges({ body: { diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index 4a5637d75b65f..8b897d279fe4a 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import _ from 'lodash'; import { first } from 'rxjs/operators'; @@ -37,6 +38,7 @@ const mockedDate = new Date('2019-02-12T21:01:22.479Z'); constructor() { return mockedDate; } + static now() { return mockedDate.getTime(); } @@ -209,7 +211,9 @@ describe('TaskStore', () => { }); async function testFetch(opts?: SearchOpts, hits: Array> = []) { - esClient.search.mockResolvedValue(asApiResponse({ hits: { hits, total: hits.length } })); + esClient.search.mockResponse({ + hits: { hits, total: hits.length }, + } as estypes.SearchResponse); const result = await store.fetch(opts); @@ -571,17 +575,4 @@ describe('TaskStore', () => { }); }); -const asApiResponse = (body: Pick) => - elasticsearchServiceMock.createSuccessTransportRequestPromise({ - hits: body.hits, - took: 0, - timed_out: false, - _shards: { - failed: 0, - successful: body.hits.hits.length, - total: 0, - skipped: 0, - }, - }); - const randomId = () => `id-${_.random(1, 20)}`; diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index 806a0db697139..db47ba25300ca 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -304,9 +304,7 @@ export class TaskStore { try { const { - body: { - hits: { hits: tasks }, - }, + hits: { hits: tasks }, } = await this.esClient.search({ index: this.index, ignore_unavailable: true, @@ -336,7 +334,7 @@ export class TaskStore { query, size = 0, }: TSearchRequest): Promise> { - const { body } = await this.esClient.search< + const body = await this.esClient.search< ConcreteTaskInstance, Record >({ @@ -359,20 +357,18 @@ export class TaskStore { ): Promise { const { query } = ensureQueryOnlyReturnsTaskObjects(opts); try { - const { - // eslint-disable-next-line @typescript-eslint/naming-convention - body: { total, updated, version_conflicts }, - } = await this.esClient.updateByQuery({ - index: this.index, - ignore_unavailable: true, - refresh: true, - conflicts: 'proceed', - body: { - ...opts, - max_docs, - query, - }, - }); + const // eslint-disable-next-line @typescript-eslint/naming-convention + { total, updated, version_conflicts } = await this.esClient.updateByQuery({ + index: this.index, + ignore_unavailable: true, + refresh: true, + conflicts: 'proceed', + body: { + ...opts, + max_docs, + query, + }, + }); const conflictsCorrectedForContinuation = correctVersionConflictsForContinuation( updated, @@ -391,6 +387,7 @@ export class TaskStore { } } } + /** * When we run updateByQuery with conflicts='proceed', it's possible for the `version_conflicts` * to count against the specified `max_docs`, as per https://github.com/elastic/elasticsearch/issues/63671 diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_license.test.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_license.test.ts index 14e4b25673ad1..7d09280b29d3e 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_license.test.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_license.test.ts @@ -25,7 +25,7 @@ describe('getLicenseFromLocalOrMaster', () => { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; // The local fetch succeeds // @ts-expect-error it's enough to test with minimal payload - esClient.license.get.mockResolvedValue({ body: { license: { type: 'basic' } } }); + esClient.license.get.mockResponse({ license: { type: 'basic' } }); const license = await getLicenseFromLocalOrMaster(esClient); @@ -53,7 +53,7 @@ describe('getLicenseFromLocalOrMaster', () => { esClient.license.get.mockRejectedValueOnce(new Error('Something went terribly wrong')); // The master fetch succeeds // @ts-expect-error it's enough to test with minimal payload - esClient.license.get.mockResolvedValue({ body: { license: { type: 'basic' } } }); + esClient.license.get.mockResolvedValue({ license: { type: 'basic' } }); const license = await getLicenseFromLocalOrMaster(esClient); diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_license.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_license.ts index 2dc63a2f72bd1..2510b467c381a 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_license.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_license.ts @@ -12,11 +12,11 @@ export type ESLicense = estypes.LicenseGetLicenseInformation; let cachedLicense: ESLicense | undefined; async function fetchLicense(esClient: ElasticsearchClient, local: boolean) { - const { body } = await esClient.license.get({ + return await esClient.license.get({ local, }); - return body; } + /** * Get the cluster's license from the connected node. * diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts index 39ffc566a06b0..7febebc2a5179 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts @@ -69,31 +69,25 @@ const mockUsageCollection = (kibanaUsage: Record = kibana) => { function mockEsClient() { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; // mock for license should return a basic license - esClient.license.get.mockResolvedValue( + esClient.license.get.mockResponse( // @ts-expect-error we only care about the response body - { body: { license: { type: 'basic' } } } + { license: { type: 'basic' } } ); // mock for xpack usage should return an empty object - esClient.xpack.usage.mockResolvedValue( + esClient.xpack.usage.mockResponse( // @ts-expect-error we only care about the response body - { body: {} } + {} ); // mock for nodes usage should resolve for this test - esClient.nodes.usage.mockResolvedValue( - // @ts-expect-error we only care about the response body - { body: { cluster_name: 'test cluster', nodes: nodesUsage } } - ); + esClient.nodes.usage.mockResponse({ cluster_name: 'test cluster', nodes: nodesUsage }); // mock for info should resolve for this test - esClient.info.mockResolvedValue( - // @ts-expect-error we only care about the response body - { - body: { - cluster_uuid: 'test', - cluster_name: 'test', - version: { number: '8.0.0' } as estypes.ElasticsearchVersionInfo, - } as estypes.InfoResponse, - } - ); + esClient.info.mockResponse({ + cluster_uuid: 'test', + cluster_name: 'test', + version: { number: '8.0.0' } as estypes.ElasticsearchVersionInfo, + } as estypes.InfoResponse); + // @ts-expect-error empty response + esClient.cluster.stats.mockResponse({}); return esClient; } diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.test.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.test.ts index 48b58c7679789..3a89e11c91a99 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.test.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.test.ts @@ -13,7 +13,7 @@ describe('get_xpack', () => { it('uses esClient to get /_xpack/usage API', async () => { const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; // @ts-expect-error we only care about the response body - esClient.xpack.usage.mockResolvedValue({ body: {} }); + esClient.xpack.usage.mockResponse({}); const result = await getXPackUsage(esClient); expect(result).toEqual({}); }); diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.ts index 3c0902c7f01bf..871a2d846f9f7 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.ts @@ -16,6 +16,5 @@ import { TIMEOUT } from './constants'; * Like any X-Pack related API, X-Pack must installed for this to work. */ export async function getXPackUsage(esClient: ElasticsearchClient) { - const { body } = await esClient.xpack.usage({ master_timeout: TIMEOUT }); - return body; + return await esClient.xpack.usage({ master_timeout: TIMEOUT }); } diff --git a/x-pack/plugins/timelines/server/search_strategy/index_fields/index.test.ts b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.test.ts index 1e3ffd72ece73..c3af5a764d6a7 100644 --- a/x-pack/plugins/timelines/server/search_strategy/index_fields/index.test.ts +++ b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.test.ts @@ -830,12 +830,8 @@ describe('Fields Provider', () => { beforeAll(() => { getFieldsForWildcardMock.mockResolvedValue([]); - esClientSearchMock.mockResolvedValue({ - body: { hits: { total: { value: 123 } } }, - }); - esClientFieldCapsMock.mockResolvedValue({ - body: { indices: ['value'] }, - }); + esClientSearchMock.mockResolvedValue({ hits: { total: { value: 123 } } }); + esClientFieldCapsMock.mockResolvedValue({ indices: ['value'] }); IndexPatternsFetcher.prototype.getFieldsForWildcard = getFieldsForWildcardMock; }); @@ -925,9 +921,7 @@ describe('Fields Provider', () => { onlyCheckIfIndicesExist: true, }; - esClientSearchMock.mockResolvedValue({ - body: { hits: { total: { value: 1 } } }, - }); + esClientSearchMock.mockResolvedValue({ hits: { total: { value: 1 } } }); const response = await requestIndexFieldSearch(request, deps, beatFields, getStartServices); expect(esClientSearchMock).toHaveBeenCalledWith({ diff --git a/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts index 7d514853ccc31..ecd4862a7bd18 100644 --- a/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts @@ -57,7 +57,7 @@ export const findExistingIndices = async ( index, body: { query: { match_all: {} }, size: 0 }, }); - return get(searchResponse, 'body.hits.total.value', 0) > 0; + return get(searchResponse, 'hits.total.value', 0) > 0; } const searchResponse = await esClient.fieldCaps({ index, @@ -65,7 +65,7 @@ export const findExistingIndices = async ( ignore_unavailable: true, allow_no_indices: false, }); - return searchResponse.body.indices.length > 0; + return searchResponse.indices.length > 0; }) .map((p) => p.catch((e) => false)) ); diff --git a/x-pack/plugins/transform/server/lib/alerting/transform_health_rule_type/transform_health_service.ts b/x-pack/plugins/transform/server/lib/alerting/transform_health_rule_type/transform_health_service.ts index 020f5739cd67b..e2512bfac2c55 100644 --- a/x-pack/plugins/transform/server/lib/alerting/transform_health_rule_type/transform_health_service.ts +++ b/x-pack/plugins/transform/server/lib/alerting/transform_health_rule_type/transform_health_service.ts @@ -64,7 +64,7 @@ export function transformHealthServiceProvider( allow_no_match: true, size: 1000, }) - ).body.transforms as Transform[]; + ).transforms as Transform[]; transformsResponse.forEach((t) => { transformsDict.set(t.id, t); @@ -94,7 +94,7 @@ export function transformHealthServiceProvider( await esClient.transform.getTransformStats({ transform_id: transformIds.join(','), }) - ).body.transforms; + ).transforms; return transformsStats .filter((t) => t.state !== 'started' && t.state !== 'indexing') diff --git a/x-pack/plugins/transform/server/routes/api/privileges.ts b/x-pack/plugins/transform/server/routes/api/privileges.ts index 6029260e13914..c952ebcf264d2 100644 --- a/x-pack/plugins/transform/server/routes/api/privileges.ts +++ b/x-pack/plugins/transform/server/routes/api/privileges.ts @@ -29,23 +29,21 @@ export function registerPrivilegesRoute({ router, license }: RouteDependencies) } // Get cluster privileges - const { - body: { has_all_requested: hasAllPrivileges, cluster }, - } = await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ - body: { - // @ts-expect-error SecurityClusterPrivilege doesn’t contain all the priviledges - cluster: APP_CLUSTER_PRIVILEGES, - }, - }); + const { has_all_requested: hasAllPrivileges, cluster } = + await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + body: { + // @ts-expect-error SecurityClusterPrivilege doesn’t contain all the priviledges + cluster: APP_CLUSTER_PRIVILEGES, + }, + }); // Find missing cluster privileges and set overall app privileges privilegesResult.missingPrivileges.cluster = extractMissingPrivileges(cluster); privilegesResult.hasAllPrivileges = hasAllPrivileges; // Get all index privileges the user has - const { - body: { indices }, - } = await ctx.core.elasticsearch.client.asCurrentUser.security.getUserPrivileges(); + const { indices } = + await ctx.core.elasticsearch.client.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 e88f71f0e7f24..09fab2b45909e 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms.ts @@ -90,12 +90,10 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute( async (ctx, req, res) => { try { - const { body } = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform( - { - size: 1000, - ...req.params, - } - ); + const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ + size: 1000, + ...req.params, + }); if (ctx.alerting) { const transformHealthService = transformHealthServiceProvider( @@ -132,7 +130,7 @@ 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 body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ transform_id: transformId, }); return res.ok({ body }); @@ -154,7 +152,7 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { license.guardApiRoute( async (ctx, req, res) => { try { - const { body } = + const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransformStats({ size: 1000, transform_id: '_all', @@ -184,10 +182,9 @@ 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({ - transform_id: transformId, - }); + const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransformStats({ + transform_id: transformId, + }); return res.ok({ body }); } catch (e) { return res.customError(wrapError(wrapEsError(e))); @@ -266,12 +263,11 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { const { transformId } = req.params; try { - const { body } = - await ctx.core.elasticsearch.client.asCurrentUser.transform.updateTransform({ - // @ts-expect-error query doesn't satisfy QueryDslQueryContainer from @elastic/elasticsearch - body: req.body, - transform_id: transformId, - }); + const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.updateTransform({ + // @ts-expect-error query doesn't satisfy QueryDslQueryContainer from @elastic/elasticsearch + body: req.body, + transform_id: transformId, + }); return res.ok({ body, }); @@ -441,7 +437,7 @@ export function registerTransformsRoutes(routeDependencies: RouteDependencies) { }, license.guardApiRoute(async (ctx, req, res) => { try { - const { body } = await ctx.core.elasticsearch.client.asCurrentUser.search(req.body); + const body = await ctx.core.elasticsearch.client.asCurrentUser.search(req.body); return res.ok({ body }); } catch (e) { return res.customError(wrapError(wrapEsError(e))); @@ -508,11 +504,9 @@ async function deleteTransforms( if (!shouldForceDelete) { // Grab destination index info to delete try { - const { body } = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform( - { - transform_id: transformId, - } - ); + const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.getTransform({ + transform_id: transformId, + }); const transformConfig = body.transforms[0]; // @ts-expect-error @elastic/elasticsearch doesn't provide typings for Transform destinationIndex = Array.isArray(transformConfig.dest.index) @@ -647,7 +641,7 @@ const previewTransformHandler: RequestHandler< > = async (ctx, req, res) => { try { const reqBody = req.body; - const { body } = await ctx.core.elasticsearch.client.asCurrentUser.transform.previewTransform({ + const body = await ctx.core.elasticsearch.client.asCurrentUser.transform.previewTransform({ body: reqBody, }); if (isLatestTransform(reqBody)) { @@ -658,10 +652,10 @@ const previewTransformHandler: RequestHandler< include_unmapped: false, }); - const fieldNamesSet = new Set(Object.keys(fieldCapsResponse.body.fields)); + const fieldNamesSet = new Set(Object.keys(fieldCapsResponse.fields)); const fields = Object.entries( - fieldCapsResponse.body.fields as Record> + fieldCapsResponse.fields as Record> ).reduce((acc, [fieldName, fieldCaps]) => { const fieldDefinition = Object.values(fieldCaps)[0]; const isMetaField = fieldDefinition.type.startsWith('_') || fieldName === '_doc_count'; 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 b6a707f0f12fd..a6d732b1208b3 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,19 +78,18 @@ export function registerTransformsAuditMessagesRoutes({ router, license }: Route } try { - const { body: resp } = - await ctx.core.elasticsearch.client.asCurrentUser.search({ - index: ML_DF_NOTIFICATION_INDEX_PATTERN, - ignore_unavailable: true, - size: SIZE, - body: { - sort: [ - { timestamp: { order: 'desc' as const } }, - { transform_id: { order: 'asc' as const } }, - ], - query, - }, - }); + const resp = await ctx.core.elasticsearch.client.asCurrentUser.search({ + index: ML_DF_NOTIFICATION_INDEX_PATTERN, + ignore_unavailable: true, + size: SIZE, + body: { + sort: [ + { timestamp: { order: 'desc' as const } }, + { transform_id: { order: 'asc' as const } }, + ], + query, + }, + }); let messages: AuditMessage[] = []; // TODO: remove typeof checks when appropriate overloading is added for the `search` API 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 5a260b63d5501..0ab01cdeb61c8 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_nodes.ts @@ -21,6 +21,7 @@ const NODE_ROLES = 'roles'; interface NodesAttributes { roles: string[]; } + type Nodes = Record; export const isNodes = (arg: unknown): arg is Nodes => { @@ -50,23 +51,20 @@ export function registerTransformNodesRoutes({ router, license }: RouteDependenc // 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 { - body: { has_all_requested: hasAllPrivileges }, - } = await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ - body: { - // @ts-expect-error SecurityClusterPrivilege doesn’t contain all the priviledges - cluster: NODES_INFO_PRIVILEGES, - }, - }); + const { has_all_requested: hasAllPrivileges } = + await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({ + body: { + // @ts-expect-error SecurityClusterPrivilege doesn’t contain all the priviledges + cluster: NODES_INFO_PRIVILEGES, + }, + }); if (!hasAllPrivileges) { return res.customError(wrapError(new Boom.Boom('Forbidden', { statusCode: 403 }))); } } - const { - body: { nodes }, - } = await ctx.core.elasticsearch.client.asInternalUser.nodes.info({ + const { nodes } = await ctx.core.elasticsearch.client.asInternalUser.nodes.info({ filter_path: `nodes.*.${NODE_ROLES}`, }); 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 6a3b5a0c44aba..c28e6200ba6a9 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 @@ -101,7 +101,7 @@ async function getRawFields(esClient: ElasticsearchClient, indexes: string[]): P allow_no_indices: true, }; const result = await esClient.fieldCaps(params); - return result.body as RawFields; + return result as RawFields; } function getFieldsFromRawFields(rawFields: RawFields): Field[] { 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 7709afa955727..ec19379cfa4ba 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 @@ -98,7 +98,7 @@ async function getIndicesFromPattern( }, }, }; - const { body: response } = await esClient.search(params); + const response = await esClient.search(params); // TODO: Investigate when the status field might appear here, type suggests it shouldn't ever happen // eslint-disable-next-line @typescript-eslint/no-explicit-any if ((response as any).status === 404 || !response.aggregations) { @@ -120,7 +120,7 @@ async function getAliasesFromPattern( }; const result: string[] = []; - const response = await esClient.indices.getAlias(params); + const response = await esClient.indices.getAlias(params, { meta: true }); const responseBody = response.body; if (response.statusCode === 404) { diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts index 2793c2c6ac818..0c1d5e9ef7960 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts @@ -12,7 +12,7 @@ import { DeprecationLoggingStatus } from '../../common/types'; export async function getDeprecationLoggingStatus( dataClient: IScopedClusterClient ): Promise { - const { body: response } = await dataClient.asCurrentUser.cluster.getSettings({ + const response = await dataClient.asCurrentUser.cluster.getSettings({ include_defaults: true, }); @@ -26,7 +26,7 @@ export async function setDeprecationLogging( dataClient: IScopedClusterClient, isEnabled: boolean ): Promise { - const { body: response } = await dataClient.asCurrentUser.cluster.putSettings({ + const response = await dataClient.asCurrentUser.cluster.putSettings({ body: { persistent: { 'logger.deprecation': isEnabled ? 'WARN' : 'ERROR', diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.test.ts index 06c0352ebcdca..efcd7d4ae0243 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.test.ts @@ -6,7 +6,6 @@ */ import _ from 'lodash'; -import { TransportResult } from '@elastic/elasticsearch'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; @@ -15,11 +14,6 @@ import fakeDeprecations from './__fixtures__/fake_deprecations.json'; const fakeIndexNames = Object.keys(fakeDeprecations.index_settings); -const asApiResponse = (body: T): TransportResult => - ({ - body, - } as TransportResult); - describe('getESUpgradeStatus', () => { const resolvedIndices = { indices: fakeIndexNames.map((indexName) => { @@ -36,31 +30,27 @@ describe('getESUpgradeStatus', () => { const esClient = elasticsearchServiceMock.createScopedClusterClient(); - esClient.asCurrentUser.migration.deprecations.mockResolvedValue( - asApiResponse(deprecationsResponse) - ); - - esClient.asCurrentUser.transport.request.mockResolvedValue( - asApiResponse({ - features: [ - { - feature_name: 'machine_learning', - minimum_index_version: '7.1.1', - migration_status: 'MIGRATION_NEEDED', - indices: [ - { - index: '.ml-config', - version: '7.1.1', - }, - ], - }, - ], - migration_status: 'MIGRATION_NEEDED', - }) - ); + esClient.asCurrentUser.migration.deprecations.mockResponse(deprecationsResponse); + + esClient.asCurrentUser.transport.request.mockResolvedValue({ + features: [ + { + feature_name: 'machine_learning', + minimum_index_version: '7.1.1', + migration_status: 'MIGRATION_NEEDED', + indices: [ + { + index: '.ml-config', + version: '7.1.1', + }, + ], + }, + ], + migration_status: 'MIGRATION_NEEDED', + }); // @ts-expect-error not full interface of response - esClient.asCurrentUser.indices.resolveIndex.mockResolvedValue(asApiResponse(resolvedIndices)); + esClient.asCurrentUser.indices.resolveIndex.mockResponse(resolvedIndices); it('calls /_migration/deprecations', async () => { await getESUpgradeStatus(esClient); @@ -73,15 +63,13 @@ describe('getESUpgradeStatus', () => { }); it('returns totalCriticalDeprecations > 0 when critical issues found', async () => { - esClient.asCurrentUser.migration.deprecations.mockResolvedValue( + esClient.asCurrentUser.migration.deprecations.mockResponse({ // @ts-expect-error not full interface - asApiResponse({ - cluster_settings: [{ level: 'critical', message: 'Do count me', url: 'https://...' }], - node_settings: [], - ml_settings: [], - index_settings: {}, - }) - ); + cluster_settings: [{ level: 'critical', message: 'Do count me', url: 'https://...' }], + node_settings: [], + ml_settings: [], + index_settings: {}, + }); await expect(getESUpgradeStatus(esClient)).resolves.toHaveProperty( 'totalCriticalDeprecations', @@ -90,15 +78,13 @@ describe('getESUpgradeStatus', () => { }); it('returns totalCriticalDeprecations === 0 when no critical issues found', async () => { - esClient.asCurrentUser.migration.deprecations.mockResolvedValue( + esClient.asCurrentUser.migration.deprecations.mockResponse({ // @ts-expect-error not full interface - asApiResponse({ - cluster_settings: [{ level: 'warning', message: 'Do not count me', url: 'https://...' }], - node_settings: [], - ml_settings: [], - index_settings: {}, - }) - ); + cluster_settings: [{ level: 'warning', message: 'Do not count me', url: 'https://...' }], + node_settings: [], + ml_settings: [], + index_settings: {}, + }); await expect(getESUpgradeStatus(esClient)).resolves.toHaveProperty( 'totalCriticalDeprecations', @@ -107,24 +93,23 @@ describe('getESUpgradeStatus', () => { }); it('filters out system indices returned by upgrade system indices API', async () => { - esClient.asCurrentUser.migration.deprecations.mockResolvedValue( - asApiResponse({ - cluster_settings: [], - node_settings: [], - ml_settings: [], - index_settings: { - '.ml-config': [ - { - level: 'critical', - message: 'Index created before 7.0', - url: 'https://', - details: '...', - resolve_during_rolling_upgrade: false, - }, - ], - }, - }) - ); + esClient.asCurrentUser.migration.deprecations.mockResponse({ + cluster_settings: [], + node_settings: [], + ml_settings: [], + index_settings: { + '.ml-config': [ + { + level: 'critical', + message: 'Index created before 7.0', + url: 'https://', + details: '...', + // @ts-expect-error not full interface + resolve_during_rolling_upgrade: false, + }, + ], + }, + }); const upgradeStatus = await getESUpgradeStatus(esClient); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.ts index e334d214f2463..610b43d247da9 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecations_status.ts @@ -19,7 +19,7 @@ import { export async function getESUpgradeStatus( dataClient: IScopedClusterClient ): Promise { - const { body: deprecations } = await dataClient.asCurrentUser.migration.deprecations(); + const deprecations = await dataClient.asCurrentUser.migration.deprecations(); const getCombinedDeprecations = async () => { const indices = await getCombinedIndexInfos(deprecations, dataClient); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts index d2595916496a5..3dcae8b307d55 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts @@ -15,7 +15,7 @@ export const esIndicesStateCheck = async ( asCurrentUser: ElasticsearchClient, indices: string[] ): Promise => { - const { body: response } = await asCurrentUser.indices.resolveIndex({ + const response = await asCurrentUser.indices.resolveIndex({ name: '*', expand_wildcards: 'all', }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_system_indices_migration.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_system_indices_migration.ts index aa239de7dd008..18345f9a0944e 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_system_indices_migration.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_system_indices_migration.ts @@ -31,7 +31,7 @@ export const convertFeaturesToIndicesArray = ( export const getESSystemIndicesMigrationStatus = async ( client: ElasticsearchClient ): Promise => { - const { body } = await client.transport.request({ + const body = await client.transport.request({ method: 'GET', path: '/_migration/system_features', }); @@ -42,7 +42,7 @@ export const getESSystemIndicesMigrationStatus = async ( export const startESSystemIndicesMigration = async ( client: ElasticsearchClient ): Promise => { - const { body } = await client.transport.request({ + const body = await client.transport.request({ method: 'POST', path: '/_migration/system_features', }); 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 1785491e5da45..7205a0458494b 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 @@ -39,12 +39,10 @@ describe('getAllNodeVersions', () => { asInternalUser: { nodes: { info: jest.fn().mockResolvedValue({ - body: { - nodes: { - node1: { version: '7.0.0' }, - node2: { version: '7.0.0' }, - node3: { version: '6.0.0' }, - }, + nodes: { + node1: { version: '7.0.0' }, + node2: { version: '7.0.0' }, + node3: { version: '6.0.0' }, }, }), }, @@ -102,19 +100,9 @@ describe('EsVersionPrecheck', () => { }); it('returns a 403 when callCluster fails with a 403', async () => { - const fakeCall = jest.fn().mockRejectedValue({ statusCode: 403 }); - const ctx = xpackMocks.createRequestHandlerContext(); - ctx.core.elasticsearch.client = { - asInternalUser: { - ...ctx.core.elasticsearch.client.asInternalUser, - nodes: { - ...ctx.core.elasticsearch.client.asInternalUser.nodes, - info: fakeCall, - }, - }, - asCurrentUser: ctx.core.elasticsearch.client.asCurrentUser, - }; + + ctx.core.elasticsearch.client.asInternalUser.nodes.info.mockRejectedValue({ statusCode: 403 }); const result = await esVersionCheck(ctx, kibanaResponseFactory); expect(result).toHaveProperty('status', 403); @@ -122,23 +110,15 @@ describe('EsVersionPrecheck', () => { it('returns a 426 message w/ allNodesUpgraded = false when nodes are not on same version', async () => { const ctx = xpackMocks.createRequestHandlerContext(); - ctx.core.elasticsearch.client = { - asInternalUser: { - ...ctx.core.elasticsearch.client.asInternalUser, - nodes: { - ...ctx.core.elasticsearch.client.asInternalUser.nodes, - info: jest.fn().mockResolvedValue({ - body: { - nodes: { - node1: { version: currentVersion.raw }, - node2: { version: new SemVer(currentVersion.raw).inc('major').raw }, - }, - }, - }), - }, + + ctx.core.elasticsearch.client.asInternalUser.nodes.info.mockResponse({ + nodes: { + // @ts-expect-error incomplete type + node1: { version: currentVersion.raw }, + // @ts-expect-error incomplete type + node2: { version: new SemVer(currentVersion.raw).inc('major').raw }, }, - asCurrentUser: ctx.core.elasticsearch.client.asCurrentUser, - }; + }); const result = await esVersionCheck(ctx, kibanaResponseFactory); expect(result).toHaveProperty('status', 426); @@ -147,23 +127,15 @@ describe('EsVersionPrecheck', () => { it('returns a 426 message w/ allNodesUpgraded = true when nodes are on next version', async () => { const ctx = xpackMocks.createRequestHandlerContext(); - ctx.core.elasticsearch.client = { - asInternalUser: { - ...ctx.core.elasticsearch.client.asInternalUser, - nodes: { - ...ctx.core.elasticsearch.client.asInternalUser.nodes, - info: jest.fn().mockResolvedValue({ - body: { - nodes: { - node1: { version: new SemVer(currentVersion.raw).inc('major').raw }, - node2: { version: new SemVer(currentVersion.raw).inc('major').raw }, - }, - }, - }), - }, + + ctx.core.elasticsearch.client.asInternalUser.nodes.info.mockResponse({ + nodes: { + // @ts-expect-error incomplete type + node1: { version: new SemVer(currentVersion.raw).inc('major').raw }, + // @ts-expect-error incomplete type + node2: { version: new SemVer(currentVersion.raw).inc('major').raw }, }, - asCurrentUser: ctx.core.elasticsearch.client.asCurrentUser, - }; + }); const result = await esVersionCheck(ctx, kibanaResponseFactory); expect(result).toHaveProperty('status', 426); @@ -172,23 +144,15 @@ describe('EsVersionPrecheck', () => { it('returns undefined when nodes are on same version', async () => { const ctx = xpackMocks.createRequestHandlerContext(); - ctx.core.elasticsearch.client = { - asInternalUser: { - ...ctx.core.elasticsearch.client.asInternalUser, - nodes: { - ...ctx.core.elasticsearch.client.asInternalUser.nodes, - info: jest.fn().mockResolvedValue({ - body: { - nodes: { - node1: { version: currentVersion.raw }, - node2: { version: currentVersion.raw }, - }, - }, - }), - }, + + ctx.core.elasticsearch.client.asInternalUser.nodes.info.mockResponse({ + nodes: { + // @ts-expect-error incomplete type + node1: { version: currentVersion.raw }, + // @ts-expect-error incomplete type + node2: { version: currentVersion.raw }, }, - asCurrentUser: ctx.core.elasticsearch.client.asCurrentUser, - }; + }); await expect(esVersionCheck(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 cefc5576159e7..7b656635d8644 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 @@ -16,22 +16,16 @@ import { } from 'src/core/server'; import { versionService } from './version'; -interface Nodes { - nodes: { - [nodeId: string]: { version: string }; - }; -} - /** * Returns an array of all the unique Elasticsearch Node Versions in the Elasticsearch cluster. */ export const getAllNodeVersions = async (adminClient: IScopedClusterClient) => { // Get the version information for all nodes in the cluster. - const response = await adminClient.asInternalUser.nodes.info({ + const response = await adminClient.asInternalUser.nodes.info({ filter_path: 'nodes.*.version', }); - const nodes = response.body.nodes; + const nodes = response.nodes; const versionStrings = Object.values(nodes).map(({ version }) => version); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts index 3f58a04949da5..b6064d76bcd7a 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { TransportResult } from '@elastic/elasticsearch'; import { SavedObjectsErrorHelpers } from 'src/core/server'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths @@ -256,21 +255,14 @@ describe('ReindexActions', () => { }); describe('getFlatSettings', () => { - const asApiResponse = (body: T): TransportResult => - ({ - body, - } as TransportResult); - it('returns flat settings', async () => { - clusterClient.asCurrentUser.indices.get.mockResolvedValueOnce( - // @ts-expect-error not full interface - asApiResponse({ - myIndex: { - settings: { 'index.mySetting': '1' }, - mappings: {}, - }, - }) - ); + clusterClient.asCurrentUser.indices.get.mockResponse({ + myIndex: { + // @ts-expect-error not full interface + settings: { 'index.mySetting': '1' }, + mappings: {}, + }, + }); await expect(actions.getFlatSettings('myIndex')).resolves.toEqual({ settings: { 'index.mySetting': '1' }, mappings: {}, @@ -278,7 +270,7 @@ describe('ReindexActions', () => { }); it('returns null if index does not exist', async () => { - clusterClient.asCurrentUser.indices.get.mockResolvedValueOnce(asApiResponse({})); + clusterClient.asCurrentUser.indices.get.mockResponse({}); await expect(actions.getFlatSettings('myIndex')).resolves.toBeNull(); }); }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts index 09ba4b744e68e..3b4e3ad79cc8c 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts @@ -212,9 +212,7 @@ export const reindexActionsFactory = ( if (versionService.getMajorVersion() === 7) { // On 7.x, we need to get index settings with mapping type - flatSettings = await esClient.indices.get<{ - [indexName: string]: FlatSettingsWithTypeName; - }>({ + flatSettings = await esClient.indices.get({ index: indexName, flat_settings: true, // This @ts-ignore is needed on master since the flag is deprecated on >7.x @@ -222,19 +220,17 @@ export const reindexActionsFactory = ( include_type_name: true, }); } else { - flatSettings = await esClient.indices.get<{ - [indexName: string]: FlatSettings; - }>({ + flatSettings = await esClient.indices.get({ index: indexName, flat_settings: true, }); } - if (!flatSettings.body[indexName]) { + if (!flatSettings[indexName]) { return null; } - return flatSettings.body[indexName]; + return flatSettings[indexName]; }, }; }; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts index 268846a31d2bd..a3628a62d8ab0 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts @@ -95,9 +95,9 @@ describe('reindexService', () => { }); it('calls security API with basic requirements', async () => { - clusterClient.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce( + clusterClient.asCurrentUser.security.hasPrivileges.mockResponse( // @ts-expect-error not full interface - asApiResponse({ has_all_requested: true }) + { has_all_requested: true } ); const hasRequired = await service.hasRequiredPrivileges('anIndex'); @@ -121,9 +121,9 @@ describe('reindexService', () => { }); it('includes checking for permissions on the baseName which could be an alias', async () => { - clusterClient.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce( + clusterClient.asCurrentUser.security.hasPrivileges.mockResponse( // @ts-expect-error not full interface - asApiResponse({ has_all_requested: true }) + { has_all_requested: true } ); const hasRequired = await service.hasRequiredPrivileges(`reindexed-v${prevMajor}-anIndex`); @@ -180,7 +180,7 @@ describe('reindexService', () => { describe('createReindexOperation', () => { it('creates new reindex operation', async () => { - clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(true)); + clusterClient.asCurrentUser.indices.exists.mockResponse(true); actions.findReindexOperations.mockResolvedValueOnce({ total: 0 }); actions.createReindexOp.mockResolvedValueOnce(); @@ -190,13 +190,13 @@ describe('reindexService', () => { }); it('fails if index does not exist', async () => { - clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(false)); + clusterClient.asCurrentUser.indices.exists.mockResponse(false); await expect(service.createReindexOperation('myIndex')).rejects.toThrow(); expect(actions.createReindexOp).not.toHaveBeenCalled(); }); it('deletes existing operation if it failed', async () => { - clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(true)); + clusterClient.asCurrentUser.indices.exists.mockResponse(true); actions.findReindexOperations.mockResolvedValueOnce({ saved_objects: [{ id: 1, attributes: { status: ReindexStatus.failed } }], total: 1, @@ -212,7 +212,7 @@ describe('reindexService', () => { }); it('deletes existing operation if it was cancelled', async () => { - clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(true)); + clusterClient.asCurrentUser.indices.exists.mockResponse(true); actions.findReindexOperations.mockResolvedValueOnce({ saved_objects: [{ id: 1, attributes: { status: ReindexStatus.cancelled } }], total: 1, @@ -228,7 +228,7 @@ describe('reindexService', () => { }); it('fails if existing operation did not fail', async () => { - clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(true)); + clusterClient.asCurrentUser.indices.exists.mockResponse(true); actions.findReindexOperations.mockResolvedValueOnce({ saved_objects: [{ id: 1, attributes: { status: ReindexStatus.inProgress } }], total: 1, @@ -388,7 +388,7 @@ describe('reindexService', () => { } as any); // @ts-expect-error not full interface - clusterClient.asCurrentUser.tasks.cancel.mockResolvedValueOnce(asApiResponse(true)); + clusterClient.asCurrentUser.tasks.cancel.mockResponse(true); await service.cancelReindexing('myIndex'); expect(clusterClient.asCurrentUser.tasks.cancel).toHaveBeenCalledWith({ task_id: '999333' }); @@ -459,9 +459,9 @@ describe('reindexService', () => { // The more intricate details of how the settings are chosen are test separately. it('creates new index with settings and mappings and updates lastCompletedStep', async () => { actions.getFlatSettings.mockResolvedValueOnce(settingsMappings); - clusterClient.asCurrentUser.indices.create.mockResolvedValueOnce( + clusterClient.asCurrentUser.indices.create.mockResponse( // @ts-expect-error not full interface - asApiResponse({ acknowledged: true }) + { acknowledged: true } ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.newIndexCreated); @@ -476,14 +476,14 @@ describe('reindexService', () => { }); it('fails if create index is not acknowledged', async () => { - clusterClient.asCurrentUser.indices.get.mockResolvedValueOnce( + clusterClient.asCurrentUser.indices.get.mockResponseOnce( // @ts-expect-error not full interface - asApiResponse({ myIndex: settingsMappings }) + { myIndex: settingsMappings } ); - clusterClient.asCurrentUser.indices.create.mockResolvedValueOnce( + clusterClient.asCurrentUser.indices.create.mockResponseOnce( // @ts-expect-error not full interface - asApiResponse({ acknowledged: false }) + { acknowledged: false } ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.readonly); @@ -493,16 +493,14 @@ describe('reindexService', () => { }); it('fails if create index fails', async () => { - clusterClient.asCurrentUser.indices.get.mockResolvedValueOnce( + clusterClient.asCurrentUser.indices.get.mockResponseOnce( // @ts-expect-error not full interface - asApiResponse({ myIndex: settingsMappings }) + { myIndex: settingsMappings } ); clusterClient.asCurrentUser.indices.create.mockRejectedValueOnce(new Error(`blah!`)); - clusterClient.asCurrentUser.indices.putSettings.mockResolvedValueOnce( - asApiResponse({ acknowledged: true }) - ); + clusterClient.asCurrentUser.indices.putSettings.mockResponseOnce({ acknowledged: true }); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.readonly); @@ -535,7 +533,7 @@ describe('reindexService', () => { }); it('starts reindex, saves taskId, and updates lastCompletedStep', async () => { - clusterClient.asCurrentUser.reindex.mockResolvedValueOnce(asApiResponse({ task: 'xyz' })); + clusterClient.asCurrentUser.reindex.mockResponseOnce({ task: 'xyz' }); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexStarted); expect(updatedOp.attributes.reindexTaskId).toEqual('xyz'); @@ -572,13 +570,11 @@ describe('reindexService', () => { describe('reindex task is not complete', () => { it('updates reindexTaskPercComplete', async () => { - clusterClient.asCurrentUser.tasks.get.mockResolvedValueOnce( + clusterClient.asCurrentUser.tasks.get.mockResponseOnce({ + completed: false, // @ts-expect-error not full interface - asApiResponse({ - completed: false, - task: { status: { created: 10, total: 100 } }, - }) - ); + task: { status: { created: 10, total: 100 } }, + }); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexStarted); @@ -588,26 +584,24 @@ describe('reindexService', () => { describe('reindex task is complete', () => { it('deletes task, updates reindexTaskPercComplete, updates lastCompletedStep', async () => { - clusterClient.asCurrentUser.tasks.get.mockResolvedValueOnce( + clusterClient.asCurrentUser.tasks.get.mockResponseOnce({ + completed: true, // @ts-expect-error not full interface - asApiResponse({ - completed: true, - task: { status: { created: 100, total: 100 } }, - }) - ); + task: { status: { created: 100, total: 100 } }, + }); - clusterClient.asCurrentUser.count.mockResolvedValueOnce( + clusterClient.asCurrentUser.count.mockResponseOnce( // @ts-expect-error not full interface - asApiResponse({ + { count: 100, - }) + } ); - clusterClient.asCurrentUser.delete.mockResolvedValueOnce( + clusterClient.asCurrentUser.delete.mockResponseOnce( // @ts-expect-error not full interface - asApiResponse({ + { result: 'deleted', - }) + } ); const updatedOp = await service.processNextStep(reindexOp); @@ -620,19 +614,17 @@ describe('reindexService', () => { }); it('fails if docs created is less than count in source index', async () => { - clusterClient.asCurrentUser.tasks.get.mockResolvedValueOnce( + clusterClient.asCurrentUser.tasks.get.mockResponseOnce({ + completed: true, // @ts-expect-error not full interface - asApiResponse({ - completed: true, - task: { status: { created: 95, total: 95 } }, - }) - ); + task: { status: { created: 95, total: 95 } }, + }); - clusterClient.asCurrentUser.count.mockResolvedValueOnce( + clusterClient.asCurrentUser.count.mockResponseOnce( // @ts-expect-error not full interface - asApiResponse({ + { count: 100, - }) + } ); const updatedOp = await service.processNextStep(reindexOp); @@ -645,17 +637,15 @@ describe('reindexService', () => { describe('reindex task is cancelled', () => { it('deletes task, updates status to cancelled', async () => { - clusterClient.asCurrentUser.tasks.get.mockResolvedValueOnce( + clusterClient.asCurrentUser.tasks.get.mockResponseOnce({ + completed: true, // @ts-expect-error not full interface - asApiResponse({ - completed: true, - task: { status: { created: 100, total: 100, canceled: 'by user request' } }, - }) - ); + task: { status: { created: 100, total: 100, canceled: 'by user request' } }, + }); - clusterClient.asCurrentUser.delete.mockResolvedValue( + clusterClient.asCurrentUser.delete.mockResponseOnce( // @ts-expect-error not full interface - asApiResponse({ result: 'deleted' }) + { result: 'deleted' } ); const updatedOp = await service.processNextStep(reindexOp); @@ -680,13 +670,8 @@ describe('reindexService', () => { } as ReindexSavedObject; it('switches aliases, sets as complete, and updates lastCompletedStep', async () => { - clusterClient.asCurrentUser.indices.getAlias.mockResolvedValue( - asApiResponse({ myIndex: { aliases: {} } }) - ); - - clusterClient.asCurrentUser.indices.updateAliases.mockResolvedValue( - asApiResponse({ acknowledged: true }) - ); + clusterClient.asCurrentUser.indices.getAlias.mockResponseOnce({ myIndex: { aliases: {} } }); + clusterClient.asCurrentUser.indices.updateAliases.mockResponseOnce({ acknowledged: true }); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); expect(clusterClient.asCurrentUser.indices.updateAliases).toHaveBeenCalledWith({ @@ -700,20 +685,16 @@ describe('reindexService', () => { }); it('moves existing aliases over to new index', async () => { - clusterClient.asCurrentUser.indices.getAlias.mockResolvedValue( - asApiResponse({ - myIndex: { - aliases: { - myAlias: {}, - myFilteredAlias: { filter: { term: { https: true } } }, - }, + clusterClient.asCurrentUser.indices.getAlias.mockResponseOnce({ + myIndex: { + aliases: { + myAlias: {}, + myFilteredAlias: { filter: { term: { https: true } } }, }, - }) - ); + }, + }); - clusterClient.asCurrentUser.indices.updateAliases.mockResolvedValue( - asApiResponse({ acknowledged: true }) - ); + clusterClient.asCurrentUser.indices.updateAliases.mockResponseOnce({ acknowledged: true }); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); @@ -736,9 +717,7 @@ describe('reindexService', () => { }); it('fails if switching aliases is not acknowledged', async () => { - clusterClient.asCurrentUser.indices.updateAliases.mockResolvedValue( - asApiResponse({ acknowledged: false }) - ); + clusterClient.asCurrentUser.indices.updateAliases.mockResponseOnce({ acknowledged: false }); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexCompleted); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts index 3182a74498994..9d613dd831630 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts @@ -165,7 +165,7 @@ export const reindexServiceFactory = ( */ const setReadonly = async (reindexOp: ReindexSavedObject) => { const { indexName } = reindexOp.attributes; - const { body: putReadonly } = await esClient.indices.putSettings({ + const putReadonly = await esClient.indices.putSettings({ index: indexName, body: { blocks: { write: true } }, }); @@ -210,7 +210,7 @@ export const reindexServiceFactory = ( } } - if (createIndex && !createIndex?.body?.acknowledged) { + if (createIndex && !createIndex?.acknowledged) { throw error.cannotCreateIndex(`Index could not be created: ${newIndexName}`); } @@ -240,7 +240,7 @@ export const reindexServiceFactory = ( throw error.indexNotFound(`Index ${indexName} does not exist.`); } - const { body: startReindexResponse } = await esClient.reindex({ + const startReindexResponse = await esClient.reindex({ refresh: true, wait_for_completion: false, body: { @@ -273,7 +273,7 @@ export const reindexServiceFactory = ( const taskId = reindexOp.attributes.reindexTaskId!; // Check reindexing task progress - const { body: taskResponse } = await esClient.tasks.get({ + const taskResponse = await esClient.tasks.get({ task_id: taskId, wait_for_completion: false, }); @@ -308,7 +308,7 @@ export const reindexServiceFactory = ( } // Delete the task from ES .tasks index - const { body: deleteTaskResp } = await esClient.delete({ + const deleteTaskResp = await esClient.delete({ index: '.tasks', id: taskId, }); @@ -321,7 +321,7 @@ export const reindexServiceFactory = ( }; const getIndexAliases = async (indexName: string) => { - const { body: response } = await esClient.indices.getAlias({ + const response = await esClient.indices.getAlias({ index: indexName, }); @@ -341,7 +341,7 @@ export const reindexServiceFactory = ( add: { index: newIndexName, alias: aliasName, ...existingAliases[aliasName] }, })); - const { body: aliasResponse } = await esClient.indices.updateAliases({ + const aliasResponse = await esClient.indices.updateAliases({ body: { actions: [ { add: { index: newIndexName, alias: indexName } }, @@ -408,7 +408,7 @@ export const reindexServiceFactory = ( ], } as any; - const { body: resp } = await esClient.security.hasPrivileges({ + const resp = await esClient.security.hasPrivileges({ body, }); @@ -434,7 +434,7 @@ export const reindexServiceFactory = ( }, async createReindexOperation(indexName: string, opts?: { enqueue: boolean }) { - const { body: indexExists } = await esClient.indices.exists({ index: indexName }); + const indexExists = await esClient.indices.exists({ index: indexName }); if (!indexExists) { throw error.indexNotFound(`Index ${indexName} does not exist in this cluster.`); } @@ -614,7 +614,7 @@ export const reindexServiceFactory = ( ); } - const { body: resp } = await esClient.tasks.cancel({ + const resp = await esClient.tasks.cancel({ task_id: reindexOp.attributes.reindexTaskId!, }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts index 34d329557f11e..ad33ad248a564 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts @@ -25,16 +25,14 @@ describe('Upgrade Assistant Usage Collector', () => { beforeEach(() => { clusterClient = elasticsearchServiceMock.createClusterClient(); (clusterClient.asInternalUser.cluster.getSettings as jest.Mock).mockResolvedValue({ - body: { - persistent: {}, - transient: { - logger: { - deprecation: 'WARN', - }, - cluster: { - deprecation_indexing: { - enabled: 'true', - }, + persistent: {}, + transient: { + logger: { + deprecation: 'WARN', + }, + cluster: { + deprecation_indexing: { + enabled: 'true', }, }, }, diff --git a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts index c535cd14f104d..97361c5f05936 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts @@ -15,7 +15,7 @@ import { async function getDeprecationLoggingStatusValue(esClient: ElasticsearchClient): Promise { try { - const { body: loggerDeprecationCallResult } = await esClient.cluster.getSettings({ + const loggerDeprecationCallResult = await esClient.cluster.getSettings({ include_defaults: true, }); diff --git a/x-pack/plugins/upgrade_assistant/server/routes/app.ts b/x-pack/plugins/upgrade_assistant/server/routes/app.ts index 682dc83410f81..b976811a87e5b 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/app.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/app.ts @@ -52,18 +52,17 @@ export function registerAppRoutes({ } try { - const { - body: { has_all_requested: hasAllPrivileges, index }, - } = await client.asCurrentUser.security.hasPrivileges({ - body: { - index: [ - { - names: [DEPRECATION_LOGS_INDEX], - privileges: ['read'], - }, - ], - }, - }); + const { has_all_requested: hasAllPrivileges, index } = + await client.asCurrentUser.security.hasPrivileges({ + body: { + index: [ + { + names: [DEPRECATION_LOGS_INDEX], + privileges: ['read'], + }, + ], + }, + }); if (!hasAllPrivileges) { privilegesResult.missingPrivileges.index = extractMissingPrivileges(index); 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 5d3ab7c854e7b..b757602c6ab53 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 @@ -20,9 +20,7 @@ export function registerCloudBackupStatusRoutes({ const { client: clusterClient } = context.core.elasticsearch; try { - const { - body: { snapshots }, - } = await clusterClient.asCurrentUser.snapshot.get({ + const { snapshots } = await clusterClient.asCurrentUser.snapshot.get({ repository: CLOUD_SNAPSHOT_REPOSITORY, snapshot: '_all', ignore_unavailable: true, // Allow request to succeed even if some snapshots are unavailable. diff --git a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts index 89d4e4cb398c6..07bc3d573e606 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts @@ -44,10 +44,8 @@ describe('deprecation logging API', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.cluster .getSettings as jest.Mock ).mockResolvedValue({ - body: { - defaults: { - cluster: { deprecation_indexing: { enabled: 'true' } }, - }, + defaults: { + cluster: { deprecation_indexing: { enabled: 'true' } }, }, }); @@ -83,11 +81,9 @@ describe('deprecation logging API', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.cluster .putSettings as jest.Mock ).mockResolvedValue({ - body: { - defaults: { - logger: { deprecation: 'WARN' }, - cluster: { deprecation_indexing: { enabled: 'true' } }, - }, + defaults: { + logger: { deprecation: 'WARN' }, + cluster: { deprecation_indexing: { enabled: 'true' } }, }, }); @@ -122,14 +118,10 @@ describe('deprecation logging API', () => { it('returns count of deprecations', async () => { ( routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.indices.exists as jest.Mock - ).mockResolvedValue({ - body: true, - }); + ).mockResolvedValue(true); ( routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.count as jest.Mock - ).mockResolvedValue({ - body: { count: 10 }, - }); + ).mockResolvedValue({ count: 10 }); const resp = await routeDependencies.router.getHandler({ method: 'get', @@ -147,9 +139,7 @@ describe('deprecation logging API', () => { it('returns zero matches when deprecation logs index is not created', async () => { ( routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.indices.exists as jest.Mock - ).mockResolvedValue({ - body: false, - }); + ).mockResolvedValue(false); const resp = await routeDependencies.router.getHandler({ method: 'get', @@ -182,9 +172,7 @@ describe('deprecation logging API', () => { ( routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.transport .request as jest.Mock - ).mockResolvedValue({ - body: 'ok', - }); + ).mockResolvedValue('ok'); const resp = await routeDependencies.router.getHandler({ method: 'delete', 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 896bddb505511..70fd5d035ad52 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts @@ -101,7 +101,7 @@ export function registerDeprecationLoggingRoutes({ response ) => { try { - const { body: indexExists } = await client.asCurrentUser.indices.exists({ + const indexExists = await client.asCurrentUser.indices.exists({ index: DEPRECATION_LOGS_INDEX, }); @@ -111,7 +111,7 @@ export function registerDeprecationLoggingRoutes({ const now = moment().toISOString(); - const { body } = await client.asCurrentUser.count({ + const body = await client.asCurrentUser.count({ index: DEPRECATION_LOGS_INDEX, body: { query: { diff --git a/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.test.ts index 603a18f2274b1..7293c397e5d9f 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.test.ts @@ -44,10 +44,8 @@ describe('ML snapshots APIs', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.ml .upgradeJobSnapshot as jest.Mock ).mockResolvedValue({ - body: { - node: NODE_ID, - completed: false, - }, + node: NODE_ID, + completed: false, }); const resp = await routeDependencies.router.getHandler({ @@ -78,10 +76,8 @@ describe('ML snapshots APIs', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.ml .upgradeJobSnapshot as jest.Mock ).mockResolvedValue({ - body: { - node: NODE_ID, - completed: true, - }, + node: NODE_ID, + completed: true, }); const resp = await routeDependencies.router.getHandler({ @@ -135,9 +131,7 @@ describe('ML snapshots APIs', () => { ( routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.ml .deleteModelSnapshot as jest.Mock - ).mockResolvedValue({ - body: { acknowledged: true }, - }); + ).mockResolvedValue({ acknowledged: true }); const resp = await routeDependencies.router.getHandler({ method: 'delete', @@ -181,9 +175,7 @@ describe('ML snapshots APIs', () => { ( routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.ml.info as jest.Mock ).mockResolvedValue({ - body: { - upgrade_mode: true, - }, + upgrade_mode: true, }); const resp = await routeDependencies.router.getHandler({ @@ -204,23 +196,21 @@ describe('ML snapshots APIs', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.ml .getModelSnapshots as jest.Mock ).mockResolvedValue({ - body: { - count: 1, - model_snapshots: [ - { - job_id: JOB_ID, - min_version: '6.4.0', - timestamp: 1575402237000, - description: 'State persisted due to job close at 2019-12-03T19:43:57+0000', - snapshot_id: SNAPSHOT_ID, - snapshot_doc_count: 1, - model_size_stats: {}, - latest_record_time_stamp: 1576971072000, - latest_result_time_stamp: 1576965600000, - retain: false, - }, - ], - }, + count: 1, + model_snapshots: [ + { + job_id: JOB_ID, + min_version: '6.4.0', + timestamp: 1575402237000, + description: 'State persisted due to job close at 2019-12-03T19:43:57+0000', + snapshot_id: SNAPSHOT_ID, + snapshot_doc_count: 1, + model_size_stats: {}, + latest_record_time_stamp: 1576971072000, + latest_result_time_stamp: 1576965600000, + retain: false, + }, + ], }); const resp = await routeDependencies.router.getHandler({ @@ -251,23 +241,21 @@ describe('ML snapshots APIs', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.ml .getModelSnapshots as jest.Mock ).mockResolvedValue({ - body: { - count: 1, - model_snapshots: [ - { - job_id: JOB_ID, - min_version: '6.4.0', - timestamp: 1575402237000, - description: 'State persisted due to job close at 2019-12-03T19:43:57+0000', - snapshot_id: SNAPSHOT_ID, - snapshot_doc_count: 1, - model_size_stats: {}, - latest_record_time_stamp: 1576971072000, - latest_result_time_stamp: 1576965600000, - retain: false, - }, - ], - }, + count: 1, + model_snapshots: [ + { + job_id: JOB_ID, + min_version: '6.4.0', + timestamp: 1575402237000, + description: 'State persisted due to job close at 2019-12-03T19:43:57+0000', + snapshot_id: SNAPSHOT_ID, + snapshot_doc_count: 1, + model_size_stats: {}, + latest_record_time_stamp: 1576971072000, + latest_result_time_stamp: 1576965600000, + retain: false, + }, + ], }); (routeHandlerContextMock.core.savedObjects.client.find as jest.Mock).mockResolvedValue({ @@ -324,23 +312,21 @@ describe('ML snapshots APIs', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.ml .getModelSnapshots as jest.Mock ).mockResolvedValue({ - body: { - count: 1, - model_snapshots: [ - { - job_id: JOB_ID, - min_version: '6.4.0', - timestamp: 1575402237000, - description: 'State persisted due to job close at 2019-12-03T19:43:57+0000', - snapshot_id: SNAPSHOT_ID, - snapshot_doc_count: 1, - model_size_stats: {}, - latest_record_time_stamp: 1576971072000, - latest_result_time_stamp: 1576965600000, - retain: false, - }, - ], - }, + count: 1, + model_snapshots: [ + { + job_id: JOB_ID, + min_version: '6.4.0', + timestamp: 1575402237000, + description: 'State persisted due to job close at 2019-12-03T19:43:57+0000', + snapshot_id: SNAPSHOT_ID, + snapshot_doc_count: 1, + model_size_stats: {}, + latest_record_time_stamp: 1576971072000, + latest_result_time_stamp: 1576965600000, + retain: false, + }, + ], }); (routeHandlerContextMock.core.savedObjects.client.find as jest.Mock).mockResolvedValue({ @@ -391,23 +377,21 @@ describe('ML snapshots APIs', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.ml .getModelSnapshots as jest.Mock ).mockResolvedValue({ - body: { - count: 1, - model_snapshots: [ - { - job_id: JOB_ID, - min_version: '6.4.0', - timestamp: 1575402237000, - description: 'State persisted due to job close at 2019-12-03T19:43:57+0000', - snapshot_id: SNAPSHOT_ID, - snapshot_doc_count: 1, - model_size_stats: {}, - latest_record_time_stamp: 1576971072000, - latest_result_time_stamp: 1576965600000, - retain: false, - }, - ], - }, + count: 1, + model_snapshots: [ + { + job_id: JOB_ID, + min_version: '6.4.0', + timestamp: 1575402237000, + description: 'State persisted due to job close at 2019-12-03T19:43:57+0000', + snapshot_id: SNAPSHOT_ID, + snapshot_doc_count: 1, + model_size_stats: {}, + latest_record_time_stamp: 1576971072000, + latest_result_time_stamp: 1576965600000, + retain: false, + }, + ], }); (routeHandlerContextMock.core.savedObjects.client.find as jest.Mock).mockResolvedValue({ @@ -432,12 +416,10 @@ describe('ML snapshots APIs', () => { routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.migration .deprecations as jest.Mock ).mockResolvedValue({ - body: { - cluster_settings: [], - ml_settings: [], - node_settings: [], - index_settings: {}, - }, + cluster_settings: [], + ml_settings: [], + node_settings: [], + index_settings: {}, }); (routeHandlerContextMock.core.savedObjects.client.delete as jest.Mock).mockResolvedValue({}); 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 fb65f6d41c43e..38d1b09650b09 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/ml_snapshots.ts @@ -63,7 +63,7 @@ const verifySnapshotUpgrade = async ( const { snapshotId, jobId } = snapshot; try { - const { body: deprecations } = await esClient.asCurrentUser.migration.deprecations(); + const deprecations = await esClient.asCurrentUser.migration.deprecations(); const mlSnapshotDeprecations = deprecations.ml_settings.filter((deprecation) => { return /[Mm]odel snapshot/.test(deprecation.message); @@ -115,10 +115,13 @@ const getModelSnapshotUpgradeStatus = async ( snapshotId: string ) => { try { - const { body } = (await esClient.asCurrentUser.transport.request({ - method: 'GET', - path: `/_ml/anomaly_detectors/${jobId}/model_snapshots/${snapshotId}/_upgrade/_stats`, - })) as TransportResult; + const { body } = (await esClient.asCurrentUser.transport.request( + { + method: 'GET', + path: `/_ml/anomaly_detectors/${jobId}/model_snapshots/${snapshotId}/_upgrade/_stats`, + }, + { meta: true } + )) as TransportResult; return body && body.model_snapshot_upgrades[0]; } catch (err) { @@ -162,7 +165,7 @@ export function registerMlSnapshotRoutes({ try { const { snapshotId, jobId } = request.body; - const { body } = await esClient.asCurrentUser.ml.upgradeJobSnapshot({ + const body = await esClient.asCurrentUser.ml.upgradeJobSnapshot({ job_id: jobId, snapshot_id: snapshotId, }); @@ -352,7 +355,7 @@ export function registerMlSnapshotRoutes({ response ) => { try { - const { body: mlInfo } = await esClient.asCurrentUser.ml.info(); + const mlInfo = await esClient.asCurrentUser.ml.info(); return response.ok({ body: { @@ -390,11 +393,10 @@ export function registerMlSnapshotRoutes({ try { const { snapshotId, jobId } = request.params; - const { body: deleteSnapshotResponse } = - await client.asCurrentUser.ml.deleteModelSnapshot({ - job_id: jobId, - snapshot_id: snapshotId, - }); + const deleteSnapshotResponse = await client.asCurrentUser.ml.deleteModelSnapshot({ + job_id: jobId, + snapshot_id: snapshotId, + }); return response.ok({ body: deleteSnapshotResponse, 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 de2177cffa1fe..0d7268e1be5be 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/remote_clusters.ts @@ -26,7 +26,7 @@ export function registerRemoteClustersRoute({ router, lib: { handleEsError } }: response ) => { try { - const { body: clustersByName } = await client.asCurrentUser.cluster.remoteInfo(); + const clustersByName = await client.asCurrentUser.cluster.remoteInfo(); const remoteClusters = Object.keys(clustersByName); diff --git a/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.test.ts index 910748661ac41..3e8da18f5f70d 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/system_indices_migration.test.ts @@ -70,9 +70,7 @@ describe('Migrate system indices API', () => { ( routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.transport .request as jest.Mock - ).mockResolvedValue({ - body: mockedResponse, - }); + ).mockResolvedValue(mockedResponse); const resp = await routeDependencies.router.getHandler({ method: 'get', @@ -113,9 +111,7 @@ describe('Migrate system indices API', () => { ( routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.transport .request as jest.Mock - ).mockResolvedValue({ - body: mockedResponse, - }); + ).mockResolvedValue(mockedResponse); const resp = await routeDependencies.router.getHandler({ method: 'post', 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 751e685002a99..c0d7134ffee5f 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 @@ -42,7 +42,7 @@ export function registerUpdateSettingsRoute({ router }: RouteDependencies) { return settingsBody; }, {} as { [key: string]: null }); - const { body: settingsResponse } = await client.asCurrentUser.indices.putSettings({ + const settingsResponse = await client.asCurrentUser.indices.putSettings({ index: indexName, body: settingsToDelete, }); diff --git a/x-pack/plugins/uptime/server/lib/lib.ts b/x-pack/plugins/uptime/server/lib/lib.ts index 577013e9cc5e8..f61497816e2d9 100644 --- a/x-pack/plugins/uptime/server/lib/lib.ts +++ b/x-pack/plugins/uptime/server/lib/lib.ts @@ -74,7 +74,7 @@ export function createUptimeESClient({ let esRequestStatus: RequestStatus = RequestStatus.PENDING; try { - res = await esClient.search(esParams); + res = await esClient.search(esParams, { meta: true }); esRequestStatus = RequestStatus.OK; } catch (e) { esError = e; @@ -117,7 +117,7 @@ export function createUptimeESClient({ const startTime = process.hrtime(); try { - res = await esClient.count(esParams); + res = await esClient.count(esParams, { meta: true }); } catch (e) { esError = e; } diff --git a/x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_charts.test.ts.snap b/x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_charts.test.ts.snap index 14e4261c28283..e33b6c52ac3b6 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_charts.test.ts.snap +++ b/x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_charts.test.ts.snap @@ -57,6 +57,9 @@ Array [ }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `; diff --git a/x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_details.test.ts.snap b/x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_details.test.ts.snap index 9464f9960b8d2..9899b75f01448 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_details.test.ts.snap +++ b/x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_details.test.ts.snap @@ -57,6 +57,9 @@ Array [ }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `; @@ -105,5 +108,8 @@ Array [ }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_certs.test.ts b/x-pack/plugins/uptime/server/lib/requests/get_certs.test.ts index 2ac31c2c59af7..72de8be638dcc 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_certs.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_certs.test.ts @@ -84,11 +84,9 @@ describe('getCerts', () => { it('parses query result and returns expected values', async () => { const { esClient, uptimeEsClient } = getUptimeESMockClient(); - esClient.search.mockResolvedValueOnce({ - body: { - hits: { - hits: mockHits, - }, + esClient.search.mockResponseOnce({ + hits: { + hits: mockHits, }, } as any); @@ -229,6 +227,9 @@ describe('getCerts', () => { }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ], ] `); diff --git a/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.test.ts b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.test.ts index e45ac5493960e..00928a0ed7c4a 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.test.ts @@ -46,25 +46,23 @@ describe('getLatestMonitor', () => { }, }; mockEsSearchResult = { - body: { - hits: { - hits: [ - { - _id: 'fejwio32', - _source: { - '@timestamp': '123456', - monitor: { - duration: { - us: 12345, - }, - id: 'testMonitor', - status: 'down', - type: 'http', + hits: { + hits: [ + { + _id: 'fejwio32', + _source: { + '@timestamp': '123456', + monitor: { + duration: { + us: 12345, }, + id: 'testMonitor', + status: 'down', + type: 'http', }, }, - ], - }, + }, + ], }, }; }); @@ -72,7 +70,7 @@ describe('getLatestMonitor', () => { it('returns data in expected shape', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); const result = await getLatestMonitor({ uptimeEsClient, @@ -100,6 +98,6 @@ describe('getLatestMonitor', () => { expect(result.timestamp).toBe('123456'); expect(result.monitor).not.toBeFalsy(); expect(result?.monitor?.id).toBe('testMonitor'); - expect(mockEsClient.search).toHaveBeenCalledWith(expectedGetLatestSearchParams); + expect(mockEsClient.search).toHaveBeenCalledWith(expectedGetLatestSearchParams, { meta: true }); }); }); diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.test.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.test.ts index 4133d2a4109b7..078ad85215176 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.test.ts @@ -821,6 +821,9 @@ describe('monitor availability', () => { }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `); }); diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_charts.test.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_charts.test.ts index d48f8a1cc0b36..b9b2416a8809f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_charts.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_charts.test.ts @@ -36,7 +36,7 @@ describe('ElasticsearchMonitorsAdapter', () => { it('inserts empty buckets for missing data', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockChartsData as any); + mockEsClient.search.mockResponseImplementationOnce(() => mockChartsData as any); expect( await getMonitorDurationChart({ diff --git a/x-pack/plugins/uptime/server/lib/requests/get_network_events.test.ts b/x-pack/plugins/uptime/server/lib/requests/get_network_events.test.ts index 68fd53729f58d..9d8f5a590bb54 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_network_events.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_network_events.test.ts @@ -171,12 +171,10 @@ describe('getNetworkEvents', () => { it('Uses the correct query', async () => { const { uptimeEsClient, esClient } = getUptimeESMockClient(); - esClient.search.mockResolvedValueOnce({ - body: { - hits: { - total: { value: 1 }, - hits: mockHits, - }, + esClient.search.mockResponseOnce({ + hits: { + total: { value: 1 }, + hits: mockHits, }, } as any); @@ -217,6 +215,9 @@ describe('getNetworkEvents', () => { }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ], ] `); @@ -225,12 +226,10 @@ describe('getNetworkEvents', () => { it('Returns the correct result', async () => { const { esClient, uptimeEsClient } = getUptimeESMockClient(); - esClient.search.mockResolvedValueOnce({ - body: { - hits: { - total: { value: 1 }, - hits: mockHits, - }, + esClient.search.mockResponseOnce({ + hits: { + total: { value: 1 }, + hits: mockHits, }, } as any); diff --git a/x-pack/plugins/uptime/server/lib/requests/get_pings.test.ts b/x-pack/plugins/uptime/server/lib/requests/get_pings.test.ts index 7b9a97a4f5cb9..f0ccae48e90b9 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_pings.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_pings.test.ts @@ -51,17 +51,15 @@ describe('getAll', () => { }, ]; mockEsSearchResult = { - body: { - hits: { - total: { - value: mockHits.length, - }, - hits: mockHits, + hits: { + total: { + value: mockHits.length, }, - aggregations: { - locations: { - buckets: [{ key: 'foo' }], - }, + hits: mockHits, + }, + aggregations: { + locations: { + buckets: [{ key: 'foo' }], }, }, }; @@ -90,7 +88,7 @@ describe('getAll', () => { it('returns data in the appropriate shape', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); const result = await getPings({ uptimeEsClient, @@ -113,7 +111,7 @@ describe('getAll', () => { it('creates appropriate sort and size parameters', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); await getPings({ uptimeEsClient, @@ -177,6 +175,9 @@ describe('getAll', () => { }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `); }); @@ -184,7 +185,7 @@ describe('getAll', () => { it('omits the sort param when no sort passed', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); await getPings({ uptimeEsClient, @@ -246,6 +247,9 @@ describe('getAll', () => { }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `); }); @@ -253,7 +257,7 @@ describe('getAll', () => { it('omits the size param when no size passed', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); await getPings({ uptimeEsClient, @@ -315,6 +319,9 @@ describe('getAll', () => { }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `); }); @@ -322,7 +329,7 @@ describe('getAll', () => { it('adds a filter for monitor ID', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); await getPings({ uptimeEsClient, @@ -389,6 +396,9 @@ describe('getAll', () => { }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `); }); @@ -396,7 +406,7 @@ describe('getAll', () => { it('adds excluded locations terms agg', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); await getPings({ uptimeEsClient, @@ -427,7 +437,7 @@ describe('getAll', () => { it('throws error for invalid exclusions', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); await expect( getPings({ @@ -441,7 +451,7 @@ describe('getAll', () => { it('adds a filter for monitor status', async () => { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + mockEsClient.search.mockResponseOnce(mockEsSearchResult); await getPings({ uptimeEsClient, @@ -508,6 +518,9 @@ describe('getAll', () => { }, "index": "heartbeat-8*,heartbeat-7*,synthetics-*", }, + Object { + "meta": true, + }, ] `); }); diff --git a/x-pack/plugins/uptime/server/lib/requests/helper.ts b/x-pack/plugins/uptime/server/lib/requests/helper.ts index 7e7e661608aa4..fbc838aa7c7dd 100644 --- a/x-pack/plugins/uptime/server/lib/requests/helper.ts +++ b/x-pack/plugins/uptime/server/lib/requests/helper.ts @@ -5,10 +5,7 @@ * 2.0. */ -import { - AggregationsAggregate, - SearchResponse, -} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { AggregationsAggregate } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ElasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { @@ -52,8 +49,8 @@ export const setupMockEsCompositeQuery = ( }, }, }; - esMock.search.mockResolvedValueOnce({ - body: mockResponse as unknown as SearchResponse, + // @ts-expect-error incomplete type definition + esMock.search.mockResponseOnce(mockResponse, { statusCode: 200, headers: {}, warnings: [], @@ -91,26 +88,24 @@ export function mockSearchResult( ): UptimeESClient { const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); - mockEsClient.search = jest.fn().mockResolvedValue({ - body: { - took: 18, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, - }, - hits: { - hits: Array.isArray(data) ? data : [data], - max_score: 0.0, - total: { - value: Array.isArray(data) ? data.length : 0, - relation: 'gte', - }, + mockEsClient.search.mockResponse({ + took: 18, + timed_out: false, + _shards: { + total: 1, + successful: 1, + skipped: 0, + failed: 0, + }, + hits: { + hits: Array.isArray(data) ? data : [data], + max_score: 0.0, + total: { + value: Array.isArray(data) ? data.length : 0, + relation: 'gte', }, - aggregations, }, + aggregations, }); return uptimeEsClient; diff --git a/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/fetch_all_from_scroll.test.js b/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/fetch_all_from_scroll.test.js index 28f3eaabb283d..92acbbff2d66e 100644 --- a/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/fetch_all_from_scroll.test.js +++ b/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/fetch_all_from_scroll.test.js @@ -59,8 +59,8 @@ describe('fetch_all_from_scroll', () => { }; mockScopedClusterClient.asCurrentUser.scroll - .mockResolvedValueOnce({ body: mockResponse1 }) - .mockResolvedValueOnce({ body: mockResponse2 }); + .mockResolvedValueOnce(mockResponse1) + .mockResolvedValueOnce(mockResponse2); }); it('should return the hits from the response', () => { diff --git a/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/fetch_all_from_scroll.ts b/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/fetch_all_from_scroll.ts index 7f6bc5d0af22a..42524dd7c70aa 100644 --- a/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/fetch_all_from_scroll.ts +++ b/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/fetch_all_from_scroll.ts @@ -26,7 +26,7 @@ export function fetchAllFromScroll( scroll: ES_SCROLL_SETTINGS.KEEPALIVE, scroll_id: scrollId!, }) - .then(({ body: innerResponse }) => { + .then((innerResponse) => { return fetchAllFromScroll(innerResponse, dataClient, hits); }); } 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 f1a14695acee3..665ff187f17a7 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 @@ -38,6 +38,7 @@ async function getIndices(dataClient: IScopedClusterClient, pattern: string, lim }, { ignore: [404], + meta: true, } ); @@ -63,6 +64,7 @@ async function getIndices(dataClient: IScopedClusterClient, pattern: string, lim }, { ignore: [404], + meta: true, } ); if (response.statusCode === 404 || !response.body.aggregations) { 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 72b3db88dffaf..62fd86bc0d5dc 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 @@ -23,7 +23,7 @@ function fetchFields(dataClient: IScopedClusterClient, indexes: string[]) { allow_no_indices: true, ignore_unavailable: true, }, - { ignore: [404] } + { ignore: [404], meta: true } ); } 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 b7699023fb457..7ea35e9e09764 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 @@ -18,18 +18,16 @@ const paramsSchema = schema.object({ }); function fetchHistoryItem(dataClient: IScopedClusterClient, watchHistoryItemId: string) { - return dataClient.asCurrentUser - .search({ - index: INDEX_NAMES.WATCHER_HISTORY, - body: { - query: { - bool: { - must: [{ term: { _id: watchHistoryItemId } }], - }, + return dataClient.asCurrentUser.search({ + index: INDEX_NAMES.WATCHER_HISTORY, + body: { + query: { + bool: { + must: [{ term: { _id: watchHistoryItemId } }], }, }, - }) - .then(({ body }) => body); + }, + }); } export function registerLoadHistoryRoute({ 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 77f52d21288c8..83ba43e8a4e88 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 @@ -11,12 +11,10 @@ import { Settings } from '../../../models/settings/index'; import { RouteDependencies } from '../../../types'; function fetchClusterSettings(client: IScopedClusterClient) { - return client.asCurrentUser.cluster - .getSettings({ - include_defaults: true, - filter_path: '**.xpack.notification', - }) - .then(({ body }) => body); + return client.asCurrentUser.cluster.getSettings({ + include_defaults: true, + filter_path: '**.xpack.notification', + }); } export function registerLoadRoute({ router, license, lib: { handleEsError } }: RouteDependencies) { 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 d743220fd5a33..f0fc5ad5b6588 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 @@ -18,12 +18,10 @@ const paramsSchema = schema.object({ }); function acknowledgeAction(dataClient: IScopedClusterClient, watchId: string, actionId: string) { - return dataClient.asCurrentUser.watcher - .ackWatch({ - watch_id: watchId, - action_id: actionId, - }) - .then(({ body }) => body); + return dataClient.asCurrentUser.watcher.ackWatch({ + watch_id: watchId, + action_id: actionId, + }); } export function registerAcknowledgeRoute({ 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 6da2993d34320..eaf7066e374c9 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 @@ -13,11 +13,9 @@ import { RouteDependencies } from '../../../types'; import { WatchStatus } from '../../../models/watch_status/index'; function activateWatch(dataClient: IScopedClusterClient, watchId: string) { - return dataClient.asCurrentUser.watcher - .activateWatch({ - watch_id: watchId, - }) - .then(({ body }) => body); + return dataClient.asCurrentUser.watcher.activateWatch({ + watch_id: watchId, + }); } const paramsSchema = schema.object({ 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 79b3b298359fa..c235e97c6e0ba 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 @@ -17,11 +17,9 @@ const paramsSchema = schema.object({ }); function deactivateWatch(dataClient: IScopedClusterClient, watchId: string) { - return dataClient.asCurrentUser.watcher - .deactivateWatch({ - watch_id: watchId, - }) - .then(({ body }) => body); + return dataClient.asCurrentUser.watcher.deactivateWatch({ + watch_id: watchId, + }); } export function registerDeactivateRoute({ 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 f48bad690878e..a2334741219ec 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 @@ -14,11 +14,9 @@ const paramsSchema = schema.object({ }); function deleteWatch(dataClient: IScopedClusterClient, watchId: string) { - return dataClient.asCurrentUser.watcher - .deleteWatch({ - id: watchId, - }) - .then(({ body }) => body); + return dataClient.asCurrentUser.watcher.deleteWatch({ + id: watchId, + }); } export function registerDeleteRoute({ 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 b8b3031b9e0ff..9882e50356c27 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 @@ -30,7 +30,7 @@ function executeWatch(dataClient: IScopedClusterClient, executeDetails: any, wat .executeWatch({ body, }) - .then(({ body: returnValue }) => returnValue); + .then((returnValue) => returnValue); } export function registerExecuteRoute({ 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 2345fe29f5a79..04050ae2b0e33 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 @@ -45,7 +45,7 @@ function fetchHistoryItems(dataClient: IScopedClusterClient, watchId: any, start return dataClient.asCurrentUser .search(params) - .then((response) => fetchAllFromScroll(response.body, dataClient)); + .then((response) => fetchAllFromScroll(response, dataClient)); } export function registerHistoryRoute({ 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 3be120d470e3c..c6d96724092d9 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 @@ -17,11 +17,9 @@ const paramsSchema = schema.object({ }); function fetchWatch(dataClient: IScopedClusterClient, watchId: string) { - return dataClient.asCurrentUser.watcher - .getWatch({ - id: watchId, - }) - .then(({ body }) => body); + return dataClient.asCurrentUser.watcher.getWatch({ + id: watchId, + }); } export function registerLoadRoute({ router, license, lib: { handleEsError } }: RouteDependencies) { 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 1ed80ff11e838..6aebd4968f066 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 @@ -42,7 +42,7 @@ export function registerSaveRoute({ router, license, lib: { handleEsError } }: R // For new watches, verify watch with the same ID doesn't already exist if (isNew) { try { - const { body: existingWatch } = await dataClient.asCurrentUser.watcher.getWatch({ + const existingWatch = await dataClient.asCurrentUser.watcher.getWatch({ id, }); if (existingWatch.found) { @@ -81,7 +81,7 @@ export function registerSaveRoute({ router, license, lib: { handleEsError } }: R try { // Create new watch - const { body: putResult } = await dataClient.asCurrentUser.watcher.putWatch({ + const putResult = await dataClient.asCurrentUser.watcher.putWatch({ id, active: isActive, body: serializedWatch, 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 60442bf43bd68..25f31ff43373f 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 @@ -30,7 +30,7 @@ function fetchVisualizeData(dataClient: IScopedClusterClient, index: any, body: }, { ignore: [404] } ) - .then(({ body: result }) => result); + .then((result) => result); } export function registerVisualizeRoute({ 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 adefe8a29be97..592ccac2135d0 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 @@ -25,7 +25,7 @@ function deleteWatches(dataClient: IScopedClusterClient, watchIds: string[]) { .deleteWatch({ id: watchId, }) - .then(({ body: success }) => ({ success })) + .then((success) => ({ success })) .catch((error) => ({ error })); }); 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 7944fb0e2f684..3ae49fae51da5 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 @@ -25,7 +25,7 @@ function fetchWatches(dataClient: IScopedClusterClient) { }, { ignore: [404] } ) - .then(({ body }) => fetchAllFromScroll(body, dataClient)); + .then((body) => fetchAllFromScroll(body, dataClient)); } export function registerListRoute({ router, license, lib: { handleEsError } }: RouteDependencies) { diff --git a/x-pack/test/api_integration/apis/lens/telemetry.ts b/x-pack/test/api_integration/apis/lens/telemetry.ts index f29df1c358d37..8cca6b589ef2b 100644 --- a/x-pack/test/api_integration/apis/lens/telemetry.ts +++ b/x-pack/test/api_integration/apis/lens/telemetry.ts @@ -7,7 +7,6 @@ import moment from 'moment'; import expect from '@kbn/expect'; -import { convertToKibanaClient } from '@kbn/test'; import { FtrProviderContext } from '../../ftr_provider_context'; @@ -106,8 +105,8 @@ export default ({ getService }: FtrProviderContext) => { }, refresh: 'wait_for', }); - const kibanaClient = convertToKibanaClient(es); - const result = await getDailyEvents('.kibana', () => Promise.resolve(kibanaClient)); + + const result = await getDailyEvents('.kibana', () => Promise.resolve(es)); expect(result).to.eql({ byDate: {}, @@ -149,8 +148,7 @@ export default ({ getService }: FtrProviderContext) => { getEvent('revert', date1, 'suggestion'), ], }); - const kibanaClient = convertToKibanaClient(es); - const result = await getDailyEvents('.kibana', () => Promise.resolve(kibanaClient)); + const result = await getDailyEvents('.kibana', () => Promise.resolve(es)); expect(result).to.eql({ byDate: { @@ -177,8 +175,7 @@ export default ({ getService }: FtrProviderContext) => { 'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json' ); - const kibanaClient = convertToKibanaClient(es); - const results = await getVisualizationCounts(() => Promise.resolve(kibanaClient), '.kibana'); + const results = await getVisualizationCounts(() => Promise.resolve(es), '.kibana'); expect(results).to.have.keys([ 'saved_overall', diff --git a/x-pack/test/api_integration/apis/metrics_ui/inventory_threshold_alert.ts b/x-pack/test/api_integration/apis/metrics_ui/inventory_threshold_alert.ts index 98502430016b2..91a446a4e5958 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/inventory_threshold_alert.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/inventory_threshold_alert.ts @@ -6,7 +6,6 @@ */ import expect from '@kbn/expect'; -import { convertToKibanaClient } from '@kbn/test'; import { Comparator, InventoryMetricConditions, @@ -87,7 +86,7 @@ export default function ({ getService }: FtrProviderContext) { it('should work FOR LAST 1 minute', async () => { const results = await evaluateCondition({ ...baseOptions, - esClient: convertToKibanaClient(esClient), + esClient, }); expect(results).to.eql({ 'host-0': { @@ -122,7 +121,7 @@ export default function ({ getService }: FtrProviderContext) { const options = { ...baseOptions, condition: { ...baseCondition, timeSize: 5 }, - esClient: convertToKibanaClient(esClient), + esClient, }; const results = await evaluateCondition(options); expect(results).to.eql({ @@ -167,7 +166,7 @@ export default function ({ getService }: FtrProviderContext) { metric: 'rx', threshold: [1], }, - esClient: convertToKibanaClient(esClient), + esClient, }); expect(results).to.eql({ 'host-0': { @@ -207,7 +206,7 @@ export default function ({ getService }: FtrProviderContext) { threshold: [1], timeSize: 5, }, - esClient: convertToKibanaClient(esClient), + esClient, }; const results = await evaluateCondition(options); expect(results).to.eql({ @@ -253,7 +252,7 @@ export default function ({ getService }: FtrProviderContext) { metric: 'logRate', threshold: [1], }, - esClient: convertToKibanaClient(esClient), + esClient, }); expect(results).to.eql({ 'host-0': { @@ -294,7 +293,7 @@ export default function ({ getService }: FtrProviderContext) { threshold: [1], timeSize: 5, }, - esClient: convertToKibanaClient(esClient), + esClient, }; const results = await evaluateCondition(options); expect(results).to.eql({ @@ -341,7 +340,7 @@ export default function ({ getService }: FtrProviderContext) { metric: 'rx', threshold: [1], }, - esClient: convertToKibanaClient(esClient), + esClient, }); expect(results).to.eql({ '7d6d7955-f853-42b1-8613-11f52d0d2725': { @@ -384,7 +383,7 @@ export default function ({ getService }: FtrProviderContext) { threshold: [1], timeSize: 5, }, - esClient: convertToKibanaClient(esClient), + esClient, }); expect(results).to.eql({ '7d6d7955-f853-42b1-8613-11f52d0d2725': { diff --git a/x-pack/test/api_integration/apis/metrics_ui/metric_threshold_alert.ts b/x-pack/test/api_integration/apis/metrics_ui/metric_threshold_alert.ts index 7e00044ef1365..1accdaf49156b 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/metric_threshold_alert.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/metric_threshold_alert.ts @@ -6,7 +6,6 @@ */ import expect from '@kbn/expect'; -import { convertToKibanaClient } from '@kbn/test'; import { Aggregators, Comparator, @@ -99,8 +98,7 @@ export default function ({ getService }: FtrProviderContext) { metricAlias: 'filebeat-*', }; const timeFrame = { end: DATES.ten_thousand_plus.max }; - const kbnClient = convertToKibanaClient(esClient); - const results = await evaluateRule(kbnClient, params, config, [], 10000, timeFrame); + const results = await evaluateRule(esClient, params, config, [], 10000, timeFrame); expect(results).to.eql([ { '*': { @@ -141,8 +139,7 @@ export default function ({ getService }: FtrProviderContext) { metricAlias: 'filebeat-*', }; const timeFrame = { end: DATES.ten_thousand_plus.max }; - const kbnClient = convertToKibanaClient(esClient); - const results = await evaluateRule(kbnClient, params, config, [], 10000, timeFrame); + const results = await evaluateRule(esClient, params, config, [], 10000, timeFrame); expect(results).to.eql([ { web: { @@ -183,15 +180,7 @@ export default function ({ getService }: FtrProviderContext) { ], }; const timeFrame = { end: gauge.max }; - const kbnClient = convertToKibanaClient(esClient); - const results = await evaluateRule( - kbnClient, - params, - configuration, - [], - 10000, - timeFrame - ); + const results = await evaluateRule(esClient, params, configuration, [], 10000, timeFrame); expect(results).to.eql([ { '*': { @@ -214,15 +203,7 @@ export default function ({ getService }: FtrProviderContext) { it('should alert on the last value when the end date is the same as the last event', async () => { const params = { ...baseParams }; const timeFrame = { end: gauge.max }; - const kbnClient = convertToKibanaClient(esClient); - const results = await evaluateRule( - kbnClient, - params, - configuration, - [], - 10000, - timeFrame - ); + const results = await evaluateRule(esClient, params, configuration, [], 10000, timeFrame); expect(results).to.eql([ { '*': { @@ -259,15 +240,7 @@ export default function ({ getService }: FtrProviderContext) { ], }; const timeFrame = { end: gauge.max }; - const kbnClient = convertToKibanaClient(esClient); - const results = await evaluateRule( - kbnClient, - params, - configuration, - [], - 10000, - timeFrame - ); + const results = await evaluateRule(esClient, params, configuration, [], 10000, timeFrame); expect(results).to.eql([ { dev: { @@ -307,15 +280,7 @@ export default function ({ getService }: FtrProviderContext) { groupBy: ['env'], }; const timeFrame = { end: gauge.max }; - const kbnClient = convertToKibanaClient(esClient); - const results = await evaluateRule( - kbnClient, - params, - configuration, - [], - 10000, - timeFrame - ); + const results = await evaluateRule(esClient, params, configuration, [], 10000, timeFrame); expect(results).to.eql([ { dev: { @@ -356,9 +321,8 @@ export default function ({ getService }: FtrProviderContext) { groupBy: ['env'], }; const timeFrame = { end: gauge.midpoint }; - const kbnClient = convertToKibanaClient(esClient); const results = await evaluateRule( - kbnClient, + esClient, params, configuration, ['dev', 'prod'], @@ -420,15 +384,7 @@ export default function ({ getService }: FtrProviderContext) { ], }; const timeFrame = { end: rate.max }; - const kbnClient = convertToKibanaClient(esClient); - const results = await evaluateRule( - kbnClient, - params, - configuration, - [], - 10000, - timeFrame - ); + const results = await evaluateRule(esClient, params, configuration, [], 10000, timeFrame); expect(results).to.eql([ { '*': { @@ -468,15 +424,7 @@ export default function ({ getService }: FtrProviderContext) { ], }; const timeFrame = { end: rate.max }; - const kbnClient = convertToKibanaClient(esClient); - const results = await evaluateRule( - kbnClient, - params, - configuration, - [], - 10000, - timeFrame - ); + const results = await evaluateRule(esClient, params, configuration, [], 10000, timeFrame); expect(results).to.eql([ { dev: { diff --git a/x-pack/test/functional/services/ml/ml_nodes_list.ts b/x-pack/test/functional/services/ml/ml_nodes_list.ts index 37cd4143e26cc..51b7404d574f8 100644 --- a/x-pack/test/functional/services/ml/ml_nodes_list.ts +++ b/x-pack/test/functional/services/ml/ml_nodes_list.ts @@ -10,6 +10,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export function MlNodesPanelProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); + const retry = getService('retry'); return { async assertNodesOverviewPanelExists(expectPanelExits: boolean = true) { @@ -25,11 +26,13 @@ export function MlNodesPanelProvider({ getService }: FtrProviderContext) { }, async assertMlNodesCount(minCount: number = 1) { - const actualCount = parseInt(await testSubjects.getVisibleText('mlTotalNodesCount'), 10); - expect(actualCount).to.not.be.lessThan( - minCount, - `Total ML nodes count should be at least '${minCount}' (got '${actualCount}')` - ); + await retry.try(async () => { + const actualCount = parseInt(await testSubjects.getVisibleText('mlTotalNodesCount'), 10); + expect(actualCount).to.not.be.lessThan( + minCount, + `Total ML nodes count should be at least '${minCount}' (got '${actualCount}')` + ); + }); }, async assertNodeOverviewPanel() { diff --git a/x-pack/test/functional/services/ml/navigation.ts b/x-pack/test/functional/services/ml/navigation.ts index 6bf753926c72a..da34c97ff127f 100644 --- a/x-pack/test/functional/services/ml/navigation.ts +++ b/x-pack/test/functional/services/ml/navigation.ts @@ -89,13 +89,15 @@ export function MachineLearningNavigationProvider({ }, async assertTabEnabled(tabSubject: string, expectedValue: boolean) { - const isEnabled = await testSubjects.isEnabled(tabSubject); - expect(isEnabled).to.eql( - expectedValue, - `Expected ML tab '${tabSubject}' to be '${expectedValue ? 'enabled' : 'disabled'}' (got '${ - isEnabled ? 'enabled' : 'disabled' - }')` - ); + await retry.tryForTime(10000, async () => { + const isEnabled = await testSubjects.isEnabled(tabSubject); + expect(isEnabled).to.eql( + expectedValue, + `Expected ML tab '${tabSubject}' to be '${ + expectedValue ? 'enabled' : 'disabled' + }' (got '${isEnabled ? 'enabled' : 'disabled'}')` + ); + }); }, async assertOverviewTabEnabled(expectedValue: boolean) { diff --git a/x-pack/test/plugin_api_integration/plugins/elasticsearch_client/server/plugin.ts b/x-pack/test/plugin_api_integration/plugins/elasticsearch_client/server/plugin.ts index 4bd8e93340be0..6041933f7590c 100644 --- a/x-pack/test/plugin_api_integration/plugins/elasticsearch_client/server/plugin.ts +++ b/x-pack/test/plugin_api_integration/plugins/elasticsearch_client/server/plugin.ts @@ -15,7 +15,7 @@ export class ElasticsearchClientXPack implements Plugin { 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(); + const body = await context.core.elasticsearch.client.asCurrentUser.security.getUser(); return res.ok({ body }); } ); @@ -24,7 +24,7 @@ export class ElasticsearchClientXPack implements Plugin { { path: '/api/elasticsearch_client_xpack/contract/user', validate: false }, async (context, req, res) => { const [coreStart] = await core.getStartServices(); - const { body } = await coreStart.elasticsearch.client + const body = await coreStart.elasticsearch.client .asScoped(req) .asCurrentUser.security.getUser(); return res.ok({ body }); @@ -33,5 +33,6 @@ export class ElasticsearchClientXPack implements Plugin { } public start() {} + public stop() {} } diff --git a/x-pack/test/rule_registry/spaces_only/tests/trial/lifecycle_executor.ts b/x-pack/test/rule_registry/spaces_only/tests/trial/lifecycle_executor.ts index 89f15705beb59..15ef6a7673d08 100644 --- a/x-pack/test/rule_registry/spaces_only/tests/trial/lifecycle_executor.ts +++ b/x-pack/test/rule_registry/spaces_only/tests/trial/lifecycle_executor.ts @@ -36,10 +36,7 @@ import { cleanupRegistryIndices } from '../../../common/lib/helpers/cleanup_regi // eslint-disable-next-line import/no-default-export export default function createLifecycleExecutorApiTest({ getService }: FtrProviderContext) { - // The getService('es') client returns the body of the transport requests. - // Where the client provided by Kibana returns the request response with headers, body, statusCode... etc. - // This cluster client will behave like the KibanaClient. - const es = getService('cluster_client'); + const es = getService('es'); const log = getService('log'); 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 9ca600970cb86..443858287cf81 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 @@ -80,7 +80,7 @@ export function initRoutes(initializerContext: PluginInitializerContext, core: C // 3. Make authentication request once again and return result. try { - const { body } = await scopedClient.asCurrentUser.security.authenticate(); + const body = await scopedClient.asCurrentUser.security.authenticate(); slowLog.info( `Successfully performed final authentication request: ${JSON.stringify(body)}` );