diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 1548669b1c0603..d50c58c7df9bb6 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -457,7 +457,7 @@ Index Management by running this series of requests in Console: |{kib-repo}blob/{branch}/x-pack/plugins/index_management/README.md[indexManagement] -|Create a data stream using Console and you'll be able to view it in the UI: +|Create an index with special characters and verify it renders correctly: |{kib-repo}blob/{branch}/x-pack/plugins/infra/README.md[infra] diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/errors/index.ts b/src/plugins/es_ui_shared/__packages_do_not_import__/errors/index.ts index 18b2362baad922..214d0eea185566 100644 --- a/src/plugins/es_ui_shared/__packages_do_not_import__/errors/index.ts +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/errors/index.ts @@ -6,6 +6,5 @@ * Side Public License, v 1. */ -export { isEsError } from './is_es_error'; export { handleEsError } from './handle_es_error'; export { parseEsError } from './es_error_parser'; diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/errors/is_es_error.ts b/src/plugins/es_ui_shared/__packages_do_not_import__/errors/is_es_error.ts deleted file mode 100644 index 5d941206c74e59..00000000000000 --- a/src/plugins/es_ui_shared/__packages_do_not_import__/errors/is_es_error.ts +++ /dev/null @@ -1,26 +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 * as legacyElasticsearch from 'elasticsearch'; - -const esErrorsParent = legacyElasticsearch.errors._Abstract; - -interface RequestError extends Error { - statusCode?: number; -} - -/* - * @deprecated - * Only works with legacy elasticsearch js client errors and will be removed after 7.x last - */ -export function isEsError(err: RequestError) { - const isInstanceOfEsError = err instanceof esErrorsParent; - const hasStatusCode = Boolean(err.statusCode); - - return isInstanceOfEsError && hasStatusCode; -} diff --git a/src/plugins/es_ui_shared/server/errors/index.ts b/src/plugins/es_ui_shared/server/errors/index.ts index 34d59653e1a4d1..0d24d16f600057 100644 --- a/src/plugins/es_ui_shared/server/errors/index.ts +++ b/src/plugins/es_ui_shared/server/errors/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export { isEsError, handleEsError, parseEsError } from '../../__packages_do_not_import__/errors'; +export { handleEsError, parseEsError } from '../../__packages_do_not_import__/errors'; diff --git a/src/plugins/es_ui_shared/server/index.ts b/src/plugins/es_ui_shared/server/index.ts index 4781c9c0b73b27..6fe8c913875a02 100644 --- a/src/plugins/es_ui_shared/server/index.ts +++ b/src/plugins/es_ui_shared/server/index.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -export { isEsError, handleEsError, parseEsError } from './errors'; +export { handleEsError, parseEsError } from './errors'; /** dummy plugin*/ export function plugin() { diff --git a/x-pack/plugins/cross_cluster_replication/README.md b/x-pack/plugins/cross_cluster_replication/README.md index 3522499c7356ae..57800646db078f 100644 --- a/x-pack/plugins/cross_cluster_replication/README.md +++ b/x-pack/plugins/cross_cluster_replication/README.md @@ -4,14 +4,15 @@ You can run a local cluster and simulate a remote cluster within a single Kibana directory. -1. Ensure Kibana isn't running so it doesn't load up any data into your cluster. Run `yarn es snapshot --license=trial` to install a fresh snapshot. Wait for ES to finish setting up. +1. Ensure Kibana isn't running so it doesn't load up any data into your cluster. Run `yarn es snapshot --license=trial` to install a fresh snapshot. Wait for ES to finish setting up and activate the license. 2. Create a "remote" copy of your ES snapshot by running: `cp -R .es/8.0.0 .es/8.0.0-2`. -4. Start your "remote" cluster by running `.es/8.0.0-2/bin/elasticsearch -E cluster.name=europe -E transport.port=9400`. -4. Run `yarn start` to start Kibana. -5. Index a document into your remote cluster by running `curl -X PUT http://elastic:changeme@localhost:9201/my-leader-index --data '{"settings":{"number_of_shards":1,"soft_deletes.enabled":true}}' --header "Content-Type: application/json"`. Note that these settings are required for testing auto-follow pattern conflicts errors (see below). +4. Start your "local" cluster by running `.es/8.0.0/bin/elasticsearch`. +5. Run `yarn start` to start Kibana so that it connects to the "local" cluster. +6. Start your "remote" cluster by running `.es/8.0.0-2/bin/elasticsearch -E cluster.name=europe -E transport.port=9400`. +7. Index a document into your "remote" cluster by running `curl -X PUT http://elastic:changeme@localhost:9201/my-leader-index --data '{"settings":{"number_of_shards":1,"soft_deletes.enabled":true}}' --header "Content-Type: application/json"`. Note that these settings are required for testing auto-follow pattern conflicts errors (see below). Now you can create follower indices and auto-follow patterns to replicate the `my-leader-index` -index on the remote cluster that's available at `127.0.0.1:9400`. +index on the "remote" cluster that's available at `127.0.0.1:9400`. ### Auto-follow pattern conflict errors diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index c371602df249c9..8041e0858ea845 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -7,14 +7,8 @@ import { Observable } from 'rxjs'; import { first } from 'rxjs/operators'; -import { - CoreSetup, - CoreStart, - Plugin, - Logger, - PluginInitializerContext, - LegacyAPICaller, -} from 'src/core/server'; +import { CoreSetup, CoreStart, Plugin, Logger, PluginInitializerContext } from 'src/core/server'; +import { IScopedClusterClient } from 'kibana/server'; import { Index } from '../../index_management/server'; import { PLUGIN } from '../common/constants'; @@ -23,20 +17,18 @@ import { registerApiRoutes } from './routes'; import { CrossClusterReplicationConfig } from './config'; import { License, handleEsError } from './shared_imports'; -// TODO replace deprecated ES client after Index Management is updated -const ccrDataEnricher = async (indicesList: Index[], callWithRequest: LegacyAPICaller) => { +const ccrDataEnricher = async (indicesList: Index[], client: IScopedClusterClient) => { if (!indicesList?.length) { return indicesList; } - const params = { - path: '/_all/_ccr/info', - method: 'GET', - }; + try { - const { follower_indices: followerIndices } = await callWithRequest( - 'transport.request', - params - ); + const { + body: { follower_indices: followerIndices }, + } = await client.asCurrentUser.ccr.followInfo({ + index: '_all', + }); + return indicesList.map((index) => { const isFollowerIndex = !!followerIndices.find( (followerIndex: { follower_index: string }) => { diff --git a/x-pack/plugins/index_lifecycle_management/server/plugin.ts b/x-pack/plugins/index_lifecycle_management/server/plugin.ts index 95793c0cad4655..533d8736931a46 100644 --- a/x-pack/plugins/index_lifecycle_management/server/plugin.ts +++ b/x-pack/plugins/index_lifecycle_management/server/plugin.ts @@ -6,44 +6,36 @@ */ import { i18n } from '@kbn/i18n'; -import { - CoreSetup, - Plugin, - Logger, - PluginInitializerContext, - LegacyAPICaller, -} from 'src/core/server'; -import { handleEsError } from './shared_imports'; +import { CoreSetup, Plugin, Logger, PluginInitializerContext } from 'src/core/server'; +import { IScopedClusterClient } from 'kibana/server'; import { Index as IndexWithoutIlm } from '../../index_management/common/types'; import { PLUGIN } from '../common/constants'; -import { Index, IndexLifecyclePolicy } from '../common/types'; +import { Index } from '../common/types'; import { Dependencies } from './types'; import { registerApiRoutes } from './routes'; import { License } from './services'; import { IndexLifecycleManagementConfig } from './config'; +import { handleEsError } from './shared_imports'; const indexLifecycleDataEnricher = async ( indicesList: IndexWithoutIlm[], - // TODO replace deprecated ES client after Index Management is updated - callAsCurrentUser: LegacyAPICaller + client: IScopedClusterClient ): Promise => { if (!indicesList || !indicesList.length) { return []; } - const params = { - path: '/*/_ilm/explain', - method: 'GET', - }; - - const { indices: ilmIndicesData } = await callAsCurrentUser<{ - indices: { [indexName: string]: IndexLifecyclePolicy }; - }>('transport.request', params); + const { + body: { indices: ilmIndicesData }, + } = await client.asCurrentUser.ilm.explainLifecycle({ + index: '*', + }); return indicesList.map((index: IndexWithoutIlm) => { return { ...index, + // @ts-expect-error @elastic/elasticsearch Element implicitly has an 'any' type ilm: { ...(ilmIndicesData[index.name] || {}) }, }; }); diff --git a/x-pack/plugins/index_management/README.md b/x-pack/plugins/index_management/README.md index 07c5b9317b5cbc..39f4821403a8d9 100644 --- a/x-pack/plugins/index_management/README.md +++ b/x-pack/plugins/index_management/README.md @@ -1,5 +1,16 @@ # Index Management UI +## Indices tab + +### Quick steps for testing + +Create an index with special characters and verify it renders correctly: + +``` +# Renders as %{[@metadata][beat]}-%{[@metadata][version]}-2020.08.23 +PUT %25%7B%5B%40metadata%5D%5Bbeat%5D%7D-%25%7B%5B%40metadata%5D%5Bversion%5D%7D-2020.08.23 +``` + ## Data streams tab ### Quick steps for testing @@ -19,4 +30,56 @@ POST ds/_doc { "@timestamp": "2020-01-27" } -``` \ No newline at end of file +``` + +Create a data stream with special characters and verify it renders correctly: + +``` +# Configure template for creating a data stream +PUT _index_template/special_ds +{ + "index_patterns": ["%{[@metadata][beat]}-%{[@metadata][version]}-2020.08.23"], + "data_stream": {} +} + +# Add a document to the data stream, which will render as %{[@metadata][beat]}-%{[@metadata][version]}-2020.08.23 +POST %25%7B%5B%40metadata%5D%5Bbeat%5D%7D-%25%7B%5B%40metadata%5D%5Bversion%5D%7D-2020.08.23/_doc +{ + "@timestamp": "2020-01-27" +} +``` + +## Index templates tab + +### Quick steps for testing + +By default, **legacy index templates** are not shown in the UI. Make them appear by creating one in Console: + +``` +PUT _template/template_1 +{ + "index_patterns": ["foo*"] +} +``` + +To test **Cloud-managed templates**: + +1. Add `cluster.metadata.managed_index_templates` setting via Dev Tools: +``` +PUT /_cluster/settings +{ + "persistent": { + "cluster.metadata.managed_index_templates": ".cloud-" + } +} +``` + +2. Create a template with the format: `.cloud-` via Dev Tools. +``` +PUT _template/.cloud-example +{ + "index_patterns": [ "foobar*"] +} +``` + +The UI will now prevent you from editing or deleting this template. \ No newline at end of file diff --git a/x-pack/plugins/index_management/public/application/components/index_templates/simulate_template/simulate_template.tsx b/x-pack/plugins/index_management/public/application/components/index_templates/simulate_template/simulate_template.tsx index 946ce46ba26262..82c3b35e0a91b5 100644 --- a/x-pack/plugins/index_management/public/application/components/index_templates/simulate_template/simulate_template.tsx +++ b/x-pack/plugins/index_management/public/application/components/index_templates/simulate_template/simulate_template.tsx @@ -6,7 +6,6 @@ */ import React, { useState, useCallback, useEffect } from 'react'; -import uuid from 'uuid'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCodeBlock, EuiCallOut } from '@elastic/eui'; @@ -37,11 +36,6 @@ export const SimulateTemplate = React.memo(({ template, filters }: Props) => { } const indexTemplate = serializeTemplate(stripEmptyFields(template) as TemplateDeserialized); - - // Until ES fixes a bug on their side we will send a random index pattern to the simulate API. - // Issue: https://github.com/elastic/elasticsearch/issues/59152 - indexTemplate.index_patterns = [uuid.v4()]; - const { data, error } = await simulateIndexTemplate(indexTemplate); let filteredTemplate = data; diff --git a/x-pack/plugins/index_management/server/client/elasticsearch.ts b/x-pack/plugins/index_management/server/client/elasticsearch.ts deleted file mode 100644 index 9585680ce3b6dc..00000000000000 --- a/x-pack/plugins/index_management/server/client/elasticsearch.ts +++ /dev/null @@ -1,174 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const elasticsearchJsPlugin = (Client: any, config: any, components: any) => { - const ca = components.clientAction.factory; - - Client.prototype.dataManagement = components.clientAction.namespaceFactory(); - const dataManagement = Client.prototype.dataManagement.prototype; - - // Data streams - - // We don't allow the user to create a data stream in the UI or API. We're just adding this here - // to enable the API integration tests. - dataManagement.createDataStream = ca({ - urls: [ - { - fmt: '/_data_stream/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - method: 'PUT', - }); - - dataManagement.deleteDataStream = ca({ - urls: [ - { - fmt: '/_data_stream/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - method: 'DELETE', - }); - - // Component templates - dataManagement.getComponentTemplates = ca({ - urls: [ - { - fmt: '/_component_template', - }, - ], - method: 'GET', - }); - - dataManagement.getComponentTemplate = ca({ - urls: [ - { - fmt: '/_component_template/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - method: 'GET', - }); - - dataManagement.saveComponentTemplate = ca({ - urls: [ - { - fmt: '/_component_template/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - method: 'PUT', - }); - - dataManagement.deleteComponentTemplate = ca({ - urls: [ - { - fmt: '/_component_template/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - method: 'DELETE', - }); - - // Composable index templates - dataManagement.getComposableIndexTemplates = ca({ - urls: [ - { - fmt: '/_index_template', - }, - ], - method: 'GET', - }); - - dataManagement.getComposableIndexTemplate = ca({ - urls: [ - { - fmt: '/_index_template/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - method: 'GET', - }); - - dataManagement.saveComposableIndexTemplate = ca({ - urls: [ - { - fmt: '/_index_template/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - needBody: true, - method: 'PUT', - }); - - dataManagement.deleteComposableIndexTemplate = ca({ - urls: [ - { - fmt: '/_index_template/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - method: 'DELETE', - }); - - dataManagement.existsTemplate = ca({ - urls: [ - { - fmt: '/_index_template/<%=name%>', - req: { - name: { - type: 'string', - }, - }, - }, - ], - method: 'HEAD', - }); - - dataManagement.simulateTemplate = ca({ - urls: [ - { - fmt: '/_index_template/_simulate', - }, - ], - needBody: true, - method: 'POST', - }); -}; diff --git a/x-pack/plugins/index_management/server/index.ts b/x-pack/plugins/index_management/server/index.ts index 1ca2705dc93ea9..507401398a407b 100644 --- a/x-pack/plugins/index_management/server/index.ts +++ b/x-pack/plugins/index_management/server/index.ts @@ -10,7 +10,7 @@ import { PluginInitializerContext } from 'src/core/server'; import { IndexMgmtServerPlugin } from './plugin'; import { configSchema } from './config'; -export const plugin = (ctx: PluginInitializerContext) => new IndexMgmtServerPlugin(ctx); +export const plugin = (context: PluginInitializerContext) => new IndexMgmtServerPlugin(context); export const config = { schema: configSchema, 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 b83843f0c615d9..48f633a8dc1029 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.ts @@ -5,99 +5,57 @@ * 2.0. */ -import { CatIndicesParams } from 'elasticsearch'; +import { IScopedClusterClient } from 'kibana/server'; import { IndexDataEnricher } from '../services'; -import { CallAsCurrentUser } from '../types'; import { Index } from '../index'; -interface Hit { - health: string; - status: string; - index: string; - uuid: string; - pri: string; - rep: string; - 'docs.count': any; - 'store.size': any; - sth: 'true' | 'false'; - hidden: boolean; -} - -interface IndexInfo { - aliases: { [aliasName: string]: unknown }; - mappings: unknown; - data_stream?: string; - settings: { - index: { - hidden: 'true' | 'false'; - }; - }; -} - -interface GetIndicesResponse { - [indexName: string]: IndexInfo; -} - async function fetchIndicesCall( - callAsCurrentUser: CallAsCurrentUser, + client: IScopedClusterClient, indexNames?: string[] ): Promise { const indexNamesString = indexNames && indexNames.length ? indexNames.join(',') : '*'; // This call retrieves alias and settings (incl. hidden status) information about indices - const indices: GetIndicesResponse = await callAsCurrentUser('transport.request', { - method: 'GET', - // transport.request doesn't do any URI encoding, unlike other JS client APIs. This enables - // working with Logstash indices with names like %{[@metadata][beat]}-%{[@metadata][version]}. - path: `/${encodeURIComponent(indexNamesString)}`, - query: { - expand_wildcards: 'hidden,all', - }, + const { body: indices } = await client.asCurrentUser.indices.get({ + index: indexNamesString, + expand_wildcards: 'hidden,all', }); if (!Object.keys(indices).length) { return []; } - const catQuery: Pick & { - expand_wildcards: string; - index?: string; - } = { + const { body: catHits } = await client.asCurrentUser.cat.indices({ format: 'json', h: 'health,status,index,uuid,pri,rep,docs.count,sth,store.size', expand_wildcards: 'hidden,all', index: indexNamesString, - }; - - // This call retrieves health and other high-level information about indices. - const catHits: Hit[] = await callAsCurrentUser('transport.request', { - method: 'GET', - path: '/_cat/indices', - query: catQuery, }); // System indices may show up in _cat APIs, as these APIs are primarily used for troubleshooting // For now, we filter them out and only return index information for the indices we have // In the future, we should migrate away from using cat APIs (https://github.com/elastic/kibana/issues/57286) return catHits.reduce((decoratedIndices, hit) => { - const index = indices[hit.index]; + const index = indices[hit.index!]; if (typeof index !== 'undefined') { - const aliases = Object.keys(index.aliases); + const aliases = Object.keys(index.aliases!); decoratedIndices.push({ - health: hit.health, - status: hit.status, - name: hit.index, - uuid: hit.uuid, - primary: hit.pri, - replica: hit.rep, + health: hit.health!, + status: hit.status!, + name: hit.index!, + uuid: hit.uuid!, + primary: hit.pri!, + replica: hit.rep!, documents: hit['docs.count'], size: hit['store.size'], isFrozen: hit.sth === 'true', // sth value coming back as a string from ES aliases: aliases.length ? aliases : 'none', + // @ts-expect-error @elastic/elasticsearch Property 'index' does not exist on type 'IndicesIndexSettings | IndicesIndexStatePrefixedSettings'. hidden: index.settings.index.hidden === 'true', - data_stream: index.data_stream, + // @ts-expect-error @elastic/elasticsearch Property 'data_stream' does not exist on type 'IndicesIndexState'. + data_stream: index.data_stream!, }); } @@ -106,10 +64,10 @@ async function fetchIndicesCall( } export const fetchIndices = async ( - callAsCurrentUser: CallAsCurrentUser, + client: IScopedClusterClient, indexDataEnricher: IndexDataEnricher, indexNames?: string[] ) => { - const indices = await fetchIndicesCall(callAsCurrentUser, indexNames); - return await indexDataEnricher.enrichIndices(indices, callAsCurrentUser); + const indices = await fetchIndicesCall(client, indexNames); + return await indexDataEnricher.enrichIndices(indices, client); }; 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 df0f4f12d9719f..8e60044dc49519 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 @@ -5,16 +5,20 @@ * 2.0. */ +import { IScopedClusterClient } from 'kibana/server'; + // Cloud has its own system for managing templates and we want to make // this clear in the UI when a template is used in a Cloud deployment. export const getCloudManagedTemplatePrefix = async ( - callAsCurrentUser: any + client: IScopedClusterClient ): Promise => { try { - const { persistent, transient, defaults } = await callAsCurrentUser('cluster.getSettings', { - filterPath: '*.*managed_index_templates', - flatSettings: true, - includeDefaults: true, + const { + body: { persistent, transient, defaults }, + } = await client.asCurrentUser.cluster.getSettings({ + filter_path: '*.*managed_index_templates', + flat_settings: true, + include_defaults: true, }); const { 'cluster.metadata.managed_index_templates': managedTemplatesPrefix = undefined } = { diff --git a/x-pack/plugins/index_management/server/plugin.ts b/x-pack/plugins/index_management/server/plugin.ts index 35d25eb452b84d..a339349c0a5a97 100644 --- a/x-pack/plugins/index_management/server/plugin.ts +++ b/x-pack/plugins/index_management/server/plugin.ts @@ -5,20 +5,13 @@ * 2.0. */ -import { - CoreSetup, - Plugin, - PluginInitializerContext, - ILegacyCustomClusterClient, -} from 'src/core/server'; +import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/server'; import { PLUGIN } from '../common/constants/plugin'; import { Dependencies } from './types'; import { ApiRoutes } from './routes'; import { IndexDataEnricher } from './services'; -import { isEsError, handleEsError, parseEsError } from './shared_imports'; -import { elasticsearchJsPlugin } from './client/elasticsearch'; -import type { IndexManagementRequestHandlerContext } from './types'; +import { handleEsError } from './shared_imports'; export interface IndexManagementPluginSetup { indexDataEnricher: { @@ -26,16 +19,9 @@ export interface IndexManagementPluginSetup { }; } -async function getCustomEsClient(getStartServices: CoreSetup['getStartServices']) { - const [core] = await getStartServices(); - const esClientConfig = { plugins: [elasticsearchJsPlugin] }; - return core.elasticsearch.legacy.createClient('dataManagement', esClientConfig); -} - export class IndexMgmtServerPlugin implements Plugin { private readonly apiRoutes: ApiRoutes; private readonly indexDataEnricher: IndexDataEnricher; - private dataManagementESClient?: ILegacyCustomClusterClient; constructor(initContext: PluginInitializerContext) { this.apiRoutes = new ApiRoutes(); @@ -46,8 +32,6 @@ export class IndexMgmtServerPlugin implements Plugin(); - features.registerElasticsearchFeature({ id: PLUGIN.id, management: { @@ -63,27 +47,13 @@ export class IndexMgmtServerPlugin implements Plugin( - 'dataManagement', - async (ctx, request) => { - this.dataManagementESClient = - this.dataManagementESClient ?? (await getCustomEsClient(getStartServices)); - - return { - client: this.dataManagementESClient.asScoped(request), - }; - } - ); - this.apiRoutes.setup({ - router, + router: http.createRouter(), config: { isSecurityEnabled: () => security !== undefined && security.license.isEnabled(), }, indexDataEnricher: this.indexDataEnricher, lib: { - isEsError, - parseEsError, handleEsError, }, }); @@ -97,9 +67,5 @@ export class IndexMgmtServerPlugin implements Plugin { +export const registerCreateRoute = ({ + router, + lib: { handleEsError }, +}: RouteDependencies): void => { router.post( { path: addBasePath('/component_templates'), @@ -20,24 +23,23 @@ export const registerCreateRoute = ({ router, lib: { isEsError } }: RouteDepende body: componentTemplateSchema, }, }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; + async (context, request, response) => { + const { client } = context.core.elasticsearch; - const serializedComponentTemplate = serializeComponentTemplate(req.body); + const serializedComponentTemplate = serializeComponentTemplate(request.body); - const { name } = req.body; + const { name } = request.body; try { // Check that a component template with the same name doesn't already exist - const componentTemplateResponse = await callAsCurrentUser( - 'dataManagement.getComponentTemplate', - { name } - ); - - const { component_templates: componentTemplates } = componentTemplateResponse; + const { + body: { component_templates: componentTemplates }, + } = await client.asCurrentUser.cluster.getComponentTemplate({ + name, + }); if (componentTemplates.length) { - return res.conflict({ + return response.conflict({ body: new Error( i18n.translate('xpack.idxMgmt.componentTemplates.createRoute.duplicateErrorMessage', { defaultMessage: "There is already a component template with name '{name}'.", @@ -53,21 +55,15 @@ export const registerCreateRoute = ({ router, lib: { isEsError } }: RouteDepende } try { - const response = await callAsCurrentUser('dataManagement.saveComponentTemplate', { + const { body: responseBody } = await client.asCurrentUser.cluster.putComponentTemplate({ name, + // @ts-expect-error @elastic/elasticsearch Type 'ComponentTemplateSerialized' is not assignable body: serializedComponentTemplate, }); - return res.ok({ body: response }); + return response.ok({ body: responseBody }); } catch (error) { - if (isEsError(error)) { - return res.customError({ - statusCode: error.statusCode, - body: error, - }); - } - - throw error; + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/delete.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/delete.ts index d30f54f6e44adf..67991ec7089466 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/delete.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/delete.ts @@ -14,7 +14,10 @@ const paramsSchema = schema.object({ names: schema.string(), }); -export const registerDeleteRoute = ({ router }: RouteDependencies): void => { +export const registerDeleteRoute = ({ + router, + lib: { handleEsError }, +}: RouteDependencies): void => { router.delete( { path: addBasePath('/component_templates/{names}'), @@ -22,32 +25,34 @@ export const registerDeleteRoute = ({ router }: RouteDependencies): void => { params: paramsSchema, }, }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - const { names } = req.params; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { names } = request.params; const componentNames = names.split(','); - const response: { itemsDeleted: string[]; errors: any[] } = { + const responseBody: { itemsDeleted: string[]; errors: any[] } = { itemsDeleted: [], errors: [], }; await Promise.all( - componentNames.map((componentName) => { - return callAsCurrentUser('dataManagement.deleteComponentTemplate', { - name: componentName, - }) - .then(() => response.itemsDeleted.push(componentName)) - .catch((e) => - response.errors.push({ - name: componentName, - error: e, - }) - ); + componentNames.map(async (componentName) => { + try { + await client.asCurrentUser.cluster.deleteComponentTemplate({ + name: componentName, + }); + + return responseBody.itemsDeleted.push(componentName); + } catch (error) { + return responseBody.errors.push({ + name: componentName, + error: handleEsError({ error, response }), + }); + } }) ); - return res.ok({ body: response }); + return response.ok({ body: responseBody }); } ); }; diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/get.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/get.ts index a5d70e65f870a9..a77aa90c52f73e 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/get.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/get.ts @@ -19,25 +19,23 @@ const paramsSchema = schema.object({ name: schema.string(), }); -export function registerGetAllRoute({ router, lib: { isEsError } }: RouteDependencies) { +export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDependencies) { // Get all component templates router.get( { path: addBasePath('/component_templates'), validate: false }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; + async (context, request, response) => { + const { client } = context.core.elasticsearch; try { const { - component_templates: componentTemplates, - }: { component_templates: ComponentTemplateFromEs[] } = await callAsCurrentUser( - 'dataManagement.getComponentTemplates' - ); + body: { component_templates: componentTemplates }, + } = await client.asCurrentUser.cluster.getComponentTemplate(); - const { index_templates: indexTemplates } = await callAsCurrentUser( - 'dataManagement.getComposableIndexTemplates' - ); + const { + body: { index_templates: indexTemplates }, + } = await client.asCurrentUser.indices.getIndexTemplate(); - const body = componentTemplates.map((componentTemplate) => { + const body = componentTemplates.map((componentTemplate: ComponentTemplateFromEs) => { const deserializedComponentTemplateListItem = deserializeComponentTemplateList( componentTemplate, indexTemplates @@ -45,16 +43,9 @@ export function registerGetAllRoute({ router, lib: { isEsError } }: RouteDepende return deserializedComponentTemplateListItem; }); - return res.ok({ body }); + return response.ok({ body }); } catch (error) { - if (isEsError(error)) { - return res.customError({ - statusCode: error.statusCode, - body: error, - }); - } - - throw error; + return handleEsError({ error, response }); } } ); @@ -67,34 +58,26 @@ export function registerGetAllRoute({ router, lib: { isEsError } }: RouteDepende params: paramsSchema, }, }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - const { name } = req.params; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { name } = request.params; try { - const { component_templates: componentTemplates } = await callAsCurrentUser( - 'dataManagement.getComponentTemplates', - { - name, - } - ); + const { + body: { component_templates: componentTemplates }, + } = await client.asCurrentUser.cluster.getComponentTemplate({ + name, + }); - const { index_templates: indexTemplates } = await callAsCurrentUser( - 'dataManagement.getComposableIndexTemplates' - ); + const { + body: { index_templates: indexTemplates }, + } = await client.asCurrentUser.indices.getIndexTemplate(); - return res.ok({ + return response.ok({ body: deserializeComponentTemplate(componentTemplates[0], indexTemplates), }); } catch (error) { - if (isEsError(error)) { - return res.customError({ - statusCode: error.statusCode, - body: error, - }); - } - - throw error; + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.test.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.test.ts index eccf2d945785f2..992c2f9ed29ddb 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.test.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.test.ts @@ -18,17 +18,15 @@ const httpService = httpServiceMock.createSetupContract(); const mockedIndexDataEnricher = new IndexDataEnricher(); -const mockRouteContext = ({ - callAsCurrentUser, -}: { - callAsCurrentUser: any; -}): RequestHandlerContext => { +const mockRouteContext = ({ hasPrivileges }: { hasPrivileges: unknown }): RequestHandlerContext => { const routeContextMock = ({ core: { elasticsearch: { - legacy: { - client: { - callAsCurrentUser, + client: { + asCurrentUser: { + security: { + hasPrivileges, + }, }, }, }, @@ -51,8 +49,6 @@ describe('GET privileges', () => { }, indexDataEnricher: mockedIndexDataEnricher, lib: { - isEsError: jest.fn(), - parseEsError: jest.fn(), handleEsError: jest.fn(), }, }); @@ -62,15 +58,17 @@ describe('GET privileges', () => { it('should return the correct response when a user has privileges', async () => { const privilegesResponseMock = { - username: 'elastic', - has_all_requested: true, - cluster: { manage_index_templates: true }, - index: {}, - application: {}, + body: { + username: 'elastic', + has_all_requested: true, + cluster: { manage_index_templates: true }, + index: {}, + application: {}, + }, }; const routeContextMock = mockRouteContext({ - callAsCurrentUser: jest.fn().mockResolvedValueOnce(privilegesResponseMock), + hasPrivileges: jest.fn().mockResolvedValueOnce(privilegesResponseMock), }); const request = httpServerMock.createKibanaRequest(); @@ -86,15 +84,17 @@ describe('GET privileges', () => { it('should return the correct response when a user does not have privileges', async () => { const privilegesResponseMock = { - username: 'elastic', - has_all_requested: false, - cluster: { manage_index_templates: false }, - index: {}, - application: {}, + body: { + username: 'elastic', + has_all_requested: false, + cluster: { manage_index_templates: false }, + index: {}, + application: {}, + }, }; const routeContextMock = mockRouteContext({ - callAsCurrentUser: jest.fn().mockResolvedValueOnce(privilegesResponseMock), + hasPrivileges: jest.fn().mockResolvedValueOnce(privilegesResponseMock), }); const request = httpServerMock.createKibanaRequest(); @@ -119,8 +119,6 @@ describe('GET privileges', () => { }, indexDataEnricher: mockedIndexDataEnricher, lib: { - isEsError: jest.fn(), - parseEsError: jest.fn(), handleEsError: jest.fn(), }, }); @@ -130,7 +128,7 @@ describe('GET privileges', () => { it('should return the default privileges response', async () => { const routeContextMock = mockRouteContext({ - callAsCurrentUser: jest.fn(), + hasPrivileges: jest.fn(), }); const request = httpServerMock.createKibanaRequest(); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.ts index 62ad93453091ec..327e6421525c6c 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/privileges.ts @@ -17,13 +17,17 @@ const extractMissingPrivileges = (privilegesObject: { [key: string]: boolean } = return privileges; }, []); -export const registerPrivilegesRoute = ({ router, config }: RouteDependencies) => { +export const registerPrivilegesRoute = ({ + router, + config, + lib: { handleEsError }, +}: RouteDependencies) => { router.get( { path: addBasePath('/component_templates/privileges'), validate: false, }, - async (ctx, req, res) => { + async (context, request, response) => { const privilegesResult: Privileges = { hasAllPrivileges: true, missingPrivileges: { @@ -33,38 +37,28 @@ export const registerPrivilegesRoute = ({ router, config }: RouteDependencies) = // Skip the privileges check if security is not enabled if (!config.isSecurityEnabled()) { - return res.ok({ body: privilegesResult }); + return response.ok({ body: privilegesResult }); } - const { - core: { - elasticsearch: { - legacy: { client }, - }, - }, - } = ctx; + const { client } = context.core.elasticsearch; try { - const { has_all_requested: hasAllPrivileges, cluster } = await client.callAsCurrentUser( - 'transport.request', - { - path: '/_security/user/_has_privileges', - method: 'POST', - body: { - cluster: ['manage_index_templates'], - }, - } - ); + const { + body: { has_all_requested: hasAllPrivileges, cluster }, + } = await client.asCurrentUser.security.hasPrivileges({ + body: { + cluster: ['manage_index_templates'], + }, + }); if (!hasAllPrivileges) { privilegesResult.missingPrivileges.cluster = extractMissingPrivileges(cluster); } privilegesResult.hasAllPrivileges = hasAllPrivileges; - - return res.ok({ body: privilegesResult }); - } catch (e) { - throw e; + return response.ok({ body: privilegesResult }); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/component_templates/update.ts b/x-pack/plugins/index_management/server/routes/api/component_templates/update.ts index ee94b8f2b0082d..17e14f1a39c420 100644 --- a/x-pack/plugins/index_management/server/routes/api/component_templates/update.ts +++ b/x-pack/plugins/index_management/server/routes/api/component_templates/update.ts @@ -15,7 +15,10 @@ const paramsSchema = schema.object({ name: schema.string(), }); -export const registerUpdateRoute = ({ router, lib: { isEsError } }: RouteDependencies): void => { +export const registerUpdateRoute = ({ + router, + lib: { handleEsError }, +}: RouteDependencies): void => { router.put( { path: addBasePath('/component_templates/{name}'), @@ -24,34 +27,28 @@ export const registerUpdateRoute = ({ router, lib: { isEsError } }: RouteDepende params: paramsSchema, }, }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - const { name } = req.params; - const { template, version, _meta } = req.body; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { name } = request.params; + const { template, version, _meta } = request.body; try { // Verify component exists; ES will throw 404 if not - await callAsCurrentUser('dataManagement.getComponentTemplate', { name }); + await client.asCurrentUser.cluster.getComponentTemplate({ name }); - const response = await callAsCurrentUser('dataManagement.saveComponentTemplate', { + const { body: responseBody } = await client.asCurrentUser.cluster.putComponentTemplate({ name, body: { + // @ts-expect-error @elastic/elasticsearch Not assignable to type 'IndicesIndexState' template, version, _meta, }, }); - return res.ok({ body: response }); + return response.ok({ body: responseBody }); } catch (error) { - if (isEsError(error)) { - return res.customError({ - statusCode: error.statusCode, - body: error, - }); - } - - throw error; + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts index 49166f4823a026..9e7b57079cc3c3 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_delete_route.ts @@ -9,23 +9,22 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; -import { wrapEsError } from '../../helpers'; const bodySchema = schema.object({ dataStreams: schema.arrayOf(schema.string()), }); -export function registerDeleteRoute({ router }: RouteDependencies) { +export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/delete_data_streams'), validate: { body: bodySchema }, }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - const { dataStreams } = req.body as TypeOf; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { dataStreams } = request.body as TypeOf; - const response: { dataStreamsDeleted: string[]; errors: any[] } = { + const responseBody: { dataStreamsDeleted: string[]; errors: any[] } = { dataStreamsDeleted: [], errors: [], }; @@ -33,21 +32,21 @@ export function registerDeleteRoute({ router }: RouteDependencies) { await Promise.all( dataStreams.map(async (name: string) => { try { - await callAsCurrentUser('dataManagement.deleteDataStream', { + await client.asCurrentUser.indices.deleteDataStream({ name, }); - return response.dataStreamsDeleted.push(name); - } catch (e) { - return response.errors.push({ + return responseBody.dataStreamsDeleted.push(name); + } catch (error) { + return responseBody.errors.push({ name, - error: wrapEsError(e), + error: handleEsError({ error, response }), }); } }) ); - return res.ok({ body: response }); + return response.ok({ body: responseBody }); } ); } 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 1ce7c14f0a2093..c7b28b46e8f002 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 @@ -7,7 +7,7 @@ import { schema, TypeOf } from '@kbn/config-schema'; -import { ElasticsearchClient } from 'kibana/server'; +import { IScopedClusterClient } from 'kibana/server'; import { deserializeDataStream, deserializeDataStreamList } from '../../../../common/lib'; import { DataStreamFromEs } from '../../../../common/types'; import { RouteDependencies } from '../../../types'; @@ -68,30 +68,23 @@ const enhanceDataStreams = ({ }); }; -const getDataStreams = (client: ElasticsearchClient, name = '*') => { - // TODO update when elasticsearch client has update requestParams for 'indices.getDataStream' - return client.transport.request({ - path: `/_data_stream/${encodeURIComponent(name)}`, - method: 'GET', - querystring: { - expand_wildcards: 'all', - }, +const getDataStreams = (client: IScopedClusterClient, name = '*') => { + return client.asCurrentUser.indices.getDataStream({ + name, + expand_wildcards: 'all', }); }; -const getDataStreamsStats = (client: ElasticsearchClient, name = '*') => { - return client.transport.request({ - path: `/_data_stream/${encodeURIComponent(name)}/_stats`, - method: 'GET', - querystring: { - human: true, - expand_wildcards: 'all', - }, +const getDataStreamsStats = (client: IScopedClusterClient, name = '*') => { + return client.asCurrentUser.indices.dataStreamsStats({ + name, + expand_wildcards: 'all', + human: true, }); }; -const getDataStreamsPrivileges = (client: ElasticsearchClient, names: string[]) => { - return client.security.hasPrivileges({ +const getDataStreamsPrivileges = (client: IScopedClusterClient, names: string[]) => { + return client.asCurrentUser.security.hasPrivileges({ body: { index: [ { @@ -109,15 +102,15 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: }); router.get( { path: addBasePath('/data_streams'), validate: { query: querySchema } }, - async (ctx, req, response) => { - const { asCurrentUser } = ctx.core.elasticsearch.client; + async (context, request, response) => { + const { client } = context.core.elasticsearch; - const includeStats = (req.query as TypeOf).includeStats === 'true'; + const includeStats = (request.query as TypeOf).includeStats === 'true'; try { - let { + const { body: { data_streams: dataStreams }, - } = await getDataStreams(asCurrentUser); + } = await getDataStreams(client); let dataStreamsStats; let dataStreamsPrivileges; @@ -125,24 +118,26 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: if (includeStats) { ({ body: { data_streams: dataStreamsStats }, - } = await getDataStreamsStats(asCurrentUser)); + } = await getDataStreamsStats(client)); } if (config.isSecurityEnabled() && dataStreams.length > 0) { ({ body: dataStreamsPrivileges } = await getDataStreamsPrivileges( - asCurrentUser, - dataStreams.map((dataStream: DataStreamFromEs) => dataStream.name) + client, + dataStreams.map((dataStream) => dataStream.name) )); } - dataStreams = enhanceDataStreams({ + const enhancedDataStreams = enhanceDataStreams({ + // @ts-expect-error @elastic/elasticsearch DataStreamFromEs incompatible with IndicesGetDataStreamIndicesGetDataStreamItem dataStreams, + // @ts-expect-error @elastic/elasticsearch StatsFromEs incompatible with IndicesDataStreamsStatsDataStreamsStatsItem dataStreamsStats, - // @ts-expect-error PrivilegesFromEs incompatible with ApplicationsPrivileges + // @ts-expect-error @elastic/elasticsearch PrivilegesFromEs incompatible with ApplicationsPrivileges dataStreamsPrivileges, }); - return response.ok({ body: deserializeDataStreamList(dataStreams) }); + return response.ok({ body: deserializeDataStreamList(enhancedDataStreams) }); } catch (error) { return handleEsError({ error, response }); } @@ -159,9 +154,9 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: path: addBasePath('/data_streams/{name}'), validate: { params: paramsSchema }, }, - async (ctx, req, response) => { - const { name } = req.params as TypeOf; - const { asCurrentUser } = ctx.core.elasticsearch.client; + async (context, request, response) => { + const { name } = request.params as TypeOf; + const { client } = context.core.elasticsearch; try { const [ { @@ -170,23 +165,22 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: { body: { data_streams: dataStreamsStats }, }, - ] = await Promise.all([ - getDataStreams(asCurrentUser, name), - getDataStreamsStats(asCurrentUser, name), - ]); + ] = await Promise.all([getDataStreams(client, name), getDataStreamsStats(client, name)]); if (dataStreams[0]) { let dataStreamsPrivileges; if (config.isSecurityEnabled()) { - ({ body: dataStreamsPrivileges } = await getDataStreamsPrivileges(asCurrentUser, [ + ({ body: dataStreamsPrivileges } = await getDataStreamsPrivileges(client, [ dataStreams[0].name, ])); } const enhancedDataStreams = enhanceDataStreams({ + // @ts-expect-error @elastic/elasticsearch DataStreamFromEs incompatible with IndicesGetDataStreamIndicesGetDataStreamItem dataStreams, + // @ts-expect-error @elastic/elasticsearch StatsFromEs incompatible with IndicesDataStreamsStatsDataStreamsStatsItem dataStreamsStats, - // @ts-expect-error PrivilegesFromEs incompatible with ApplicationsPrivileges + // @ts-expect-error @elastic/elasticsearch PrivilegesFromEs incompatible with ApplicationsPrivileges dataStreamsPrivileges, }); const body = deserializeDataStream(enhancedDataStreams[0]); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts index 593f0cda6886e3..e9b34e9a72d9b8 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts @@ -14,31 +14,24 @@ const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), }); -export function registerClearCacheRoute({ router, lib }: RouteDependencies) { +export function registerClearCacheRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/clear_cache'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const payload = req.body as typeof bodySchema.type; - const { indices = [] } = payload; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indices = [] } = request.body as typeof bodySchema.type; const params = { - expandWildcards: 'none', + expand_wildcards: 'none', format: 'json', index: indices, }; try { - await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('indices.clearCache', params); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.clearCache(params); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts index 777adcd0557095..9b9bb8238038a1 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts @@ -14,31 +14,24 @@ const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), }); -export function registerCloseRoute({ router, lib }: RouteDependencies) { +export function registerCloseRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/close'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const payload = req.body as typeof bodySchema.type; - const { indices = [] } = payload; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indices = [] } = request.body as typeof bodySchema.type; const params = { - expandWildcards: 'none', + expand_wildcards: 'none', format: 'json', index: indices, }; try { - await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('indices.close', params); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.close(params); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts index 914835089a4381..2bd564e8a4c921 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts @@ -14,31 +14,24 @@ const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), }); -export function registerDeleteRoute({ router, lib }: RouteDependencies) { +export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/delete'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const body = req.body as typeof bodySchema.type; - const { indices = [] } = body; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indices = [] } = request.body as typeof bodySchema.type; const params = { - expandWildcards: 'none', + expand_wildcards: 'none', format: 'json', index: indices, }; try { - await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('indices.delete', params); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.delete(params); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts index bb1759a034cc7e..b008494ab8157b 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts @@ -14,31 +14,24 @@ const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), }); -export function registerFlushRoute({ router, lib }: RouteDependencies) { +export function registerFlushRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/flush'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const body = req.body as typeof bodySchema.type; - const { indices = [] } = body; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indices = [] } = request.body as typeof bodySchema.type; const params = { - expandWildcards: 'none', + expand_wildcards: 'none', format: 'json', index: indices, }; try { - await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('indices.flush', params); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.flush(params); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts index 6f0e8f0fec5673..48d0e1bc974c63 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts @@ -15,7 +15,7 @@ const bodySchema = schema.object({ maxNumSegments: schema.maybe(schema.number()), }); -export function registerForcemergeRoute({ router, lib }: RouteDependencies) { +export function registerForcemergeRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/forcemerge'), @@ -23,10 +23,11 @@ export function registerForcemergeRoute({ router, lib }: RouteDependencies) { body: bodySchema, }, }, - async (ctx, req, res) => { - const { maxNumSegments, indices = [] } = req.body as typeof bodySchema.type; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { maxNumSegments, indices = [] } = request.body as typeof bodySchema.type; const params = { - expandWildcards: 'none', + expand_wildcards: 'none', index: indices, }; @@ -35,17 +36,10 @@ export function registerForcemergeRoute({ router, lib }: RouteDependencies) { } try { - await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('indices.forcemerge', params); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.forcemerge(params); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_freeze_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_freeze_route.ts index 4b1281e0f21219..fcab1d6338b6f8 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_freeze_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_freeze_route.ts @@ -14,33 +14,20 @@ const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), }); -export function registerFreezeRoute({ router, lib }: RouteDependencies) { +export function registerFreezeRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/freeze'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const body = req.body as typeof bodySchema.type; - const { indices = [] } = body; - - const params = { - path: `/${encodeURIComponent(indices.join(','))}/_freeze`, - method: 'POST', - }; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indices = [] } = request.body as typeof bodySchema.type; try { - await await ctx.core.elasticsearch.legacy.client.callAsCurrentUser( - 'transport.request', - params - ); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.freeze({ + index: indices.join(','), + }); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts index 47c454e96c8e2a..d8a7fcb29bb350 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_list_route.ts @@ -9,23 +9,21 @@ import { fetchIndices } from '../../../lib/fetch_indices'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; -export function registerListRoute({ router, indexDataEnricher, lib }: RouteDependencies) { - router.get({ path: addBasePath('/indices'), validate: false }, async (ctx, req, res) => { - try { - const indices = await fetchIndices( - ctx.core.elasticsearch.legacy.client.callAsCurrentUser, - indexDataEnricher - ); - return res.ok({ body: indices }); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); +export function registerListRoute({ + router, + indexDataEnricher, + lib: { handleEsError }, +}: RouteDependencies) { + router.get( + { path: addBasePath('/indices'), validate: false }, + async (context, request, response) => { + const { client } = context.core.elasticsearch; + try { + const indices = await fetchIndices(client, indexDataEnricher); + return response.ok({ body: indices }); + } catch (error) { + return handleEsError({ error, response }); } - // Case: default - throw e; } - }); + ); } diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts index cad57ce60de654..be4b84fdcda82a 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts @@ -14,31 +14,24 @@ const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), }); -export function registerOpenRoute({ router, lib }: RouteDependencies) { +export function registerOpenRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/open'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const body = req.body as typeof bodySchema.type; - const { indices = [] } = body; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indices = [] } = request.body as typeof bodySchema.type; const params = { - expandWildcards: 'none', + expand_wildcards: 'none', format: 'json', index: indices, }; try { - await await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('indices.open', params); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.open(params); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts index e2c0155e280865..c747653f0bb80d 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts @@ -14,31 +14,24 @@ const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), }); -export function registerRefreshRoute({ router, lib }: RouteDependencies) { +export function registerRefreshRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/refresh'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const body = req.body as typeof bodySchema.type; - const { indices = [] } = body; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indices = [] } = request.body as typeof bodySchema.type; const params = { - expandWildcards: 'none', + expand_wildcards: 'none', format: 'json', index: indices, }; try { - await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('indices.refresh', params); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.refresh(params); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts index 8d83cd21f427dd..4c5bd1fb030e85 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts @@ -17,28 +17,22 @@ const bodySchema = schema.maybe( }) ); -export function registerReloadRoute({ router, indexDataEnricher, lib }: RouteDependencies) { +export function registerReloadRoute({ + router, + indexDataEnricher, + lib: { handleEsError }, +}: RouteDependencies) { router.post( { path: addBasePath('/indices/reload'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const { indexNames = [] } = (req.body as typeof bodySchema.type) ?? {}; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indexNames = [] } = (request.body as typeof bodySchema.type) ?? {}; try { - const indices = await fetchIndices( - ctx.core.elasticsearch.legacy.client.callAsCurrentUser, - indexDataEnricher, - indexNames - ); - return res.ok({ body: indices }); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + const indices = await fetchIndices(client, indexDataEnricher, indexNames); + return response.ok({ body: indices }); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts index 45102f4874129a..71a7c27ad2cba7 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts @@ -14,28 +14,20 @@ const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), }); -export function registerUnfreezeRoute({ router, lib }: RouteDependencies) { +export function registerUnfreezeRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/indices/unfreeze'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const { indices = [] } = req.body as typeof bodySchema.type; - const params = { - path: `/${encodeURIComponent(indices.join(','))}/_unfreeze`, - method: 'POST', - }; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indices = [] } = request.body as typeof bodySchema.type; try { - await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('transport.request', params); - return res.ok(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + await client.asCurrentUser.indices.unfreeze({ + index: indices.join(','), + }); + return response.ok(); + } catch (error) { + return handleEsError({ error, response }); } } ); 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 406ceba16c8bda..b5891e579a1f65 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 @@ -21,32 +21,23 @@ function formatHit(hit: { [key: string]: { mappings: any } }, indexName: string) }; } -export function registerMappingRoute({ router, lib }: RouteDependencies) { +export function registerMappingRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.get( { path: addBasePath('/mapping/{indexName}'), validate: { params: paramsSchema } }, - async (ctx, req, res) => { - const { indexName } = req.params as typeof paramsSchema.type; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indexName } = request.params as typeof paramsSchema.type; const params = { expand_wildcards: 'none', index: indexName, }; try { - const hit = await ctx.core.elasticsearch.legacy.client.callAsCurrentUser( - 'indices.getMapping', - params - ); - const response = formatHit(hit, indexName); - return res.ok({ body: response }); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + const { body: hit } = await client.asCurrentUser.indices.getMapping(params); + const responseBody = formatHit(hit, indexName); + return response.ok({ body: responseBody }); + } catch (error) { + return handleEsError({ error, response }); } } ); 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 276b326929e8f9..a819315f5231fe 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 @@ -21,34 +21,25 @@ function formatHit(hit: { [key: string]: {} }) { return hit[key]; } -export function registerLoadRoute({ router, lib }: RouteDependencies) { +export function registerLoadRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.get( { path: addBasePath('/settings/{indexName}'), validate: { params: paramsSchema } }, - async (ctx, req, res) => { - const { indexName } = req.params as typeof paramsSchema.type; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indexName } = request.params as typeof paramsSchema.type; const params = { - expandWildcards: 'none', - flatSettings: false, + expand_wildcards: 'none', + flat_settings: false, local: false, - includeDefaults: true, + include_defaults: true, index: indexName, }; try { - const hit = await ctx.core.elasticsearch.legacy.client.callAsCurrentUser( - 'indices.getSettings', - params - ); - return res.ok({ body: formatHit(hit) }); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + const { body: 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 b4f12b91083df9..5dc825738cfaae 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 @@ -16,37 +16,28 @@ const paramsSchema = schema.object({ indexName: schema.string(), }); -export function registerUpdateRoute({ router, lib }: RouteDependencies) { +export function registerUpdateRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.put( { path: addBasePath('/settings/{indexName}'), validate: { body: bodySchema, params: paramsSchema }, }, - async (ctx, req, res) => { - const { indexName } = req.params as typeof paramsSchema.type; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indexName } = request.params as typeof paramsSchema.type; const params = { - ignoreUnavailable: true, - allowNoIndices: false, - expandWildcards: 'none', + ignore_unavailable: true, + allow_no_indices: false, + expand_wildcards: 'none', index: indexName, - body: req.body, + body: request.body, }; try { - const response = await ctx.core.elasticsearch.legacy.client.callAsCurrentUser( - 'indices.putSettings', - params - ); - return res.ok({ body: response }); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + const { body: 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 42a3012ea8e174..7458b98f5092fb 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 @@ -6,6 +6,7 @@ */ import { schema } from '@kbn/config-schema'; +import type { estypes } from '@elastic/elasticsearch'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; @@ -14,40 +15,37 @@ const paramsSchema = schema.object({ indexName: schema.string(), }); -function formatHit(hit: { _shards: any; indices: { [key: string]: any } }, indexName: string) { +interface Hit { + _shards: unknown; + indices?: Record; +} + +function formatHit(hit: Hit, indexName: string) { const { _shards, indices } = hit; - const stats = indices[indexName]; + const stats = indices![indexName]; return { _shards, stats, }; } -export function registerStatsRoute({ router, lib }: RouteDependencies) { +export function registerStatsRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.get( { path: addBasePath('/stats/{indexName}'), validate: { params: paramsSchema } }, - async (ctx, req, res) => { - const { indexName } = req.params as typeof paramsSchema.type; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { indexName } = request.params as typeof paramsSchema.type; const params = { expand_wildcards: 'none', index: indexName, }; try { - const hit = await ctx.core.elasticsearch.legacy.client.callAsCurrentUser( - 'indices.stats', - params - ); - return res.ok({ body: formatHit(hit, indexName) }); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + const { body: hit } = await client.asCurrentUser.indices.stats(params); + + return response.ok({ body: formatHit(hit, indexName) }); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/templates/lib.ts b/x-pack/plugins/index_management/server/routes/api/templates/lib.ts index d64bb719d23eb0..ef2642399d76dc 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/lib.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/lib.ts @@ -5,32 +5,33 @@ * 2.0. */ +import { IScopedClusterClient } from 'kibana/server'; import { serializeTemplate, serializeLegacyTemplate } from '../../../../common/lib'; import { TemplateDeserialized, LegacyTemplateSerialized } from '../../../../common'; -import { CallAsCurrentUser } from '../../../types'; export const doesTemplateExist = async ({ name, - callAsCurrentUser, + client, isLegacy, }: { name: string; - callAsCurrentUser: CallAsCurrentUser; + client: IScopedClusterClient; isLegacy?: boolean; }) => { if (isLegacy) { - return await callAsCurrentUser('indices.existsTemplate', { name }); + return await client.asCurrentUser.indices.existsTemplate({ name }); } - return await callAsCurrentUser('dataManagement.existsTemplate', { name }); + + return await client.asCurrentUser.indices.existsIndexTemplate({ name }); }; export const saveTemplate = async ({ template, - callAsCurrentUser, + client, isLegacy, }: { template: TemplateDeserialized; - callAsCurrentUser: CallAsCurrentUser; + client: IScopedClusterClient; isLegacy?: boolean; }) => { const serializedTemplate = isLegacy @@ -48,8 +49,9 @@ export const saveTemplate = async ({ aliases, } = serializedTemplate as LegacyTemplateSerialized; - return await callAsCurrentUser('indices.putTemplate', { + return await client.asCurrentUser.indices.putTemplate({ name: template.name, + // @ts-expect-error @elastic/elasticsearch not assignable to parameter of type 'IndicesPutTemplateRequest' order, body: { index_patterns, @@ -61,8 +63,9 @@ export const saveTemplate = async ({ }); } - return await callAsCurrentUser('dataManagement.saveComposableIndexTemplate', { + return await client.asCurrentUser.indices.putIndexTemplate({ name: template.name, + // @ts-expect-error @elastic/elasticsearch Type 'LegacyTemplateSerialized | TemplateSerialized' is not assignable body: serializedTemplate, }); }; 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 d8a236bdebd155..21be254eb9d732 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 @@ -15,54 +15,44 @@ import { saveTemplate, doesTemplateExist } from './lib'; const bodySchema = templateSchema; -export function registerCreateRoute({ router, lib }: RouteDependencies) { +export function registerCreateRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/index_templates'), validate: { body: bodySchema } }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - const template = req.body as TemplateDeserialized; - const { - _kbnMeta: { isLegacy }, - } = template; - - // Check that template with the same name doesn't already exist - const templateExists = await doesTemplateExist({ - name: template.name, - callAsCurrentUser, - isLegacy, - }); - - if (templateExists) { - return res.conflict({ - body: new Error( - i18n.translate('xpack.idxMgmt.createRoute.duplicateTemplateIdErrorMessage', { - defaultMessage: "There is already a template with name '{name}'.", - values: { - name: template.name, - }, - }) - ), - }); - } + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const template = request.body as TemplateDeserialized; try { - // Otherwise create new index template - const response = await saveTemplate({ template, callAsCurrentUser, isLegacy }); + const { + _kbnMeta: { isLegacy }, + } = template; + + // Check that template with the same name doesn't already exist + const { body: templateExists } = await doesTemplateExist({ + name: template.name, + client, + isLegacy, + }); - return res.ok({ body: response }); - } catch (e) { - if (lib.isEsError(e)) { - const error = lib.parseEsError(e.response); - return res.customError({ - statusCode: e.statusCode, - body: { - message: error.message, - attributes: error, - }, + if (templateExists) { + return response.conflict({ + body: new Error( + i18n.translate('xpack.idxMgmt.createRoute.duplicateTemplateIdErrorMessage', { + defaultMessage: "There is already a template with name '{name}'.", + values: { + name: template.name, + }, + }) + ), }); } - // Case: default - throw e; + + // Otherwise create new index template + const { body: responseBody } = await saveTemplate({ template, client, isLegacy }); + + return response.ok({ body: responseBody }); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts index 083964dec9edcc..fbfcab3a8f5ed6 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts @@ -9,7 +9,6 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; -import { wrapEsError } from '../../helpers'; import { TemplateDeserialized } from '../../../../common'; @@ -22,16 +21,19 @@ const bodySchema = schema.object({ ), }); -export function registerDeleteRoute({ router }: RouteDependencies) { +export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/delete_index_templates'), validate: { body: bodySchema }, }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - const { templates } = req.body as TypeOf; - const response: { templatesDeleted: Array; errors: any[] } = { + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { templates } = request.body as TypeOf; + const responseBody: { + templatesDeleted: Array; + errors: any[]; + } = { templatesDeleted: [], errors: [], }; @@ -40,26 +42,26 @@ export function registerDeleteRoute({ router }: RouteDependencies) { templates.map(async ({ name, isLegacy }) => { try { if (isLegacy) { - await callAsCurrentUser('indices.deleteTemplate', { + await client.asCurrentUser.indices.deleteTemplate({ name, }); } else { - await callAsCurrentUser('dataManagement.deleteComposableIndexTemplate', { + await client.asCurrentUser.indices.deleteIndexTemplate({ name, }); } - return response.templatesDeleted.push(name); - } catch (e) { - return response.errors.push({ + return responseBody.templatesDeleted.push(name); + } catch (error) { + return responseBody.errors.push({ name, - error: wrapEsError(e), + error: handleEsError({ error, response }), }); } }) ); - return res.ok({ body: response }); + return response.ok({ body: responseBody }); } ); } 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 231a2764d27106..9d0b7302b5587b 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 @@ -17,41 +17,37 @@ import { getCloudManagedTemplatePrefix } from '../../../lib/get_managed_template import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; -export function registerGetAllRoute({ router, lib: { isEsError } }: RouteDependencies) { - router.get({ path: addBasePath('/index_templates'), validate: false }, async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - - try { - const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(callAsCurrentUser); - - const legacyTemplatesEs = await callAsCurrentUser('indices.getTemplate'); - const { index_templates: templatesEs } = await callAsCurrentUser( - 'dataManagement.getComposableIndexTemplates' - ); - - const legacyTemplates = deserializeLegacyTemplateList( - legacyTemplatesEs, - cloudManagedTemplatePrefix - ); - const templates = deserializeTemplateList(templatesEs, cloudManagedTemplatePrefix); - - const body = { - templates, - legacyTemplates, - }; - - return res.ok({ body }); - } catch (error) { - if (isEsError(error)) { - return res.customError({ - statusCode: error.statusCode, - body: error, - }); +export function registerGetAllRoute({ router, lib: { handleEsError } }: RouteDependencies) { + router.get( + { path: addBasePath('/index_templates'), validate: false }, + async (context, request, response) => { + const { client } = context.core.elasticsearch; + + 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 legacyTemplates = deserializeLegacyTemplateList( + legacyTemplatesEs, + cloudManagedTemplatePrefix + ); + const templates = deserializeTemplateList(templatesEs, cloudManagedTemplatePrefix); + + const body = { + templates, + legacyTemplates, + }; + + return response.ok({ body }); + } catch (error) { + return handleEsError({ error, response }); } - // Case: default - throw error; } - }); + ); } const paramsSchema = schema.object({ @@ -63,26 +59,27 @@ const querySchema = schema.object({ legacy: schema.maybe(schema.oneOf([schema.literal('true'), schema.literal('false')])), }); -export function registerGetOneRoute({ router, lib }: RouteDependencies) { +export function registerGetOneRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.get( { path: addBasePath('/index_templates/{name}'), validate: { params: paramsSchema, query: querySchema }, }, - async (ctx, req, res) => { - const { name } = req.params as TypeOf; - const { callAsCurrentUser } = ctx.dataManagement!.client; - - const isLegacy = (req.query as TypeOf).legacy === 'true'; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { name } = request.params as TypeOf; + const isLegacy = (request.query as TypeOf).legacy === 'true'; try { - const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(callAsCurrentUser); + const cloudManagedTemplatePrefix = await getCloudManagedTemplatePrefix(client); if (isLegacy) { - const indexTemplateByName = await callAsCurrentUser('indices.getTemplate', { name }); + const { body: indexTemplateByName } = await client.asCurrentUser.indices.getTemplate({ + name, + }); if (indexTemplateByName[name]) { - return res.ok({ + return response.ok({ body: deserializeLegacyTemplate( { ...indexTemplateByName[name], name }, cloudManagedTemplatePrefix @@ -91,11 +88,11 @@ export function registerGetOneRoute({ router, lib }: RouteDependencies) { } } else { const { - index_templates: indexTemplates, - } = await callAsCurrentUser('dataManagement.getComposableIndexTemplate', { name }); + body: { index_templates: indexTemplates }, + } = await client.asCurrentUser.indices.getIndexTemplate({ name }); if (indexTemplates.length > 0) { - return res.ok({ + return response.ok({ body: deserializeTemplate( { ...indexTemplates[0].index_template, name }, cloudManagedTemplatePrefix @@ -104,16 +101,9 @@ export function registerGetOneRoute({ router, lib }: RouteDependencies) { } } - return res.notFound(); - } catch (e) { - if (lib.isEsError(e)) { - return res.customError({ - statusCode: e.statusCode, - body: e, - }); - } - // Case: default - throw e; + return response.notFound(); + } catch (error) { + return handleEsError({ error, response }); } } ); 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 0c3d8faea628cf..cd363cbd7d0038 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 @@ -12,35 +12,30 @@ import { addBasePath } from '../index'; const bodySchema = schema.object({}, { unknowns: 'allow' }); -export function registerSimulateRoute({ router, lib }: RouteDependencies) { +export function registerSimulateRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.post( { path: addBasePath('/index_templates/simulate'), validate: { body: bodySchema }, }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - const template = req.body as TypeOf; + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const template = request.body as TypeOf; try { - const templatePreview = await callAsCurrentUser('dataManagement.simulateTemplate', { - body: template, + const { body: templatePreview } = await client.asCurrentUser.indices.simulateTemplate({ + body: { + ...template, + // Until ES fixes a bug on their side we need to send a fake index pattern + // that won't match any indices. + // Issue: https://github.com/elastic/elasticsearch/issues/59152 + index_patterns: ['a_fake_index_pattern_that_wont_match_any_indices'], + }, }); - return res.ok({ body: templatePreview }); - } catch (e) { - if (lib.isEsError(e)) { - const error = lib.parseEsError(e.response); - return res.customError({ - statusCode: e.statusCode, - body: { - message: error.message, - attributes: error, - }, - }); - } - // Case: default - throw e; + return response.ok({ body: templatePreview }); + } catch (error) { + return handleEsError({ error, response }); } } ); 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 07a7d457f04737..669a1fff663177 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 @@ -18,45 +18,35 @@ const paramsSchema = schema.object({ name: schema.string(), }); -export function registerUpdateRoute({ router, lib }: RouteDependencies) { +export function registerUpdateRoute({ router, lib: { handleEsError } }: RouteDependencies) { router.put( { path: addBasePath('/index_templates/{name}'), validate: { body: bodySchema, params: paramsSchema }, }, - async (ctx, req, res) => { - const { callAsCurrentUser } = ctx.dataManagement!.client; - const { name } = req.params as typeof paramsSchema.type; - const template = req.body as TemplateDeserialized; - const { - _kbnMeta: { isLegacy }, - } = template; - - // Verify the template exists (ES will throw 404 if not) - const doesExist = await doesTemplateExist({ name, callAsCurrentUser, isLegacy }); - - if (!doesExist) { - return res.notFound(); - } + async (context, request, response) => { + const { client } = context.core.elasticsearch; + const { name } = request.params as typeof paramsSchema.type; + const template = request.body as TemplateDeserialized; try { - // Next, update index template - const response = await saveTemplate({ template, callAsCurrentUser, isLegacy }); - - return res.ok({ body: response }); - } catch (e) { - if (lib.isEsError(e)) { - const error = lib.parseEsError(e.response); - return res.customError({ - statusCode: e.statusCode, - body: { - message: error.message, - attributes: error, - }, - }); + const { + _kbnMeta: { isLegacy }, + } = template; + + // Verify the template exists (ES will throw 404 if not) + const { body: templateExists } = await doesTemplateExist({ name, client, isLegacy }); + + if (!templateExists) { + return response.notFound(); } - // Case: default - throw e; + + // Next, update index template + const { body: responseBody } = await saveTemplate({ template, client, isLegacy }); + + return response.ok({ body: responseBody }); + } catch (error) { + return handleEsError({ error, response }); } } ); diff --git a/x-pack/plugins/index_management/server/routes/helpers.ts b/x-pack/plugins/index_management/server/routes/helpers.ts deleted file mode 100644 index 1f5d0af18279dc..00000000000000 --- a/x-pack/plugins/index_management/server/routes/helpers.ts +++ /dev/null @@ -1,58 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -const extractCausedByChain = (causedBy: any = {}, accumulator: any[] = []): any => { - const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/naming-convention - - if (reason) { - accumulator.push(reason); - } - - if (caused_by) { - return extractCausedByChain(caused_by, accumulator); - } - - return accumulator; -}; - -/** - * Wraps an error thrown by the ES JS client into a Boom error response and returns it - * - * @param err Object Error thrown by ES JS client - * @param statusCodeToMessageMap Object Optional map of HTTP status codes => error messages - * @return Object Boom error response - */ -export const wrapEsError = (err: any, statusCodeToMessageMap: any = {}) => { - const { statusCode, response } = err; - - const { - error: { - root_cause = [], // eslint-disable-line @typescript-eslint/naming-convention - caused_by = {}, // eslint-disable-line @typescript-eslint/naming-convention - } = {}, - } = JSON.parse(response); - - // If no custom message if specified for the error's status code, just - // wrap the error as a Boom error response, include the additional information from ES, and return it - if (!statusCodeToMessageMap[statusCode]) { - // const boomError = Boom.boomify(err, { statusCode }); - const error: any = { statusCode }; - - // The caused_by chain has the most information so use that if it's available. If not then - // settle for the root_cause. - const causedByChain = extractCausedByChain(caused_by); - const defaultCause = root_cause.length ? extractCausedByChain(root_cause[0]) : undefined; - - error.cause = causedByChain.length ? causedByChain : defaultCause; - return error; - } - - // Otherwise, use the custom message to create a Boom error response and - // return it - const message = statusCodeToMessageMap[statusCode]; - return { message, statusCode }; -}; diff --git a/x-pack/plugins/index_management/server/services/index_data_enricher.ts b/x-pack/plugins/index_management/server/services/index_data_enricher.ts index eb2169aebf2c50..532485201b99e8 100644 --- a/x-pack/plugins/index_management/server/services/index_data_enricher.ts +++ b/x-pack/plugins/index_management/server/services/index_data_enricher.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { CallAsCurrentUser } from '../types'; +import { IScopedClusterClient } from 'kibana/server'; import { Index } from '../index'; -export type Enricher = (indices: Index[], callAsCurrentUser: CallAsCurrentUser) => Promise; +export type Enricher = (indices: Index[], client: IScopedClusterClient) => Promise; export class IndexDataEnricher { private readonly _enrichers: Enricher[] = []; @@ -19,14 +19,14 @@ export class IndexDataEnricher { public enrichIndices = async ( indices: Index[], - callAsCurrentUser: CallAsCurrentUser + client: IScopedClusterClient ): Promise => { let enrichedIndices = indices; for (let i = 0; i < this.enrichers.length; i++) { const dataEnricher = this.enrichers[i]; try { - const dataEnricherResponse = await dataEnricher(enrichedIndices, callAsCurrentUser); + const dataEnricherResponse = await dataEnricher(enrichedIndices, client); enrichedIndices = dataEnricherResponse; } catch (e) { // silently swallow enricher response errors diff --git a/x-pack/plugins/index_management/server/shared_imports.ts b/x-pack/plugins/index_management/server/shared_imports.ts index 6daa94900e5592..7f55d189457c70 100644 --- a/x-pack/plugins/index_management/server/shared_imports.ts +++ b/x-pack/plugins/index_management/server/shared_imports.ts @@ -5,8 +5,4 @@ * 2.0. */ -export { - isEsError, - parseEsError, - handleEsError, -} from '../../../../src/plugins/es_ui_shared/server'; +export { handleEsError } from '../../../../src/plugins/es_ui_shared/server'; diff --git a/x-pack/plugins/index_management/server/types.ts b/x-pack/plugins/index_management/server/types.ts index c980279d5bf306..ba40d22f2eafc6 100644 --- a/x-pack/plugins/index_management/server/types.ts +++ b/x-pack/plugins/index_management/server/types.ts @@ -5,17 +5,13 @@ * 2.0. */ -import type { - LegacyScopedClusterClient, - ILegacyScopedClusterClient, - IRouter, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter } from 'src/core/server'; + import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; import { LicensingPluginSetup } from '../../licensing/server'; import { SecurityPluginSetup } from '../../security/server'; import { IndexDataEnricher } from './services'; -import { isEsError, parseEsError, handleEsError } from './shared_imports'; +import { handleEsError } from './shared_imports'; export interface Dependencies { security: SecurityPluginSetup; @@ -24,39 +20,12 @@ export interface Dependencies { } export interface RouteDependencies { - router: IndexManagementRouter; + router: IRouter; config: { isSecurityEnabled: () => boolean; }; indexDataEnricher: IndexDataEnricher; lib: { - isEsError: typeof isEsError; - parseEsError: typeof parseEsError; handleEsError: typeof handleEsError; }; } - -export type CallAsCurrentUser = LegacyScopedClusterClient['callAsCurrentUser']; - -export interface DataManagementContext { - client: ILegacyScopedClusterClient; -} - -/** - * @internal - */ -export interface IndexManagementApiRequestHandlerContext { - client: ILegacyScopedClusterClient; -} - -/** - * @internal - */ -export interface IndexManagementRequestHandlerContext extends RequestHandlerContext { - dataManagement: IndexManagementApiRequestHandlerContext; -} - -/** - * @internal - */ -export type IndexManagementRouter = IRouter; diff --git a/x-pack/plugins/rollup/server/rollup_data_enricher.ts b/x-pack/plugins/rollup/server/rollup_data_enricher.ts index 8f115687d54334..2c334780720fab 100644 --- a/x-pack/plugins/rollup/server/rollup_data_enricher.ts +++ b/x-pack/plugins/rollup/server/rollup_data_enricher.ts @@ -5,20 +5,19 @@ * 2.0. */ +import { IScopedClusterClient } from 'kibana/server'; import { Index } from '../../../plugins/index_management/server'; -export const rollupDataEnricher = async (indicesList: Index[], callWithRequest: any) => { +export const rollupDataEnricher = async (indicesList: Index[], client: IScopedClusterClient) => { if (!indicesList || !indicesList.length) { return Promise.resolve(indicesList); } - const params = { - path: '/_all/_rollup/data', - method: 'GET', - }; - try { - const rollupJobData = await callWithRequest('transport.request', params); + const { body: rollupJobData } = await client.asCurrentUser.rollup.getRollupIndexCaps({ + index: '_all', + }); + return indicesList.map((index) => { const isRollupIndex = !!rollupJobData[index.name]; return { diff --git a/x-pack/test/api_integration/apis/management/index_management/component_templates.ts b/x-pack/test/api_integration/apis/management/index_management/component_templates.ts index b631869145e1e7..c6a3b77edd1c0f 100644 --- a/x-pack/test/api_integration/apis/management/index_management/component_templates.ts +++ b/x-pack/test/api_integration/apis/management/index_management/component_templates.ts @@ -281,8 +281,19 @@ export default function ({ getService }: FtrProviderContext) { expect(body).to.eql({ statusCode: 404, error: 'Not Found', - message: - '[resource_not_found_exception] component template matching [component_does_not_exist] not found', + message: 'component template matching [component_does_not_exist] not found', + attributes: { + error: { + reason: 'component template matching [component_does_not_exist] not found', + root_cause: [ + { + reason: 'component template matching [component_does_not_exist] not found', + type: 'resource_not_found_exception', + }, + ], + type: 'resource_not_found_exception', + }, + }, }); }); }); @@ -356,10 +367,19 @@ export default function ({ getService }: FtrProviderContext) { const uri = `${API_BASE_PATH}/component_templates/${componentTemplateName},${COMPONENT_DOES_NOT_EXIST}`; const { body } = await supertest.delete(uri).set('kbn-xsrf', 'xxx').expect(200); - expect(body.itemsDeleted).to.eql([componentTemplateName]); expect(body.errors[0].name).to.eql(COMPONENT_DOES_NOT_EXIST); - expect(body.errors[0].error.msg).to.contain('resource_not_found_exception'); + + expect(body.errors[0].error.payload.attributes.error).to.eql({ + root_cause: [ + { + type: 'resource_not_found_exception', + reason: 'component_does_not_exist', + }, + ], + type: 'resource_not_found_exception', + reason: 'component_does_not_exist', + }); }); }); diff --git a/x-pack/test/api_integration/apis/management/index_management/data_streams.ts b/x-pack/test/api_integration/apis/management/index_management/data_streams.ts index 74498eb8c91b92..8970e8cd642fdd 100644 --- a/x-pack/test/api_integration/apis/management/index_management/data_streams.ts +++ b/x-pack/test/api_integration/apis/management/index_management/data_streams.ts @@ -14,11 +14,11 @@ import { DataStream } from '../../../../../plugins/index_management/common'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); - const es = getService('legacyEs'); + const es = getService('es'); const createDataStream = async (name: string) => { // A data stream requires an index template before it can be created. - await es.dataManagement.saveComposableIndexTemplate({ + await es.indices.putIndexTemplate({ name, body: { // We need to match the names of backing indices with this template. @@ -36,15 +36,15 @@ export default function ({ getService }: FtrProviderContext) { }, }); - await es.dataManagement.createDataStream({ name }); + await es.indices.createDataStream({ name }); }; const deleteComposableIndexTemplate = async (name: string) => { - await es.dataManagement.deleteComposableIndexTemplate({ name }); + await es.indices.deleteIndexTemplate({ name }); }; const deleteDataStream = async (name: string) => { - await es.dataManagement.deleteDataStream({ name }); + await es.indices.deleteDataStream({ name }); await deleteComposableIndexTemplate(name); }; diff --git a/x-pack/test/api_integration/apis/management/index_management/indices.js b/x-pack/test/api_integration/apis/management/index_management/indices.js index 25b1ef97d30875..589887329fcd18 100644 --- a/x-pack/test/api_integration/apis/management/index_management/indices.js +++ b/x-pack/test/api_integration/apis/management/index_management/indices.js @@ -56,13 +56,17 @@ export default function ({ getService }) { const index = await createIndex(); // Make sure the index is open - const [cat1] = await catIndex(index); + const { + body: [cat1], + } = await catIndex(index); expect(cat1.status).to.be('open'); await closeIndex(index).expect(200); // Make sure the index has been closed - const [cat2] = await catIndex(index); + const { + body: [cat2], + } = await catIndex(index); expect(cat2.status).to.be('close'); }); }); @@ -78,13 +82,17 @@ export default function ({ getService }) { await closeIndex(index); // Make sure the index is closed - const [cat1] = await catIndex(index); + const { + body: [cat1], + } = await catIndex(index); expect(cat1.status).to.be('close'); await openIndex(index).expect(200); // Make sure the index is opened - const [cat2] = await catIndex(index); + const { + body: [cat2], + } = await catIndex(index); expect(cat2.status).to.be('open'); }); }); @@ -93,12 +101,12 @@ export default function ({ getService }) { it('should delete an index', async () => { const index = await createIndex(); - const indices1 = await catIndex(undefined, 'i'); + const { body: indices1 } = await catIndex(undefined, 'i'); expect(indices1.map((index) => index.i)).to.contain(index); await deleteIndex([index]).expect(200); - const indices2 = await catIndex(undefined, 'i'); + const { body: indices2 } = await catIndex(undefined, 'i'); expect(indices2.map((index) => index.i)).not.to.contain(index); }); @@ -112,12 +120,16 @@ export default function ({ getService }) { it('should flush an index', async () => { const index = await createIndex(); - const { indices: indices1 } = await indexStats(index, 'flush'); + const { + body: { indices: indices1 }, + } = await indexStats(index, 'flush'); expect(indices1[index].total.flush.total).to.be(0); await flushIndex(index).expect(200); - const { indices: indices2 } = await indexStats(index, 'flush'); + const { + body: { indices: indices2 }, + } = await indexStats(index, 'flush'); expect(indices2[index].total.flush.total).to.be(1); }); }); @@ -126,12 +138,16 @@ export default function ({ getService }) { it('should refresh an index', async () => { const index = await createIndex(); - const { indices: indices1 } = await indexStats(index, 'refresh'); + const { + body: { indices: indices1 }, + } = await indexStats(index, 'refresh'); const previousRefreshes = indices1[index].total.refresh.total; await refreshIndex(index).expect(200); - const { indices: indices2 } = await indexStats(index, 'refresh'); + const { + body: { indices: indices2 }, + } = await indexStats(index, 'refresh'); expect(indices2[index].total.refresh.total).to.be(previousRefreshes + 1); }); }); @@ -153,12 +169,16 @@ export default function ({ getService }) { const index = await createIndex(); // "sth" correspond to search throttling. Frozen indices are normal indices // with search throttling turned on. - const [cat1] = await catIndex(index, 'sth'); + const { + body: [cat1], + } = await catIndex(index, 'sth'); expect(cat1.sth).to.be('false'); await freeze(index).expect(200); - const [cat2] = await catIndex(index, 'sth'); + const { + body: [cat2], + } = await catIndex(index, 'sth'); expect(cat2.sth).to.be('true'); }); }); @@ -168,11 +188,15 @@ export default function ({ getService }) { const index = await createIndex(); await freeze(index).expect(200); - const [cat1] = await catIndex(index, 'sth'); + const { + body: [cat1], + } = await catIndex(index, 'sth'); expect(cat1.sth).to.be('true'); await unfreeze(index).expect(200); - const [cat2] = await catIndex(index, 'sth'); + const { + body: [cat2], + } = await catIndex(index, 'sth'); expect(cat2.sth).to.be('false'); }); }); diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js b/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js index 5a26356328f1f3..22824227f12753 100644 --- a/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js +++ b/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js @@ -13,7 +13,7 @@ import { getRandomString } from './random'; * @param {ElasticsearchClient} es The Elasticsearch client instance */ export const initElasticsearchHelpers = (getService) => { - const es = getService('legacyEs'); + const es = getService('es'); const esDeleteAllIndices = getService('esDeleteAllIndices'); let indicesCreated = []; @@ -42,11 +42,11 @@ export const initElasticsearchHelpers = (getService) => { componentTemplatesCreated.push(componentTemplate.name); } - return es.dataManagement.saveComponentTemplate(componentTemplate); + return es.cluster.putComponentTemplate(componentTemplate); }; const deleteComponentTemplate = (componentTemplateName) => { - return es.dataManagement.deleteComponentTemplate({ name: componentTemplateName }); + return es.cluster.deleteComponentTemplate({ name: componentTemplateName }); }; const cleanUpComponentTemplates = () => diff --git a/x-pack/test/api_integration/apis/management/index_management/templates.js b/x-pack/test/api_integration/apis/management/index_management/templates.js index fd214273435773..1cb58c0957e170 100644 --- a/x-pack/test/api_integration/apis/management/index_management/templates.js +++ b/x-pack/test/api_integration/apis/management/index_management/templates.js @@ -193,8 +193,8 @@ export default function ({ getService }) { }); it('should parse the ES error and return the cause', async () => { - const templateName = `template-${getRandomString()}`; - const payload = getTemplatePayload(templateName, [getRandomString()]); + const templateName = `template-create-parse-es-error}`; + const payload = getTemplatePayload(templateName, ['create-parse-es-error']); const runtime = { myRuntimeField: { type: 'boolean', @@ -207,9 +207,9 @@ export default function ({ getService }) { const { body } = await createTemplate(payload).expect(400); expect(body.attributes).an('object'); - expect(body.attributes.message).contain('template after composition is invalid'); + expect(body.attributes.error.reason).contain('template after composition is invalid'); // one of the item of the cause array should point to our script - expect(body.attributes.cause.join(',')).contain('"hello with error'); + expect(body.attributes.causes.join(',')).contain('"hello with error'); }); }); @@ -220,7 +220,7 @@ export default function ({ getService }) { await createTemplate(indexTemplate).expect(200); - let catTemplateResponse = await catTemplate(templateName); + let { body: catTemplateResponse } = await catTemplate(templateName); const { name, version } = indexTemplate; @@ -234,7 +234,7 @@ export default function ({ getService }) { 200 ); - catTemplateResponse = await catTemplate(templateName); + ({ body: catTemplateResponse } = await catTemplate(templateName)); expect( catTemplateResponse.find(({ name: templateName }) => templateName === name).version @@ -247,7 +247,7 @@ export default function ({ getService }) { await createTemplate(legacyIndexTemplate).expect(200); - let catTemplateResponse = await catTemplate(templateName); + let { body: catTemplateResponse } = await catTemplate(templateName); const { name, version } = legacyIndexTemplate; @@ -262,7 +262,7 @@ export default function ({ getService }) { templateName ).expect(200); - catTemplateResponse = await catTemplate(templateName); + ({ body: catTemplateResponse } = await catTemplate(templateName)); expect( catTemplateResponse.find(({ name: templateName }) => templateName === name).version @@ -270,8 +270,8 @@ export default function ({ getService }) { }); it('should parse the ES error and return the cause', async () => { - const templateName = `template-${getRandomString()}`; - const payload = getTemplatePayload(templateName, [getRandomString()]); + const templateName = `template-update-parse-es-error}`; + const payload = getTemplatePayload(templateName, ['update-parse-es-error']); const runtime = { myRuntimeField: { type: 'keyword', @@ -292,7 +292,7 @@ export default function ({ getService }) { expect(body.attributes).an('object'); // one of the item of the cause array should point to our script - expect(body.attributes.cause.join(',')).contain('"hello with error'); + expect(body.attributes.causes.join(',')).contain('"hello with error'); }); }); @@ -306,7 +306,7 @@ export default function ({ getService }) { throw new Error(`Error creating template: ${createStatus} ${createBody.message}`); } - let catTemplateResponse = await catTemplate(templateName); + let { body: catTemplateResponse } = await catTemplate(templateName); expect( catTemplateResponse.find((template) => template.name === payload.name).name @@ -322,7 +322,7 @@ export default function ({ getService }) { expect(deleteBody.errors).to.be.empty; expect(deleteBody.templatesDeleted[0]).to.equal(templateName); - catTemplateResponse = await catTemplate(templateName); + ({ body: catTemplateResponse } = await catTemplate(templateName)); expect(catTemplateResponse.find((template) => template.name === payload.name)).to.equal( undefined @@ -335,7 +335,7 @@ export default function ({ getService }) { await createTemplate(payload).expect(200); - let catTemplateResponse = await catTemplate(templateName); + let { body: catTemplateResponse } = await catTemplate(templateName); expect( catTemplateResponse.find((template) => template.name === payload.name).name @@ -348,7 +348,7 @@ export default function ({ getService }) { expect(body.errors).to.be.empty; expect(body.templatesDeleted[0]).to.equal(templateName); - catTemplateResponse = await catTemplate(templateName); + ({ body: catTemplateResponse } = await catTemplate(templateName)); expect(catTemplateResponse.find((template) => template.name === payload.name)).to.equal( undefined diff --git a/x-pack/test/api_integration/services/legacy_es.js b/x-pack/test/api_integration/services/legacy_es.js index 0b02d394b107fc..bc0f9946243c8e 100644 --- a/x-pack/test/api_integration/services/legacy_es.js +++ b/x-pack/test/api_integration/services/legacy_es.js @@ -9,7 +9,6 @@ import { format as formatUrl } from 'url'; import * as legacyElasticsearch from 'elasticsearch'; -import { elasticsearchJsPlugin as indexManagementEsClientPlugin } from '../../../plugins/index_management/server/client/elasticsearch'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { DEFAULT_API_VERSION } from '../../../../src/core/server/elasticsearch/elasticsearch_config'; @@ -20,6 +19,5 @@ export function LegacyEsProvider({ getService }) { apiVersion: DEFAULT_API_VERSION, host: formatUrl(config.get('servers.elasticsearch')), requestTimeout: config.get('timeouts.esRequestTimeout'), - plugins: [indexManagementEsClientPlugin], }); }