diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 58ae6aa5440b0c..934548dae083fb 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -5,8 +5,6 @@ */ import { SavedObject, SavedObjectAttributes } from 'src/core/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../src/core/server/elasticsearch/legacy/api_types'; export enum ReindexStep { // Enum values are spaced out by 10 to give us room to insert steps in between. @@ -164,6 +162,23 @@ export interface UpgradeAssistantTelemetrySavedObjectAttributes { [key: string]: any; } +export type MIGRATION_DEPRECATION_LEVEL = 'none' | 'info' | 'warning' | 'critical'; +export interface DeprecationInfo { + level: MIGRATION_DEPRECATION_LEVEL; + message: string; + url: string; + details?: string; +} + +export interface IndexSettingsDeprecationInfo { + [indexName: string]: DeprecationInfo[]; +} +export interface DeprecationAPIResponse { + cluster_settings: DeprecationInfo[]; + ml_settings: DeprecationInfo[]; + node_settings: DeprecationInfo[]; + index_settings: IndexSettingsDeprecationInfo; +} export interface EnrichedDeprecationInfo extends DeprecationInfo { index?: string; node?: string; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx index 66c802097055b6..8637099b77c9b4 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx @@ -6,8 +6,7 @@ import { IconColor } from '@elastic/eui'; import { invert } from 'lodash'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../../../../../src/core/server/elasticsearch/legacy/api_types'; +import { DeprecationInfo } from '../../../../../common/types'; export const LEVEL_MAP: { [level: string]: number } = { warning: 0, diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/controls.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/controls.tsx index d75a25a95d67f4..c75db7e2f96e14 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/controls.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/controls.tsx @@ -8,8 +8,7 @@ import React, { FunctionComponent, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButton, EuiFieldSearch, EuiFlexGroup, EuiFlexItem, EuiCallOut } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../../../../../src/core/server/elasticsearch/legacy/api_types'; +import { DeprecationInfo } from '../../../../../common/types'; import { GroupByOption, LevelFilterOption, LoadingState } from '../../types'; import { FilterBar } from './filter_bar'; import { GroupByBar } from './group_by_bar'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.test.tsx index 6bdb5df0362245..727d959f49a71a 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.test.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.test.tsx @@ -9,9 +9,7 @@ import React from 'react'; import { mountWithIntl, shallowWithIntl } from '@kbn/test/jest'; import { EuiBadge, EuiPagination } from '@elastic/eui'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../../../../../../src/core/server/elasticsearch/legacy/api_types'; -import { EnrichedDeprecationInfo } from '../../../../../../common/types'; +import { DeprecationInfo, EnrichedDeprecationInfo } from '../../../../../../common/types'; import { GroupByOption, LevelFilterOption } from '../../../types'; import { DeprecationAccordion, filterDeps, GroupedDeprecations } from './grouped'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.tsx index de1a5a996d75f3..20ffbae143672b 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.tsx @@ -18,9 +18,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../../../../../../src/core/server/elasticsearch/legacy/api_types'; -import { EnrichedDeprecationInfo } from '../../../../../../common/types'; +import { DeprecationInfo, EnrichedDeprecationInfo } from '../../../../../../common/types'; import { GroupByOption, LevelFilterOption } from '../../../types'; import { DeprecationCountSummary } from './count_summary'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/health.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/health.tsx index 3ce40d0c4fdf0b..c866c1e1f68470 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/health.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/health.tsx @@ -10,8 +10,7 @@ import React, { FunctionComponent } from 'react'; import { EuiBadge, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../../../../../../src/core/server/elasticsearch/legacy/api_types'; +import { DeprecationInfo } from '../../../../../../common/types'; import { COLOR_MAP, LEVEL_MAP, REVERSE_LEVEL_MAP } from '../constants'; const LocalizedLevels: { [level: string]: string } = { diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.tsx index 043d0ed6e500a4..6cd5c831cdf67e 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.tsx @@ -6,9 +6,7 @@ import React, { FunctionComponent } from 'react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../../../../../../src/core/server/elasticsearch/legacy/api_types'; -import { EnrichedDeprecationInfo } from '../../../../../../common/types'; +import { DeprecationInfo, EnrichedDeprecationInfo } from '../../../../../../common/types'; import { GroupByOption } from '../../../types'; import { COLOR_MAP, LEVEL_MAP } from '../constants'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.test.tsx index 053ef21d6b3092..231b15fc52d72b 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.test.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.test.tsx @@ -6,9 +6,8 @@ import { mount, shallow } from 'enzyme'; import React from 'react'; +import { DeprecationInfo } from '../../../../../common/types'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../../../../../src/core/server/elasticsearch/legacy/api_types'; import { LevelFilterOption } from '../../types'; import { FilterBar } from './filter_bar'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.tsx index 6939c547fee571..abcd02d5a5ce41 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.tsx @@ -10,8 +10,7 @@ import React from 'react'; import { EuiFilterButton, EuiFilterGroup, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationInfo } from '../../../../../../../../src/core/server/elasticsearch/legacy/api_types'; +import { DeprecationInfo } from '../../../../../common/types'; import { LevelFilterOption } from '../../types'; const LocalizedOptions: { [option: string]: string } = { diff --git a/x-pack/plugins/upgrade_assistant/server/lib/apm/index.ts b/x-pack/plugins/upgrade_assistant/server/lib/apm/index.ts index 0703d55aa8050c..02aa5ab2dc1131 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/apm/index.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/apm/index.ts @@ -7,20 +7,20 @@ import { get } from 'lodash'; import minimatch from 'minimatch'; import { SemVer, valid } from 'semver'; -import { ILegacyScopedClusterClient } from 'src/core/server'; +import { IScopedClusterClient } from 'src/core/server'; import { EnrichedDeprecationInfo } from '../../../common/types'; import { FlatSettings } from '../reindexing/types'; export async function getDeprecatedApmIndices( - clusterClient: ILegacyScopedClusterClient, + clusterClient: IScopedClusterClient, indexPatterns: string[] = [] ): Promise { - const indices = await clusterClient.callAsCurrentUser('indices.getMapping', { + const indices = await clusterClient.asCurrentUser.indices.getMapping({ index: indexPatterns.join(','), // we include @timestamp to prevent filtering mappings without a version // since @timestamp is expected to always exist - filterPath: '*.mappings._meta.version,*.mappings.properties.@timestamp', + filter_path: '*.mappings._meta.version,*.mappings.properties.@timestamp', }); return Object.keys(indices).reduce((deprecations: EnrichedDeprecationInfo[], index) => { diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts index b0dec299b2b12c..dee05c97f11af4 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts @@ -12,10 +12,10 @@ import { describe('getDeprecationLoggingStatus', () => { it('calls cluster.getSettings', async () => { - const dataClient = elasticsearchServiceMock.createLegacyScopedClusterClient(); + const dataClient = elasticsearchServiceMock.createScopedClusterClient(); await getDeprecationLoggingStatus(dataClient); - expect(dataClient.callAsCurrentUser).toHaveBeenCalledWith('cluster.getSettings', { - includeDefaults: true, + expect(dataClient.asCurrentUser.cluster.getSettings).toHaveBeenCalledWith({ + include_defaults: true, }); }); }); @@ -23,9 +23,9 @@ describe('getDeprecationLoggingStatus', () => { describe('setDeprecationLogging', () => { describe('isEnabled = true', () => { it('calls cluster.putSettings with logger.deprecation = WARN', async () => { - const dataClient = elasticsearchServiceMock.createLegacyScopedClusterClient(); + const dataClient = elasticsearchServiceMock.createScopedClusterClient(); await setDeprecationLogging(dataClient, true); - expect(dataClient.callAsCurrentUser).toHaveBeenCalledWith('cluster.putSettings', { + expect(dataClient.asCurrentUser.cluster.putSettings).toHaveBeenCalledWith({ body: { transient: { 'logger.deprecation': 'WARN' } }, }); }); @@ -33,9 +33,9 @@ describe('setDeprecationLogging', () => { describe('isEnabled = false', () => { it('calls cluster.putSettings with logger.deprecation = ERROR', async () => { - const dataClient = elasticsearchServiceMock.createLegacyScopedClusterClient(); + const dataClient = elasticsearchServiceMock.createScopedClusterClient(); await setDeprecationLogging(dataClient, false); - expect(dataClient.callAsCurrentUser).toHaveBeenCalledWith('cluster.putSettings', { + expect(dataClient.asCurrentUser.cluster.putSettings).toHaveBeenCalledWith({ body: { transient: { 'logger.deprecation': 'ERROR' } }, }); }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts index 348eebb97e384b..c545d12ac1b823 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts @@ -4,17 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ import { get } from 'lodash'; -import { ILegacyScopedClusterClient } from 'src/core/server'; +import { IScopedClusterClient } from 'src/core/server'; interface DeprecationLoggingStatus { isEnabled: boolean; } export async function getDeprecationLoggingStatus( - dataClient: ILegacyScopedClusterClient + dataClient: IScopedClusterClient ): Promise { - const response = await dataClient.callAsCurrentUser('cluster.getSettings', { - includeDefaults: true, + const { body: response } = await dataClient.asCurrentUser.cluster.getSettings({ + include_defaults: true, }); return { @@ -23,10 +23,10 @@ export async function getDeprecationLoggingStatus( } export async function setDeprecationLogging( - dataClient: ILegacyScopedClusterClient, + dataClient: IScopedClusterClient, isEnabled: boolean ): Promise { - const response = await dataClient.callAsCurrentUser('cluster.putSettings', { + const { body: response } = await dataClient.asCurrentUser.cluster.putSettings({ body: { transient: { 'logger.deprecation': isEnabled ? 'WARN' : 'ERROR', diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts index bce48b152700f0..739499e2235b55 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts @@ -4,22 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LegacyAPICaller } from 'kibana/server'; +import { ElasticsearchClient } from 'kibana/server'; import { getIndexState } from '../../common/get_index_state'; import { ResolveIndexResponseFromES } from '../../common/types'; type StatusCheckResult = Record; export const esIndicesStateCheck = async ( - callAsUser: LegacyAPICaller, + asCurrentUser: ElasticsearchClient, indices: string[] ): Promise => { - const response: ResolveIndexResponseFromES = await callAsUser('transport.request', { - method: 'GET', - path: `/_resolve/index/*`, - query: { - expand_wildcards: 'all', - }, + const { body: response } = await asCurrentUser.indices.resolveIndex({ + name: '*', + expand_wildcards: 'all', }); const result: StatusCheckResult = {}; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.test.ts index e0518e9447ec5c..b6bf389cf454fe 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.test.ts @@ -5,95 +5,95 @@ */ import _ from 'lodash'; +import { RequestEvent } from '@elastic/elasticsearch/lib/Transport'; import { elasticsearchServiceMock } from 'src/core/server/mocks'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationAPIResponse } from '../../../../../src/core/server/elasticsearch/legacy/api_types'; +import { DeprecationAPIResponse } from '../../common/types'; import { getUpgradeAssistantStatus } from './es_migration_apis'; import fakeDeprecations from './__fixtures__/fake_deprecations.json'; const fakeIndexNames = Object.keys(fakeDeprecations.index_settings); +const asApiResponse = (body: T): RequestEvent => +({ + body, +} as RequestEvent); + describe('getUpgradeAssistantStatus', () => { const resolvedIndices = { indices: fakeIndexNames.map((f) => ({ name: f, attributes: ['open'] })), }; - let deprecationsResponse: DeprecationAPIResponse; - - const dataClient = elasticsearchServiceMock.createLegacyScopedClusterClient(); - (dataClient.callAsCurrentUser as jest.Mock).mockImplementation(async (api, { path }) => { - if (path === '/_migration/deprecations') { - return deprecationsResponse; - } else if (path === '/_resolve/index/*') { - return resolvedIndices; - } else if (api === 'indices.getMapping') { - return {}; - } else { - throw new Error(`Unexpected API call: ${path}`); - } - }); - beforeEach(() => { - // @ts-expect-error mock data is too loosely typed - deprecationsResponse = _.cloneDeep(fakeDeprecations); - }); + // @ts-expect-error mock data is too loosely typed + const deprecationsResponse: DeprecationAPIResponse = _.cloneDeep(fakeDeprecations); + + const esClient = elasticsearchServiceMock.createScopedClusterClient(); + + esClient.asCurrentUser.migration.deprecations.mockResolvedValue( + asApiResponse(deprecationsResponse) + ); + + esClient.asCurrentUser.indices.resolveIndex.mockResolvedValue(asApiResponse(resolvedIndices)); it('calls /_migration/deprecations', async () => { - await getUpgradeAssistantStatus(dataClient, false, []); - expect(dataClient.callAsCurrentUser).toHaveBeenCalledWith('transport.request', { - path: '/_migration/deprecations', - method: 'GET', - }); + await getUpgradeAssistantStatus(esClient, false, []); + expect(esClient.asCurrentUser.migration.deprecations).toHaveBeenCalled(); }); it('returns the correct shape of data', async () => { - const resp = await getUpgradeAssistantStatus(dataClient, false, []); + const resp = await getUpgradeAssistantStatus(esClient, false, []); expect(resp).toMatchSnapshot(); }); it('returns readyForUpgrade === false when critical issues found', async () => { - deprecationsResponse = { - cluster_settings: [{ level: 'critical', message: 'Do count me', url: 'https://...' }], - node_settings: [], - ml_settings: [], - index_settings: {}, - }; - - await expect(getUpgradeAssistantStatus(dataClient, false, [])).resolves.toHaveProperty( + esClient.asCurrentUser.migration.deprecations.mockResolvedValue( + asApiResponse({ + cluster_settings: [{ level: 'critical', message: 'Do count me', url: 'https://...' }], + node_settings: [], + ml_settings: [], + index_settings: {}, + }) + ); + + await expect(getUpgradeAssistantStatus(esClient, false, [])).resolves.toHaveProperty( 'readyForUpgrade', false ); }); it('returns readyForUpgrade === true when no critical issues found', async () => { - deprecationsResponse = { - cluster_settings: [{ level: 'warning', message: 'Do not count me', url: 'https://...' }], - node_settings: [], - ml_settings: [], - index_settings: {}, - }; - - await expect(getUpgradeAssistantStatus(dataClient, false, [])).resolves.toHaveProperty( + esClient.asCurrentUser.migration.deprecations.mockResolvedValue( + asApiResponse({ + cluster_settings: [{ level: 'warning', message: 'Do not count me', url: 'https://...' }], + node_settings: [], + ml_settings: [], + index_settings: {}, + }) + ); + + await expect(getUpgradeAssistantStatus(esClient, false, [])).resolves.toHaveProperty( 'readyForUpgrade', true ); }); it('filters out security realm deprecation on Cloud', async () => { - deprecationsResponse = { - cluster_settings: [ - { - level: 'critical', - message: 'Security realm settings structure changed', - url: 'https://...', - }, - ], - node_settings: [], - ml_settings: [], - index_settings: {}, - }; - - const result = await getUpgradeAssistantStatus(dataClient, true, []); + esClient.asCurrentUser.migration.deprecations.mockResolvedValue( + asApiResponse({ + cluster_settings: [ + { + level: 'critical', + message: 'Security realm settings structure changed', + url: 'https://...', + }, + ], + node_settings: [], + ml_settings: [], + index_settings: {}, + }) + ); + + const result = await getUpgradeAssistantStatus(esClient, true, []); expect(result).toHaveProperty('readyForUpgrade', true); expect(result).toHaveProperty('cluster', []); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.ts index 0f8c2991af295f..04e0af18d71ce7 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.ts @@ -4,25 +4,25 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ILegacyScopedClusterClient } from 'src/core/server'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import type { DeprecationAPIResponse } from '../../../../../src/core/server/elasticsearch/legacy/api_types'; -import { EnrichedDeprecationInfo, UpgradeAssistantStatus } from '../../common/types'; +import { IScopedClusterClient } from 'src/core/server'; +import { + DeprecationAPIResponse, + EnrichedDeprecationInfo, + UpgradeAssistantStatus, +} from '../../common/types'; + import { getDeprecatedApmIndices } from './apm'; import { isSystemIndex } from './reindexing'; import { esIndicesStateCheck } from './es_indices_state_check'; export async function getUpgradeAssistantStatus( - dataClient: ILegacyScopedClusterClient, + dataClient: IScopedClusterClient, isCloudEnabled: boolean, apmIndices: string[] ): Promise { - const [deprecations, apmIndexDeprecations] = await Promise.all([ - dataClient.callAsCurrentUser('transport.request', { - path: '/_migration/deprecations', - method: 'GET', - }), + const [{ body: deprecations }, apmIndexDeprecations] = await Promise.all([ + dataClient.asCurrentUser.migration.deprecations(), getDeprecatedApmIndices(dataClient, apmIndices), ]); @@ -34,10 +34,7 @@ export async function getUpgradeAssistantStatus( // If we have found deprecation information for index/indices check whether the index is // open or closed. if (indexNames.length) { - const indexStates = await esIndicesStateCheck( - dataClient.callAsCurrentUser.bind(dataClient), - indexNames - ); + const indexStates = await esIndicesStateCheck(dataClient.asCurrentUser, indexNames); indices.forEach((indexData) => { indexData.blockerForReindexing = diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts index 78f159ed988674..2310f993ce27d2 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts @@ -5,7 +5,7 @@ */ import { SemVer } from 'semver'; -import { ILegacyScopedClusterClient, kibanaResponseFactory } from 'src/core/server'; +import { IScopedClusterClient, kibanaResponseFactory } from 'src/core/server'; import { xpackMocks } from '../../../../mocks'; import { CURRENT_VERSION } from '../../common/version'; import { @@ -17,14 +17,20 @@ import { describe('getAllNodeVersions', () => { it('returns a list of unique node versions', async () => { const adminClient = ({ - callAsInternalUser: jest.fn().mockResolvedValue({ + asInternalUser: { nodes: { - node1: { version: '7.0.0' }, - node2: { version: '7.0.0' }, - node3: { version: '6.0.0' }, + info: jest.fn().mockResolvedValue({ + body: { + nodes: { + node1: { version: '7.0.0' }, + node2: { version: '7.0.0' }, + node3: { version: '6.0.0' }, + }, + }, + }), }, - }), - } as unknown) as ILegacyScopedClusterClient; + }, + } as unknown) as IScopedClusterClient; await expect(getAllNodeVersions(adminClient)).resolves.toEqual([ new SemVer('6.0.0'), @@ -73,12 +79,18 @@ describe('verifyAllMatchKibanaVersion', () => { describe('EsVersionPrecheck', () => { it('returns a 403 when callCluster fails with a 403', async () => { - const fakeCall = jest.fn().mockRejectedValue({ status: 403 }); + const fakeCall = jest.fn().mockRejectedValue({ statusCode: 403 }); const ctx = xpackMocks.createRequestHandlerContext(); - ctx.core.elasticsearch.legacy.client = { - callAsCurrentUser: jest.fn(), - callAsInternalUser: fakeCall, + ctx.core.elasticsearch.client = { + asInternalUser: { + ...ctx.core.elasticsearch.client.asInternalUser, + nodes: { + ...ctx.core.elasticsearch.client.asInternalUser.nodes, + info: fakeCall, + }, + }, + asCurrentUser: ctx.core.elasticsearch.client.asCurrentUser, }; const result = await esVersionCheck(ctx, kibanaResponseFactory); @@ -87,14 +99,22 @@ describe('EsVersionPrecheck', () => { it('returns a 426 message w/ allNodesUpgraded = false when nodes are not on same version', async () => { const ctx = xpackMocks.createRequestHandlerContext(); - ctx.core.elasticsearch.legacy.client = { - callAsCurrentUser: jest.fn(), - callAsInternalUser: jest.fn().mockResolvedValue({ + ctx.core.elasticsearch.client = { + asInternalUser: { + ...ctx.core.elasticsearch.client.asInternalUser, nodes: { - node1: { version: CURRENT_VERSION.raw }, - node2: { version: new SemVer(CURRENT_VERSION.raw).inc('major').raw }, + ...ctx.core.elasticsearch.client.asInternalUser.nodes, + info: jest.fn().mockResolvedValue({ + body: { + nodes: { + node1: { version: CURRENT_VERSION.raw }, + node2: { version: new SemVer(CURRENT_VERSION.raw).inc('major').raw }, + }, + }, + }), }, - }), + }, + asCurrentUser: ctx.core.elasticsearch.client.asCurrentUser, }; const result = await esVersionCheck(ctx, kibanaResponseFactory); @@ -104,14 +124,22 @@ describe('EsVersionPrecheck', () => { it('returns a 426 message w/ allNodesUpgraded = true when nodes are on next version', async () => { const ctx = xpackMocks.createRequestHandlerContext(); - ctx.core.elasticsearch.legacy.client = { - callAsCurrentUser: jest.fn(), - callAsInternalUser: jest.fn().mockResolvedValue({ + ctx.core.elasticsearch.client = { + asInternalUser: { + ...ctx.core.elasticsearch.client.asInternalUser, nodes: { - node1: { version: new SemVer(CURRENT_VERSION.raw).inc('major').raw }, - node2: { version: new SemVer(CURRENT_VERSION.raw).inc('major').raw }, + ...ctx.core.elasticsearch.client.asInternalUser.nodes, + info: jest.fn().mockResolvedValue({ + body: { + nodes: { + node1: { version: new SemVer(CURRENT_VERSION.raw).inc('major').raw }, + node2: { version: new SemVer(CURRENT_VERSION.raw).inc('major').raw }, + }, + }, + }), }, - }), + }, + asCurrentUser: ctx.core.elasticsearch.client.asCurrentUser, }; const result = await esVersionCheck(ctx, kibanaResponseFactory); @@ -121,14 +149,22 @@ describe('EsVersionPrecheck', () => { it('returns undefined when nodes are on same version', async () => { const ctx = xpackMocks.createRequestHandlerContext(); - ctx.core.elasticsearch.legacy.client = { - callAsCurrentUser: jest.fn(), - callAsInternalUser: jest.fn().mockResolvedValue({ + ctx.core.elasticsearch.client = { + asInternalUser: { + ...ctx.core.elasticsearch.client.asInternalUser, nodes: { - node1: { version: CURRENT_VERSION.raw }, - node2: { version: CURRENT_VERSION.raw }, + ...ctx.core.elasticsearch.client.asInternalUser.nodes, + info: jest.fn().mockResolvedValue({ + body: { + nodes: { + node1: { version: CURRENT_VERSION.raw }, + node2: { version: CURRENT_VERSION.raw }, + }, + }, + }), }, - }), + }, + asCurrentUser: ctx.core.elasticsearch.client.asCurrentUser, }; await expect(esVersionCheck(ctx, kibanaResponseFactory)).resolves.toBe(undefined); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts index 2b49d4c286f610..be6c4f5ff02308 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts @@ -7,7 +7,7 @@ import { uniq } from 'lodash'; import { SemVer } from 'semver'; import { - ILegacyScopedClusterClient, + IScopedClusterClient, KibanaRequest, KibanaResponseFactory, RequestHandler, @@ -15,14 +15,22 @@ import { } from 'src/core/server'; import { CURRENT_VERSION } from '../../common/version'; +interface Nodes { + nodes: { + [nodeId: string]: { version: string }; + }; +} + /** * Returns an array of all the unique Elasticsearch Node Versions in the Elasticsearch cluster. */ -export const getAllNodeVersions = async (adminClient: ILegacyScopedClusterClient) => { +export const getAllNodeVersions = async (adminClient: IScopedClusterClient) => { // Get the version information for all nodes in the cluster. - const { nodes } = (await adminClient.callAsInternalUser('nodes.info', { - filterPath: 'nodes.*.version', - })) as { nodes: { [nodeId: string]: { version: string } } }; + const response = await adminClient.asInternalUser.nodes.info({ + filter_path: 'nodes.*.version', + }); + + const nodes = response.body.nodes; const versionStrings = Object.values(nodes).map(({ version }) => version); @@ -62,13 +70,13 @@ export const esVersionCheck = async ( ctx: RequestHandlerContext, response: KibanaResponseFactory ) => { - const { client } = ctx.core.elasticsearch.legacy; + const { client } = ctx.core.elasticsearch; let allNodeVersions: SemVer[]; try { allNodeVersions = await getAllNodeVersions(client); } catch (e) { - if (e.status === 403) { + if (e.statusCode === 403) { return response.forbidden({ body: e.message }); } diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts index 525c3781be7495..d059c03bcecb11 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts @@ -3,7 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectsErrorHelpers } from '../../../../../../src/core/server'; +import { RequestEvent } from '@elastic/elasticsearch/lib/Transport'; +import { SavedObjectsErrorHelpers } from 'src/core/server'; +import { elasticsearchServiceMock } from 'src/core/server/mocks'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { ScopedClusterClientMock } from 'src/core/server/elasticsearch/client/mocks'; import moment from 'moment'; import { @@ -18,7 +22,7 @@ import { LOCK_WINDOW, ReindexActions, reindexActionsFactory } from './reindex_ac describe('ReindexActions', () => { let client: jest.Mocked; - let callCluster: jest.Mock; + let clusterClient: ScopedClusterClientMock; let actions: ReindexActions; const unimplemented = (name: string) => () => @@ -38,8 +42,8 @@ describe('ReindexActions', () => { Promise.resolve({ id, attributes } as ReindexSavedObject) ) as any, }; - callCluster = jest.fn(); - actions = reindexActionsFactory(client, callCluster); + clusterClient = elasticsearchServiceMock.createScopedClusterClient(); + actions = reindexActionsFactory(client, clusterClient.asCurrentUser); }); describe('createReindexOp', () => { @@ -281,13 +285,20 @@ describe('ReindexActions', () => { }); describe('getFlatSettings', () => { + const asApiResponse = (body: T): RequestEvent => + ({ + body, + } as RequestEvent); + it('returns flat settings', async () => { - callCluster.mockResolvedValueOnce({ - myIndex: { - settings: { 'index.mySetting': '1' }, - mappings: {}, - }, - }); + clusterClient.asCurrentUser.indices.getSettings.mockResolvedValueOnce( + asApiResponse({ + myIndex: { + settings: { 'index.mySetting': '1' }, + mappings: {}, + }, + }) + ); await expect(actions.getFlatSettings('myIndex')).resolves.toEqual({ settings: { 'index.mySetting': '1' }, mappings: {}, @@ -295,7 +306,7 @@ describe('ReindexActions', () => { }); it('returns null if index does not exist', async () => { - callCluster.mockResolvedValueOnce({}); + clusterClient.asCurrentUser.indices.getSettings.mockResolvedValueOnce(asApiResponse({})); await expect(actions.getFlatSettings('myIndex')).resolves.toBeNull(); }); }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts index cae2519b38a5d2..4eed90eac0ae7f 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts @@ -9,7 +9,7 @@ import moment from 'moment'; import { SavedObjectsFindResponse, SavedObjectsClientContract, - LegacyAPICaller, + ElasticsearchClient, } from 'src/core/server'; import { IndexGroup, @@ -122,7 +122,7 @@ export interface ReindexActions { export const reindexActionsFactory = ( client: SavedObjectsClientContract, - callAsUser: LegacyAPICaller + esClient: ElasticsearchClient ): ReindexActions => { // ----- Internal functions const isLocked = (reindexOp: ReindexSavedObject) => { @@ -242,9 +242,13 @@ export const reindexActionsFactory = ( }, async getFlatSettings(indexName: string) { - const flatSettings = (await callAsUser('transport.request', { - path: `/${encodeURIComponent(indexName)}?flat_settings=true&include_type_name=false`, - })) as { [indexName: string]: FlatSettings }; + const { body: flatSettings } = await esClient.indices.getSettings<{ + [indexName: string]: FlatSettings; + }>({ + index: indexName, + flat_settings: true, + include_type_name: false, + }); if (!flatSettings[indexName]) { return null; @@ -254,9 +258,13 @@ export const reindexActionsFactory = ( }, async getFlatSettingsWithTypeName(indexName: string) { - const flatSettings = (await callAsUser('transport.request', { - path: `/${encodeURIComponent(indexName)}?flat_settings=true&include_type_name=true`, - })) as { [indexName: string]: FlatSettingsWithTypeName }; + const { body: flatSettings } = await esClient.indices.getSettings<{ + [indexName: string]: FlatSettings; + }>({ + index: indexName, + flat_settings: true, + include_type_name: true, + }); if (!flatSettings[indexName]) { return null; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts index a7f8b3e214f118..fc625535820c29 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts @@ -5,8 +5,11 @@ */ jest.mock('../es_indices_state_check', () => ({ esIndicesStateCheck: jest.fn() })); import { BehaviorSubject } from 'rxjs'; +import { RequestEvent } from '@elastic/elasticsearch/lib/Transport'; import { Logger } from 'src/core/server'; -import { loggingSystemMock } from 'src/core/server/mocks'; +import { elasticsearchServiceMock, loggingSystemMock } from 'src/core/server/mocks'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { ScopedClusterClientMock } from 'src/core/server/elasticsearch/client/mocks'; import { IndexGroup, @@ -31,9 +34,14 @@ import { reindexServiceFactory, } from './reindex_service'; +const asApiResponse = (body: T): RequestEvent => + ({ + body, + } as RequestEvent); + describe('reindexService', () => { let actions: jest.Mocked; - let callCluster: jest.Mock; + let clusterClient: ScopedClusterClientMock; let log: Logger; let service: ReindexService; let licensingPluginSetup: LicensingPluginSetup; @@ -63,7 +71,7 @@ describe('reindexService', () => { decrementIndexGroupReindexes: jest.fn(unimplemented('decrementIndexGroupReindexes')), runWhileIndexGroupLocked: jest.fn(async (group: string, f: any) => f({ attributes: {} })), }; - callCluster = jest.fn(); + clusterClient = elasticsearchServiceMock.createScopedClusterClient(); log = loggingSystemMock.create().get(); licensingPluginSetup = licensingMock.createSetup(); licensingPluginSetup.license$ = new BehaviorSubject( @@ -72,9 +80,13 @@ describe('reindexService', () => { }) ); - service = reindexServiceFactory(callCluster as any, actions, log, licensingPluginSetup, [ - 'apm-*', - ]); + service = reindexServiceFactory( + clusterClient.asCurrentUser, + actions, + log, + licensingPluginSetup, + [ 'apm-*'], + ); }); describe('hasRequiredPrivileges', () => { @@ -89,13 +101,13 @@ describe('reindexService', () => { }); it('calls security API with basic requirements', async () => { - callCluster.mockResolvedValueOnce({ has_all_requested: true }); + clusterClient.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce( + asApiResponse({ has_all_requested: true }) + ); const hasRequired = await service.hasRequiredPrivileges('anIndex'); expect(hasRequired).toBe(true); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_security/user/_has_privileges', - method: 'POST', + expect(clusterClient.asCurrentUser.security.hasPrivileges).toHaveBeenCalledWith({ body: { cluster: ['manage'], index: [ @@ -114,12 +126,12 @@ describe('reindexService', () => { }); it('includes manage_ml for ML indices', async () => { - callCluster.mockResolvedValueOnce({ has_all_requested: true }); + clusterClient.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce( + asApiResponse({ has_all_requested: true }) + ); await service.hasRequiredPrivileges('.ml-anomalies'); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_security/user/_has_privileges', - method: 'POST', + expect(clusterClient.asCurrentUser.security.hasPrivileges).toHaveBeenCalledWith({ body: { cluster: ['manage', 'manage_ml'], index: [ @@ -138,15 +150,15 @@ describe('reindexService', () => { }); it('includes checking for permissions on the baseName which could be an alias', async () => { - callCluster.mockResolvedValueOnce({ has_all_requested: true }); + clusterClient.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce( + asApiResponse({ has_all_requested: true }) + ); const hasRequired = await service.hasRequiredPrivileges( `reindexed-v${PREV_MAJOR_VERSION}-anIndex` ); expect(hasRequired).toBe(true); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_security/user/_has_privileges', - method: 'POST', + expect(clusterClient.asCurrentUser.security.hasPrivileges).toHaveBeenCalledWith({ body: { cluster: ['manage'], index: [ @@ -169,12 +181,14 @@ describe('reindexService', () => { }); it('includes manage_watcher for watcher indices', async () => { - callCluster.mockResolvedValueOnce({ has_all_requested: true }); + clusterClient.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce( + asApiResponse({ + has_all_requested: true, + }) + ); await service.hasRequiredPrivileges('.watches'); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_security/user/_has_privileges', - method: 'POST', + expect(clusterClient.asCurrentUser.security.hasPrivileges).toHaveBeenCalledWith({ body: { cluster: ['manage', 'manage_watcher'], index: [ @@ -218,7 +232,7 @@ describe('reindexService', () => { describe('createReindexOperation', () => { it('creates new reindex operation', async () => { - callCluster.mockResolvedValueOnce(true); // indices.exist + clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(true)); actions.findReindexOperations.mockResolvedValueOnce({ total: 0 }); actions.createReindexOp.mockResolvedValueOnce(); @@ -228,7 +242,7 @@ describe('reindexService', () => { }); it('fails if index does not exist', async () => { - callCluster.mockResolvedValueOnce(false); // indices.exist + clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(false)); await expect(service.createReindexOperation('myIndex')).rejects.toThrow(); expect(actions.createReindexOp).not.toHaveBeenCalled(); }); @@ -240,7 +254,7 @@ describe('reindexService', () => { }); it('deletes existing operation if it failed', async () => { - callCluster.mockResolvedValueOnce(true); // indices.exist + clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(true)); actions.findReindexOperations.mockResolvedValueOnce({ saved_objects: [{ id: 1, attributes: { status: ReindexStatus.failed } }], total: 1, @@ -256,7 +270,7 @@ describe('reindexService', () => { }); it('deletes existing operation if it was cancelled', async () => { - callCluster.mockResolvedValueOnce(true); // indices.exist + clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(true)); actions.findReindexOperations.mockResolvedValueOnce({ saved_objects: [{ id: 1, attributes: { status: ReindexStatus.cancelled } }], total: 1, @@ -272,7 +286,7 @@ describe('reindexService', () => { }); it('fails if existing operation did not fail', async () => { - callCluster.mockResolvedValueOnce(true); // indices.exist + clusterClient.asCurrentUser.indices.exists.mockResolvedValueOnce(asApiResponse(true)); actions.findReindexOperations.mockResolvedValueOnce({ saved_objects: [{ id: 1, attributes: { status: ReindexStatus.inProgress } }], total: 1, @@ -430,10 +444,11 @@ describe('reindexService', () => { reindexTaskId: '999333', }, } as any); - callCluster.mockResolvedValueOnce(true); + + clusterClient.asCurrentUser.tasks.cancel.mockResolvedValueOnce(asApiResponse(true)); await service.cancelReindexing('myIndex'); - expect(callCluster).toHaveBeenCalledWith('tasks.cancel', { taskId: '999333' }); + expect(clusterClient.asCurrentUser.tasks.cancel).toHaveBeenCalledWith({ task_id: '999333' }); findSpy.mockRestore(); }); @@ -445,7 +460,11 @@ describe('reindexService', () => { const findSpy = jest.spyOn(service, 'findReindexOperation').mockResolvedValueOnce(reindexOp); await expect(service.cancelReindexing('myIndex')).rejects.toThrow(); - expect(callCluster).not.toHaveBeenCalledWith('tasks.cancel', { taskId: '999333' }); + expect(clusterClient.asCurrentUser.tasks.cancel).not.toHaveBeenCalledWith( + asApiResponse({ + taskId: '999333', + }) + ); findSpy.mockRestore(); }); @@ -462,7 +481,11 @@ describe('reindexService', () => { const findSpy = jest.spyOn(service, 'findReindexOperation').mockResolvedValueOnce(reindexOp); await expect(service.cancelReindexing('myIndex')).rejects.toThrow(); - expect(callCluster).not.toHaveBeenCalledWith('tasks.cancel', { taskId: '999333' }); + expect(clusterClient.asCurrentUser.tasks.cancel).not.toHaveBeenCalledWith( + asApiResponse({ + taskId: '999333', + }) + ); findSpy.mockRestore(); }); @@ -537,7 +560,7 @@ describe('reindexService', () => { ); expect(actions.incrementIndexGroupReindexes).not.toHaveBeenCalled(); expect(actions.runWhileIndexGroupLocked).not.toHaveBeenCalled(); - expect(callCluster).not.toHaveBeenCalled(); + expect(clusterClient.asCurrentUser.nodes.info).not.toHaveBeenCalled(); }); it('supports an already migrated ML index', async () => { @@ -545,11 +568,12 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f() ); - callCluster - // Mock call to /_nodes for version check - .mockResolvedValueOnce({ nodes: { nodeX: { version: '6.7.0-alpha' } } }) - // Mock call to /_ml/set_upgrade_mode?enabled=true - .mockResolvedValueOnce({ acknowledged: true }); + clusterClient.asCurrentUser.nodes.info.mockResolvedValueOnce( + asApiResponse({ nodes: { nodeX: { version: '6.7.0-alpha' } } }) + ); + clusterClient.asCurrentUser.ml.setUpgradeMode.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const mlReindexedOp = { id: '2', @@ -565,9 +589,8 @@ describe('reindexService', () => { ); expect(actions.incrementIndexGroupReindexes).toHaveBeenCalled(); expect(actions.runWhileIndexGroupLocked).toHaveBeenCalled(); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=true', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).toHaveBeenCalledWith({ + enabled: true, }); }); @@ -576,11 +599,13 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f() ); - callCluster - // Mock call to /_nodes for version check - .mockResolvedValueOnce({ nodes: { nodeX: { version: '6.7.0-alpha' } } }) - // Mock call to /_ml/set_upgrade_mode?enabled=true - .mockResolvedValueOnce({ acknowledged: true }); + + clusterClient.asCurrentUser.nodes.info.mockResolvedValueOnce( + asApiResponse({ nodes: { nodeX: { version: '6.7.0-alpha' } } }) + ); + clusterClient.asCurrentUser.ml.setUpgradeMode.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(mlReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual( @@ -588,9 +613,8 @@ describe('reindexService', () => { ); expect(actions.incrementIndexGroupReindexes).toHaveBeenCalled(); expect(actions.runWhileIndexGroupLocked).toHaveBeenCalled(); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=true', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).toHaveBeenCalledWith({ + enabled: true, }); }); @@ -602,9 +626,8 @@ describe('reindexService', () => { expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=true', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).not.toHaveBeenCalledWith({ + enabled: true, }); }); @@ -617,9 +640,8 @@ describe('reindexService', () => { expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=true', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).not.toHaveBeenCalledWith({ + enabled: true, }); }); @@ -628,11 +650,12 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f() ); - callCluster - // Mock call to /_nodes for version check - .mockResolvedValueOnce({ nodes: { nodeX: { version: '6.7.0' } } }) - // Mock call to /_ml/set_upgrade_mode?enabled=true - .mockResolvedValueOnce({ acknowledged: false }); + clusterClient.asCurrentUser.nodes.info.mockResolvedValueOnce( + asApiResponse({ nodes: { nodeX: { version: '6.7.0' } } }) + ); + clusterClient.asCurrentUser.ml.setUpgradeMode.mockResolvedValueOnce( + asApiResponse({ acknowledged: false }) + ); const updatedOp = await service.processNextStep(mlReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.created); @@ -641,9 +664,8 @@ describe('reindexService', () => { updatedOp.attributes.errorMessage!.includes('Could not stop ML jobs') ).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=true', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).toHaveBeenCalledWith({ + enabled: true, }); }); @@ -652,9 +674,9 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f() ); - callCluster - // Mock call to /_nodes for version check - .mockResolvedValueOnce({ nodes: { nodeX: { version: '6.6.0' } } }); + clusterClient.asCurrentUser.nodes.info.mockResolvedValueOnce( + asApiResponse({ nodes: { nodeX: { version: '6.6.0' } } }) + ); const updatedOp = await service.processNextStep(mlReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.created); @@ -664,9 +686,8 @@ describe('reindexService', () => { ).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); // Should not have called ML endpoint at all - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=true', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).not.toHaveBeenCalledWith({ + enabled: true, }); }); }); @@ -684,7 +705,7 @@ describe('reindexService', () => { ); expect(actions.incrementIndexGroupReindexes).not.toHaveBeenCalled(); expect(actions.runWhileIndexGroupLocked).not.toHaveBeenCalled(); - expect(callCluster).not.toHaveBeenCalled(); + expect(clusterClient.asCurrentUser.watcher.stop).not.toHaveBeenCalled(); }); it('increments ML reindexes and calls watcher stop endpoint', async () => { @@ -692,9 +713,9 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (type: string, f: any) => f() ); - callCluster - // Mock call to /_watcher/_stop - .mockResolvedValueOnce({ acknowledged: true }); + clusterClient.asCurrentUser.watcher.stop.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(watcherReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual( @@ -702,10 +723,7 @@ describe('reindexService', () => { ); expect(actions.incrementIndexGroupReindexes).toHaveBeenCalledWith(IndexGroup.watcher); expect(actions.runWhileIndexGroupLocked).toHaveBeenCalled(); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_stop', - method: 'POST', - }); + expect(clusterClient.asCurrentUser.watcher.stop).toHaveBeenCalled(); }); it('fails if watcher reindexes cannot be incremented', async () => { @@ -716,9 +734,8 @@ describe('reindexService', () => { expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_stop', - method: 'POST', + expect(clusterClient.asCurrentUser.watcher.stop).not.toHaveBeenCalledWith({ + enabled: true, }); }); @@ -731,10 +748,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_stop', - method: 'POST', - }); + expect(clusterClient.asCurrentUser.watcher.stop).not.toHaveBeenCalled(); }); it('fails if watcher endpoint fails', async () => { @@ -742,9 +756,9 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (type: string, f: any) => f() ); - callCluster - // Mock call to /_watcher/_stop - .mockResolvedValueOnce({ acknowledged: false }); + clusterClient.asCurrentUser.watcher.stop.mockResolvedValueOnce( + asApiResponse({ acknowledged: false }) + ); const updatedOp = await service.processNextStep(watcherReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.created); @@ -753,10 +767,7 @@ describe('reindexService', () => { updatedOp.attributes.errorMessage!.includes('Could not stop Watcher') ).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_stop', - method: 'POST', - }); + expect(clusterClient.asCurrentUser.watcher.stop).toHaveBeenCalled(); }); }); }); @@ -771,17 +782,21 @@ describe('reindexService', () => { } as ReindexSavedObject; it('blocks writes and updates lastCompletedStep', async () => { - callCluster.mockResolvedValueOnce({ acknowledged: true }); + clusterClient.asCurrentUser.indices.putSettings.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.readonly); - expect(callCluster).toHaveBeenCalledWith('indices.putSettings', { + expect(clusterClient.asCurrentUser.indices.putSettings).toHaveBeenCalledWith({ index: 'myIndex', body: { 'index.blocks.write': true }, }); }); it('fails if setting updates are not acknowledged', async () => { - callCluster.mockResolvedValueOnce({ acknowledged: false }); + clusterClient.asCurrentUser.indices.putSettings.mockResolvedValueOnce( + asApiResponse({ acknowledged: false }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual( ReindexStep.indexGroupServicesStopped @@ -792,7 +807,7 @@ describe('reindexService', () => { }); it('fails if setting updates fail', async () => { - callCluster.mockRejectedValueOnce(new Error('blah!')); + clusterClient.asCurrentUser.indices.putSettings.mockRejectedValueOnce(new Error('blah!')); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual( ReindexStep.indexGroupServicesStopped @@ -812,11 +827,12 @@ describe('reindexService', () => { // The more intricate details of how the settings are chosen are test separately. it('creates new index with settings and mappings and updates lastCompletedStep', async () => { actions.getFlatSettings.mockResolvedValueOnce(settingsMappings); - callCluster.mockResolvedValueOnce({ acknowledged: true }); // indices.create - + clusterClient.asCurrentUser.indices.create.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.newIndexCreated); - expect(callCluster).toHaveBeenCalledWith('indices.create', { + expect(clusterClient.asCurrentUser.indices.create).toHaveBeenCalledWith({ index: 'myIndex-reindex-0', body: { // index.blocks.write should be removed from the settings for the new index. @@ -841,7 +857,10 @@ describe('reindexService', () => { }, }); - callCluster.mockResolvedValueOnce({ acknowledged: true }); // indices.create + clusterClient.asCurrentUser.indices.create.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); + await service.processNextStep({ id: '1', attributes: { @@ -852,7 +871,7 @@ describe('reindexService', () => { }, } as ReindexSavedObject); - expect(callCluster).toHaveBeenCalledWith('indices.create', { + expect(clusterClient.asCurrentUser.indices.create).toHaveBeenCalledWith({ index: newIndexName, body: { mappings: apmMappings, @@ -864,9 +883,13 @@ describe('reindexService', () => { }); it('fails if create index is not acknowledged', async () => { - callCluster - .mockResolvedValueOnce({ myIndex: settingsMappings }) - .mockResolvedValueOnce({ acknowledged: false }); + clusterClient.asCurrentUser.indices.getSettings.mockResolvedValueOnce( + asApiResponse({ myIndex: settingsMappings }) + ); + + clusterClient.asCurrentUser.indices.create.mockResolvedValueOnce( + asApiResponse({ acknowledged: false }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.readonly); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); @@ -875,10 +898,16 @@ describe('reindexService', () => { }); it('fails if create index fails', async () => { - callCluster - .mockResolvedValueOnce({ myIndex: settingsMappings }) - .mockRejectedValueOnce(new Error(`blah!`)) - .mockResolvedValueOnce({ acknowledged: true }); + clusterClient.asCurrentUser.indices.getSettings.mockResolvedValueOnce( + asApiResponse({ myIndex: settingsMappings }) + ); + + clusterClient.asCurrentUser.indices.create.mockRejectedValueOnce(new Error(`blah!`)); + + clusterClient.asCurrentUser.indices.putSettings.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); + const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.readonly); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); @@ -886,7 +915,7 @@ describe('reindexService', () => { expect(log.error).toHaveBeenCalledWith(expect.any(String)); // Original index should have been set back to allow reads. - expect(callCluster).toHaveBeenCalledWith('indices.putSettings', { + expect(clusterClient.asCurrentUser.indices.putSettings).toHaveBeenCalledWith({ index: 'myIndex', body: { 'index.blocks.write': false }, }); @@ -910,14 +939,14 @@ describe('reindexService', () => { }); it('starts reindex, saves taskId, and updates lastCompletedStep', async () => { - callCluster.mockResolvedValueOnce({ task: 'xyz' }); // reindex + clusterClient.asCurrentUser.reindex.mockResolvedValueOnce(asApiResponse({ task: 'xyz' })); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexStarted); expect(updatedOp.attributes.reindexTaskId).toEqual('xyz'); expect(updatedOp.attributes.reindexTaskPercComplete).toEqual(0); - expect(callCluster).toHaveBeenLastCalledWith('reindex', { + expect(clusterClient.asCurrentUser.reindex).toHaveBeenLastCalledWith({ refresh: true, - waitForCompletion: false, + wait_for_completion: false, body: { source: { index: 'myIndex' }, dest: { index: 'myIndex-reindex-0' }, @@ -929,7 +958,8 @@ describe('reindexService', () => { const indexName = 'apm-1'; const newIndexName = 'apm-1-reindexed'; - callCluster.mockResolvedValueOnce({ task: 'xyz' }); // reindex + clusterClient.asCurrentUser.reindex.mockResolvedValueOnce(asApiResponse({ task: 'xyz' })); + actions.getFlatSettings.mockResolvedValueOnce({ settings: {}, mappings: { @@ -948,7 +978,7 @@ describe('reindexService', () => { lastCompletedStep: ReindexStep.newIndexCreated, }, } as ReindexSavedObject); - expect(callCluster).toHaveBeenLastCalledWith('reindex', { + expect(clusterClient.asCurrentUser.reindex).toHaveBeenLastCalledWith({ refresh: true, waitForCompletion: false, body: { @@ -963,7 +993,7 @@ describe('reindexService', () => { }); it('fails if starting reindex fails', async () => { - callCluster.mockRejectedValueOnce(new Error('blah!')).mockResolvedValueOnce({}); + clusterClient.asCurrentUser.reindex.mockRejectedValueOnce(new Error('blah!')); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.newIndexCreated); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); @@ -984,10 +1014,13 @@ describe('reindexService', () => { describe('reindex task is not complete', () => { it('updates reindexTaskPercComplete', async () => { - callCluster.mockResolvedValueOnce({ - completed: false, - task: { status: { created: 10, total: 100 } }, - }); + clusterClient.asCurrentUser.tasks.get.mockResolvedValueOnce( + asApiResponse({ + completed: false, + task: { status: { created: 10, total: 100 } }, + }) + ); + const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexStarted); expect(updatedOp.attributes.reindexTaskPercComplete).toEqual(0.1); // 10 / 100 = 0.1 @@ -996,18 +1029,29 @@ describe('reindexService', () => { describe('reindex task is complete', () => { it('deletes task, updates reindexTaskPercComplete, updates lastCompletedStep', async () => { - callCluster - .mockResolvedValueOnce({ + clusterClient.asCurrentUser.tasks.get.mockResolvedValueOnce( + asApiResponse({ completed: true, task: { status: { created: 100, total: 100 } }, }) - .mockResolvedValueOnce({ count: 100 }) - .mockResolvedValueOnce({ result: 'deleted' }); + ); + + clusterClient.asCurrentUser.count.mockResolvedValueOnce( + asApiResponse({ + count: 100, + }) + ); + + clusterClient.asCurrentUser.delete.mockResolvedValueOnce( + asApiResponse({ + result: 'deleted', + }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexCompleted); expect(updatedOp.attributes.reindexTaskPercComplete).toEqual(1); - expect(callCluster).toHaveBeenCalledWith('delete', { + expect(clusterClient.asCurrentUser.delete).toHaveBeenCalledWith({ index: '.tasks', type: 'task', id: 'xyz', @@ -1015,12 +1059,18 @@ describe('reindexService', () => { }); it('fails if docs created is less than count in source index', async () => { - callCluster - .mockResolvedValueOnce({ + clusterClient.asCurrentUser.tasks.get.mockResolvedValueOnce( + asApiResponse({ completed: true, task: { status: { created: 95, total: 95 } }, }) - .mockReturnValueOnce({ count: 100 }); + ); + + clusterClient.asCurrentUser.count.mockResolvedValueOnce( + asApiResponse({ + count: 100, + }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexStarted); @@ -1031,18 +1081,22 @@ describe('reindexService', () => { }); describe('reindex task is cancelled', () => { - it('deletes tsk, updates status to cancelled', async () => { - callCluster - .mockResolvedValueOnce({ + it('deletes task, updates status to cancelled', async () => { + clusterClient.asCurrentUser.tasks.get.mockResolvedValueOnce( + asApiResponse({ completed: true, task: { status: { created: 100, total: 100, canceled: 'by user request' } }, }) - .mockResolvedValue({ result: 'deleted' }); + ); + + clusterClient.asCurrentUser.delete.mockResolvedValue( + asApiResponse({ result: 'deleted' }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexStarted); expect(updatedOp.attributes.status).toEqual(ReindexStatus.cancelled); - expect(callCluster).toHaveBeenCalledWith('delete', { + expect(clusterClient.asCurrentUser.delete).toHaveBeenLastCalledWith({ index: '.tasks', type: 'task', id: 'xyz', @@ -1062,12 +1116,16 @@ describe('reindexService', () => { } as ReindexSavedObject; it('switches aliases, sets as complete, and updates lastCompletedStep', async () => { - callCluster - .mockResolvedValueOnce({ myIndex: { aliases: {} } }) - .mockResolvedValueOnce({ acknowledged: true }); + clusterClient.asCurrentUser.indices.getAlias.mockResolvedValue( + asApiResponse({ myIndex: { aliases: {} } }) + ); + + clusterClient.asCurrentUser.indices.updateAliases.mockResolvedValue( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); - expect(callCluster).toHaveBeenCalledWith('indices.updateAliases', { + expect(clusterClient.asCurrentUser.indices.updateAliases).toHaveBeenCalledWith({ body: { actions: [ { add: { index: 'myIndex-reindex-0', alias: 'myIndex' } }, @@ -1078,8 +1136,8 @@ describe('reindexService', () => { }); it('moves existing aliases over to new index', async () => { - callCluster - .mockResolvedValueOnce({ + clusterClient.asCurrentUser.indices.getAlias.mockResolvedValue( + asApiResponse({ myIndex: { aliases: { myAlias: {}, @@ -1087,10 +1145,15 @@ describe('reindexService', () => { }, }, }) - .mockResolvedValueOnce({ acknowledged: true }); + ); + + clusterClient.asCurrentUser.indices.updateAliases.mockResolvedValue( + asApiResponse({ acknowledged: true }) + ); + const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); - expect(callCluster).toHaveBeenCalledWith('indices.updateAliases', { + expect(clusterClient.asCurrentUser.indices.updateAliases).toHaveBeenCalledWith({ body: { actions: [ { add: { index: 'myIndex-reindex-0', alias: 'myIndex' } }, @@ -1109,7 +1172,9 @@ describe('reindexService', () => { }); it('fails if switching aliases is not acknowledged', async () => { - callCluster.mockResolvedValueOnce({ acknowledged: false }); + clusterClient.asCurrentUser.indices.updateAliases.mockResolvedValue( + asApiResponse({ acknowledged: false }) + ); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexCompleted); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); @@ -1118,7 +1183,7 @@ describe('reindexService', () => { }); it('fails if switching aliases fails', async () => { - callCluster.mockRejectedValueOnce(new Error('blah!')); + clusterClient.asCurrentUser.indices.updateAliases.mockRejectedValueOnce(new Error('blah!')); const updatedOp = await service.processNextStep(reindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexCompleted); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); @@ -1144,7 +1209,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual( ReindexStep.indexGroupServicesStarted ); - expect(callCluster).not.toHaveBeenCalled(); + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).not.toHaveBeenCalled(); }); it('decrements ML reindexes and calls ML start endpoint if no remaining ML jobs', async () => { @@ -1152,17 +1217,17 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f({ attributes: { runningReindexCount: 0 } }) ); - // Mock call to /_ml/set_upgrade_mode?enabled=false - callCluster.mockResolvedValueOnce({ acknowledged: true }); + clusterClient.asCurrentUser.ml.setUpgradeMode.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(mlReindexOp); expect(actions.decrementIndexGroupReindexes).toHaveBeenCalledWith(IndexGroup.ml); expect(updatedOp.attributes.lastCompletedStep).toEqual( ReindexStep.indexGroupServicesStarted ); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=false', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).toHaveBeenCalledWith({ + enabled: false, }); }); @@ -1171,16 +1236,16 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f({ attributes: { runningReindexCount: 2 } }) ); - // Mock call to /_ml/set_upgrade_mode?enabled=false - callCluster.mockResolvedValueOnce({ acknowledged: true }); + clusterClient.asCurrentUser.ml.setUpgradeMode.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(mlReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual( ReindexStep.indexGroupServicesStarted ); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=false', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).not.toHaveBeenCalledWith({ + enabled: false, }); }); @@ -1193,9 +1258,8 @@ describe('reindexService', () => { expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=false', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).not.toHaveBeenCalledWith({ + enabled: false, }); }); @@ -1209,9 +1273,8 @@ describe('reindexService', () => { expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=false', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).not.toHaveBeenCalledWith({ + enabled: false, }); }); @@ -1220,9 +1283,9 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f({ attributes: { runningReindexCount: 0 } }) ); - // Mock call to /_ml/set_upgrade_mode?enabled=true - callCluster.mockResolvedValueOnce({ acknowledged: false }); - + clusterClient.asCurrentUser.ml.setUpgradeMode.mockResolvedValueOnce( + asApiResponse({ acknowledged: false }) + ); const updatedOp = await service.processNextStep(mlReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); @@ -1230,9 +1293,8 @@ describe('reindexService', () => { updatedOp.attributes.errorMessage!.includes('Could not resume ML jobs') ).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=false', - method: 'POST', + expect(clusterClient.asCurrentUser.ml.setUpgradeMode).toHaveBeenCalledWith({ + enabled: false, }); }); }); @@ -1248,7 +1310,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual( ReindexStep.indexGroupServicesStarted ); - expect(callCluster).not.toHaveBeenCalled(); + expect(clusterClient.asCurrentUser.watcher.start).not.toHaveBeenCalled(); }); it('decrements watcher reindexes and calls wathcer start endpoint if no remaining watcher reindexes', async () => { @@ -1256,36 +1318,31 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f({ attributes: { runningReindexCount: 0 } }) ); - // Mock call to /_watcher/_start - callCluster.mockResolvedValueOnce({ acknowledged: true }); + clusterClient.asCurrentUser.watcher.start.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(watcherReindexOp); expect(actions.decrementIndexGroupReindexes).toHaveBeenCalledWith(IndexGroup.watcher); expect(updatedOp.attributes.lastCompletedStep).toEqual( ReindexStep.indexGroupServicesStarted ); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_start', - method: 'POST', - }); + expect(clusterClient.asCurrentUser.watcher.start).toHaveBeenCalled(); }); - it('does not call wathcer start endpoint if there are remaining wathcer reindexes', async () => { + it('does not call watcher start endpoint if there are remaining watcher reindexes', async () => { actions.decrementIndexGroupReindexes.mockResolvedValue(); actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f({ attributes: { runningReindexCount: 2 } }) ); - // Mock call to /_watcher/_start - callCluster.mockResolvedValueOnce({ acknowledged: true }); - + clusterClient.asCurrentUser.watcher.start.mockResolvedValueOnce( + asApiResponse({ acknowledged: true }) + ); const updatedOp = await service.processNextStep(watcherReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual( ReindexStep.indexGroupServicesStarted ); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_start', - method: 'POST', - }); + expect(clusterClient.asCurrentUser.watcher.start).not.toHaveBeenCalledWith(); }); it('fails if watcher reindexes cannot be decremented', async () => { @@ -1297,10 +1354,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_start', - method: 'POST', - }); + expect(clusterClient.asCurrentUser.watcher.start).not.toHaveBeenCalledWith(); }); it('fails if watcher doc cannot be locked', async () => { @@ -1313,10 +1367,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).not.toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_start', - method: 'POST', - }); + expect(clusterClient.asCurrentUser.watcher.start).not.toHaveBeenCalledWith(); }); it('fails if watcher endpoint fails', async () => { @@ -1324,9 +1375,10 @@ describe('reindexService', () => { actions.runWhileIndexGroupLocked.mockImplementationOnce(async (group: string, f: any) => f({ attributes: { runningReindexCount: 0 } }) ); - // Mock call to /_watcher/_start - callCluster.mockResolvedValueOnce({ acknowledged: false }); + clusterClient.asCurrentUser.watcher.start.mockResolvedValueOnce( + asApiResponse({ acknowledged: false }) + ); const updatedOp = await service.processNextStep(watcherReindexOp); expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); @@ -1334,10 +1386,7 @@ describe('reindexService', () => { updatedOp.attributes.errorMessage!.includes('Could not start Watcher') ).toBeTruthy(); expect(log.error).toHaveBeenCalledWith(expect.any(String)); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_watcher/_start', - method: 'POST', - }); + expect(clusterClient.asCurrentUser.watcher.start).toHaveBeenCalled(); }); }); }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts index c3bdbc0acb5705..19220856e74dc6 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { LegacyAPICaller, Logger } from 'src/core/server'; +import { ElasticsearchClient, Logger } from 'src/core/server'; import { first } from 'rxjs/operators'; import { LicensingPluginSetup } from '../../../../licensing/server'; @@ -130,7 +130,7 @@ export interface ReindexService { } export const reindexServiceFactory = ( - callAsUser: LegacyAPICaller, + esClient: ElasticsearchClient, actions: ReindexActions, log: Logger, licensing: LicensingPluginSetup, @@ -148,12 +148,11 @@ export const reindexServiceFactory = ( await actions.runWhileIndexGroupLocked(IndexGroup.ml, async (mlDoc) => { await validateNodesMinimumVersion(6, 7); - const res = await callAsUser('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=true', - method: 'POST', + const { body } = await esClient.ml.setUpgradeMode({ + enabled: true, }); - if (!res.acknowledged) { + if (!body.acknowledged) { throw new Error(`Could not stop ML jobs`); } @@ -168,12 +167,11 @@ export const reindexServiceFactory = ( await actions.decrementIndexGroupReindexes(IndexGroup.ml); await actions.runWhileIndexGroupLocked(IndexGroup.ml, async (mlDoc) => { if (mlDoc.attributes.runningReindexCount === 0) { - const res = await callAsUser('transport.request', { - path: '/_ml/set_upgrade_mode?enabled=false', - method: 'POST', + const { body } = await esClient.ml.setUpgradeMode({ + enabled: false, }); - if (!res.acknowledged) { + if (!body.acknowledged) { throw new Error(`Could not resume ML jobs`); } } @@ -188,12 +186,9 @@ export const reindexServiceFactory = ( const stopWatcher = async () => { await actions.incrementIndexGroupReindexes(IndexGroup.watcher); await actions.runWhileIndexGroupLocked(IndexGroup.watcher, async (watcherDoc) => { - const { acknowledged } = await callAsUser('transport.request', { - path: '/_watcher/_stop', - method: 'POST', - }); + const { body } = await esClient.watcher.stop(); - if (!acknowledged) { + if (!body.acknowledged) { throw new Error('Could not stop Watcher'); } @@ -208,12 +203,9 @@ export const reindexServiceFactory = ( await actions.decrementIndexGroupReindexes(IndexGroup.watcher); await actions.runWhileIndexGroupLocked(IndexGroup.watcher, async (watcherDoc) => { if (watcherDoc.attributes.runningReindexCount === 0) { - const { acknowledged } = await callAsUser('transport.request', { - path: '/_watcher/_start', - method: 'POST', - }); + const { body } = await esClient.watcher.start(); - if (!acknowledged) { + if (!body.acknowledged) { throw new Error('Could not start Watcher'); } } @@ -225,14 +217,16 @@ export const reindexServiceFactory = ( const cleanupChanges = async (reindexOp: ReindexSavedObject) => { // Cancel reindex task if it was started but not completed if (reindexOp.attributes.lastCompletedStep === ReindexStep.reindexStarted) { - await callAsUser('tasks.cancel', { - taskId: reindexOp.attributes.reindexTaskId, - }).catch((e) => undefined); // Ignore any exceptions trying to cancel (it may have already completed). + await esClient.tasks + .cancel({ + task_id: reindexOp.attributes.reindexTaskId ?? undefined, + }) + .catch(() => undefined); // Ignore any exceptions trying to cancel (it may have already completed). } // Set index back to writable if we ever got past this point. if (reindexOp.attributes.lastCompletedStep >= ReindexStep.readonly) { - await callAsUser('indices.putSettings', { + await esClient.indices.putSettings({ index: reindexOp.attributes.indexName, body: { 'index.blocks.write': false }, }); @@ -242,7 +236,9 @@ export const reindexServiceFactory = ( reindexOp.attributes.lastCompletedStep >= ReindexStep.newIndexCreated && reindexOp.attributes.lastCompletedStep < ReindexStep.aliasCreated ) { - await callAsUser('indices.delete', { index: reindexOp.attributes.newIndexName }); + await esClient.indices.delete({ + index: reindexOp.attributes.newIndexName, + }); } // Resume consumers if we ever got past this point. @@ -256,10 +252,7 @@ export const reindexServiceFactory = ( // ------ Functions used to process the state machine const validateNodesMinimumVersion = async (minMajor: number, minMinor: number) => { - const nodesResponse = await callAsUser('transport.request', { - path: '/_nodes', - method: 'GET', - }); + const { body: nodesResponse } = await esClient.nodes.info(); const outDatedNodes = Object.values(nodesResponse.nodes).filter((node: any) => { const matches = node.version.match(VERSION_REGEX); @@ -297,7 +290,7 @@ export const reindexServiceFactory = ( */ const setReadonly = async (reindexOp: ReindexSavedObject) => { const { indexName } = reindexOp.attributes; - const putReadonly = await callAsUser('indices.putSettings', { + const { body: putReadonly } = await esClient.indices.putSettings({ index: indexName, body: { 'index.blocks.write': true }, }); @@ -324,7 +317,7 @@ export const reindexServiceFactory = ( const { settings, mappings } = transformFlatSettings(flatSettings); const legacyApmIndex = isLegacyApmIndex(indexName, apmIndexPatterns, flatSettings.mappings); - const createIndex = await callAsUser('indices.create', { + const { body: createIndex } = await esClient.indices.create({ index: newIndexName, body: { settings, @@ -350,11 +343,11 @@ export const reindexServiceFactory = ( // Where possible, derive reindex options at the last moment before reindexing // to prevent them from becoming stale as they wait in the queue. - const indicesState = await esIndicesStateCheck(callAsUser, [indexName]); + const indicesState = await esIndicesStateCheck(esClient, [indexName]); const shouldOpenAndClose = indicesState[indexName] === 'closed'; if (shouldOpenAndClose) { log.debug(`Detected closed index ${indexName}, opening...`); - await callAsUser('indices.open', { index: indexName }); + await esClient.indices.open({ index: indexName }); } const reindexBody = { @@ -374,15 +367,16 @@ export const reindexServiceFactory = ( source: apmReindexScript, }; } - const startReindex = (await callAsUser('reindex', { + + const { body: startReindexResponse } = await esClient.reindex({ refresh: true, - waitForCompletion: false, + wait_for_completion: false, body: reindexBody, - })) as any; + }); return actions.updateReindexOp(reindexOp, { lastCompletedStep: ReindexStep.reindexStarted, - reindexTaskId: startReindex.task, + reindexTaskId: startReindexResponse.task, reindexTaskPercComplete: 0, reindexOptions: { ...(reindexOptions ?? {}), @@ -398,12 +392,12 @@ export const reindexServiceFactory = ( * @param reindexOp */ const updateReindexStatus = async (reindexOp: ReindexSavedObject) => { - const taskId = reindexOp.attributes.reindexTaskId; + const taskId = reindexOp.attributes.reindexTaskId!; // Check reindexing task progress - const taskResponse = await callAsUser('tasks.get', { - taskId, - waitForCompletion: false, + const { body: taskResponse } = await esClient.tasks.get({ + task_id: taskId, + wait_for_completion: false, }); if (!taskResponse.completed) { @@ -422,7 +416,7 @@ export const reindexServiceFactory = ( reindexOp = await cleanupChanges(reindexOp); } else { // Check that it reindexed all documents - const { count } = await callAsUser('count', { index: reindexOp.attributes.indexName }); + const { body: count } = await esClient.count({ index: reindexOp.attributes.indexName }); if (taskResponse.task.status.created < count) { // Include the entire task result in the error message. This should be guaranteed @@ -438,7 +432,7 @@ export const reindexServiceFactory = ( } // Delete the task from ES .tasks index - const deleteTaskResp = await callAsUser('delete', { + const { body: deleteTaskResp } = await esClient.delete({ index: '.tasks', type: 'task', id: taskId, @@ -458,22 +452,22 @@ export const reindexServiceFactory = ( const switchAlias = async (reindexOp: ReindexSavedObject) => { const { indexName, newIndexName, reindexOptions } = reindexOp.attributes; - const existingAliases = ( - await callAsUser('indices.getAlias', { - index: indexName, - }) - )[indexName].aliases; + const { body: response } = await esClient.indices.getAlias({ + index: indexName, + }); + + const existingAliases = response[indexName].aliases; - const extraAlises = Object.keys(existingAliases).map((aliasName) => ({ + const extraAliases = Object.keys(existingAliases).map((aliasName) => ({ add: { index: newIndexName, alias: aliasName, ...existingAliases[aliasName] }, })); - const aliasResponse = await callAsUser('indices.updateAliases', { + const { body: aliasResponse } = await esClient.indices.updateAliases({ body: { actions: [ { add: { index: newIndexName, alias: indexName } }, { remove_index: { index: indexName } }, - ...extraAlises, + ...extraAliases, ], }, }); @@ -483,7 +477,7 @@ export const reindexServiceFactory = ( } if (reindexOptions?.openAndClose === true) { - await callAsUser('indices.close', { index: indexName }); + await esClient.indices.close({ index: indexName }); } return actions.updateReindexOp(reindexOp, { @@ -560,9 +554,7 @@ export const reindexServiceFactory = ( body.cluster = [...body.cluster, 'manage_watcher']; } - const resp = await callAsUser('transport.request', { - path: '/_security/user/_has_privileges', - method: 'POST', + const { body: resp } = await esClient.security.hasPrivileges({ body, }); @@ -593,7 +585,7 @@ export const reindexServiceFactory = ( ); } - const indexExists = await callAsUser('indices.exists', { index: indexName }); + const { body: indexExists } = await esClient.indices.exists({ index: indexName }); if (!indexExists) { throw error.indexNotFound(`Index ${indexName} does not exist in this cluster.`); } @@ -778,8 +770,8 @@ export const reindexServiceFactory = ( ); } - const resp = await callAsUser('tasks.cancel', { - taskId: reindexOp.attributes.reindexTaskId, + const { body: resp } = await esClient.tasks.cancel({ + task_id: reindexOp.attributes.reindexTaskId!, }); if (resp.node_failures && resp.node_failures.length > 0) { diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts index 45177d2fa2dc75..ab354fe67accfb 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts @@ -3,12 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { - ILegacyClusterClient, - Logger, - SavedObjectsClientContract, - FakeRequest, -} from 'src/core/server'; +import { IClusterClient, Logger, SavedObjectsClientContract, FakeRequest } from 'src/core/server'; import moment from 'moment'; import { ReindexSavedObject, ReindexStatus } from '../../../common/types'; import { Credential, CredentialStore } from './credential_store'; @@ -53,7 +48,7 @@ export class ReindexWorker { constructor( private client: SavedObjectsClientContract, private credentialStore: CredentialStore, - private clusterClient: ILegacyClusterClient, + private clusterClient: IClusterClient, log: Logger, private licensing: LicensingPluginSetup, private apmIndexPatterns: string[] @@ -63,7 +58,7 @@ export class ReindexWorker { throw new Error(`More than one ReindexWorker cannot be created.`); } - const callAsInternalUser = this.clusterClient.callAsInternalUser.bind(this.clusterClient); + const callAsInternalUser = this.clusterClient.asInternalUser; this.reindexService = reindexServiceFactory( callAsInternalUser, @@ -153,7 +148,7 @@ export class ReindexWorker { private getCredentialScopedReindexService = (credential: Credential) => { const fakeRequest: FakeRequest = { headers: credential }; const scopedClusterClient = this.clusterClient.asScoped(fakeRequest); - const callAsCurrentUser = scopedClusterClient.callAsCurrentUser.bind(scopedClusterClient); + const callAsCurrentUser = scopedClusterClient.asCurrentUser; const actions = reindexActionsFactory(this.client, callAsCurrentUser); return reindexServiceFactory( callAsCurrentUser, diff --git a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts index e14056439ca6b2..9b5223d07bfbfe 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts @@ -5,7 +5,7 @@ */ import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { registerUpgradeAssistantUsageCollector } from './usage_collector'; -import { ILegacyClusterClient } from 'src/core/server'; +import { IClusterClient } from 'src/core/server'; /** * Since these route callbacks are so thin, these serve simply as integration tests @@ -18,15 +18,17 @@ describe('Upgrade Assistant Usage Collector', () => { let dependencies: any; let callClusterStub: any; let usageCollection: any; - let clusterClient: ILegacyClusterClient; + let clusterClient: IClusterClient; beforeEach(() => { - clusterClient = elasticsearchServiceMock.createLegacyClusterClient(); - (clusterClient.callAsInternalUser as jest.Mock).mockResolvedValue({ - persistent: {}, - transient: { - logger: { - deprecation: 'WARN', + clusterClient = elasticsearchServiceMock.createClusterClient(); + (clusterClient.asInternalUser.cluster.getSettings as jest.Mock).mockResolvedValue({ + body: { + persistent: {}, + transient: { + logger: { + deprecation: 'WARN', + }, }, }, }); @@ -59,7 +61,7 @@ describe('Upgrade Assistant Usage Collector', () => { }), }, elasticsearch: { - legacy: { client: clusterClient }, + client: clusterClient, }, }; }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts index 276e639678fd8e..1eafefb4238c20 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts @@ -6,7 +6,7 @@ import { get } from 'lodash'; import { - LegacyAPICaller, + ElasticsearchClient, ElasticsearchServiceStart, ISavedObjectsRepository, SavedObjectsServiceStart, @@ -38,12 +38,10 @@ async function getSavedObjectAttributesFromRepo( } } -async function getDeprecationLoggingStatusValue( - callAsCurrentUser: LegacyAPICaller -): Promise { +async function getDeprecationLoggingStatusValue(esClient: ElasticsearchClient): Promise { try { - const loggerDeprecationCallResult = await callAsCurrentUser('cluster.getSettings', { - includeDefaults: true, + const { body: loggerDeprecationCallResult } = await esClient.cluster.getSettings({ + include_defaults: true, }); return isDeprecationLoggingEnabled(loggerDeprecationCallResult); @@ -53,7 +51,7 @@ async function getDeprecationLoggingStatusValue( } export async function fetchUpgradeAssistantMetrics( - { legacy: { client: esClient } }: ElasticsearchServiceStart, + { client: esClient }: ElasticsearchServiceStart, savedObjects: SavedObjectsServiceStart ): Promise { const savedObjectsRepository = savedObjects.createInternalRepository(); @@ -62,8 +60,9 @@ export async function fetchUpgradeAssistantMetrics( UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID ); - const callAsInternalUser = esClient.callAsInternalUser.bind(esClient); - const deprecationLoggingStatusValue = await getDeprecationLoggingStatusValue(callAsInternalUser); + const deprecationLoggingStatusValue = await getDeprecationLoggingStatusValue( + esClient.asInternalUser + ); const getTelemetrySavedObject = ( upgradeAssistantTelemetrySavedObjectAttrs: UpgradeAssistantTelemetrySavedObjectAttributes | null diff --git a/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts index 2df770c3ce45c0..43fe8af18c392a 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts @@ -12,9 +12,7 @@ import { export const routeHandlerContextMock = ({ core: { elasticsearch: { - legacy: { - client: elasticsearchServiceMock.createLegacyScopedClusterClient(), - }, + client: elasticsearchServiceMock.createScopedClusterClient(), }, savedObjects: { client: savedObjectsClientMock.create() }, }, diff --git a/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.test.ts index 346f0fd64dbbed..16c9df46a54519 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.test.ts @@ -100,7 +100,7 @@ describe('cluster checkup API', () => { it('returns an 403 error if it throws forbidden', async () => { const e: any = new Error(`you can't go here!`); - e.status = 403; + e.statusCode = 403; MigrationApis.getUpgradeAssistantStatus.mockRejectedValue(e); const resp = await routeDependencies.router.getHandler({ diff --git a/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.ts b/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.ts index df962aeded7e4a..977e5ae7d75ece 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.ts @@ -30,9 +30,7 @@ export function registerClusterCheckupRoutes({ { core: { savedObjects: { client: savedObjectsClient }, - elasticsearch: { - legacy: { client }, - }, + elasticsearch: { client }, }, }, request, @@ -44,10 +42,10 @@ export function registerClusterCheckupRoutes({ const status = await getUpgradeAssistantStatus(client, isCloudEnabled, indexPatterns); - const callAsCurrentUser = client.callAsCurrentUser.bind(client); - const reindexActions = reindexActionsFactory(savedObjectsClient, callAsCurrentUser); + const asCurrentUser = client.asCurrentUser; + const reindexActions = reindexActionsFactory(savedObjectsClient, asCurrentUser); const reindexService = reindexServiceFactory( - callAsCurrentUser, + asCurrentUser, reindexActions, log, licensing @@ -62,7 +60,7 @@ export function registerClusterCheckupRoutes({ body: status, }); } catch (e) { - if (e.status === 403) { + if (e.statusCode === 403) { return response.forbidden(e.message); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts index b8021eeef75e60..f76a86704e2c4e 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts @@ -37,9 +37,9 @@ describe('deprecation logging API', () => { describe('GET /api/upgrade_assistant/deprecation_logging', () => { it('returns isEnabled', async () => { - (routeHandlerContextMock.core.elasticsearch.legacy.client - .callAsCurrentUser as jest.Mock).mockResolvedValue({ - default: { logger: { deprecation: 'WARN' } }, + (routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.cluster + .getSettings as jest.Mock).mockResolvedValue({ + body: { default: { logger: { deprecation: 'WARN' } } }, }); const resp = await routeDependencies.router.getHandler({ method: 'get', @@ -51,8 +51,8 @@ describe('deprecation logging API', () => { }); it('returns an error if it throws', async () => { - (routeHandlerContextMock.core.elasticsearch.legacy.client - .callAsCurrentUser as jest.Mock).mockRejectedValue(new Error(`scary error!`)); + (routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.cluster + .getSettings as jest.Mock).mockRejectedValue(new Error(`scary error!`)); const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/deprecation_logging', @@ -64,21 +64,21 @@ describe('deprecation logging API', () => { describe('PUT /api/upgrade_assistant/deprecation_logging', () => { it('returns isEnabled', async () => { - (routeHandlerContextMock.core.elasticsearch.legacy.client - .callAsCurrentUser as jest.Mock).mockResolvedValue({ - default: { logger: { deprecation: 'ERROR' } }, + (routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.cluster + .putSettings as jest.Mock).mockResolvedValue({ + body: { default: { logger: { deprecation: 'ERROR' } } }, }); const resp = await routeDependencies.router.getHandler({ - method: 'get', + method: 'put', pathPattern: '/api/upgrade_assistant/deprecation_logging', - })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); + })(routeHandlerContextMock, { body: { isEnabled: true } }, kibanaResponseFactory); expect(resp.payload).toEqual({ isEnabled: false }); }); it('returns an error if it throws', async () => { - (routeHandlerContextMock.core.elasticsearch.legacy.client - .callAsCurrentUser as jest.Mock).mockRejectedValue(new Error(`scary error!`)); + (routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.cluster + .putSettings as jest.Mock).mockRejectedValue(new Error(`scary error!`)); const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/deprecation_logging', diff --git a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts index 38f244a4e11547..4bdb1364b071a6 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts @@ -23,9 +23,7 @@ export function registerDeprecationLoggingRoutes({ router }: RouteDependencies) async ( { core: { - elasticsearch: { - legacy: { client }, - }, + elasticsearch: { client }, }, }, request, @@ -54,9 +52,7 @@ export function registerDeprecationLoggingRoutes({ router }: RouteDependencies) async ( { core: { - elasticsearch: { - legacy: { client }, - }, + elasticsearch: { client }, }, }, request, diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_handler.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_handler.ts index fffde339c59e57..e33398fdcc93bb 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_handler.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_handler.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { i18n } from '@kbn/i18n'; -import { ILegacyScopedClusterClient, Logger, SavedObjectsClientContract } from 'kibana/server'; +import { IScopedClusterClient, Logger, SavedObjectsClientContract } from 'kibana/server'; import { LicensingPluginSetup } from '../../../../licensing/server'; @@ -17,7 +17,7 @@ import { error } from '../../lib/reindexing/error'; interface ReindexHandlerArgs { savedObjects: SavedObjectsClientContract; - dataClient: ILegacyScopedClusterClient; + dataClient: IScopedClusterClient; indexName: string; log: Logger; licensing: LicensingPluginSetup; @@ -38,7 +38,7 @@ export const reindexHandler = async ({ savedObjects, reindexOptions, }: ReindexHandlerArgs): Promise => { - const callAsCurrentUser = dataClient.callAsCurrentUser.bind(dataClient); + const callAsCurrentUser = dataClient.asCurrentUser; const reindexActions = reindexActionsFactory(savedObjects, callAsCurrentUser); const reindexService = reindexServiceFactory(callAsCurrentUser, reindexActions, log, licensing); diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts index fb72520900e2e2..7c618cd2d81661 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts @@ -54,15 +54,8 @@ export function createReindexWorker({ licensing, apmIndexPatterns, }: CreateReindexWorker) { - const esClient = elasticsearchService.legacy.client; - return new ReindexWorker( - savedObjects, - credentialStore, - esClient, - logger, - licensing, - apmIndexPatterns - ); + const esClient = elasticsearchService.client; + return new ReindexWorker(savedObjects, credentialStore, esClient, logger, licensing, apmIndexPatterns); } const mapAnyErrorToKibanaHttpResponse = (e: any) => { @@ -113,9 +106,7 @@ export function registerReindexIndicesRoutes( { core: { savedObjects: { client: savedObjectsClient }, - elasticsearch: { - legacy: { client: esClient }, - }, + elasticsearch: { client: esClient }, }, }, request, @@ -155,9 +146,7 @@ export function registerReindexIndicesRoutes( async ( { core: { - elasticsearch: { - legacy: { client: esClient }, - }, + elasticsearch: { client: esClient }, savedObjects, }, }, @@ -165,7 +154,7 @@ export function registerReindexIndicesRoutes( response ) => { const { client } = savedObjects; - const callAsCurrentUser = esClient.callAsCurrentUser.bind(esClient); + const callAsCurrentUser = esClient.asCurrentUser; const reindexActions = reindexActionsFactory(client, callAsCurrentUser); try { const inProgressOps = await reindexActions.findAllByStatus(ReindexStatus.inProgress); @@ -197,9 +186,7 @@ export function registerReindexIndicesRoutes( { core: { savedObjects: { client: savedObjectsClient }, - elasticsearch: { - legacy: { client: esClient }, - }, + elasticsearch: { client: esClient }, }, }, request, @@ -258,9 +245,7 @@ export function registerReindexIndicesRoutes( { core: { savedObjects, - elasticsearch: { - legacy: { client: esClient }, - }, + elasticsearch: { client: esClient }, }, }, request, @@ -268,14 +253,9 @@ export function registerReindexIndicesRoutes( ) => { const { client } = savedObjects; const { indexName } = request.params; - const callAsCurrentUser = esClient.callAsCurrentUser.bind(esClient); - const reindexActions = reindexActionsFactory(client, callAsCurrentUser); - const reindexService = reindexServiceFactory( - callAsCurrentUser, - reindexActions, - log, - licensing - ); + const asCurrentUser = esClient.asCurrentUser; + const reindexActions = reindexActionsFactory(client, asCurrentUser); + const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); try { const hasRequiredPrivileges = await reindexService.hasRequiredPrivileges(indexName); @@ -316,9 +296,7 @@ export function registerReindexIndicesRoutes( { core: { savedObjects, - elasticsearch: { - legacy: { client: esClient }, - }, + elasticsearch: { client: esClient }, }, }, request, @@ -326,7 +304,7 @@ export function registerReindexIndicesRoutes( ) => { const { indexName } = request.params; const { client } = savedObjects; - const callAsCurrentUser = esClient.callAsCurrentUser.bind(esClient); + const callAsCurrentUser = esClient.asCurrentUser; const reindexActions = reindexActionsFactory(client, callAsCurrentUser); const reindexService = reindexServiceFactory( callAsCurrentUser, diff --git a/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts b/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts index daeb71ef123826..bdfbff61bc5db8 100644 --- a/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts +++ b/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts @@ -10,7 +10,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; import { reindexOperationWithLargeErrorMessage } from './reindex_operation_with_large_error_message'; export default function ({ getService }: FtrProviderContext) { - const es = getService('legacyEs'); + const es = getService('es'); describe('Reindex operation saved object', function () { const dotKibanaIndex = '.kibana'; diff --git a/x-pack/test/upgrade_assistant_integration/config.js b/x-pack/test/upgrade_assistant_integration/config.js index d11b39ff74e355..5409d8a4705029 100644 --- a/x-pack/test/upgrade_assistant_integration/config.js +++ b/x-pack/test/upgrade_assistant_integration/config.js @@ -5,7 +5,6 @@ */ import path from 'path'; -import { LegacyEsProvider } from './services'; export default async function ({ readConfigFile }) { // Read the Kibana API integration tests config file so that we can utilize its services. @@ -25,7 +24,6 @@ export default async function ({ readConfigFile }) { services: { ...kibanaCommonConfig.get('services'), supertest: kibanaAPITestsConfig.get('services.supertest'), - legacyEs: LegacyEsProvider, }, esArchiver: xPackFunctionalTestsConfig.get('esArchiver'), junit: { diff --git a/x-pack/test/upgrade_assistant_integration/services/index.js b/x-pack/test/upgrade_assistant_integration/services/index.js deleted file mode 100644 index 83424ad1eb50c9..00000000000000 --- a/x-pack/test/upgrade_assistant_integration/services/index.js +++ /dev/null @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { LegacyEsProvider } from './legacy_es'; diff --git a/x-pack/test/upgrade_assistant_integration/services/legacy_es.js b/x-pack/test/upgrade_assistant_integration/services/legacy_es.js deleted file mode 100644 index 78bfd63ded3c92..00000000000000 --- a/x-pack/test/upgrade_assistant_integration/services/legacy_es.js +++ /dev/null @@ -1,18 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { format as formatUrl } from 'url'; - -import * as legacyElasticsearch from 'elasticsearch'; - -export function LegacyEsProvider({ getService }) { - const config = getService('config'); - - return new legacyElasticsearch.Client({ - host: formatUrl(config.get('servers.elasticsearch')), - requestTimeout: config.get('timeouts.esRequestTimeout'), - }); -} diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js index 828f1366d24449..498d8ea22e9c84 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js @@ -17,7 +17,7 @@ import { getIndexState } from '../../../plugins/upgrade_assistant/common/get_ind export default function ({ getService }) { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); - const es = getService('legacyEs'); + const es = getService('es'); // Utility function that keeps polling API until reindex operation has completed or failed. const waitForReindexToComplete = async (indexName) => { @@ -69,14 +69,14 @@ export default function ({ getService }) { expect(lastState.status).to.equal(ReindexStatus.completed); const { newIndexName } = lastState; - const indexSummary = await es.indices.get({ index: 'dummydata' }); + const { body: indexSummary } = await es.indices.get({ index: 'dummydata' }); // The new index was created expect(indexSummary[newIndexName]).to.be.an('object'); // The original index name is aliased to the new one expect(indexSummary[newIndexName].aliases.dummydata).to.be.an('object'); // The number of documents in the new index matches what we expect - expect((await es.count({ index: lastState.newIndexName })).count).to.be(3); + expect((await es.count({ index: lastState.newIndexName })).body.count).to.be(3); // Cleanup newly created index await es.indices.delete({ @@ -99,9 +99,9 @@ export default function ({ getService }) { ], }, }); - expect((await es.count({ index: 'myAlias' })).count).to.be(3); - expect((await es.count({ index: 'wildcardAlias' })).count).to.be(3); - expect((await es.count({ index: 'myHttpsAlias' })).count).to.be(2); + expect((await es.count({ index: 'myAlias' })).body.count).to.be(3); + expect((await es.count({ index: 'wildcardAlias' })).body.count).to.be(3); + expect((await es.count({ index: 'myHttpsAlias' })).body.count).to.be(2); // Reindex await supertest @@ -111,10 +111,10 @@ export default function ({ getService }) { const lastState = await waitForReindexToComplete('dummydata'); // The regular aliases should still return 3 docs - expect((await es.count({ index: 'myAlias' })).count).to.be(3); - expect((await es.count({ index: 'wildcardAlias' })).count).to.be(3); + expect((await es.count({ index: 'myAlias' })).body.count).to.be(3); + expect((await es.count({ index: 'wildcardAlias' })).body.count).to.be(3); // The filtered alias should still return 2 docs - expect((await es.count({ index: 'myHttpsAlias' })).count).to.be(2); + expect((await es.count({ index: 'myHttpsAlias' })).body.count).to.be(2); // Cleanup newly created index await es.indices.delete({ @@ -208,8 +208,8 @@ export default function ({ getService }) { await assertQueueState(undefined, 0); // Check that the closed index is still closed after reindexing - const resolvedIndices = await es.transport.request({ - path: `_resolve/index/${nameOfIndexThatShouldBeClosed}`, + const { body: resolvedIndices } = await es.indices.resolveIndex({ + name: nameOfIndexThatShouldBeClosed, }); const test1ReindexedState = getIndexState(nameOfIndexThatShouldBeClosed, resolvedIndices);