From bc25674a6c5bd629de6b19a281e3d26128d876a0 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 28 Feb 2020 10:06:43 +0100 Subject: [PATCH 01/27] Exclude disallowed, private setting at index creation --- .../upgrade_assistant/server/lib/reindexing/index_settings.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts index f6dc471d0945d..5722a6c29b68f 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts @@ -88,6 +88,7 @@ const removeUnsettableSettings = (settings: FlatSettings['settings']) => 'index.routing.allocation.initial_recovery._id', 'index.version.created', 'index.version.upgraded', + 'index.verified_before_close', ]); // Use `flow` to pipe the settings through each function. From 7c758b358b0a333272c79ccbc5f16c8773439737 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 28 Feb 2020 10:11:08 +0100 Subject: [PATCH 02/27] Remove intl from tabs component --- .../public/application/components/tabs.tsx | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs.tsx index 43ec5554aaaee..77ee3448cd06d 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs.tsx @@ -14,7 +14,8 @@ import { EuiTabbedContent, EuiTabbedContentTab, } from '@elastic/eui'; -import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; import { HttpSetup } from 'src/core/public'; import { UpgradeAssistantStatus } from '../../../common/types'; @@ -38,9 +39,11 @@ interface TabsState { clusterUpgradeState: ClusterUpgradeState; } -type Props = ReactIntl.InjectedIntlProps & { http: HttpSetup }; +interface Props { + http: HttpSetup; +} -export class UpgradeAssistantTabsUI extends React.Component { +export class UpgradeAssistantTabs extends React.Component { constructor(props: Props) { super(props); this.state = { @@ -172,7 +175,6 @@ export class UpgradeAssistantTabsUI extends React.Component { }; private get tabs() { - const { intl } = this.props; const { loadingError, loadingState, checkupData } = this.state; const commonProps: UpgradeAssistantTabProps = { loadingError, @@ -186,24 +188,21 @@ export class UpgradeAssistantTabsUI extends React.Component { return [ { id: 'overview', - name: intl.formatMessage({ - id: 'xpack.upgradeAssistant.overviewTab.overviewTabTitle', + name: i18n.translate('xpack.upgradeAssistant.overviewTab.overviewTabTitle', { defaultMessage: 'Overview', }), content: , }, { id: 'cluster', - name: intl.formatMessage({ - id: 'xpack.upgradeAssistant.checkupTab.clusterTabLabel', + name: i18n.translate('xpack.upgradeAssistant.checkupTab.clusterTabLabel', { defaultMessage: 'Cluster', }), content: ( { }, { id: 'indices', - name: intl.formatMessage({ - id: 'xpack.upgradeAssistant.checkupTab.indicesTabLabel', + name: i18n.translate('xpack.upgradeAssistant.checkupTab.indicesTabLabel', { defaultMessage: 'Indices', }), content: ( { this.setState({ telemetryState: TelemetryState.Complete }); } } - -export const UpgradeAssistantTabs = injectI18n(UpgradeAssistantTabsUI); From 2f8d9e2d96aed5eade17d6f830fcc145f997566a Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 28 Feb 2020 11:22:04 +0100 Subject: [PATCH 03/27] Added logic for checking the current index status --- .../plugins/upgrade_assistant/common/types.ts | 46 +++++++++++++++++++ .../server/lib/es_migration_apis.ts | 26 ++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index a0c12154988a1..f64fd0fa2ec96 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -120,6 +120,7 @@ export interface EnrichedDeprecationInfo extends DeprecationInfo { index?: string; node?: string; reindex?: boolean; + isIndexClosed?: boolean; } export interface UpgradeAssistantStatus { @@ -127,3 +128,48 @@ export interface UpgradeAssistantStatus { cluster: EnrichedDeprecationInfo[]; indices: EnrichedDeprecationInfo[]; } + +export interface ClusterStateIndexAPIResponse { + state: 'open' | 'closed'; + settings: { + index: { + verified_before_close: string; + search: { + throttled: string; + }; + number_of_shards: string; + provided_name: string; + frozen: string; + creation_date: string; + number_of_replicas: string; + uuid: string; + version: { + created: string; + }; + }; + }; + mappings: any; + aliases: any[]; + primary_terms: { + '0': number; + }; + in_sync_allocations: { + '0': string[]; + }; +} + +export interface ClusterStateAPIResponse { + cluster_name: string; + cluster_uuid: string; + metadata: { + cluster_uuid: string; + cluster_coordination: { + term: number; + last_committed_config: string[]; + last_accepted_config: string[]; + voting_config_exclusions: []; + }; + templates: any; + indices: { [indexName: string]: ClusterStateIndexAPIResponse }; + }; +} 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 68f21c1fd93b5..e529fd54cb703 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 @@ -6,7 +6,11 @@ import { IScopedClusterClient } from 'src/core/server'; import { DeprecationAPIResponse } from 'src/legacy/core_plugins/elasticsearch'; -import { EnrichedDeprecationInfo, UpgradeAssistantStatus } from '../../common/types'; +import { + ClusterStateAPIResponse, + EnrichedDeprecationInfo, + UpgradeAssistantStatus, +} from '../../common/types'; export async function getUpgradeAssistantStatus( dataClient: IScopedClusterClient, @@ -20,6 +24,26 @@ export async function getUpgradeAssistantStatus( const cluster = getClusterDeprecations(deprecations, isCloudEnabled); const indices = getCombinedIndexInfos(deprecations); + const indexNames = indices.map(({ index }) => index!); + + // If we have found deprecation information for index/indices, add some additional information; + // is it currently open or closed? + if (indexNames.length) { + const indicesMetadata: ClusterStateAPIResponse = await dataClient.callAsCurrentUser( + 'cluster.state', + { + index: indexNames, + metric: 'metadata', + } + ); + + indices.forEach(indexData => { + indexData.isIndexClosed = Boolean( + indicesMetadata.metadata.indices[indexData.index!]?.state === 'closed' + ); + }); + } + const criticalWarnings = cluster.concat(indices).filter(d => d.level === 'critical'); return { From 28d1a3d7d7440c99524564847389b18cfc8a0f44 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 28 Feb 2020 13:58:06 +0100 Subject: [PATCH 04/27] Added ES contract integration test Using _cluster/state is considered internal. This adds an integration test for checking the contract in CI. --- .../server/lib/es_migration_apis.ts | 4 ++ .../upgrade_assistant/index.js | 1 + .../upgrade_assistant/status.ts | 40 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts 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 e529fd54cb703..da77f6fc7e07b 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 @@ -29,6 +29,10 @@ export async function getUpgradeAssistantStatus( // If we have found deprecation information for index/indices, add some additional information; // is it currently open or closed? if (indexNames.length) { + // According to https://www.elastic.co/guide/en/elasticsearch/reference/7.6/cluster-state.html + // The response from this call is considered internal and subject to change. We have an API + // integration test for asserting that the current ES version still returns what we expect. + // This lives in x-pack/test/upgrade_assistant_integration const indicesMetadata: ClusterStateAPIResponse = await dataClient.callAsCurrentUser( 'cluster.state', { diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/index.js b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/index.js index 196e06a61833b..fa8c3fd99f71d 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/index.js +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/index.js @@ -9,5 +9,6 @@ export default function({ loadTestFile }) { this.tags('ciGroup7'); loadTestFile(require.resolve('./reindexing')); + loadTestFile(require.resolve('./status')); }); } diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts new file mode 100644 index 0000000000000..552688813e82e --- /dev/null +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +// eslint-disable-next-line import/no-default-export +export default function({ getService }) { + const esArchiver = getService('esArchiver'); + const es = getService('es'); + + describe('status and _cluster/state contract', () => { + // According to https://www.elastic.co/guide/en/elasticsearch/reference/7.6/cluster-state.html + // The response from this call is considered internal and subject to change. We check that + // the contract has not changed in this integration test. + it('the _cluster/state endpoint is still what we expect', async () => { + await esArchiver.load('upgrade_assistant/reindex'); + const result = await es.cluster.state({ + index: '7.0-data', + metric: 'metadata', + }); + + try { + if (result.body.metadata.indices['7.0-data'].state === 'open') { + return; + } + } catch (e) { + expect().fail( + `Can no longer access index open/closed state. Please update Upgrade Assistant checkup.` + ); + return; + } + expect().fail( + `The response contract for _cluster/state metadata has changed. Please update Upgrade Assistant checkup.` + ); + }); + }); +} From 3ff7ae630ac32fafbdc144fc03d488611e62ad95 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 28 Feb 2020 16:01:36 +0100 Subject: [PATCH 05/27] Add the client side notification for closed indices --- .../plugins/upgrade_assistant/common/types.ts | 2 +- .../public/application/app.tsx | 2 +- .../public/application/app_context.tsx | 3 +- .../tabs/checkup/deprecations/index_table.tsx | 38 +++++++++++++++---- .../tabs/checkup/deprecations/list.tsx | 1 + .../reindex/closed_warning_icon.tsx | 36 ++++++++++++++++++ .../checkup/deprecations/reindex/index.tsx | 1 + .../upgrade_assistant/public/plugin.ts | 4 +- .../server/lib/es_migration_apis.ts | 8 ++-- 9 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index f64fd0fa2ec96..84506f7840073 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -120,7 +120,7 @@ export interface EnrichedDeprecationInfo extends DeprecationInfo { index?: string; node?: string; reindex?: boolean; - isIndexClosed?: boolean; + blockerForReindexing?: 'index-closed'; } export interface UpgradeAssistantStatus { diff --git a/x-pack/plugins/upgrade_assistant/public/application/app.tsx b/x-pack/plugins/upgrade_assistant/public/application/app.tsx index 17eff71f1039b..a65f003e14b27 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/app.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/app.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { I18nStart } from 'src/core/public'; +import { DocLinksStart, I18nStart } from 'src/core/public'; import { EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { NEXT_MAJOR_VERSION } from '../../common/version'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/app_context.tsx b/x-pack/plugins/upgrade_assistant/public/application/app_context.tsx index 1ae9dabd69481..11c88a52ea24e 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/app_context.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/app_context.tsx @@ -3,12 +3,13 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { HttpSetup } from 'src/core/public'; +import { DocLinksStart, HttpSetup } from 'src/core/public'; import React, { createContext, useContext } from 'react'; export interface ContextValue { http: HttpSetup; isCloudEnabled: boolean; + docLinks: DocLinksStart; } export const AppContext = createContext({} as any); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx index 5506528a3ded0..13afb69d4635c 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx @@ -7,16 +7,18 @@ import { sortBy } from 'lodash'; import React from 'react'; -import { EuiBasicTable } from '@elastic/eui'; +import { EuiBasicTable, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { injectI18n } from '@kbn/i18n/react'; -import { ReindexButton } from './reindex'; +import { ReindexButton, ReindexClosedWarningIcon } from './reindex'; import { AppContext } from '../../../../app_context'; +import { EnrichedDeprecationInfo } from '../../../../../../common/types'; const PAGE_SIZES = [10, 25, 50, 100, 250, 500, 1000]; export interface IndexDeprecationDetails { index: string; reindex: boolean; + blockerForReindexing?: EnrichedDeprecationInfo['blockerForReindexing']; details?: string; } @@ -68,9 +70,10 @@ export class IndexDeprecationTableUI extends React.Component< }, ]; - if (this.actionsColumn) { - // @ts-ignore - columns.push(this.actionsColumn); + const actionsColumn = this.generateActionsColumn(); + + if (actionsColumn) { + columns.push(actionsColumn); } const sorting = { @@ -134,7 +137,7 @@ export class IndexDeprecationTableUI extends React.Component< return { totalItemCount, pageSizeOptions, hidePerPageOptions: false }; } - private get actionsColumn() { + private generateActionsColumn() { // NOTE: this naive implementation assumes all indices in the table are // should show the reindex button. This should work for known usecases. const { indices } = this.props; @@ -148,7 +151,28 @@ export class IndexDeprecationTableUI extends React.Component< render(indexDep: IndexDeprecationDetails) { return ( - {({ http }) => } + {({ http, docLinks }) => { + return ( + + {indexDep.blockerForReindexing === 'index-closed' ? ( + + + + ) : null} + + + + + ); + }} ); }, 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 a46bc0d12fad4..411c3b6815202 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 @@ -89,6 +89,7 @@ export const DeprecationList: FunctionComponent<{ index: dep.index!, details: dep.details, reindex: dep.reindex === true, + blockerForReindexing: dep.blockerForReindexing, })); return ; } else if (currentGroupBy === GroupByOption.index) { diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx new file mode 100644 index 0000000000000..9be661fdb8be8 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FunctionComponent } from 'react'; +import { EuiIcon, EuiToolTip, EuiText, EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { DocLinksStart } from 'src/core/public'; + +export interface Props { + indexName: string; + docLinks: DocLinksStart; +} + +export const ReindexClosedWarningIcon: FunctionComponent = ({ + indexName, + docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, +}) => ( + + {`"${indexName}" needs to be reindexed but it is currently closed. The Upgrade Assistant will open,`} + {` reindex and then close the index. Reindexing may take longer than usual.`} + + } + > + + + + +); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/index.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/index.tsx index 5fcebb75e1784..8bec14cfde461 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/index.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/index.tsx @@ -5,3 +5,4 @@ */ export { ReindexButton } from './button'; +export { ReindexClosedWarningIcon } from './closed_warning_icon'; diff --git a/x-pack/plugins/upgrade_assistant/public/plugin.ts b/x-pack/plugins/upgrade_assistant/public/plugin.ts index 614221272dd5c..300da4eccae15 100644 --- a/x-pack/plugins/upgrade_assistant/public/plugin.ts +++ b/x-pack/plugins/upgrade_assistant/public/plugin.ts @@ -37,8 +37,8 @@ export class UpgradeAssistantUIPlugin implements Plugin { }), order: 1000, async mount({ element }) { - const [{ i18n: i18nDep }] = await getStartServices(); - return renderApp({ element, isCloudEnabled, http, i18n: i18nDep }); + const [{ i18n: i18nDep, docLinks }] = await getStartServices(); + return renderApp({ element, isCloudEnabled, http, i18n: i18nDep, docLinks }); }, }); } 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 da77f6fc7e07b..588f5ba399594 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 @@ -42,9 +42,11 @@ export async function getUpgradeAssistantStatus( ); indices.forEach(indexData => { - indexData.isIndexClosed = Boolean( - indicesMetadata.metadata.indices[indexData.index!]?.state === 'closed' - ); + indexData.blockerForReindexing = Boolean( + indicesMetadata.metadata.indices[indexData.index!]?.state !== 'open' + ) + ? 'index-closed' + : undefined; }); } From 56e2693eaf7264e1cece6f8ae7ed8d430754f991 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 28 Feb 2020 17:02:50 +0100 Subject: [PATCH 06/27] First version of end-to-end functionality working --- .../plugins/upgrade_assistant/common/types.ts | 7 ++++ .../tabs/checkup/deprecations/cell.tsx | 12 +++++- .../tabs/checkup/deprecations/index_table.tsx | 30 +++++---------- .../tabs/checkup/deprecations/list.tsx | 9 ++++- .../checkup/deprecations/reindex/button.tsx | 37 +++++++++++++++---- .../deprecations/reindex/polling_service.ts | 13 ++++++- .../server/lib/reindexing/reindex_actions.ts | 7 +++- .../server/lib/reindexing/reindex_service.ts | 21 ++++++++--- .../server/routes/reindex_indices.ts | 6 ++- 9 files changed, 102 insertions(+), 40 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 84506f7840073..496a652b24c65 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -28,6 +28,11 @@ export enum ReindexStatus { } export const REINDEX_OP_TYPE = 'upgrade-assistant-reindex-operation'; + +export interface ReindexOptions { + openAndClose: boolean; +} + export interface ReindexOperation extends SavedObjectAttributes { indexName: string; newIndexName: string; @@ -38,6 +43,8 @@ export interface ReindexOperation extends SavedObjectAttributes { reindexTaskPercComplete: number | null; errorMessage: string | null; + reindexOptions: ReindexOptions; + // This field is only used for the singleton IndexConsumerType documents. runningReindexCount: number | null; } diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/cell.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/cell.tsx index 879bb695ca60a..6eaa0de530673 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/cell.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/cell.tsx @@ -18,6 +18,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { ReindexButton } from './reindex'; import { AppContext } from '../../../../app_context'; +import { EnrichedDeprecationInfo } from '../../../../../../common/types'; interface DeprecationCellProps { items?: Array<{ title?: string; body: string }>; @@ -26,6 +27,7 @@ interface DeprecationCellProps { headline?: string; healthColor?: string; children?: ReactNode; + reindexBlocker?: EnrichedDeprecationInfo['blockerForReindexing']; } /** @@ -38,6 +40,7 @@ export const DeprecationCell: FunctionComponent = ({ docUrl, items = [], children, + reindexBlocker, }) => (
@@ -79,7 +82,14 @@ export const DeprecationCell: FunctionComponent = ({ {reindexIndexName && ( - {({ http }) => } + {({ http, docLinks }) => ( + + )} )} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx index 13afb69d4635c..19767c34a1b06 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx @@ -7,9 +7,9 @@ import { sortBy } from 'lodash'; import React from 'react'; -import { EuiBasicTable, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiBasicTable } from '@elastic/eui'; import { injectI18n } from '@kbn/i18n/react'; -import { ReindexButton, ReindexClosedWarningIcon } from './reindex'; +import { ReindexButton } from './reindex'; import { AppContext } from '../../../../app_context'; import { EnrichedDeprecationInfo } from '../../../../../../common/types'; @@ -73,7 +73,7 @@ export class IndexDeprecationTableUI extends React.Component< const actionsColumn = this.generateActionsColumn(); if (actionsColumn) { - columns.push(actionsColumn); + columns.push(actionsColumn as any); } const sorting = { @@ -153,24 +153,12 @@ export class IndexDeprecationTableUI extends React.Component< {({ http, docLinks }) => { return ( - - {indexDep.blockerForReindexing === 'index-closed' ? ( - - - - ) : null} - - - - + ); }} 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 411c3b6815202..ab71972f361ea 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 @@ -32,6 +32,7 @@ const MessageDeprecation: FunctionComponent<{ deprecation: EnrichedDeprecationIn return ( ; + return ( + + ); }; interface IndexDeprecationProps { diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx index 30b46e0c15213..23378198d5f47 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx @@ -8,17 +8,24 @@ import { set } from 'lodash'; import React, { Fragment, ReactNode } from 'react'; import { Subscription } from 'rxjs'; -import { EuiButton, EuiLoadingSpinner } from '@elastic/eui'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { HttpSetup } from 'src/core/public'; -import { ReindexStatus, UIReindexOption } from '../../../../../../../common/types'; +import { DocLinksStart, HttpSetup } from 'src/core/public'; +import { + EnrichedDeprecationInfo, + ReindexStatus, + UIReindexOption, +} from '../../../../../../../common/types'; import { LoadingState } from '../../../../types'; import { ReindexFlyout } from './flyout'; import { ReindexPollingService, ReindexState } from './polling_service'; +import { ReindexClosedWarningIcon } from './closed_warning_icon'; interface ReindexButtonProps { indexName: string; http: HttpSetup; + docLinks: DocLinksStart; + reindexBlocker?: EnrichedDeprecationInfo['blockerForReindexing']; } interface ReindexButtonState { @@ -61,7 +68,7 @@ export class ReindexButton extends React.Component - {buttonContent} + + {reindexBlocker === 'index-closed' && reindexState.status !== ReindexStatus.completed ? ( + + + + ) : null} + + {buttonContent} + + {flyoutVisible && ( ; private pollTimeout?: NodeJS.Timeout; - constructor(private indexName: string, private http: HttpSetup) { + constructor( + private indexName: string, + private http: HttpSetup, + private reindexOptions?: { openAndClose: boolean } + ) { this.status$ = new BehaviorSubject({ loadingState: LoadingState.Loading, errorMessage: null, @@ -94,8 +98,13 @@ export class ReindexPollingService { errorMessage: null, cancelLoadingState: undefined, }); + + const options = { + openAndClose: Boolean(this.reindexOptions?.openAndClose), + }; const data = await this.http.post( - `/api/upgrade_assistant/reindex/${this.indexName}` + `/api/upgrade_assistant/reindex/${this.indexName}`, + { body: JSON.stringify(options) } ); this.updateWithResponse({ reindexOp: data }); 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 2ae340f12d80c..c16cfbd75d3fe 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 @@ -14,6 +14,7 @@ import { ReindexSavedObject, ReindexStatus, ReindexStep, + ReindexOptions, } from '../../../common/types'; import { generateNewIndexName } from './index_settings'; import { FlatSettings } from './types'; @@ -34,8 +35,9 @@ export interface ReindexActions { /** * Creates a new reindexOp, does not perform any pre-flight checks. * @param indexName + * @param opts Additional options when creating the reindex operation */ - createReindexOp(indexName: string): Promise; + createReindexOp(indexName: string, opts?: ReindexOptions): Promise; /** * Deletes a reindexOp. @@ -150,10 +152,11 @@ export const reindexActionsFactory = ( // ----- Public interface return { - async createReindexOp(indexName: string) { + async createReindexOp(indexName: string, options = { openAndClose: false }) { return client.create(REINDEX_OP_TYPE, { indexName, newIndexName: generateNewIndexName(indexName), + reindexOptions: options, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: null, 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 8f1df5b34372b..ba1205a9ba1e2 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 @@ -14,7 +14,9 @@ import { ReindexStatus, ReindexStep, ReindexWarning, + ReindexOptions, } from '../../../common/types'; + import { generateNewIndexName, getReindexWarnings, @@ -51,8 +53,9 @@ export interface ReindexService { /** * Creates a new reindex operation for a given index. * @param indexName + * @param opts Additional options when creating a new reindex operation */ - createReindexOperation(indexName: string): Promise; + createReindexOperation(indexName: string, opts?: ReindexOptions): Promise; /** * Retrieves all reindex operations that have the given status. @@ -311,7 +314,11 @@ export const reindexServiceFactory = ( * @param reindexOp */ const startReindexing = async (reindexOp: ReindexSavedObject) => { - const { indexName } = reindexOp.attributes; + const { indexName, reindexOptions } = reindexOp.attributes; + + if (reindexOptions.openAndClose) { + await callAsUser('indices.open', { index: indexName }); + } const startReindex = (await callAsUser('reindex', { refresh: true, @@ -391,7 +398,7 @@ export const reindexServiceFactory = ( * @param reindexOp */ const switchAlias = async (reindexOp: ReindexSavedObject) => { - const { indexName, newIndexName } = reindexOp.attributes; + const { indexName, newIndexName, reindexOptions } = reindexOp.attributes; const existingAliases = ( await callAsUser('indices.getAlias', { @@ -417,6 +424,10 @@ export const reindexServiceFactory = ( throw Boom.badImplementation(`Index aliases could not be created.`); } + if (reindexOptions.openAndClose) { + await callAsUser('indices.close', { index: indexName }); + } + return actions.updateReindexOp(reindexOp, { lastCompletedStep: ReindexStep.aliasCreated, }); @@ -517,7 +528,7 @@ export const reindexServiceFactory = ( } }, - async createReindexOperation(indexName: string) { + async createReindexOperation(indexName: string, opts = { openAndClose: false }) { const indexExists = await callAsUser('indices.exists', { index: indexName }); if (!indexExists) { throw Boom.notFound(`Index ${indexName} does not exist in this cluster.`); @@ -537,7 +548,7 @@ export const reindexServiceFactory = ( } } - return actions.createReindexOp(indexName); + return actions.createReindexOp(indexName, opts); }, async findReindexOperation(indexName: string) { diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts index a910145474061..8ad93ea8f51f0 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts @@ -47,6 +47,9 @@ export function registerReindexIndicesRoutes( params: schema.object({ indexName: schema.string(), }), + body: schema.object({ + openAndClose: schema.boolean({ defaultValue: false }), + }), }, }, versionCheckHandlerWrapper( @@ -61,6 +64,7 @@ export function registerReindexIndicesRoutes( response ) => { const { indexName } = request.params as any; + const { openAndClose } = request.body as any; const { client } = savedObjects; const callAsCurrentUser = dataClient.callAsCurrentUser.bind(dataClient); const reindexActions = reindexActionsFactory(client, callAsCurrentUser); @@ -84,7 +88,7 @@ export function registerReindexIndicesRoutes( const reindexOp = existingOp && existingOp.attributes.status === ReindexStatus.paused ? await reindexService.resumeReindexOperation(indexName) - : await reindexService.createReindexOperation(indexName); + : await reindexService.createReindexOperation(indexName, { openAndClose }); // Add users credentials for the worker to use credentialStore.set(reindexOp, request.headers); From 755977d80d25b96203223420a4a487a95ca4fdc9 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 09:42:26 +0100 Subject: [PATCH 07/27] Clean up unused, incorrect type information --- x-pack/plugins/upgrade_assistant/common/types.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 496a652b24c65..2c00930d380c5 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -157,12 +157,6 @@ export interface ClusterStateIndexAPIResponse { }; mappings: any; aliases: any[]; - primary_terms: { - '0': number; - }; - in_sync_allocations: { - '0': string[]; - }; } export interface ClusterStateAPIResponse { From e06ebcac71092ba07e033b7364e9552b313b740f Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 09:53:26 +0100 Subject: [PATCH 08/27] Fix type issues and added a comment about the new reindex options --- x-pack/plugins/upgrade_assistant/common/types.ts | 7 ++++++- .../plugins/upgrade_assistant/public/application/app.tsx | 2 +- .../checkup/deprecations/reindex/closed_warning_icon.tsx | 2 +- .../upgrade_assistant/status.ts | 3 ++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 2c00930d380c5..b354ce35a0353 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -29,7 +29,12 @@ export enum ReindexStatus { export const REINDEX_OP_TYPE = 'upgrade-assistant-reindex-operation'; -export interface ReindexOptions { +export interface ReindexOptions extends SavedObjectAttributes { + /** + * Whether to treat the index as if it were closed. This instructs the + * reindex strategy to first open the index, perform reindexing and + * then close the index again. + */ openAndClose: boolean; } diff --git a/x-pack/plugins/upgrade_assistant/public/application/app.tsx b/x-pack/plugins/upgrade_assistant/public/application/app.tsx index a65f003e14b27..17eff71f1039b 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/app.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/app.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { DocLinksStart, I18nStart } from 'src/core/public'; +import { I18nStart } from 'src/core/public'; import { EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { NEXT_MAJOR_VERSION } from '../../common/version'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx index 9be661fdb8be8..7512dc76b4c08 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx @@ -5,7 +5,7 @@ */ import React, { FunctionComponent } from 'react'; -import { EuiIcon, EuiToolTip, EuiText, EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiIcon, EuiToolTip, EuiText, EuiLink } from '@elastic/eui'; import { DocLinksStart } from 'src/core/public'; export interface Props { diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts index 552688813e82e..82324ee0e3396 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts @@ -5,9 +5,10 @@ */ import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../api_integration/ftr_provider_context'; // eslint-disable-next-line import/no-default-export -export default function({ getService }) { +export default function({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const es = getService('es'); From d7890c968fac88a03e086ff6e3936c0634978b23 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 10:38:32 +0100 Subject: [PATCH 09/27] Fixed server side tests, added comments and logic updates Updated the handling of reindexOptions to make it more backwards compatible (treat it as if it could be undefined). Also update the logic for checking for open or closed indices. No optional chaining! It should break if the response does not exactly match. --- .../plugins/upgrade_assistant/common/types.ts | 12 +++++++++--- .../es_migration_apis.test.ts.snap | 6 ++++++ .../server/lib/es_migration_apis.test.ts | 18 +++++++++++++++++- .../server/lib/es_migration_apis.ts | 2 +- .../lib/reindexing/reindex_actions.test.ts | 12 ++++++++++++ .../lib/reindexing/reindex_service.test.ts | 14 +++++++++++--- .../server/lib/reindexing/reindex_service.ts | 4 ++-- .../server/routes/reindex_indices.test.ts | 12 +++++++++--- 8 files changed, 67 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index b354ce35a0353..0aae5c3831236 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -47,11 +47,17 @@ export interface ReindexOperation extends SavedObjectAttributes { reindexTaskId: string | null; reindexTaskPercComplete: number | null; errorMessage: string | null; - - reindexOptions: ReindexOptions; - // This field is only used for the singleton IndexConsumerType documents. runningReindexCount: number | null; + + /** + * Options for the reindexing strategy. + * + * @remark + * Marked as optional for backwards compatibility. We should still + * be able to handle older ReindexOperation objects. + */ + reindexOptions?: ReindexOptions; } export type ReindexSavedObject = SavedObject; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_migration_apis.test.ts.snap b/x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_migration_apis.test.ts.snap index 10f66fd1fc01a..244fc96acd194 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_migration_apis.test.ts.snap +++ b/x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_migration_apis.test.ts.snap @@ -30,6 +30,7 @@ Object { ], "indices": Array [ Object { + "blockerForReindexing": undefined, "details": "[[type: doc, field: spins], [type: doc, field: mlockall], [type: doc, field: node_master], [type: doc, field: primary]]", "index": ".monitoring-es-6-2018.11.07", "level": "warning", @@ -38,6 +39,7 @@ Object { "url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields", }, Object { + "blockerForReindexing": undefined, "details": "[[type: tweet, field: liked]]", "index": "twitter", "level": "warning", @@ -46,6 +48,7 @@ Object { "url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields", }, Object { + "blockerForReindexing": undefined, "details": "[[type: index-pattern, field: notExpandable], [type: config, field: xPackMonitoring:allowReport], [type: config, field: xPackMonitoring:showBanner], [type: dashboard, field: pause], [type: dashboard, field: timeRestore]]", "index": ".kibana", "level": "warning", @@ -54,6 +57,7 @@ Object { "url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields", }, Object { + "blockerForReindexing": undefined, "details": "[[type: doc, field: notify], [type: doc, field: created], [type: doc, field: attach_payload], [type: doc, field: met]]", "index": ".watcher-history-6-2018.11.07", "level": "warning", @@ -62,6 +66,7 @@ Object { "url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields", }, Object { + "blockerForReindexing": undefined, "details": "[[type: doc, field: snapshot]]", "index": ".monitoring-kibana-6-2018.11.07", "level": "warning", @@ -70,6 +75,7 @@ Object { "url": "https://www.elastic.co/guide/en/elasticsearch/reference/6.0/breaking_60_mappings_changes.html#_coercion_of_boolean_fields", }, Object { + "blockerForReindexing": undefined, "details": "[[type: tweet, field: liked]]", "index": "twitter2", "level": "warning", 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 4ab4227ba3e91..bac46234709bc 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 @@ -15,9 +15,25 @@ describe('getUpgradeAssistantStatus', () => { let deprecationsResponse: DeprecationAPIResponse; const dataClient = elasticsearchServiceMock.createScopedClusterClient(); - (dataClient.callAsCurrentUser as jest.Mock).mockImplementation(async (api, { path }) => { + (dataClient.callAsCurrentUser as jest.Mock).mockImplementation(async (api, { path, index }) => { if (path === '/_migration/deprecations') { return deprecationsResponse; + } else if (api === 'cluster.state') { + return { + metadata: { + indices: { + ...index.reduce((acc, i) => { + return { + ...acc, + [i]: { + state: 'open', + }, + }; + }, {}), + }, + }, + }; + return indicesMetadata.metadata.indices[indexData.index!]?.state !== 'open'; } else if (api === 'indices.getMapping') { return {}; } else { 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 588f5ba399594..199e70528163b 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 @@ -43,7 +43,7 @@ export async function getUpgradeAssistantStatus( indices.forEach(indexData => { indexData.blockerForReindexing = Boolean( - indicesMetadata.metadata.indices[indexData.index!]?.state !== 'open' + indicesMetadata.metadata.indices[indexData.index!].state !== 'open' ) ? 'index-closed' : undefined; 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 4569fdfa33a83..b012a50fd7b4b 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 @@ -51,6 +51,9 @@ describe('ReindexActions', () => { expect(client.create).toHaveBeenCalledWith(REINDEX_OP_TYPE, { indexName: 'myIndex', newIndexName: `reindexed-v${CURRENT_MAJOR_VERSION}-myIndex`, + reindexOptions: { + openAndClose: false, + }, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: null, @@ -66,6 +69,9 @@ describe('ReindexActions', () => { expect(client.create).toHaveBeenCalledWith(REINDEX_OP_TYPE, { indexName: '.internalIndex', newIndexName: `.reindexed-v${CURRENT_MAJOR_VERSION}-internalIndex`, + reindexOptions: { + openAndClose: false, + }, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: null, @@ -83,6 +89,9 @@ describe('ReindexActions', () => { expect(client.create).toHaveBeenCalledWith(REINDEX_OP_TYPE, { indexName, newIndexName: `reindexed-v${CURRENT_MAJOR_VERSION}-myIndex`, + reindexOptions: { + openAndClose: false, + }, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: null, @@ -98,6 +107,9 @@ describe('ReindexActions', () => { expect(client.create).toHaveBeenCalledWith(REINDEX_OP_TYPE, { indexName: `reindexed-v${PREV_MAJOR_VERSION}-myIndex`, newIndexName: `reindexed-v${CURRENT_MAJOR_VERSION}-myIndex`, + reindexOptions: { + openAndClose: false, + }, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: 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 6c3b2c869dc7f..d2e4c68466ade 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 @@ -215,7 +215,7 @@ describe('reindexService', () => { await service.createReindexOperation('myIndex'); - expect(actions.createReindexOp).toHaveBeenCalledWith('myIndex'); + expect(actions.createReindexOp).toHaveBeenCalledWith('myIndex', { openAndClose: false }); }); it('fails if index does not exist', async () => { @@ -841,7 +841,11 @@ describe('reindexService', () => { describe('newIndexCreated', () => { const reindexOp = { id: '1', - attributes: { ...defaultAttributes, lastCompletedStep: ReindexStep.newIndexCreated }, + attributes: { + ...defaultAttributes, + lastCompletedStep: ReindexStep.newIndexCreated, + reindexOptions: { openAndClose: false }, + }, } as ReindexSavedObject; beforeEach(() => { @@ -957,7 +961,11 @@ describe('reindexService', () => { describe('reindexCompleted', () => { const reindexOp = { id: '1', - attributes: { ...defaultAttributes, lastCompletedStep: ReindexStep.reindexCompleted }, + attributes: { + ...defaultAttributes, + lastCompletedStep: ReindexStep.reindexCompleted, + reindexOptions: { openAndClose: false }, + }, } as ReindexSavedObject; it('switches aliases, sets as complete, and updates lastCompletedStep', async () => { 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 ba1205a9ba1e2..1c6fe54f04dfa 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 @@ -316,7 +316,7 @@ export const reindexServiceFactory = ( const startReindexing = async (reindexOp: ReindexSavedObject) => { const { indexName, reindexOptions } = reindexOp.attributes; - if (reindexOptions.openAndClose) { + if (reindexOptions?.openAndClose) { await callAsUser('indices.open', { index: indexName }); } @@ -424,7 +424,7 @@ export const reindexServiceFactory = ( throw Boom.badImplementation(`Index aliases could not be created.`); } - if (reindexOptions.openAndClose) { + if (reindexOptions?.openAndClose) { await callAsUser('indices.close', { index: indexName }); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.test.ts index 695bb6304cfdf..294ade4d0eeb6 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.test.ts @@ -156,12 +156,14 @@ describe('reindex API', () => { pathPattern: '/api/upgrade_assistant/reindex/{indexName}', })( routeHandlerContextMock, - createRequestMock({ params: { indexName: 'theIndex' } }), + createRequestMock({ params: { indexName: 'theIndex' }, body: { openAndClose: false } }), kibanaResponseFactory ); // It called create correctly - expect(mockReindexService.createReindexOperation).toHaveBeenCalledWith('theIndex'); + expect(mockReindexService.createReindexOperation).toHaveBeenCalledWith('theIndex', { + openAndClose: false, + }); // It returned the right results expect(resp.status).toEqual(200); @@ -179,7 +181,7 @@ describe('reindex API', () => { pathPattern: '/api/upgrade_assistant/reindex/{indexName}', })( routeHandlerContextMock, - createRequestMock({ params: { indexName: 'theIndex' } }), + createRequestMock({ params: { indexName: 'theIndex' }, body: { openAndClose: false } }), kibanaResponseFactory ); @@ -202,6 +204,7 @@ describe('reindex API', () => { 'kbn-auth-x': 'HERE!', }, params: { indexName: 'theIndex' }, + body: { openAndClose: false }, }), kibanaResponseFactory ); @@ -224,6 +227,7 @@ describe('reindex API', () => { routeHandlerContextMock, createRequestMock({ params: { indexName: 'theIndex' }, + body: { openAndClose: false }, }), kibanaResponseFactory ); @@ -247,6 +251,7 @@ describe('reindex API', () => { routeHandlerContextMock, createRequestMock({ params: { indexName: 'theIndex' }, + body: { openAndClose: false }, }), kibanaResponseFactory ); @@ -266,6 +271,7 @@ describe('reindex API', () => { routeHandlerContextMock, createRequestMock({ params: { indexName: 'cancelMe' }, + body: { openAndClose: false }, }), kibanaResponseFactory ); From b1f42bd8ba596315d5fae4390493e3feb668aaf7 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 10:43:41 +0100 Subject: [PATCH 10/27] Clean up unused code --- .../upgrade_assistant/server/lib/es_migration_apis.test.ts | 1 - 1 file changed, 1 deletion(-) 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 bac46234709bc..f7b8a07a66034 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 @@ -33,7 +33,6 @@ describe('getUpgradeAssistantStatus', () => { }, }, }; - return indicesMetadata.metadata.indices[indexData.index!]?.state !== 'open'; } else if (api === 'indices.getMapping') { return {}; } else { From 039361bc30e09b507f2fa7070b725ffd4b04f3e2 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 10:53:54 +0100 Subject: [PATCH 11/27] Improved idempotency of test and check explicitly for "close". Rather check for the specific value we want, as this is what is also gauranteed by the tests. In this way, the information we send back to the client is also more accurate regarding the index status. If, in future, more index states are introduced this will need to be revisited if it affects the ability for an index to be re-indexed. --- .../plugins/upgrade_assistant/common/types.ts | 7 +++++++ .../server/lib/es_migration_apis.ts | 9 ++++----- .../upgrade_assistant/status.ts | 19 +++++++++++++++++-- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 0aae5c3831236..855c309f06357 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -138,6 +138,13 @@ export interface EnrichedDeprecationInfo extends DeprecationInfo { index?: string; node?: string; reindex?: boolean; + /** + * Indicate what blockers have been detected for calling reindex + * against this index. + * + * @remark + * In future this could be an array of blockers. + */ blockerForReindexing?: 'index-closed'; } 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 199e70528163b..540fcfe68a57d 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 @@ -42,11 +42,10 @@ export async function getUpgradeAssistantStatus( ); indices.forEach(indexData => { - indexData.blockerForReindexing = Boolean( - indicesMetadata.metadata.indices[indexData.index!].state !== 'open' - ) - ? 'index-closed' - : undefined; + indexData.blockerForReindexing = + indicesMetadata.metadata.indices[indexData.index!].state === 'close' + ? 'index-closed' + : undefined; }); } diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts index 82324ee0e3396..ba25376e355ff 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts @@ -13,18 +13,27 @@ export default function({ getService }: FtrProviderContext) { const es = getService('es'); describe('status and _cluster/state contract', () => { + beforeEach(async () => { + await es.indices.open({ index: '7.0-data' }); + }); + + afterEach(async () => { + await es.indices.open({ index: '7.0-data' }); + }); + // According to https://www.elastic.co/guide/en/elasticsearch/reference/7.6/cluster-state.html // The response from this call is considered internal and subject to change. We check that // the contract has not changed in this integration test. it('the _cluster/state endpoint is still what we expect', async () => { await esArchiver.load('upgrade_assistant/reindex'); + await es.indices.close({ index: '7.0-data' }); const result = await es.cluster.state({ index: '7.0-data', metric: 'metadata', }); try { - if (result.body.metadata.indices['7.0-data'].state === 'open') { + if (result.body.metadata.indices['7.0-data'].state === 'close') { return; } } catch (e) { @@ -34,7 +43,13 @@ export default function({ getService }: FtrProviderContext) { return; } expect().fail( - `The response contract for _cluster/state metadata has changed. Please update Upgrade Assistant checkup.` + `The response contract for _cluster/state metadata has changed. Please update Upgrade Assistant checkup. Received ${JSON.stringify( + result, + null, + 2 + )}. + +Expected body.metadata.indices['7.0-data'].state to be "close".` ); }); }); From c4c4f0389db5d84a97538b294cdc48d2b0893c34 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 11:06:56 +0100 Subject: [PATCH 12/27] Update client-side tests --- .../tabs/checkup/deprecations/list.test.tsx | 148 +++++++++--------- .../reindex/polling_service.test.ts | 4 +- 2 files changed, 78 insertions(+), 74 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.test.tsx index a1e173737bab0..606faf52b8e2b 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.test.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.test.tsx @@ -23,29 +23,29 @@ describe('DeprecationList', () => { test('shows simple messages when index field is not present', () => { expect(shallow()).toMatchInlineSnapshot(` -
- - -
-`); +
+ + +
+ `); }); test('shows index deprecation when index field is present', () => { @@ -59,31 +59,33 @@ describe('DeprecationList', () => { }; const wrapper = shallow(); expect(wrapper).toMatchInlineSnapshot(` - -`); + + `); }); }); @@ -98,31 +100,31 @@ describe('DeprecationList', () => { test('shows detailed messages', () => { expect(shallow()).toMatchInlineSnapshot(` -
- - -
-`); +
+ + +
+ `); }); }); }); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts index 4228426d62159..d9892d9c2805c 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts @@ -71,7 +71,9 @@ describe('ReindexPollingService', () => { const service = new ReindexPollingService('myIndex', mockClient); await service.startReindex(); - expect(mockClient.post).toHaveBeenCalledWith('/api/upgrade_assistant/reindex/myIndex'); + expect(mockClient.post).toHaveBeenCalledWith('/api/upgrade_assistant/reindex/myIndex', { + body: JSON.stringify({ openAndClose: false }), + }); }); }); From b1ebd0dfb8de4bfec0d502c0c629fa461a87a00e Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 12:37:03 +0100 Subject: [PATCH 13/27] Fix types --- x-pack/plugins/upgrade_assistant/common/types.ts | 2 +- .../upgrade_assistant/server/lib/es_migration_apis.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 855c309f06357..9274c880644c6 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -155,7 +155,7 @@ export interface UpgradeAssistantStatus { } export interface ClusterStateIndexAPIResponse { - state: 'open' | 'closed'; + state: 'open' | 'close'; settings: { index: { verified_before_close: string; 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 f7b8a07a66034..89571a4a18231 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 @@ -22,7 +22,7 @@ describe('getUpgradeAssistantStatus', () => { return { metadata: { indices: { - ...index.reduce((acc, i) => { + ...index.reduce((acc: any, i: any) => { return { ...acc, [i]: { From 920b86c5640870eb5f2bc02f3de34e81d68e53bb Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 16:13:50 +0100 Subject: [PATCH 14/27] Handle a case where the index name provided may be an alias --- ...get_index_state_from_cluster_state.test.ts | 53 +++++++++++++++++++ .../get_index_state_from_cluster_state.ts | 28 ++++++++++ .../plugins/upgrade_assistant/common/types.ts | 2 +- .../server/lib/es_migration_apis.ts | 5 +- .../upgrade_assistant/reindexing.js | 9 ++++ .../upgrade_assistant/status.ts | 5 +- 6 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.test.ts create mode 100644 x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.ts diff --git a/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.test.ts b/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.test.ts new file mode 100644 index 0000000000000..f1f34820ff07b --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.test.ts @@ -0,0 +1,53 @@ +/* + * 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 { getIndexStateFromClusterState } from './get_index_state_from_cluster_state'; +import { ClusterStateAPIResponse } from './types'; + +describe('getIndexStateFromClusterState', () => { + const indexName = 'indexName'; + const clusterState: ClusterStateAPIResponse = { + metadata: { + indices: {}, + cluster_coordination: {}, + cluster_uuid: 'test', + templates: {}, + }, + cluster_name: 'test', + cluster_uuid: 'test', + }; + + afterEach(() => { + clusterState.metadata.indices = {}; + }); + + it('correctly extracts state from cluster state', () => { + clusterState.metadata.indices[indexName] = { state: 'open' } as any; + clusterState.metadata.indices.aTotallyDifferentIndex = { state: 'close' } as any; + expect(getIndexStateFromClusterState(indexName, clusterState)).toBe('open'); + }); + + it('correctly extracts state from aliased index in cluster state', () => { + clusterState.metadata.indices.aTotallyDifferentName = { + state: 'close', + aliases: [indexName, 'test'], + }; + clusterState.metadata.indices.aTotallyDifferentName1 = { + state: 'open', + aliases: ['another', 'test'], + }; + + expect(getIndexStateFromClusterState(indexName, clusterState)).toBe('close'); + }); + + it('throws if the index name cannot be found in the cluster state', () => { + expect(() => getIndexStateFromClusterState(indexName, clusterState)).toThrow('not found'); + clusterState.metadata.indices.aTotallyDifferentName1 = { + state: 'open', + aliases: ['another', 'test'], + }; + expect(() => getIndexStateFromClusterState(indexName, clusterState)).toThrow('not found'); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.ts b/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.ts new file mode 100644 index 0000000000000..75b71fee000d4 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ClusterStateAPIResponse } from './types'; + +const checkAllAliases = ( + indexName: string, + clusterState: ClusterStateAPIResponse +): 'open' | 'close' => { + for (const index of Object.values(clusterState.metadata.indices)) { + if (index.aliases?.some(alias => alias === indexName)) { + return index.state; + } + } + + throw new Error(`${indexName} not found in cluster state!`); +}; + +export const getIndexStateFromClusterState = ( + indexName: string, + clusterState: ClusterStateAPIResponse +): 'open' | 'close' => + clusterState.metadata.indices[indexName] + ? clusterState.metadata.indices[indexName].state + : checkAllAliases(indexName, clusterState); diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 9274c880644c6..e3a06093ddc3d 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -174,7 +174,7 @@ export interface ClusterStateIndexAPIResponse { }; }; mappings: any; - aliases: any[]; + aliases: string[]; } export interface ClusterStateAPIResponse { 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 540fcfe68a57d..8d5047c01dbe4 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 @@ -11,6 +11,7 @@ import { EnrichedDeprecationInfo, UpgradeAssistantStatus, } from '../../common/types'; +import { getIndexStateFromClusterState } from '../../common/get_index_state_from_cluster_state'; export async function getUpgradeAssistantStatus( dataClient: IScopedClusterClient, @@ -33,7 +34,7 @@ export async function getUpgradeAssistantStatus( // The response from this call is considered internal and subject to change. We have an API // integration test for asserting that the current ES version still returns what we expect. // This lives in x-pack/test/upgrade_assistant_integration - const indicesMetadata: ClusterStateAPIResponse = await dataClient.callAsCurrentUser( + const clusterState: ClusterStateAPIResponse = await dataClient.callAsCurrentUser( 'cluster.state', { index: indexNames, @@ -43,7 +44,7 @@ export async function getUpgradeAssistantStatus( indices.forEach(indexData => { indexData.blockerForReindexing = - indicesMetadata.metadata.indices[indexData.index!].state === 'close' + getIndexStateFromClusterState(indexData.index!, clusterState) === 'close' ? 'index-closed' : undefined; }); 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 38fc1f0c6356f..0bc6e83ad1065 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js @@ -53,6 +53,9 @@ export default function({ getService }) { const { body } = await supertest .post(`/api/upgrade_assistant/reindex/dummydata`) .set('kbn-xsrf', 'xxx') + .send({ + openAndClose: false, + }) .expect(200); expect(body.indexName).to.equal('dummydata'); @@ -101,6 +104,9 @@ export default function({ getService }) { await supertest .post(`/api/upgrade_assistant/reindex/dummydata`) .set('kbn-xsrf', 'xxx') + .send({ + openAndClose: false, + }) .expect(200); const lastState = await waitForReindexToComplete('dummydata'); @@ -125,6 +131,9 @@ export default function({ getService }) { const { body } = await supertest .post(`/api/upgrade_assistant/reindex/7.0-data`) .set('kbn-xsrf', 'xxx') + .send({ + openAndClose: false, + }) .expect(200); expect(body.indexName).to.equal('7.0-data'); diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts index ba25376e355ff..f38130aa594c1 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/status.ts @@ -6,6 +6,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../api_integration/ftr_provider_context'; +import { getIndexStateFromClusterState } from '../../../plugins/upgrade_assistant/common/get_index_state_from_cluster_state'; // eslint-disable-next-line import/no-default-export export default function({ getService }: FtrProviderContext) { @@ -33,12 +34,12 @@ export default function({ getService }: FtrProviderContext) { }); try { - if (result.body.metadata.indices['7.0-data'].state === 'close') { + if (getIndexStateFromClusterState('7.0-data', result.body) === 'close') { return; } } catch (e) { expect().fail( - `Can no longer access index open/closed state. Please update Upgrade Assistant checkup.` + `Can no longer access index open/closed state. Please update Upgrade Assistant checkup. (${e.message})` ); return; } From 8d75ecb06bb53b998eb251d5be07ffe07aab28cc Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 2 Mar 2020 17:19:26 +0100 Subject: [PATCH 15/27] Fix types --- .../common/get_index_state_from_cluster_state.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.test.ts b/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.test.ts index f1f34820ff07b..1098594a68f8a 100644 --- a/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.test.ts +++ b/x-pack/plugins/upgrade_assistant/common/get_index_state_from_cluster_state.test.ts @@ -11,9 +11,9 @@ describe('getIndexStateFromClusterState', () => { const clusterState: ClusterStateAPIResponse = { metadata: { indices: {}, - cluster_coordination: {}, + cluster_coordination: {} as any, cluster_uuid: 'test', - templates: {}, + templates: {} as any, }, cluster_name: 'test', cluster_uuid: 'test', @@ -33,11 +33,11 @@ describe('getIndexStateFromClusterState', () => { clusterState.metadata.indices.aTotallyDifferentName = { state: 'close', aliases: [indexName, 'test'], - }; + } as any; clusterState.metadata.indices.aTotallyDifferentName1 = { state: 'open', aliases: ['another', 'test'], - }; + } as any; expect(getIndexStateFromClusterState(indexName, clusterState)).toBe('close'); }); @@ -47,7 +47,7 @@ describe('getIndexStateFromClusterState', () => { clusterState.metadata.indices.aTotallyDifferentName1 = { state: 'open', aliases: ['another', 'test'], - }; + } as any; expect(() => getIndexStateFromClusterState(indexName, clusterState)).toThrow('not found'); }); }); From 951f0efb8a1723ea5c7d989e1c93bfc8de2579a2 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 12:40:15 +0100 Subject: [PATCH 16/27] merge-conflict: finish merge conflict resolution --- .../routes/reindex_indices/reindex_indices.ts | 38 +++---------------- 1 file changed, 5 insertions(+), 33 deletions(-) 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 041510165df5e..c06e7e4d92381 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 @@ -109,38 +109,8 @@ export function registerReindexIndicesRoutes( request, response ) => { -<<<<<<< HEAD:x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts - const { indexName } = request.params as any; - const { openAndClose } = request.body as any; - const { client } = savedObjects; - const callAsCurrentUser = dataClient.callAsCurrentUser.bind(dataClient); - const reindexActions = reindexActionsFactory(client, callAsCurrentUser); - const reindexService = reindexServiceFactory( - callAsCurrentUser, - reindexActions, - log, - licensing - ); - - try { - if (!(await reindexService.hasRequiredPrivileges(indexName))) { - return response.forbidden({ - body: `You do not have adequate privileges to reindex this index.`, - }); - } - - const existingOp = await reindexService.findReindexOperation(indexName); - - // If the reindexOp already exists and it's paused, resume it. Otherwise create a new one. - const reindexOp = - existingOp && existingOp.attributes.status === ReindexStatus.paused - ? await reindexService.resumeReindexOperation(indexName) - : await reindexService.createReindexOperation(indexName, { openAndClose }); - - // Add users credentials for the worker to use - credentialStore.set(reindexOp, request.headers); -======= const { indexName } = request.params; + const { openAndClose } = request.body; try { const result = await reindexHandler({ savedObjects: savedObjectsClient, @@ -150,8 +120,8 @@ export function registerReindexIndicesRoutes( licensing, headers: request.headers, credentialStore, + reindexOptions: { openAndClose }, }); ->>>>>>> 3a53fe8e452b6b872fe59c53682b7f79c4cea7ad:x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts // Kick the worker on this node to immediately pickup the new reindex operation. getWorker().forceRefresh(); @@ -236,7 +206,9 @@ export function registerReindexIndicesRoutes( licensing, headers: request.headers, credentialStore, - enqueue: true, + reindexOptions: { + enqueue: true, + }, }); results.enqueued.push(result); } catch (e) { From 15866c9f48588445943a6b39e3a154609316cd54 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 12:45:03 +0100 Subject: [PATCH 17/27] Update x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx Co-Authored-By: Alison Goryachev --- .../tabs/checkup/deprecations/reindex/closed_warning_icon.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx index 7512dc76b4c08..5742a25b218e5 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx @@ -21,7 +21,7 @@ export const ReindexClosedWarningIcon: FunctionComponent = ({ position="top" content={ - {`"${indexName}" needs to be reindexed but it is currently closed. The Upgrade Assistant will open,`} + {`"${indexName}" needs to be reindexed, but it is currently closed. The Upgrade Assistant will open,`} {` reindex and then close the index. Reindexing may take longer than usual.`} } From 4b046f0e087fc90835df588e3b5d6f0bcc450664 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 12:52:18 +0100 Subject: [PATCH 18/27] merge-conflict: Remove duplicate import VSCode does not auto-save as expected :sigh: --- .../upgrade_assistant/server/lib/reindexing/reindex_service.ts | 1 - 1 file changed, 1 deletion(-) 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 8c9e271c5ea68..592eb224a8fe3 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 @@ -13,7 +13,6 @@ import { ReindexStatus, ReindexStep, ReindexWarning, - ReindexOptions, } from '../../../common/types'; import { From 83e18d8d7e123e00e89d65dbcaab77664d84ebab Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 13:46:22 +0100 Subject: [PATCH 19/27] ui: Revisit the UI Moved the warning icon to inside of the button and tooltip to on the button. Added a callout to the reindex flyout for when an index is closed. --- .../checkup/deprecations/reindex/button.tsx | 52 +++++++++---- .../reindex/closed_warning_icon.tsx | 36 --------- .../reindex/flyout/checklist_step.tsx | 4 +- .../deprecations/reindex/flyout/container.tsx | 77 ++++++++++++++++++- .../reindex/flyout/warnings_step.tsx | 4 +- .../checkup/deprecations/reindex/index.tsx | 1 - 6 files changed, 115 insertions(+), 59 deletions(-) delete mode 100644 x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/closed_warning_icon.tsx diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx index 23378198d5f47..65d873fe5b51d 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx @@ -6,9 +6,10 @@ import { set } from 'lodash'; import React, { Fragment, ReactNode } from 'react'; +import { i18n } from '@kbn/i18n'; import { Subscription } from 'rxjs'; -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; +import { EuiButton, EuiLoadingSpinner, EuiText, EuiToolTip } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { DocLinksStart, HttpSetup } from 'src/core/public'; import { @@ -19,7 +20,6 @@ import { import { LoadingState } from '../../../../types'; import { ReindexFlyout } from './flyout'; import { ReindexPollingService, ReindexState } from './polling_service'; -import { ReindexClosedWarningIcon } from './closed_warning_icon'; interface ReindexButtonProps { indexName: string; @@ -142,26 +142,44 @@ export class ReindexButton extends React.Component{buttonContent}; + return ( - - {reindexBlocker === 'index-closed' && reindexState.status !== ReindexStatus.completed ? ( - - - - ) : null} - - {buttonContent} - - + {showIndexedClosedWarning ? ( + + {i18n.translate( + 'xpack.upgradeAssistant.checkupTab.reindexing.reindexButton.indexClosedToolTipDetails', + { + defaultMessage: + '"{indexName}" needs to be reindexed, but it is currently closed. The Upgrade Assistant will open, reindex and then close the index. Reindexing may take longer than usual.', + values: { indexName }, + } + )} + + } + > + {button} + + ) : ( + button + )} {flyoutVisible && ( = ({ - indexName, - docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, -}) => ( - - {`"${indexName}" needs to be reindexed, but it is currently closed. The Upgrade Assistant will open,`} - {` reindex and then close the index. Reindexing may take longer than usual.`} - - } - > - - - - -); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx index e1b8f29757078..96c036af83ba7 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx @@ -68,17 +68,19 @@ const buttonLabel = (status?: ReindexStatus) => { * Displays a flyout that shows the current reindexing status for a given index. */ export const ChecklistFlyoutStep: React.FunctionComponent<{ + renderGlobalCallouts: () => React.Node; closeFlyout: () => void; reindexState: ReindexState; startReindex: () => void; cancelReindex: () => void; -}> = ({ closeFlyout, reindexState, startReindex, cancelReindex }) => { +}> = ({ closeFlyout, reindexState, startReindex, cancelReindex, renderGlobalCallouts }) => { const { loadingState, status, hasRequiredPrivileges } = reindexState; const loading = loadingState === LoadingState.Loading || status === ReindexStatus.inProgress; return ( + {renderGlobalCallouts()} void; cancelReindex: () => void; + docLinks: DocLinksStart; + reindexBlocker?: EnrichedDeprecationInfo['blockerForReindexing']; } interface ReindexFlyoutState { currentFlyoutStep: ReindexFlyoutStep; } +const getOpenAndCloseIndexDocLink = ({ ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }: DocLinksStart) => ( + + {i18n.translate( + 'xpack.upgradeAssistant.checkupTab.reindexing.flyout.openAndCloseDocumentation', + { defaultMessage: 'documentation' } + )} + +); + +const getIndexClosedCallout = (docLinks: DocLinksStart) => ( + <> + +

+ + {i18n.translate( + 'xpack.upgradeAssistant.checkupTab.reindexing.flyout.indexClosedCallout.calloutDetails.reindexingTakesLongerEmphasis', + { defaultMessage: 'Reindexing may take longer than usual' } + )} + + ), + }} + /> +

+
+ + +); + /** * Wrapper for the contents of the flyout that manages which step of the flyout to show. */ @@ -48,7 +105,15 @@ export class ReindexFlyout extends React.Component + reindexBlocker === 'index-closed' ? getIndexClosedCallout(docLinks) : undefined + } closeFlyout={closeFlyout} warnings={reindexState.reindexWarnings!} advanceNextStep={this.advanceNextStep} @@ -65,6 +133,9 @@ export class ReindexFlyout extends React.Component + reindexBlocker === 'index-closed' ? getIndexClosedCallout(docLinks) : undefined + } closeFlyout={closeFlyout} reindexState={reindexState} startReindex={startReindex} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx index 643dd2e9b6efc..b2ceb94f492ee 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx @@ -62,6 +62,7 @@ const WarningCheckbox: React.FunctionComponent<{ ); interface WarningsConfirmationFlyoutProps { + renderGlobalCallouts: () => React.Node; closeFlyout: () => void; warnings: ReindexWarning[]; advanceNextStep: () => void; @@ -91,7 +92,7 @@ export class WarningsFlyoutStep extends React.Component< } public render() { - const { warnings, closeFlyout, advanceNextStep } = this.props; + const { warnings, closeFlyout, advanceNextStep, renderGlobalCallouts } = this.props; const { checkedIds } = this.state; // Do not allow to proceed until all checkboxes are checked. @@ -100,6 +101,7 @@ export class WarningsFlyoutStep extends React.Component< return ( + {renderGlobalCallouts()} Date: Fri, 6 Mar 2020 13:55:12 +0100 Subject: [PATCH 20/27] logic: slight update to when the index closed callout is shown We only show the index closed callout in the flyout when the reindex operation is not considered "completed" --- .../deprecations/reindex/flyout/container.tsx | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx index 8cb102d75f083..42f8a8c4a1717 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx @@ -9,16 +9,16 @@ import { DocLinksStart } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { + EuiCallOut, EuiFlyout, EuiFlyoutHeader, - EuiPortal, - EuiTitle, - EuiCallOut, EuiLink, + EuiPortal, EuiSpacer, + EuiTitle, } from '@elastic/eui'; -import { EnrichedDeprecationInfo } from '../../../../../../../../common/types'; +import { EnrichedDeprecationInfo, ReindexStatus } from '../../../../../../../../common/types'; import { ReindexState } from '../polling_service'; import { ChecklistFlyoutStep } from './checklist_step'; @@ -117,13 +117,16 @@ export class ReindexFlyout extends React.Component - reindexBlocker === 'index-closed' ? getIndexClosedCallout(docLinks) : undefined - } + renderGlobalCallouts={() => globalCallout} closeFlyout={closeFlyout} warnings={reindexState.reindexWarnings!} advanceNextStep={this.advanceNextStep} @@ -133,9 +136,7 @@ export class ReindexFlyout extends React.Component - reindexBlocker === 'index-closed' ? getIndexClosedCallout(docLinks) : undefined - } + renderGlobalCallouts={() => globalCallout} closeFlyout={closeFlyout} reindexState={reindexState} startReindex={startReindex} From 568fe3ff4ee5e8b32343663c54152f5b69e8115e Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 14:21:04 +0100 Subject: [PATCH 21/27] tests: fix jest tests --- .../reindex/flyout/checklist_step.test.tsx | 1 + .../reindex/flyout/warning_step.test.tsx | 1 + .../lib/reindexing/reindex_actions.test.ts | 16 ++++------------ .../lib/reindexing/reindex_service.test.ts | 2 +- .../routes/reindex_indices/reindex_handler.ts | 2 +- .../reindex_indices/reindex_indices.test.ts | 5 ++++- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.test.tsx index b3eefd40f65e4..b550063af4fe3 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.test.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.test.tsx @@ -21,6 +21,7 @@ describe('ChecklistFlyout', () => { onConfirmInputChange: jest.fn(), startReindex: jest.fn(), cancelReindex: jest.fn(), + renderGlobalCallouts: jest.fn(), reindexState: { loadingState: LoadingState.Success, lastCompletedStep: undefined, diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warning_step.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warning_step.test.tsx index fddbe84e28461..318d2bc7baffe 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warning_step.test.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warning_step.test.tsx @@ -16,6 +16,7 @@ describe('WarningsFlyoutStep', () => { advanceNextStep: jest.fn(), warnings: [ReindexWarning.allField, ReindexWarning.booleanFields], closeFlyout: jest.fn(), + renderGlobalCallouts: jest.fn(), }; it('renders', () => { 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 b012a50fd7b4b..0a8887083c27e 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 @@ -51,9 +51,7 @@ describe('ReindexActions', () => { expect(client.create).toHaveBeenCalledWith(REINDEX_OP_TYPE, { indexName: 'myIndex', newIndexName: `reindexed-v${CURRENT_MAJOR_VERSION}-myIndex`, - reindexOptions: { - openAndClose: false, - }, + reindexOptions: undefined, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: null, @@ -69,9 +67,7 @@ describe('ReindexActions', () => { expect(client.create).toHaveBeenCalledWith(REINDEX_OP_TYPE, { indexName: '.internalIndex', newIndexName: `.reindexed-v${CURRENT_MAJOR_VERSION}-internalIndex`, - reindexOptions: { - openAndClose: false, - }, + reindexOptions: undefined, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: null, @@ -89,9 +85,7 @@ describe('ReindexActions', () => { expect(client.create).toHaveBeenCalledWith(REINDEX_OP_TYPE, { indexName, newIndexName: `reindexed-v${CURRENT_MAJOR_VERSION}-myIndex`, - reindexOptions: { - openAndClose: false, - }, + reindexOptions: undefined, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: null, @@ -107,9 +101,7 @@ describe('ReindexActions', () => { expect(client.create).toHaveBeenCalledWith(REINDEX_OP_TYPE, { indexName: `reindexed-v${PREV_MAJOR_VERSION}-myIndex`, newIndexName: `reindexed-v${CURRENT_MAJOR_VERSION}-myIndex`, - reindexOptions: { - openAndClose: false, - }, + reindexOptions: undefined, status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: 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 d2e4c68466ade..beb7b28e05e97 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 @@ -215,7 +215,7 @@ describe('reindexService', () => { await service.createReindexOperation('myIndex'); - expect(actions.createReindexOp).toHaveBeenCalledWith('myIndex', { openAndClose: false }); + expect(actions.createReindexOp).toHaveBeenCalledWith('myIndex', undefined); }); it('fails if index does not exist', async () => { 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 dfacd587d7524..b7569d8679590 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 @@ -56,7 +56,7 @@ export const reindexHandler = async ({ const opts: ReindexOptions | undefined = reindexOptions ? { - ...reindexOptions, + openAndClose: reindexOptions.openAndClose, queueSettings: reindexOptions.enqueue ? { queuedAt: Date.now() } : undefined, } : undefined; diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts index e517195d4db21..8beddc4a5e624 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts @@ -237,7 +237,10 @@ describe('reindex API', () => { kibanaResponseFactory ); // It called resume correctly - expect(mockReindexService.resumeReindexOperation).toHaveBeenCalledWith('theIndex', undefined); + expect(mockReindexService.resumeReindexOperation).toHaveBeenCalledWith('theIndex', { + openAndClose: false, + queueSettings: undefined, + }); expect(mockReindexService.createReindexOperation).not.toHaveBeenCalled(); // It returned the right results From d2355b41a7824f3faa47af1df9c6fa1d349d9013 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 14:45:33 +0100 Subject: [PATCH 22/27] refactor: remove "openAndClose" from reindex endpoints "openAndClose" should just happen automatically. The user should not have to pass the flag in, that would be a weird API. We just need to warn the user about that reindexing a closed index will take more resources --- .../plugins/upgrade_assistant/common/types.ts | 2 +- .../checkup/deprecations/reindex/button.tsx | 6 ++-- .../reindex/polling_service.test.ts | 4 +-- .../deprecations/reindex/polling_service.ts | 12 ++----- .../server/lib/es_indices_state_check.ts | 36 +++++++++++++++++++ .../server/lib/es_migration_apis.ts | 29 ++++----------- .../reindex_indices/reindex_indices.test.ts | 5 ++- .../routes/reindex_indices/reindex_indices.ts | 10 +++--- 8 files changed, 58 insertions(+), 46 deletions(-) create mode 100644 x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index e1081a9c2cbd6..1114e889882c2 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -155,7 +155,7 @@ export interface EnrichedDeprecationInfo extends DeprecationInfo { * @remark * In future this could be an array of blockers. */ - blockerForReindexing?: 'index-closed'; + blockerForReindexing?: 'index-closed'; // 'index-closed' can be handled automatically, but requires more resources, user should be warned } export interface UpgradeAssistantStatus { diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx index 65d873fe5b51d..3738e265515a0 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx @@ -192,10 +192,8 @@ export class ReindexButton extends React.Component { const service = new ReindexPollingService('myIndex', mockClient); await service.startReindex(); - expect(mockClient.post).toHaveBeenCalledWith('/api/upgrade_assistant/reindex/myIndex', { - body: JSON.stringify({ openAndClose: false }), - }); + expect(mockClient.post).toHaveBeenCalledWith('/api/upgrade_assistant/reindex/myIndex'); }); }); diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.ts b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.ts index 2745deb1d1a8b..bcd3abb98f8d4 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.ts @@ -44,11 +44,7 @@ export class ReindexPollingService { public status$: BehaviorSubject; private pollTimeout?: NodeJS.Timeout; - constructor( - private indexName: string, - private http: HttpSetup, - private reindexOptions?: { openAndClose: boolean } - ) { + constructor(private indexName: string, private http: HttpSetup) { this.status$ = new BehaviorSubject({ loadingState: LoadingState.Loading, errorMessage: null, @@ -99,12 +95,8 @@ export class ReindexPollingService { cancelLoadingState: undefined, }); - const options = { - openAndClose: Boolean(this.reindexOptions?.openAndClose), - }; const data = await this.http.post( - `/api/upgrade_assistant/reindex/${this.indexName}`, - { body: JSON.stringify(options) } + `/api/upgrade_assistant/reindex/${this.indexName}` ); this.updateWithResponse({ reindexOp: data }); 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 new file mode 100644 index 0000000000000..9931abf7f416c --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_indices_state_check.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IScopedClusterClient } from 'kibana/server'; +import { getIndexStateFromClusterState } from '../../common/get_index_state_from_cluster_state'; +import { ClusterStateAPIResponse } from '../../common/types'; + +type StatusCheckResult = Record; + +export const esIndicesStateCheck = async ( + dataClient: IScopedClusterClient, + indices: string[] +): Promise => { + // According to https://www.elastic.co/guide/en/elasticsearch/reference/7.6/cluster-state.html + // The response from this call is considered internal and subject to change. We have an API + // integration test for asserting that the current ES version still returns what we expect. + // This lives in x-pack/test/upgrade_assistant_integration + const clusterState: ClusterStateAPIResponse = await dataClient.callAsCurrentUser( + 'cluster.state', + { + index: indices, + metric: 'metadata', + } + ); + + const result: StatusCheckResult = {}; + + indices.forEach(index => { + result[index] = getIndexStateFromClusterState(index, clusterState); + }); + + return result; +}; 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 8d5047c01dbe4..3381e5506f39a 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 @@ -6,12 +6,9 @@ import { IScopedClusterClient } from 'src/core/server'; import { DeprecationAPIResponse } from 'src/legacy/core_plugins/elasticsearch'; -import { - ClusterStateAPIResponse, - EnrichedDeprecationInfo, - UpgradeAssistantStatus, -} from '../../common/types'; -import { getIndexStateFromClusterState } from '../../common/get_index_state_from_cluster_state'; +import { EnrichedDeprecationInfo, UpgradeAssistantStatus } from '../../common/types'; + +import { esIndicesStateCheck } from './es_indices_state_check'; export async function getUpgradeAssistantStatus( dataClient: IScopedClusterClient, @@ -27,26 +24,14 @@ export async function getUpgradeAssistantStatus( const indexNames = indices.map(({ index }) => index!); - // If we have found deprecation information for index/indices, add some additional information; - // is it currently open or closed? + // If we have found deprecation information for index/indices check whether the index is + // open or closed. if (indexNames.length) { - // According to https://www.elastic.co/guide/en/elasticsearch/reference/7.6/cluster-state.html - // The response from this call is considered internal and subject to change. We have an API - // integration test for asserting that the current ES version still returns what we expect. - // This lives in x-pack/test/upgrade_assistant_integration - const clusterState: ClusterStateAPIResponse = await dataClient.callAsCurrentUser( - 'cluster.state', - { - index: indexNames, - metric: 'metadata', - } - ); + const indexStates = await esIndicesStateCheck(dataClient, indexNames); indices.forEach(indexData => { indexData.blockerForReindexing = - getIndexStateFromClusterState(indexData.index!, clusterState) === 'close' - ? 'index-closed' - : undefined; + indexStates[indexData.index!] === 'close' ? 'index-closed' : undefined; }); } diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts index 8beddc4a5e624..55ab2b247dcb1 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts @@ -20,7 +20,7 @@ const mockReindexService = { resumeReindexOperation: jest.fn(), cancelReindexing: jest.fn(), }; - +jest.mock('../../lib/es_indices_state_check', () => ({ esIndicesStateCheck: jest.fn() })); jest.mock('../../lib/es_version_precheck', () => ({ versionCheckHandlerWrapper: (a: any) => a, })); @@ -39,6 +39,7 @@ import { } from '../../../common/types'; import { credentialStoreFactory } from '../../lib/reindexing/credential_store'; import { registerReindexIndicesRoutes } from './reindex_indices'; +import { esIndicesStateCheck } from '../../lib/es_indices_state_check'; /** * Since these route callbacks are so thin, these serve simply as integration tests @@ -56,6 +57,7 @@ describe('reindex API', () => { } as any; beforeEach(() => { + (esIndicesStateCheck as jest.Mock).mockResolvedValue({}); mockRouter = createMockRouter(); routeDependencies = { credentialStore, @@ -270,6 +272,7 @@ describe('reindex API', () => { describe('POST /api/upgrade_assistant/reindex/batch', () => { const queueSettingsArg = { + openAndClose: false, queueSettings: { queuedAt: expect.any(Number) }, }; it('creates a collection of index operations', async () => { 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 c06e7e4d92381..0846e6c0d31d3 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 @@ -16,6 +16,7 @@ import { LicensingPluginSetup } from '../../../../licensing/server'; import { ReindexStatus } from '../../../common/types'; import { versionCheckHandlerWrapper } from '../../lib/es_version_precheck'; +import { esIndicesStateCheck } from '../../lib/es_indices_state_check'; import { reindexServiceFactory, ReindexWorker } from '../../lib/reindexing'; import { CredentialStore } from '../../lib/reindexing/credential_store'; import { reindexActionsFactory } from '../../lib/reindexing/reindex_actions'; @@ -93,9 +94,6 @@ export function registerReindexIndicesRoutes( params: schema.object({ indexName: schema.string(), }), - body: schema.object({ - openAndClose: schema.boolean({ defaultValue: false }), - }), }, }, versionCheckHandlerWrapper( @@ -110,7 +108,7 @@ export function registerReindexIndicesRoutes( response ) => { const { indexName } = request.params; - const { openAndClose } = request.body; + const indexStates = await esIndicesStateCheck(dataClient, [indexName]); try { const result = await reindexHandler({ savedObjects: savedObjectsClient, @@ -120,7 +118,7 @@ export function registerReindexIndicesRoutes( licensing, headers: request.headers, credentialStore, - reindexOptions: { openAndClose }, + reindexOptions: { openAndClose: indexStates[indexName] === 'close' }, }); // Kick the worker on this node to immediately pickup the new reindex operation. @@ -192,6 +190,7 @@ export function registerReindexIndicesRoutes( response ) => { const { indexNames } = request.body; + const indexStates = await esIndicesStateCheck(dataClient, indexNames); const results: PostBatchResponse = { enqueued: [], errors: [], @@ -207,6 +206,7 @@ export function registerReindexIndicesRoutes( headers: request.headers, credentialStore, reindexOptions: { + openAndClose: indexStates[indexName] === 'close', enqueue: true, }, }); From 97d6d72a51b7c86d9143c5b58abd71685e5980d9 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 15:07:39 +0100 Subject: [PATCH 23/27] test: update upgrade assistant integration test --- .../upgrade_assistant/reindexing.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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 fb11a814af071..b50aba20c9b83 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js @@ -8,6 +8,7 @@ import expect from '@kbn/expect'; import { ReindexStatus, REINDEX_OP_TYPE } from '../../../plugins/upgrade_assistant/common/types'; import { generateNewIndexName } from '../../../plugins/upgrade_assistant/server/lib/reindexing/index_settings'; +import { getIndexStateFromClusterState } from '../../../plugins/upgrade_assistant/common/get_index_state_from_cluster_state'; export default function({ getService }) { const supertest = getService('supertest'); @@ -187,6 +188,8 @@ export default function({ getService }) { await es.indices.create({ index: test2 }); await es.indices.create({ index: test3 }); + await es.indices.close({ index: test1 }); + const result = await supertest .post(`/api/upgrade_assistant/reindex/batch`) .set('kbn-xsrf', 'xxx') @@ -206,6 +209,18 @@ export default function({ getService }) { await waitForReindexToComplete(test3); await assertQueueState(undefined, 0); + + // Check that the closed index is still closed after reindexing + const clusterStateResponse = await es.cluster.state({ + index: generateNewIndexName(test1), + metric: 'metadata', + }); + + const test1ReindexedState = getIndexStateFromClusterState( + generateNewIndexName(test1), + clusterStateResponse + ); + expect(test1ReindexedState).to.be('close'); } finally { await cleanupReindex(test1); await cleanupReindex(test2); From a2dd0ead686feee373678ed590cefea2c5b15ebe Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 17:11:51 +0100 Subject: [PATCH 24/27] fix: types --- .../tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx | 2 +- .../tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx index 96c036af83ba7..31ddaba99a896 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx @@ -68,7 +68,7 @@ const buttonLabel = (status?: ReindexStatus) => { * Displays a flyout that shows the current reindexing status for a given index. */ export const ChecklistFlyoutStep: React.FunctionComponent<{ - renderGlobalCallouts: () => React.Node; + renderGlobalCallouts: () => React.ReactNode; closeFlyout: () => void; reindexState: ReindexState; startReindex: () => void; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx index b2ceb94f492ee..4e296aca3d0b7 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx @@ -62,7 +62,7 @@ const WarningCheckbox: React.FunctionComponent<{ ); interface WarningsConfirmationFlyoutProps { - renderGlobalCallouts: () => React.Node; + renderGlobalCallouts: () => React.ReactNode; closeFlyout: () => void; warnings: ReindexWarning[]; advanceNextStep: () => void; From 53fedc617141453c5b2d287ae12b108a6b44e7a3 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Fri, 6 Mar 2020 17:12:07 +0100 Subject: [PATCH 25/27] copy: use sentence case --- .../tabs/checkup/deprecations/reindex/flyout/container.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx index 42f8a8c4a1717..be4138b7a29f3 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx @@ -60,7 +60,7 @@ const getIndexClosedCallout = (docLinks: DocLinksStart) => ( Date: Fri, 6 Mar 2020 17:19:20 +0100 Subject: [PATCH 26/27] refactor: use the in scope declaration of reindex op --- .../upgrade_assistant/server/lib/reindexing/reindex_service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 592eb224a8fe3..4cc465e1f10b9 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 @@ -656,7 +656,7 @@ export const reindexServiceFactory = ( return actions.updateReindexOp(op, { status: ReindexStatus.inProgress, - reindexOptions: opts ?? reindexOp.attributes.reindexOptions, + reindexOptions: opts ?? op.attributes.reindexOptions, }); }); }, From 42dbd5a2eb4d440dc8116af5f25cd2065d6b241e Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Sat, 7 Mar 2020 11:44:01 +0100 Subject: [PATCH 27/27] test: Clean up tests Reindexing test was generating index name, could just get it from server response. Also removed openAndClose from all integration tests --- .../reindex_indices/reindex_indices.test.ts | 8 ++------ .../upgrade_assistant/reindexing.js | 15 ++++----------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts index 55ab2b247dcb1..dc1516ad76560 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts @@ -163,7 +163,7 @@ describe('reindex API', () => { pathPattern: '/api/upgrade_assistant/reindex/{indexName}', })( routeHandlerContextMock, - createRequestMock({ params: { indexName: 'theIndex' }, body: { openAndClose: false } }), + createRequestMock({ params: { indexName: 'theIndex' } }), kibanaResponseFactory ); @@ -188,7 +188,7 @@ describe('reindex API', () => { pathPattern: '/api/upgrade_assistant/reindex/{indexName}', })( routeHandlerContextMock, - createRequestMock({ params: { indexName: 'theIndex' }, body: { openAndClose: false } }), + createRequestMock({ params: { indexName: 'theIndex' } }), kibanaResponseFactory ); @@ -211,7 +211,6 @@ describe('reindex API', () => { 'kbn-auth-x': 'HERE!', }, params: { indexName: 'theIndex' }, - body: { openAndClose: false }, }), kibanaResponseFactory ); @@ -234,7 +233,6 @@ describe('reindex API', () => { routeHandlerContextMock, createRequestMock({ params: { indexName: 'theIndex' }, - body: { openAndClose: false }, }), kibanaResponseFactory ); @@ -261,7 +259,6 @@ describe('reindex API', () => { routeHandlerContextMock, createRequestMock({ params: { indexName: 'theIndex' }, - body: { openAndClose: false }, }), kibanaResponseFactory ); @@ -387,7 +384,6 @@ describe('reindex API', () => { routeHandlerContextMock, createRequestMock({ params: { indexName: 'cancelMe' }, - body: { openAndClose: false }, }), kibanaResponseFactory ); 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 b50aba20c9b83..d2cae9830d31a 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js @@ -55,9 +55,6 @@ export default function({ getService }) { const { body } = await supertest .post(`/api/upgrade_assistant/reindex/dummydata`) .set('kbn-xsrf', 'xxx') - .send({ - openAndClose: false, - }) .expect(200); expect(body.indexName).to.equal('dummydata'); @@ -106,9 +103,6 @@ export default function({ getService }) { await supertest .post(`/api/upgrade_assistant/reindex/dummydata`) .set('kbn-xsrf', 'xxx') - .send({ - openAndClose: false, - }) .expect(200); const lastState = await waitForReindexToComplete('dummydata'); @@ -133,9 +127,6 @@ export default function({ getService }) { const { body } = await supertest .post(`/api/upgrade_assistant/reindex/7.0-data`) .set('kbn-xsrf', 'xxx') - .send({ - openAndClose: false, - }) .expect(200); expect(body.indexName).to.equal('7.0-data'); @@ -199,6 +190,8 @@ export default function({ getService }) { expect(result.body.enqueued.length).to.equal(3); expect(result.body.errors.length).to.equal(0); + const [{ newIndexName: newTest1Name }] = result.body.enqueued; + await assertQueueState(test1, 3); await waitForReindexToComplete(test1); @@ -212,12 +205,12 @@ export default function({ getService }) { // Check that the closed index is still closed after reindexing const clusterStateResponse = await es.cluster.state({ - index: generateNewIndexName(test1), + index: newTest1Name, metric: 'metadata', }); const test1ReindexedState = getIndexStateFromClusterState( - generateNewIndexName(test1), + newTest1Name, clusterStateResponse ); expect(test1ReindexedState).to.be('close');