diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 818a6fd74ed1b..7bb071e348a13 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -845,7 +845,9 @@ x-pack/platform/packages/private/security/authorization_core @elastic/kibana-sec x-pack/platform/packages/private/security/authorization_core_common @elastic/kibana-security x-pack/platform/packages/private/security/role_management_model @elastic/kibana-security x-pack/platform/packages/private/security/ui_components @elastic/kibana-security -x-pack/platform/packages/private/upgrade-assistant @elastic/kibana-management +x-pack/platform/packages/private/upgrade-assistant/common @elastic/kibana-management +x-pack/platform/packages/private/upgrade-assistant/public @elastic/kibana-management +x-pack/platform/packages/private/upgrade-assistant/server @elastic/kibana-management x-pack/platform/packages/shared/ai-assistant/ai-assistant-cta @elastic/appex-sharedux x-pack/platform/packages/shared/ai-assistant/common @elastic/search-kibana x-pack/platform/packages/shared/ai-assistant/icon @elastic/appex-sharedux @@ -931,6 +933,7 @@ x-pack/platform/plugins/private/monitoring_collection @elastic/stack-monitoring x-pack/platform/plugins/private/observability_ai_assistant_management @elastic/obs-ai-assistant x-pack/platform/plugins/private/painless_lab @elastic/kibana-management x-pack/platform/plugins/private/product_intercept @elastic/appex-sharedux +x-pack/platform/plugins/private/reindex_service @elastic/kibana-management x-pack/platform/plugins/private/remote_clusters @elastic/kibana-management x-pack/platform/plugins/private/reporting @elastic/response-ops x-pack/platform/plugins/private/rollup @elastic/kibana-management diff --git a/docs/extend/plugin-list.md b/docs/extend/plugin-list.md index 42b1b56ed7f58..cceab98055369 100644 --- a/docs/extend/plugin-list.md +++ b/docs/extend/plugin-list.md @@ -187,6 +187,7 @@ mapped_pages: | [productIntercept](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/private/product_intercept/README.md) | This is a standalone plugin that leverages the intercept plugin to display product intercept used to gather information that is turn used to compute CSAT about user's experience of Kibana. | | [profiling](https://github.com/elastic/kibana/blob/main/x-pack/solutions/observability/plugins/profiling/README.md) | Universal Profiling provides fleet-wide, whole-system, continuous profiling with zero instrumentation. Get a comprehensive understanding of what lines of code are consuming compute resources throughout your entire fleet by visualizing your data in Kibana using the flamegraph, stacktraces, and top functions views. | | [profilingDataAccess](https://github.com/elastic/kibana/blob/main/x-pack/solutions/observability/plugins/profiling_data_access) | WARNING: Missing or empty README. | +| [reindexService](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/private/reindex_service/README.md) | Reindexing as a service | | [remoteClusters](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/private/remote_clusters/README.md) | This plugin helps users manage their remote clusters, which enable cross-cluster search and cross-cluster replication. | | [reporting](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/private/reporting/README.md) | An awesome Kibana reporting plugin | | [rollup](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/private/rollup/README.md) | Welcome to the Kibana rollup plugin! This plugin provides Kibana support for Elasticsearch's rollup feature. Please refer to the Elasticsearch documentation to understand rollup indices and how to create rollup jobs. | diff --git a/package.json b/package.json index cc4fad81be0ca..109da328967bf 100644 --- a/package.json +++ b/package.json @@ -789,6 +789,7 @@ "@kbn/react-kibana-mount": "link:src/platform/packages/shared/react/kibana_mount", "@kbn/react-mute-legacy-root-warning": "link:src/platform/packages/private/kbn-react-mute-legacy-root-warning", "@kbn/recently-accessed": "link:src/platform/packages/shared/kbn-recently-accessed", + "@kbn/reindex-service-plugin": "link:x-pack/platform/plugins/private/reindex_service", "@kbn/remote-clusters-plugin": "link:x-pack/platform/plugins/private/remote_clusters", "@kbn/rendering-plugin": "link:src/platform/test/plugin_functional/plugins/rendering_plugin", "@kbn/repo-info": "link:src/platform/packages/shared/kbn-repo-info", @@ -1048,7 +1049,9 @@ "@kbn/unified-tabs-examples-plugin": "link:examples/unified_tabs_examples", "@kbn/unsaved-changes-badge": "link:src/platform/packages/private/kbn-unsaved-changes-badge", "@kbn/unsaved-changes-prompt": "link:src/platform/packages/shared/kbn-unsaved-changes-prompt", - "@kbn/upgrade-assistant": "link:x-pack/platform/packages/private/upgrade-assistant", + "@kbn/upgrade-assistant-pkg-common": "link:x-pack/platform/packages/private/upgrade-assistant/common", + "@kbn/upgrade-assistant-pkg-public": "link:x-pack/platform/packages/private/upgrade-assistant/public", + "@kbn/upgrade-assistant-pkg-server": "link:x-pack/platform/packages/private/upgrade-assistant/server", "@kbn/upgrade-assistant-plugin": "link:x-pack/platform/plugins/private/upgrade_assistant", "@kbn/uptime-plugin": "link:x-pack/solutions/observability/plugins/uptime", "@kbn/url-drilldown-plugin": "link:x-pack/platform/plugins/private/drilldowns/url_drilldown", diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index fb56a7966ab03..4bd8220dbe09d 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -67,5 +67,5 @@ export const storybookAliases = { ui_actions_enhanced: 'src/platform/plugins/shared/ui_actions_enhanced/.storybook', unified_search: 'src/platform/plugins/shared/unified_search/.storybook', unified_tabs: 'src/platform/packages/shared/kbn-unified-tabs/.storybook', - upgrade_assistant: 'x-pack/platform/packages/private/upgrade-assistant/.storybook', + upgrade_assistant: 'x-pack/platform/packages/private/upgrade-assistant/public/.storybook', }; diff --git a/tsconfig.base.json b/tsconfig.base.json index 2cc5ad2ad7d32..8399119ca836c 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1538,6 +1538,8 @@ "@kbn/react-mute-legacy-root-warning/*": ["src/platform/packages/private/kbn-react-mute-legacy-root-warning/*"], "@kbn/recently-accessed": ["src/platform/packages/shared/kbn-recently-accessed"], "@kbn/recently-accessed/*": ["src/platform/packages/shared/kbn-recently-accessed/*"], + "@kbn/reindex-service-plugin": ["x-pack/platform/plugins/private/reindex_service"], + "@kbn/reindex-service-plugin/*": ["x-pack/platform/plugins/private/reindex_service/*"], "@kbn/relocate": ["packages/kbn-relocate"], "@kbn/relocate/*": ["packages/kbn-relocate/*"], "@kbn/remote-clusters-plugin": ["x-pack/platform/plugins/private/remote_clusters"], @@ -2162,8 +2164,12 @@ "@kbn/unsaved-changes-badge/*": ["src/platform/packages/private/kbn-unsaved-changes-badge/*"], "@kbn/unsaved-changes-prompt": ["src/platform/packages/shared/kbn-unsaved-changes-prompt"], "@kbn/unsaved-changes-prompt/*": ["src/platform/packages/shared/kbn-unsaved-changes-prompt/*"], - "@kbn/upgrade-assistant": ["x-pack/platform/packages/private/upgrade-assistant"], - "@kbn/upgrade-assistant/*": ["x-pack/platform/packages/private/upgrade-assistant/*"], + "@kbn/upgrade-assistant-pkg-common": ["x-pack/platform/packages/private/upgrade-assistant/common"], + "@kbn/upgrade-assistant-pkg-common/*": ["x-pack/platform/packages/private/upgrade-assistant/common/*"], + "@kbn/upgrade-assistant-pkg-public": ["x-pack/platform/packages/private/upgrade-assistant/public"], + "@kbn/upgrade-assistant-pkg-public/*": ["x-pack/platform/packages/private/upgrade-assistant/public/*"], + "@kbn/upgrade-assistant-pkg-server": ["x-pack/platform/packages/private/upgrade-assistant/server"], + "@kbn/upgrade-assistant-pkg-server/*": ["x-pack/platform/packages/private/upgrade-assistant/server/*"], "@kbn/upgrade-assistant-plugin": ["x-pack/platform/plugins/private/upgrade_assistant"], "@kbn/upgrade-assistant-plugin/*": ["x-pack/platform/plugins/private/upgrade_assistant/*"], "@kbn/uptime-plugin": ["x-pack/solutions/observability/plugins/uptime"], diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 7aa30c8abcfa2..9f3f094b366c5 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -166,7 +166,10 @@ "xpack.triggersActionsUI": "platform/plugins/shared/triggers_actions_ui", "xpack.upgradeAssistant": [ "platform/plugins/private/upgrade_assistant", - "platform/packages/private/upgrade-assistant" + "platform/plugins/private/reindex_service", + "platform/packages/private/upgrade-assistant/common", + "platform/packages/private/upgrade-assistant/public", + "platform/packages/private/upgrade-assistant/server" ], "xpack.uptime": [ "solutions/observability/plugins/uptime" diff --git a/x-pack/platform/packages/private/upgrade-assistant/common/README.md b/x-pack/platform/packages/private/upgrade-assistant/common/README.md new file mode 100644 index 0000000000000..889c29bc903dc --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/common/README.md @@ -0,0 +1,3 @@ +# @kbn/upgrade-assistant-common + +Contains Upgrade Assistant related common code diff --git a/x-pack/platform/packages/private/upgrade-assistant/common/index.ts b/x-pack/platform/packages/private/upgrade-assistant/common/index.ts new file mode 100644 index 0000000000000..9883a2ec5eaac --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/common/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './src/types'; +export * from './src/constants'; diff --git a/x-pack/platform/packages/private/upgrade-assistant/jest.config.js b/x-pack/platform/packages/private/upgrade-assistant/common/jest.config.js similarity index 87% rename from x-pack/platform/packages/private/upgrade-assistant/jest.config.js rename to x-pack/platform/packages/private/upgrade-assistant/common/jest.config.js index 77dd904f1a955..616d18e072991 100644 --- a/x-pack/platform/packages/private/upgrade-assistant/jest.config.js +++ b/x-pack/platform/packages/private/upgrade-assistant/common/jest.config.js @@ -7,6 +7,6 @@ module.exports = { preset: '@kbn/test', - rootDir: '../../../../..', - roots: ['/x-pack/platform/packages/private/upgrade-assistant'], + rootDir: '../../../../../..', + roots: ['/x-pack/platform/packages/private/upgrade-assistant/common'], }; diff --git a/x-pack/platform/packages/private/upgrade-assistant/common/kibana.jsonc b/x-pack/platform/packages/private/upgrade-assistant/common/kibana.jsonc new file mode 100644 index 0000000000000..e829bd3a2b887 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/common/kibana.jsonc @@ -0,0 +1,9 @@ +{ + "type": "shared-common", + "id": "@kbn/upgrade-assistant-pkg-common", + "owner": [ + "@elastic/kibana-management" + ], + "group": "platform", + "visibility": "private" +} diff --git a/x-pack/platform/packages/private/upgrade-assistant/package.json b/x-pack/platform/packages/private/upgrade-assistant/common/package.json similarity index 62% rename from x-pack/platform/packages/private/upgrade-assistant/package.json rename to x-pack/platform/packages/private/upgrade-assistant/common/package.json index 2c2b26b06436a..9df85d3c287f9 100644 --- a/x-pack/platform/packages/private/upgrade-assistant/package.json +++ b/x-pack/platform/packages/private/upgrade-assistant/common/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/upgrade-assistant", + "name": "@kbn/upgrade-assistant-pkg-common", "private": true, "version": "1.0.0", "license": "Elastic License 2.0" diff --git a/x-pack/platform/packages/private/upgrade-assistant/common/src/constants.ts b/x-pack/platform/packages/private/upgrade-assistant/common/src/constants.ts new file mode 100644 index 0000000000000..5fe95b4d72ea9 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/common/src/constants.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +const ML_UPGRADE_OP_TYPE = 'upgrade-assistant-ml-upgrade-operation'; +const REINDEX_OP_TYPE = 'upgrade-assistant-reindex-operation'; +const UA_BASE_PATH = '/api/upgrade_assistant'; + +export { ML_UPGRADE_OP_TYPE, REINDEX_OP_TYPE, UA_BASE_PATH }; diff --git a/x-pack/platform/packages/private/upgrade-assistant/common/src/types.ts b/x-pack/platform/packages/private/upgrade-assistant/common/src/types.ts new file mode 100644 index 0000000000000..f34e7b43a0210 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/common/src/types.ts @@ -0,0 +1,143 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SavedObject } from '@kbn/core/types'; + +// 8.0 -> 9.0 warnings +export type IndexWarningType = 'indexSetting' | 'replaceIndexWithAlias' | 'makeIndexReadonly'; + +export interface IndexWarning { + warningType: IndexWarningType; + flow: 'reindex' | 'readonly' | 'all'; + /** + * Optional metadata for deprecations + * + * @remark + * For "indexSetting" we want to surface the deprecated settings. + */ + meta?: { + [key: string]: string | string[] | boolean; + }; +} + +export interface QueueSettings { + /** + * A Unix timestamp of when the reindex operation was enqueued. + * + * @remark + * This is used by the reindexing scheduler to determine execution + * order. + */ + queuedAt: number; + + /** + * A Unix timestamp of when the reindex operation was started. + * + * @remark + * Updating this field is useful for _also_ updating the saved object "updated_at" field + * which is used to determine stale or abandoned reindex operations. + * + * For now this is used by the reindex worker scheduler to determine whether we have + * A queue item at the start of the queue. + * + */ + startedAt?: number; +} + +export interface ReindexOptions { + /** + * 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; + + /** + * Set this key to configure a reindex operation as part of a + * batch to be run in series. + */ + queueSettings?: QueueSettings; +} + +export interface ReindexStatusResponse { + meta: { + indexName: string; + reindexName: string; + // Array of aliases pointing to the index being reindexed + aliases: string[]; + isReadonly: boolean; + isFrozen: boolean; + isInDataStream: boolean; + isFollowerIndex: boolean; + }; + warnings?: IndexWarning[]; + reindexOp?: ReindexOperation; + hasRequiredPrivileges?: boolean; +} + +export interface ReindexOperation { + indexName: string; + newIndexName: string; + status: ReindexStatus; + lastCompletedStep: ReindexStep; + locked: string | null; + reindexTaskId: string | null; + reindexTaskPercComplete: number | null; + errorMessage: string | null; + // This field is only used for the singleton IndexConsumerType documents. + runningReindexCount: number | null; + rollupJob?: string; + + /** + * The original index settings to set after reindex is completed. + * The target index is created with other defaults to improve reindexing performance. + * https://github.com/elastic/kibana/issues/201605 + */ + backupSettings?: { + 'index.number_of_replicas'?: number; + 'index.refresh_interval'?: number; + }; + + /** + * 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 interface ReindexOperationCancelResponse { + acknowledged: true; +} + +export enum ReindexStep { + // Enum values are spaced out by 10 to give us room to insert steps in between. + created = 0, + readonly = 20, + newIndexCreated = 30, + reindexStarted = 40, + reindexCompleted = 50, + indexSettingsRestored = 55, + aliasCreated = 60, + originalIndexDeleted = 70, + existingAliasesUpdated = 80, +} + +export enum ReindexStatus { + inProgress, + completed, + failed, + paused, + cancelled, + // Used by the UI to differentiate if there was a failure retrieving + // the status from the server API + fetchFailed, +} + +export type ReindexSavedObject = SavedObject; diff --git a/x-pack/platform/packages/private/upgrade-assistant/common/tsconfig.json b/x-pack/platform/packages/private/upgrade-assistant/common/tsconfig.json new file mode 100644 index 0000000000000..192ab525c7ea6 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/common/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [ + "@kbn/core", + ] +} diff --git a/x-pack/platform/packages/private/upgrade-assistant/.storybook/main.js b/x-pack/platform/packages/private/upgrade-assistant/public/.storybook/main.js similarity index 100% rename from x-pack/platform/packages/private/upgrade-assistant/.storybook/main.js rename to x-pack/platform/packages/private/upgrade-assistant/public/.storybook/main.js diff --git a/x-pack/platform/packages/private/upgrade-assistant/README.md b/x-pack/platform/packages/private/upgrade-assistant/public/README.md similarity index 73% rename from x-pack/platform/packages/private/upgrade-assistant/README.md rename to x-pack/platform/packages/private/upgrade-assistant/public/README.md index 8c417f066410e..cff5470a7f302 100644 --- a/x-pack/platform/packages/private/upgrade-assistant/README.md +++ b/x-pack/platform/packages/private/upgrade-assistant/public/README.md @@ -1,3 +1,3 @@ -# @kbn/upgrade-assistant +# @kbn/upgrade-assistant-pkg-public Contains Upgrade Assistant related components and constants to be used by the Upgrade Assistant app. diff --git a/x-pack/platform/packages/private/upgrade-assistant/index.ts b/x-pack/platform/packages/private/upgrade-assistant/public/index.ts similarity index 100% rename from x-pack/platform/packages/private/upgrade-assistant/index.ts rename to x-pack/platform/packages/private/upgrade-assistant/public/index.ts diff --git a/x-pack/platform/packages/private/upgrade-assistant/public/jest.config.js b/x-pack/platform/packages/private/upgrade-assistant/public/jest.config.js new file mode 100644 index 0000000000000..d4395ae7ef4d1 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/public/jest.config.js @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/platform/packages/private/upgrade-assistant/public'], +}; diff --git a/x-pack/platform/packages/private/upgrade-assistant/kibana.jsonc b/x-pack/platform/packages/private/upgrade-assistant/public/kibana.jsonc similarity index 74% rename from x-pack/platform/packages/private/upgrade-assistant/kibana.jsonc rename to x-pack/platform/packages/private/upgrade-assistant/public/kibana.jsonc index 2dc3f43f49881..4095b16d8dc28 100644 --- a/x-pack/platform/packages/private/upgrade-assistant/kibana.jsonc +++ b/x-pack/platform/packages/private/upgrade-assistant/public/kibana.jsonc @@ -1,6 +1,6 @@ { "type": "shared-browser", - "id": "@kbn/upgrade-assistant", + "id": "@kbn/upgrade-assistant-pkg-public", "owner": [ "@elastic/kibana-management" ], diff --git a/x-pack/platform/packages/private/upgrade-assistant/public/package.json b/x-pack/platform/packages/private/upgrade-assistant/public/package.json new file mode 100644 index 0000000000000..e9663e1b397a3 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/public/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/upgrade-assistant-pkg-public", + "private": true, + "version": "1.0.0", + "license": "Elastic License 2.0" +} \ No newline at end of file diff --git a/x-pack/platform/packages/private/upgrade-assistant/src/components/deprecation_badge.stories.tsx b/x-pack/platform/packages/private/upgrade-assistant/public/src/components/deprecation_badge.stories.tsx similarity index 100% rename from x-pack/platform/packages/private/upgrade-assistant/src/components/deprecation_badge.stories.tsx rename to x-pack/platform/packages/private/upgrade-assistant/public/src/components/deprecation_badge.stories.tsx diff --git a/x-pack/platform/packages/private/upgrade-assistant/src/components/deprecation_badge.tsx b/x-pack/platform/packages/private/upgrade-assistant/public/src/components/deprecation_badge.tsx similarity index 100% rename from x-pack/platform/packages/private/upgrade-assistant/src/components/deprecation_badge.tsx rename to x-pack/platform/packages/private/upgrade-assistant/public/src/components/deprecation_badge.tsx diff --git a/x-pack/platform/packages/private/upgrade-assistant/src/components/index.ts b/x-pack/platform/packages/private/upgrade-assistant/public/src/components/index.ts similarity index 100% rename from x-pack/platform/packages/private/upgrade-assistant/src/components/index.ts rename to x-pack/platform/packages/private/upgrade-assistant/public/src/components/index.ts diff --git a/x-pack/platform/packages/private/upgrade-assistant/src/index.ts b/x-pack/platform/packages/private/upgrade-assistant/public/src/index.ts similarity index 100% rename from x-pack/platform/packages/private/upgrade-assistant/src/index.ts rename to x-pack/platform/packages/private/upgrade-assistant/public/src/index.ts diff --git a/x-pack/platform/packages/private/upgrade-assistant/tsconfig.json b/x-pack/platform/packages/private/upgrade-assistant/public/tsconfig.json similarity index 82% rename from x-pack/platform/packages/private/upgrade-assistant/tsconfig.json rename to x-pack/platform/packages/private/upgrade-assistant/public/tsconfig.json index b396ea0bc88e0..585ca6f19ac6a 100644 --- a/x-pack/platform/packages/private/upgrade-assistant/tsconfig.json +++ b/x-pack/platform/packages/private/upgrade-assistant/public/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../../../tsconfig.base.json", + "extends": "../../../../../../tsconfig.base.json", "compilerOptions": { "outDir": "target/types", "types": [ diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/README.md b/x-pack/platform/packages/private/upgrade-assistant/server/README.md new file mode 100644 index 0000000000000..e3f43a43b641b --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/README.md @@ -0,0 +1,3 @@ +# @kbn/upgrade-assistant-pkg-server + +Contains Upgrade Assistant related server side utilities. diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/index.ts b/x-pack/platform/packages/private/upgrade-assistant/server/index.ts new file mode 100644 index 0000000000000..a2c3dd5cdb8ff --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { + FlatSettings, + IndexWarning, + IndexWarningType, + ResolveIndexResponseFromES, +} from './src/types'; +export { getRollupJobByIndexName } from './src/rollup_job'; +export { getReindexWarnings } from './src/index_settings'; +export { Version } from './src/version'; +export { esIndicesStateCheck } from './src/es_indices_state_check'; +export { getIndexState } from './src/get_index_state'; +export { + reindexOperationSavedObjectType, + mlSavedObjectType, + REINDEX_OP_TYPE, +} from './src/saved_object_types'; +export { versionCheckHandlerWrapper } from './src/es_version_precheck'; diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/jest.config.js b/x-pack/platform/packages/private/upgrade-assistant/server/jest.config.js new file mode 100644 index 0000000000000..010ed7bb8838d --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/jest.config.js @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/platform/packages/private/upgrade-assistant/server'], +}; diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/kibana.jsonc b/x-pack/platform/packages/private/upgrade-assistant/server/kibana.jsonc new file mode 100644 index 0000000000000..16115e9244cd7 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/kibana.jsonc @@ -0,0 +1,9 @@ +{ + "type": "shared-server", + "id": "@kbn/upgrade-assistant-pkg-server", + "owner": [ + "@elastic/kibana-management" + ], + "group": "platform", + "visibility": "private" +} diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/package.json b/x-pack/platform/packages/private/upgrade-assistant/server/package.json new file mode 100644 index 0000000000000..37142cc5e66e4 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/upgrade-assistant-pkg-server", + "private": true, + "version": "1.0.0", + "license": "Elastic License 2.0" +} \ No newline at end of file diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/src/__fixtures__/version.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/__fixtures__/version.ts new file mode 100644 index 0000000000000..98d0f1e6bbaa2 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/__fixtures__/version.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { SemVer } from 'semver'; + +const kibanaVersion = new SemVer('8.0.0'); + +export const getMockVersionInfo = () => { + const currentMajor = kibanaVersion.major; + + return { + currentVersion: kibanaVersion, + currentMajor, + prevMajor: currentMajor - 1, + nextMajor: currentMajor + 1, + }; +}; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_indices_state_check.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/es_indices_state_check.ts similarity index 79% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_indices_state_check.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/es_indices_state_check.ts index ea18f8c5ce43a..14046921c2449 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_indices_state_check.ts +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/es_indices_state_check.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { ElasticsearchClient } from '@kbn/core/server'; -import { getIndexState } from '../../common/get_index_state'; -import { ResolveIndexResponseFromES } from '../../common/types'; +import type { ElasticsearchClient } from '@kbn/core/server'; +import { ResolveIndexResponseFromES } from './types'; +import { getIndexState } from './get_index_state'; type StatusCheckResult = Record; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_version_precheck.test.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/es_version_precheck.test.ts similarity index 94% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_version_precheck.test.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/es_version_precheck.test.ts index 952d2b9a21da4..7a2a984961287 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_version_precheck.test.ts +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/es_version_precheck.test.ts @@ -16,7 +16,6 @@ import { getAllNodeVersions, verifyAllMatchKibanaVersion, } from './es_version_precheck'; -import { versionService } from './version'; const { currentMajor, currentVersion } = getMockVersionInfo(); @@ -94,10 +93,6 @@ describe('verifyAllMatchKibanaVersion', () => { }); describe('EsVersionPrecheck', () => { - beforeEach(() => { - versionService.setup('8.0.0'); - }); - it('returns a 403 when callCluster fails with a 403', async () => { const ctx = xpackMocks.createRequestHandlerContext(); @@ -105,7 +100,8 @@ describe('EsVersionPrecheck', () => { const result = await esVersionCheck( coreMock.createCustomRequestHandlerContext(ctx), - kibanaResponseFactory + kibanaResponseFactory, + currentMajor ); expect(result).toHaveProperty('status', 403); }); @@ -124,7 +120,8 @@ describe('EsVersionPrecheck', () => { const result = await esVersionCheck( coreMock.createCustomRequestHandlerContext(ctx), - kibanaResponseFactory + kibanaResponseFactory, + currentMajor ); expect(result).toHaveProperty('status', 426); expect(result).toHaveProperty('payload.attributes.allNodesUpgraded', false); @@ -144,7 +141,8 @@ describe('EsVersionPrecheck', () => { const result = await esVersionCheck( coreMock.createCustomRequestHandlerContext(ctx), - kibanaResponseFactory + kibanaResponseFactory, + currentMajor ); expect(result).toHaveProperty('status', 426); expect(result).toHaveProperty('payload.attributes.allNodesUpgraded', true); @@ -163,7 +161,11 @@ describe('EsVersionPrecheck', () => { }); await expect( - esVersionCheck(coreMock.createCustomRequestHandlerContext(ctx), kibanaResponseFactory) + esVersionCheck( + coreMock.createCustomRequestHandlerContext(ctx), + kibanaResponseFactory, + currentMajor + ) ).resolves.toBe(undefined); }); }); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_version_precheck.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/es_version_precheck.ts similarity index 91% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_version_precheck.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/es_version_precheck.ts index 2e85cbaf73a94..4d8ebb4026b06 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_version_precheck.ts +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/es_version_precheck.ts @@ -7,14 +7,13 @@ import { uniq } from 'lodash'; import { SemVer } from 'semver'; -import { +import type { IScopedClusterClient, KibanaRequest, KibanaResponseFactory, RequestHandler, RequestHandlerContext, } from '@kbn/core/server'; -import { versionService } from './version'; /** * Returns an array of all the unique Elasticsearch Node Versions in the Elasticsearch cluster. @@ -63,7 +62,8 @@ export const verifyAllMatchKibanaVersion = (allNodeVersions: SemVer[], majorVers */ export const esVersionCheck = async ( ctx: RequestHandlerContext, - response: KibanaResponseFactory + response: KibanaResponseFactory, + kibanaMajorVersion: number ) => { const { client } = (await ctx.core).elasticsearch; let allNodeVersions: SemVer[]; @@ -78,9 +78,7 @@ export const esVersionCheck = async ( throw e; } - const majorVersion = versionService.getMajorVersion(); - - const result = verifyAllMatchKibanaVersion(allNodeVersions, majorVersion); + const result = verifyAllMatchKibanaVersion(allNodeVersions, kibanaMajorVersion); if (!result.allNodesMatch) { return response.customError({ // 426 means "Upgrade Required" and is used when semver compatibility is not met. @@ -96,13 +94,14 @@ export const esVersionCheck = async ( }; export const versionCheckHandlerWrapper = + (kibanaMajorVersion: number) => (handler: RequestHandler) => async ( ctx: RequestHandlerContext, request: KibanaRequest, response: KibanaResponseFactory ) => { - const errorResponse = await esVersionCheck(ctx, response); + const errorResponse = await esVersionCheck(ctx, response, kibanaMajorVersion); if (errorResponse) { return errorResponse; } diff --git a/x-pack/platform/plugins/private/upgrade_assistant/common/get_index_state.test.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/get_index_state.test.ts similarity index 100% rename from x-pack/platform/plugins/private/upgrade_assistant/common/get_index_state.test.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/get_index_state.test.ts diff --git a/x-pack/platform/plugins/private/upgrade_assistant/common/get_index_state.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/get_index_state.ts similarity index 100% rename from x-pack/platform/plugins/private/upgrade_assistant/common/get_index_state.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/get_index_state.ts diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/src/index_settings.test.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/index_settings.test.ts new file mode 100644 index 0000000000000..e52434d128176 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/index_settings.test.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getReindexWarnings } from '..'; + +describe('index settings', () => { + describe('getReindexWarnings', () => { + it('does not blow up for empty mappings', () => { + expect( + getReindexWarnings( + { + settings: {}, + mappings: {}, + }, + 8 + ) + ).toEqual([]); + }); + }); +}); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index_settings.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/index_settings.ts similarity index 58% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index_settings.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/index_settings.ts index 28955ab019cf8..13a4c70ace486 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index_settings.ts +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/index_settings.ts @@ -5,15 +5,8 @@ * 2.0. */ -import { IndexWarning } from '../../../common/types'; -import { versionService } from '../version'; -import { FlatSettings } from './types'; -export interface ParsedIndexName { - cleanIndexName: string; - baseName: string; - newIndexName: string; - cleanBaseName: string; -} +import { FlatSettings, IndexWarning } from './types'; + /** * An array of deprecated index settings specific to 7.0 --> 8.0 upgrade * This excludes the deprecated translog retention settings @@ -26,43 +19,6 @@ const deprecatedSettings = [ 'index.soft_deletes.enabled', ]; -/** - * Provides the assumed source of the index name stripping any prefixing - * introduced by the upgrade assistant - * - * Examples: - * .reindex-v7-foo => .foo - * reindex-v7-foo => foo - * - * @param indexName - */ -export const sourceNameForIndex = (indexName: string): string => { - const matches = indexName.match(/^([\.])?(.*)$/) || []; - const internal = matches[1] || ''; - const baseName = matches[2]; - - // in 6.7+ we prepend to avoid conflicts with index patterns/templates/etc - const reindexedMatcher = new RegExp(`reindexed-v${versionService.getPrevMajorVersion()}-`, 'g'); - - const cleanBaseName = baseName.replace(reindexedMatcher, ''); - return `${internal}${cleanBaseName}`; -}; - -/** - * Provides the index name to re-index into - * - * .foo -> .reindexed-v7-foo - * foo => reindexed-v7-foo - */ -export const generateNewIndexName = (indexName: string): string => { - const sourceName = sourceNameForIndex(indexName); - const currentVersion = `reindexed-v${versionService.getMajorVersion()}`; - - return indexName.startsWith('.') - ? `.${currentVersion}-${sourceName.substr(1)}` - : `${currentVersion}-${sourceName}`; -}; - export const getDeprecatedSettingWarning = ( flatSettings: FlatSettings ): IndexWarning | undefined => { @@ -101,10 +57,13 @@ export const getDeprecatedSettingWarning = ( * Returns an array of warnings that should be displayed to user before reindexing begins. * @param flatSettings */ -export const getReindexWarnings = (flatSettings: FlatSettings): IndexWarning[] => { +export const getReindexWarnings = ( + flatSettings: FlatSettings, + kibanaMajorVersion: number +): IndexWarning[] => { const warnings = [] as IndexWarning[]; - if (versionService.getMajorVersion() === 8) { + if (kibanaMajorVersion === 8) { const deprecatedSettingWarning = getDeprecatedSettingWarning(flatSettings); if (deprecatedSettingWarning) { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/rollup_job.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/rollup_job.ts similarity index 100% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/rollup_job.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/rollup_job.ts diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/index.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/index.ts similarity index 90% rename from x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/index.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/index.ts index f8e9ec86d437a..ce504df49db20 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/index.ts +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/index.ts @@ -11,3 +11,4 @@ import { mlSavedObjectType } from './ml_upgrade_operation_saved_object_type'; export { reindexOperationSavedObjectType } from './reindex_operation_saved_object_type'; export { mlSavedObjectType } from './ml_upgrade_operation_saved_object_type'; export const hiddenTypes = [reindexOperationSavedObjectType.name, mlSavedObjectType.name]; +export const REINDEX_OP_TYPE = reindexOperationSavedObjectType.name; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/ml_upgrade_operation_saved_object_type.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/ml_upgrade_operation_saved_object_type.ts similarity index 82% rename from x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/ml_upgrade_operation_saved_object_type.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/ml_upgrade_operation_saved_object_type.ts index 9f677120a5374..723e4dae8ab5d 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/ml_upgrade_operation_saved_object_type.ts +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/ml_upgrade_operation_saved_object_type.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { SavedObjectsType } from '@kbn/core/server'; +import type { SavedObjectsType } from '@kbn/core/server'; -import { ML_UPGRADE_OP_TYPE } from '../../common/types'; +import { ML_UPGRADE_OP_TYPE } from '@kbn/upgrade-assistant-pkg-common'; export const mlSavedObjectType: SavedObjectsType = { name: ML_UPGRADE_OP_TYPE, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/reindex_operation_saved_object_type.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/reindex_operation_saved_object_type.ts similarity index 81% rename from x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/reindex_operation_saved_object_type.ts rename to x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/reindex_operation_saved_object_type.ts index 0c66253312c7a..9bfd13366a3cb 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/saved_object_types/reindex_operation_saved_object_type.ts +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/saved_object_types/reindex_operation_saved_object_type.ts @@ -5,9 +5,8 @@ * 2.0. */ -import { SavedObjectsType } from '@kbn/core/server'; - -import { REINDEX_OP_TYPE } from '../../common/types'; +import type { SavedObjectsType } from '@kbn/core/server'; +import { REINDEX_OP_TYPE } from '@kbn/upgrade-assistant-pkg-common'; export const reindexOperationSavedObjectType: SavedObjectsType = { name: REINDEX_OP_TYPE, diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/src/types.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/types.ts new file mode 100644 index 0000000000000..50c00ee0793cc --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/types.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type * as estypes from '@elastic/elasticsearch/lib/api/types'; + +interface Mapping { + type?: string; + properties?: MappingProperties; +} + +export interface MappingProperties { + [key: string]: Mapping; +} + +interface MetaProperties { + [key: string]: string; +} + +export interface FlatSettings { + settings?: estypes.IndicesIndexState['settings']; + mappings?: { + properties?: MappingProperties; + _meta?: MetaProperties; + }; +} + +// 8.0 -> 9.0 warnings +export type IndexWarningType = 'indexSetting' | 'replaceIndexWithAlias' | 'makeIndexReadonly'; + +export interface IndexWarning { + warningType: IndexWarningType; + flow: 'reindex' | 'readonly' | 'all'; + /** + * Optional metadata for deprecations + * + * @remark + * For "indexSetting" we want to surface the deprecated settings. + */ + meta?: { + [key: string]: string | string[] | boolean; + }; +} + +export interface ResolveIndexResponseFromES { + indices: Array<{ + name: string; + // per https://github.com/elastic/elasticsearch/pull/57626 + attributes: Array<'open' | 'closed' | 'hidden' | 'frozen'>; + aliases?: string[]; + data_stream?: string; + }>; + aliases: Array<{ + name: string; + indices: string[]; + }>; + data_streams: Array<{ name: string; backing_indices: string[]; timestamp_field: string }>; +} diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/src/version.ts b/x-pack/platform/packages/private/upgrade-assistant/server/src/version.ts new file mode 100644 index 0000000000000..bd46863b10997 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/src/version.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 + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import SemVer from 'semver/classes/semver'; + +export interface IVersion { + setup(version: string): void; + getCurrentVersion(): SemVer; + getMajorVersion(): number; + getNextMajorVersion(): number; + getPrevMajorVersion(): number; +} + +export class Version implements IVersion { + private version!: SemVer; + + public setup(version: string) { + this.version = new SemVer(version); + } + + public getCurrentVersion() { + return this.version; + } + + public getMajorVersion() { + return this.version?.major; + } + + public getNextMajorVersion() { + return this.version?.major + 1; + } + + public getPrevMajorVersion() { + return this.version?.major - 1; + } +} diff --git a/x-pack/platform/packages/private/upgrade-assistant/server/tsconfig.json b/x-pack/platform/packages/private/upgrade-assistant/server/tsconfig.json new file mode 100644 index 0000000000000..e8a07f67d0721 --- /dev/null +++ b/x-pack/platform/packages/private/upgrade-assistant/server/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [ + "@kbn/core", + "@kbn/licensing-plugin", + "@kbn/upgrade-assistant-pkg-common", + ] +} diff --git a/x-pack/platform/plugins/private/reindex_service/README.md b/x-pack/platform/plugins/private/reindex_service/README.md new file mode 100644 index 0000000000000..51bd09b6757a8 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/README.md @@ -0,0 +1,5 @@ +# Reindex Service + +## About + +Reindexing as a service \ No newline at end of file diff --git a/x-pack/platform/plugins/private/reindex_service/jest.config.js b/x-pack/platform/plugins/private/reindex_service/jest.config.js new file mode 100644 index 0000000000000..5da34c46241ad --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/jest.config.js @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../..', + roots: ['/x-pack/platform/plugins/private/reindex_service'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/platform/plugins/private/reindex_service', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/platform/plugins/private/reindex_service/{common,public,server}/**/*.{ts,tsx}', + ], +}; diff --git a/x-pack/platform/plugins/private/reindex_service/kibana.jsonc b/x-pack/platform/plugins/private/reindex_service/kibana.jsonc new file mode 100644 index 0000000000000..7fa24c1650a42 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/kibana.jsonc @@ -0,0 +1,24 @@ +{ + "type": "plugin", + "id": "@kbn/reindex-service-plugin", + "owner": "@elastic/kibana-management", + "group": "platform", + "visibility": "private", + "plugin": { + "id": "reindexService", + "server": true, + "browser": true, + "configPath": [ + "xpack", + "reindex_service" + ], + "requiredPlugins": [ + "licensing", + ], + "optionalPlugins": [ + ], + "requiredBundles": [ + "esUiShared", + ] + } +} diff --git a/x-pack/platform/plugins/private/reindex_service/public/index.ts b/x-pack/platform/plugins/private/reindex_service/public/index.ts new file mode 100644 index 0000000000000..85156c2ca6c3a --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/public/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { ReindexService } from './src/reindex_service'; +export type { ReindexServicePublicSetup, ReindexServicePublicStart } from './types'; + +import { ReindexServerPublicPlugin } from './plugin'; + +export function plugin() { + return new ReindexServerPublicPlugin(); +} diff --git a/x-pack/platform/plugins/private/reindex_service/public/plugin.ts b/x-pack/platform/plugins/private/reindex_service/public/plugin.ts new file mode 100644 index 0000000000000..95974fa6b890f --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/public/plugin.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Plugin, CoreSetup } from '@kbn/core/public'; + +import { ReindexService } from './src/reindex_service'; +import type { ReindexServicePublicSetup, ReindexServicePublicStart } from './types'; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface SetupDependencies {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface StartDependencies {} + +export class ReindexServerPublicPlugin + implements + Plugin< + ReindexServicePublicSetup, + ReindexServicePublicStart, + SetupDependencies, + StartDependencies + > +{ + private reindexService?: ReindexService; + + setup({ http }: CoreSetup) { + this.reindexService = new ReindexService(http); + return { + reindexService: this.reindexService, + }; + } + + start() { + return { + reindexService: this.reindexService!, + }; + } + stop() {} +} diff --git a/x-pack/platform/plugins/private/reindex_service/public/src/reindex_service.ts b/x-pack/platform/plugins/private/reindex_service/public/src/reindex_service.ts new file mode 100644 index 0000000000000..c7fbe378bcb6a --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/public/src/reindex_service.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { HttpSetup } from '@kbn/core/public'; +import { + ReindexStatusResponse, + ReindexOperation, + ReindexOperationCancelResponse, + UA_BASE_PATH, +} from '@kbn/upgrade-assistant-pkg-common'; +import { sendRequest } from '@kbn/es-ui-shared-plugin/public'; + +export class ReindexService { + private client: HttpSetup; + + constructor(client: HttpSetup) { + this.client = client; + } + + public async getReindexStatus(indexName: string) { + return sendRequest(this.client, { + method: 'get', + path: `${UA_BASE_PATH}/reindex/${indexName}`, + }); + } + + public async startReindex(indexName: string) { + return sendRequest(this.client, { + method: 'post', + path: `${UA_BASE_PATH}/reindex/${indexName}`, + }); + } + + public async cancelReindex(indexName: string) { + return sendRequest(this.client, { + method: 'post', + path: `${UA_BASE_PATH}/reindex/${indexName}/cancel`, + }); + } +} + +// diff --git a/x-pack/platform/plugins/private/reindex_service/public/types.ts b/x-pack/platform/plugins/private/reindex_service/public/types.ts new file mode 100644 index 0000000000000..762e7e8510537 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/public/types.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ReindexService } from './src/reindex_service'; + +export interface ReindexServicePublicSetup { + reindexService: ReindexService; +} + +export interface ReindexServicePublicStart { + reindexService: ReindexService; +} diff --git a/x-pack/platform/plugins/private/reindex_service/server/index.ts b/x-pack/platform/plugins/private/reindex_service/server/index.ts new file mode 100644 index 0000000000000..e63e57e9cf061 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PluginInitializerContext } from '@kbn/core/server'; + +import { ReindexServiceServerPlugin } from './plugin'; + +export type { ReindexServiceServerPluginStart } from './types'; + +// exported for use in api integration test +export { generateNewIndexName } from './src/lib/index_settings'; + +export const plugin = async (ctx: PluginInitializerContext) => { + return new ReindexServiceServerPlugin(ctx); +}; diff --git a/x-pack/platform/plugins/private/reindex_service/server/plugin.ts b/x-pack/platform/plugins/private/reindex_service/server/plugin.ts new file mode 100644 index 0000000000000..06c292cdb9b40 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/plugin.ts @@ -0,0 +1,133 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SecurityPluginStart } from '@kbn/security-plugin/server'; +import { handleEsError } from '@kbn/es-ui-shared-plugin/server'; + +import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; +import { + CoreSetup, + Logger, + SavedObjectsClient, + SavedObjectsServiceStart, + ElasticsearchServiceStart, + Plugin, + PluginInitializerContext, +} from '@kbn/core/server'; + +import { reindexOperationSavedObjectType, Version } from '@kbn/upgrade-assistant-pkg-server'; +import { RouteDependencies, ReindexServiceServerPluginStart } from './types'; + +import { ReindexWorker } from './src/lib'; +import { CredentialStore, credentialStoreFactory } from './src/lib/credential_store'; +import { registerBatchReindexIndicesRoutes, registerReindexIndicesRoutes } from './src/routes'; + +interface PluginsSetup { + licensing: LicensingPluginSetup; +} + +interface PluginsStart { + security: SecurityPluginStart; +} + +export class ReindexServiceServerPlugin + implements Plugin +{ + private reindexWorker: ReindexWorker | null = null; + + // Properties set at setup + private licensing?: LicensingPluginSetup; + + private readonly logger: Logger; + private readonly credentialStore: CredentialStore; + private securityPluginStart?: SecurityPluginStart; + private version: Version; + + constructor({ logger, env }: PluginInitializerContext) { + this.logger = logger.get(); + // used by worker and passed to routes + this.credentialStore = credentialStoreFactory(this.logger); + this.version = new Version(); + this.version.setup(env.packageInfo.version); + } + + public setup({ http, savedObjects }: CoreSetup, { licensing }: PluginsSetup) { + this.licensing = licensing; + const router = http.createRouter(); + + const dependencies: RouteDependencies = { + router, + credentialStore: this.credentialStore, + log: this.logger, + licensing, + getSecurityPlugin: () => this.securityPluginStart, + lib: { + handleEsError, + }, + version: this.version, + }; + + savedObjects.registerType(reindexOperationSavedObjectType); + + registerReindexIndicesRoutes(dependencies, () => this.getWorker()); + registerBatchReindexIndicesRoutes(dependencies, () => this.getWorker()); + } + + public start( + { + savedObjects, + elasticsearch, + }: { savedObjects: SavedObjectsServiceStart; elasticsearch: ElasticsearchServiceStart }, + { security }: PluginsStart + ) { + this.securityPluginStart = security; + + const soClient = new SavedObjectsClient( + savedObjects.createInternalRepository([reindexOperationSavedObjectType.name]) + ); + + // The ReindexWorker uses a map of request headers that contain the authentication credentials + // for a given reindex. We cannot currently store these in an the .kibana index b/c we do not + // want to expose these credentials to any unauthenticated users. We also want to avoid any need + // to add a user for a special index just for upgrading. This in-memory cache allows us to + // process jobs without the browser staying on the page, but will require that jobs go into + // a paused state if no Kibana nodes have the required credentials. + + // The ReindexWorker will use the credentials stored in the cache to reindex the data + + this.reindexWorker = ReindexWorker.create( + soClient, + this.credentialStore, + elasticsearch.client, + this.logger, + this.licensing!, + security, + this.version + ); + + this.reindexWorker?.start(); + + return { + cleanupReindexOperations: this.reindexWorker?.cleanupReindexOperations.bind( + this.reindexWorker + ), + }; + } + + public stop() { + if (this.reindexWorker) { + this.reindexWorker.stop(); + } + } + + private getWorker() { + if (!this.reindexWorker) { + throw new Error('Worker unavailable'); + } + return this.reindexWorker; + } +} diff --git a/x-pack/platform/plugins/private/reindex_service/server/src/__fixtures__/version.ts b/x-pack/platform/plugins/private/reindex_service/server/src/__fixtures__/version.ts new file mode 100644 index 0000000000000..98d0f1e6bbaa2 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/src/__fixtures__/version.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { SemVer } from 'semver'; + +const kibanaVersion = new SemVer('8.0.0'); + +export const getMockVersionInfo = () => { + const currentMajor = kibanaVersion.major; + + return { + currentVersion: kibanaVersion, + currentMajor, + prevMajor: currentMajor - 1, + nextMajor: currentMajor + 1, + }; +}; diff --git a/x-pack/platform/plugins/private/reindex_service/server/src/__mocks__/request.mock.ts b/x-pack/platform/plugins/private/reindex_service/server/src/__mocks__/request.mock.ts new file mode 100644 index 0000000000000..c77f3a6661ebe --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/src/__mocks__/request.mock.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const createRequestMock = (opts?: { + headers?: any; + params?: Record; + query?: Record; + body?: Record; +}) => { + return Object.assign({ headers: {} }, opts || {}); +}; diff --git a/x-pack/platform/plugins/private/reindex_service/server/src/__mocks__/routes.mock.ts b/x-pack/platform/plugins/private/reindex_service/server/src/__mocks__/routes.mock.ts new file mode 100644 index 0000000000000..3e6870391328a --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/src/__mocks__/routes.mock.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AwaitedProperties } from '@kbn/utility-types'; +import { RequestHandler, RequestHandlerContext } from '@kbn/core/server'; +import { + elasticsearchServiceMock, + savedObjectsClientMock, + deprecationsServiceMock, +} from '@kbn/core/server/mocks'; + +export const savedObjectsClient = savedObjectsClientMock.create(); +export const routeHandlerContextMock = { + core: { + elasticsearch: { + client: elasticsearchServiceMock.createScopedClusterClient(), + }, + savedObjects: { getClient: () => savedObjectsClient }, + deprecations: { client: deprecationsServiceMock.createClient() }, + }, +} as unknown as AwaitedProperties; + +/** + * Creates a very crude mock of the new platform router implementation. This enables use to test + * controller/handler logic without making HTTP requests to an actual server. This does not enable + * us to test whether our paths actual match, only the response codes of controllers given certain + * inputs. This should be replaced by a more wholistic solution (like functional tests) eventually. + * + * This also bypasses any validation installed on the route. + */ +export const createMockRouter = () => { + const paths: Record>> = {}; + + const assign = + (method: string) => + ({ path }: { path: string }, handler: RequestHandler) => { + paths[method] = { + ...(paths[method] || {}), + ...{ [path]: handler }, + }; + }; + + return { + getHandler({ method, pathPattern }: { method: string; pathPattern: string }) { + return paths[method][pathPattern]; + }, + get: assign('get'), + post: assign('post'), + put: assign('put'), + patch: assign('patch'), + delete: assign('delete'), + }; +}; + +export type MockRouter = ReturnType; diff --git a/x-pack/platform/plugins/private/reindex_service/server/src/constants.ts b/x-pack/platform/plugins/private/reindex_service/server/src/constants.ts new file mode 100644 index 0000000000000..6e14c40144f67 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/src/constants.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// +export const API_BASE_PATH_UPRGRADE_ASSISTANT = '/api/upgrade_assistant'; diff --git a/x-pack/platform/plugins/private/reindex_service/server/src/index.ts b/x-pack/platform/plugins/private/reindex_service/server/src/index.ts new file mode 100644 index 0000000000000..1fec1c76430eb --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/src/index.ts @@ -0,0 +1,6 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/credential_store.test.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/credential_store.test.ts similarity index 97% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/credential_store.test.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/credential_store.test.ts index 5be26c69922aa..b550f26dbb42e 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/credential_store.test.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/credential_store.test.ts @@ -10,7 +10,11 @@ import { securityMock } from '@kbn/security-plugin/server/mocks'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { httpServerMock } from '@kbn/core-http-server-mocks'; import { credentialStoreFactory } from './credential_store'; -import { ReindexStep, ReindexStatus, type ReindexSavedObject } from '../../../common/types'; +import { + ReindexStep, + ReindexStatus, + type ReindexSavedObject, +} from '@kbn/upgrade-assistant-pkg-common'; const basicAuthHeader = 'Basic abc'; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/credential_store.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/credential_store.ts similarity index 98% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/credential_store.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/credential_store.ts index 4555dfb02d8c1..70c4016618b37 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/credential_store.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/credential_store.ts @@ -11,7 +11,7 @@ import stringify from 'json-stable-stringify'; import { KibanaRequest, Logger } from '@kbn/core/server'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; -import { ReindexSavedObject, ReindexStatus } from '../../../common/types'; +import { ReindexSavedObject, ReindexStatus } from '@kbn/upgrade-assistant-pkg-common'; export type Credential = Record; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/error.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/error.ts similarity index 100% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/error.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/error.ts diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/error_symbols.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/error_symbols.ts similarity index 100% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/error_symbols.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/error_symbols.ts diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/index.ts similarity index 75% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/index.ts index 1ab6a26e90ffb..4d645118e2495 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/index.ts @@ -5,6 +5,8 @@ * 2.0. */ +export { reindexHandler } from './reindex_handler'; +export { type CredentialStore, credentialStoreFactory } from './credential_store'; export { reindexServiceFactory } from './reindex_service'; export { ReindexWorker } from './worker'; export { generateNewIndexName } from './index_settings'; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index_settings.test.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/index_settings.test.ts similarity index 58% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index_settings.test.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/index_settings.test.ts index 17eadc16c6229..232c59b0c13e2 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/index_settings.test.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/index_settings.test.ts @@ -5,13 +5,17 @@ * 2.0. */ -import { versionService } from '../version'; +import { Version } from '@kbn/upgrade-assistant-pkg-server'; + import { getMockVersionInfo } from '../__fixtures__/version'; -import { generateNewIndexName, getReindexWarnings, sourceNameForIndex } from './index_settings'; +import { generateNewIndexName, sourceNameForIndex } from './index_settings'; const { currentMajor, prevMajor } = getMockVersionInfo(); +const versionService = new Version(); +versionService.setup('8.0.0'); + describe('index settings', () => { describe('sourceNameForIndex', () => { beforeEach(() => { @@ -19,18 +23,20 @@ describe('index settings', () => { }); it('parses internal indices', () => { - expect(sourceNameForIndex('.myInternalIndex')).toEqual('.myInternalIndex'); + expect(sourceNameForIndex('.myInternalIndex', versionService)).toEqual('.myInternalIndex'); }); it('parses non-internal indices', () => { - expect(sourceNameForIndex('myIndex')).toEqual('myIndex'); + expect(sourceNameForIndex('myIndex', versionService)).toEqual('myIndex'); }); it(`replaces reindexed-v${prevMajor} with reindexed-v${currentMajor} in newIndexName`, () => { - expect(sourceNameForIndex(`reindexed-v${prevMajor}-myIndex`)).toEqual('myIndex'); - expect(sourceNameForIndex(`.reindexed-v${prevMajor}-myInternalIndex`)).toEqual( - '.myInternalIndex' + expect(sourceNameForIndex(`reindexed-v${prevMajor}-myIndex`, versionService)).toEqual( + 'myIndex' ); + expect( + sourceNameForIndex(`.reindexed-v${prevMajor}-myInternalIndex`, versionService) + ).toEqual('.myInternalIndex'); }); }); @@ -40,34 +46,25 @@ describe('index settings', () => { }); it('parses internal indices', () => { - expect(generateNewIndexName('.myInternalIndex')).toEqual( + expect(generateNewIndexName('.myInternalIndex', versionService)).toEqual( `.reindexed-v${currentMajor}-myInternalIndex` ); }); it('parses non-internal indices', () => { - expect(generateNewIndexName('myIndex')).toEqual(`reindexed-v${currentMajor}-myIndex`); + expect(generateNewIndexName('myIndex', versionService)).toEqual( + `reindexed-v${currentMajor}-myIndex` + ); }); it(`replaces reindexed-v${prevMajor} with reindexed-v${currentMajor} in generateNewIndexName`, () => { - expect(generateNewIndexName(`reindexed-v${prevMajor}-myIndex`)).toEqual( + expect(generateNewIndexName(`reindexed-v${prevMajor}-myIndex`, versionService)).toEqual( `reindexed-v${currentMajor}-myIndex` ); - expect(generateNewIndexName(`.reindexed-v${prevMajor}-myInternalIndex`)).toEqual( - `.reindexed-v${currentMajor}-myInternalIndex` - ); - }); - }); - - describe('getReindexWarnings', () => { - it('does not blow up for empty mappings', () => { expect( - getReindexWarnings({ - settings: {}, - mappings: {}, - }) - ).toEqual([]); + generateNewIndexName(`.reindexed-v${prevMajor}-myInternalIndex`, versionService) + ).toEqual(`.reindexed-v${currentMajor}-myInternalIndex`); }); }); }); diff --git a/x-pack/platform/plugins/private/reindex_service/server/src/lib/index_settings.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/index_settings.ts new file mode 100644 index 0000000000000..ba406023df233 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/index_settings.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Version } from '@kbn/upgrade-assistant-pkg-server'; +export interface ParsedIndexName { + cleanIndexName: string; + baseName: string; + newIndexName: string; + cleanBaseName: string; +} + +/** + * Provides the assumed source of the index name stripping any prefixing + * introduced by the upgrade assistant + * + * Examples: + * .reindex-v7-foo => .foo + * reindex-v7-foo => foo + * + * @param indexName + */ +export const sourceNameForIndex = (indexName: string, versionService: Version): string => { + const matches = indexName.match(/^([\.])?(.*)$/) || []; + const internal = matches[1] || ''; + const baseName = matches[2]; + + // in 6.7+ we prepend to avoid conflicts with index patterns/templates/etc + const reindexedMatcher = new RegExp(`reindexed-v${versionService.getPrevMajorVersion()}-`, 'g'); + + const cleanBaseName = baseName.replace(reindexedMatcher, ''); + return `${internal}${cleanBaseName}`; +}; + +/** + * Provides the index name to re-index into + * + * .foo -> .reindexed-v7-foo + * foo => reindexed-v7-foo + */ +export const generateNewIndexName = (indexName: string, versionService: Version): string => { + const sourceName = sourceNameForIndex(indexName, versionService); + const currentVersion = `reindexed-v${versionService.getMajorVersion()}`; + + return indexName.startsWith('.') + ? `.${currentVersion}-${sourceName.substr(1)}` + : `${currentVersion}-${sourceName}`; +}; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/op_utils.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/op_utils.ts similarity index 96% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/op_utils.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/op_utils.ts index ee2707f8275cc..737fe818a3ea2 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/op_utils.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/op_utils.ts @@ -6,7 +6,7 @@ */ import { flow } from 'fp-ts/function'; -import { ReindexSavedObject } from '../../../common/types'; +import { ReindexSavedObject } from '@kbn/upgrade-assistant-pkg-common'; export interface SortedReindexSavedObjects { /** diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_actions.test.ts similarity index 95% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_actions.test.ts index ff1ab17f59441..fff74a5ba982a 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_actions.test.ts @@ -10,22 +10,22 @@ import { elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mo import type { ScopedClusterClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; import moment from 'moment'; -import { - REINDEX_OP_TYPE, - ReindexSavedObject, - ReindexStatus, - ReindexStep, -} from '../../../common/types'; -import { versionService } from '../version'; +import { ReindexSavedObject, ReindexStatus, ReindexStep } from '@kbn/upgrade-assistant-pkg-common'; +import { REINDEX_OP_TYPE, type Version } from '@kbn/upgrade-assistant-pkg-server'; import { LOCK_WINDOW, ReindexActions, reindexActionsFactory } from './reindex_actions'; import { getMockVersionInfo } from '../__fixtures__/version'; const { currentMajor, prevMajor } = getMockVersionInfo(); -jest.mock('../rollup_job', () => ({ +jest.mock('@kbn/upgrade-assistant-pkg-server', () => ({ getRollupJobByIndexName: jest.fn(), })); +const versionMock = { + getMajorVersion: jest.fn().mockReturnValue(8), + getPrevMajorVersion: jest.fn().mockReturnValue(7), +} as unknown as Version; + describe('ReindexActions', () => { let client: jest.Mocked; let clusterClient: ScopedClusterClientMock; @@ -50,12 +50,11 @@ describe('ReindexActions', () => { ) as any, }; clusterClient = elasticsearchServiceMock.createScopedClusterClient(); - actions = reindexActionsFactory(client, clusterClient.asCurrentUser, log); + actions = reindexActionsFactory(client, clusterClient.asCurrentUser, log, versionMock); }); describe('createReindexOp', () => { beforeEach(() => { - versionService.setup('8.0.0'); client.create.mockResolvedValue(); }); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_actions.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_actions.ts similarity index 94% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_actions.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_actions.ts index 04c0615e24dea..256457384e7ef 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_actions.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_actions.ts @@ -13,17 +13,17 @@ import { ElasticsearchClient, Logger, } from '@kbn/core/server'; +import { REINDEX_OP_TYPE, getRollupJobByIndexName } from '@kbn/upgrade-assistant-pkg-server'; +import type { Version } from '@kbn/upgrade-assistant-pkg-server'; +import { FlatSettings } from '@kbn/upgrade-assistant-pkg-server'; import { - REINDEX_OP_TYPE, ReindexOperation, ReindexOptions, ReindexSavedObject, ReindexStatus, ReindexStep, -} from '../../../common/types'; +} from '@kbn/upgrade-assistant-pkg-common'; import { generateNewIndexName } from './index_settings'; -import { FlatSettings } from './types'; -import { getRollupJobByIndexName } from '../rollup_job'; // TODO: base on elasticsearch.requestTimeout? export const LOCK_WINDOW = moment.duration(90, 'seconds'); @@ -87,7 +87,8 @@ export interface ReindexActions { export const reindexActionsFactory = ( client: SavedObjectsClientContract, esClient: ElasticsearchClient, - log: Logger + log: Logger, + versionService: Version ): ReindexActions => { // ----- Internal functions const isLocked = (reindexOp: ReindexSavedObject) => { @@ -133,7 +134,7 @@ export const reindexActionsFactory = ( return client.create(REINDEX_OP_TYPE, { indexName, - newIndexName: generateNewIndexName(indexName), + newIndexName: generateNewIndexName(indexName, versionService), status: ReindexStatus.inProgress, lastCompletedStep: ReindexStep.created, locked: null, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_handler.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_handler.ts similarity index 76% rename from x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_handler.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_handler.ts index 7808a0885c0ae..8970f1edff711 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_handler.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_handler.ts @@ -15,13 +15,14 @@ import { import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; +import type { Version } from '@kbn/upgrade-assistant-pkg-server'; -import { ReindexOperation, ReindexStatus } from '../../../common/types'; +import { ReindexOperation, ReindexStatus } from '@kbn/upgrade-assistant-pkg-common'; -import { reindexActionsFactory } from '../../lib/reindexing/reindex_actions'; -import { reindexServiceFactory } from '../../lib/reindexing'; -import { CredentialStore } from '../../lib/reindexing/credential_store'; -import { error } from '../../lib/reindexing/error'; +import { reindexActionsFactory } from './reindex_actions'; +import { reindexServiceFactory } from './reindex_service'; +import { CredentialStore } from './credential_store'; +import { error } from './error'; interface ReindexHandlerArgs { savedObjects: SavedObjectsClientContract; @@ -35,6 +36,7 @@ interface ReindexHandlerArgs { enqueue?: boolean; }; security?: SecurityPluginStart; + version: Version; } export const reindexHandler = async ({ @@ -47,10 +49,18 @@ export const reindexHandler = async ({ savedObjects, reindexOptions, security, -}: ReindexHandlerArgs): Promise => { + version, +}: // accept index settings as params +ReindexHandlerArgs): Promise => { const callAsCurrentUser = dataClient.asCurrentUser; - const reindexActions = reindexActionsFactory(savedObjects, callAsCurrentUser, log); - const reindexService = reindexServiceFactory(callAsCurrentUser, reindexActions, log, licensing); + const reindexActions = reindexActionsFactory(savedObjects, callAsCurrentUser, log, version); + const reindexService = reindexServiceFactory( + callAsCurrentUser, + reindexActions, + log, + licensing, + version + ); if (!(await reindexService.hasRequiredPrivileges(indexName))) { throw error.accessForbidden( diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_service.test.ts similarity index 98% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_service.test.ts index 10ee1bc81ac1e..7d91024b4f458 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_service.test.ts @@ -5,7 +5,9 @@ * 2.0. */ -jest.mock('../es_indices_state_check', () => ({ esIndicesStateCheck: jest.fn() })); +jest.mock('@kbn/upgrade-assistant-pkg-server/src/es_indices_state_check', () => ({ + esIndicesStateCheck: jest.fn(), +})); import { BehaviorSubject } from 'rxjs'; import { TransportResult } from '@elastic/elasticsearch'; import { Logger } from '@kbn/core/server'; @@ -17,16 +19,20 @@ import { ReindexSavedObject, ReindexStatus, ReindexStep, -} from '../../../common/types'; +} from '@kbn/upgrade-assistant-pkg-common'; import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; import { getMockVersionInfo } from '../__fixtures__/version'; -import { esIndicesStateCheck } from '../es_indices_state_check'; -import { versionService } from '../version'; +import { esIndicesStateCheck, type Version } from '@kbn/upgrade-assistant-pkg-server'; import { ReindexService, reindexServiceFactory } from './reindex_service'; +const versionMock = { + getMajorVersion: jest.fn().mockReturnValue(8), + getPrevMajorVersion: jest.fn().mockReturnValue(7), +} as unknown as Version; + const asApiResponse = (body: T): TransportResult => ({ body, @@ -75,10 +81,9 @@ describe('reindexService', () => { clusterClient.asCurrentUser, actions, log, - licensingPluginSetup + licensingPluginSetup, + versionMock ); - - versionService.setup('8.0.0'); }); describe('hasRequiredPrivileges', () => { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_service.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_service.ts similarity index 97% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_service.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_service.ts index 8545ba12216fd..9a8b97d8fcaec 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/reindex_service.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/reindex_service.ts @@ -11,16 +11,19 @@ import { firstValueFrom } from 'rxjs'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; import { IndicesAlias, IndicesIndexSettings } from '@elastic/elasticsearch/lib/api/types'; +import { + esIndicesStateCheck, + getReindexWarnings, + type Version, +} from '@kbn/upgrade-assistant-pkg-server'; import { ReindexSavedObject, ReindexStatus, ReindexStep, IndexWarning, -} from '../../../common/types'; - -import { esIndicesStateCheck } from '../es_indices_state_check'; +} from '@kbn/upgrade-assistant-pkg-common'; -import { generateNewIndexName, getReindexWarnings, sourceNameForIndex } from './index_settings'; +import { generateNewIndexName, sourceNameForIndex } from './index_settings'; import { ReindexActions } from './reindex_actions'; @@ -128,7 +131,8 @@ export const reindexServiceFactory = ( esClient: ElasticsearchClient, actions: ReindexActions, log: Logger, - licensing: LicensingPluginSetup + licensing: LicensingPluginSetup, + kibanaVersion: Version ): ReindexService => { // ------ Utility functions const cleanupChanges = async (reindexOp: ReindexSavedObject) => { @@ -404,7 +408,9 @@ export const reindexServiceFactory = ( // Get the warnings for this index to check for deprecated settings const flatSettings = await actions.getFlatSettings(indexName); - const warnings = flatSettings ? getReindexWarnings(flatSettings) : undefined; + const warnings = flatSettings + ? getReindexWarnings(flatSettings, kibanaVersion.getMajorVersion()) + : undefined; const indexSettingsWarning = warnings?.find( (warning) => warning.warningType === 'indexSetting' && @@ -505,8 +511,8 @@ export const reindexServiceFactory = ( return true; } - const names = [indexName, generateNewIndexName(indexName)]; - const sourceName = sourceNameForIndex(indexName); + const names = [indexName, generateNewIndexName(indexName, kibanaVersion)]; + const sourceName = sourceNameForIndex(indexName, kibanaVersion); // if we have re-indexed this in the past, there will be an // underlying alias we will also need to update. @@ -549,7 +555,7 @@ export const reindexServiceFactory = ( warningType: 'replaceIndexWithAlias', flow: 'reindex', }, - ...getReindexWarnings(flatSettings), + ...getReindexWarnings(flatSettings, kibanaVersion.getMajorVersion()), ]; } }, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/worker.ts b/x-pack/platform/plugins/private/reindex_service/server/src/lib/worker.ts similarity index 93% rename from x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/worker.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/lib/worker.ts index d81866391a3a6..8ee68ba44f66a 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/worker.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/lib/worker.ts @@ -10,7 +10,8 @@ import { exhaustMap, Subject, takeUntil, timer } from 'rxjs'; import moment from 'moment'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; -import { ReindexSavedObject, ReindexStatus } from '../../../common/types'; +import { ReindexSavedObject, ReindexStatus } from '@kbn/upgrade-assistant-pkg-common'; +import { Version } from '@kbn/upgrade-assistant-pkg-server'; import { Credential, CredentialStore } from './credential_store'; import { reindexActionsFactory } from './reindex_actions'; import { ReindexService, reindexServiceFactory } from './reindex_service'; @@ -51,6 +52,7 @@ const MAX_WORKER_PADDING_MS = Math.floor(PAUSE_WINDOW / PAUSE_THRESHOLD_MULTIPLI * the lock for this reindex operation. */ export class ReindexWorker { + private static version: Version; private static workerSingleton?: ReindexWorker; private readonly stop$ = new Subject(); private updateOperationLoopRunning: boolean = false; @@ -66,7 +68,8 @@ export class ReindexWorker { clusterClient: IClusterClient, log: Logger, licensing: LicensingPluginSetup, - security: SecurityPluginStart + security: SecurityPluginStart, + version: Version ): ReindexWorker { if (ReindexWorker.workerSingleton) { log.debug(`More than one ReindexWorker cannot be created, returning existing worker.`); @@ -77,7 +80,8 @@ export class ReindexWorker { clusterClient, log, licensing, - security + security, + version ); } @@ -90,18 +94,21 @@ export class ReindexWorker { private clusterClient: IClusterClient, log: Logger, private licensing: LicensingPluginSetup, - security: SecurityPluginStart + security: SecurityPluginStart, + version: Version ) { this.log = log.get('reindex_worker'); this.security = security; + ReindexWorker.version = version; const callAsInternalUser = this.clusterClient.asInternalUser; this.reindexService = reindexServiceFactory( callAsInternalUser, - reindexActionsFactory(this.client, callAsInternalUser, this.log), + reindexActionsFactory(this.client, callAsInternalUser, this.log, version), log, - this.licensing + this.licensing, + version ); } @@ -128,6 +135,10 @@ export class ReindexWorker { this.currentWorkerPadding = INITIAL_WORKER_PADDING_MS; }; + public cleanupReindexOperations = async (indexNames: string[]) => { + await this.reindexService.cleanupReindexOperations(indexNames); + }; + /** * Should be called immediately after this server has started a new reindex operation. */ @@ -195,8 +206,19 @@ export class ReindexWorker { const fakeRequest: FakeRequest = { headers: credential }; const scopedClusterClient = this.clusterClient.asScoped(fakeRequest); const callAsCurrentUser = scopedClusterClient.asCurrentUser; - const actions = reindexActionsFactory(this.client, callAsCurrentUser, this.log); - return reindexServiceFactory(callAsCurrentUser, actions, this.log, this.licensing); + const actions = reindexActionsFactory( + this.client, + callAsCurrentUser, + this.log, + ReindexWorker.version + ); + return reindexServiceFactory( + callAsCurrentUser, + actions, + this.log, + this.licensing, + ReindexWorker.version + ); }; private updateInProgressOps = async () => { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.test.ts b/x-pack/platform/plugins/private/reindex_service/server/src/routes/batch_reindex_indices.test.ts similarity index 93% rename from x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.test.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/routes/batch_reindex_indices.test.ts index 21c88aea907ea..9e20d23eea10d 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.test.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/routes/batch_reindex_indices.test.ts @@ -11,7 +11,7 @@ import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; import { securityMock } from '@kbn/security-plugin/server/mocks'; import { createMockRouter, MockRouter, routeHandlerContextMock } from '../__mocks__/routes.mock'; import { createRequestMock } from '../__mocks__/request.mock'; -import { handleEsError } from '../../shared_imports'; +import { handleEsError } from '@kbn/es-ui-shared-plugin/server'; const mockReindexService = { hasRequiredPrivileges: jest.fn(), @@ -24,17 +24,15 @@ const mockReindexService = { resumeReindexOperation: jest.fn(), cancelReindexing: jest.fn(), }; -jest.mock('../../lib/es_version_precheck', () => ({ - versionCheckHandlerWrapper: (a: any) => a, +jest.mock('@kbn/upgrade-assistant-pkg-server/src/es_version_precheck', () => ({ + versionCheckHandlerWrapper: () => (a: any) => a, })); -jest.mock('../../lib/reindexing', () => { - return { - reindexServiceFactory: () => mockReindexService, - }; -}); +jest.mock('../lib/reindex_service', () => ({ + reindexServiceFactory: () => mockReindexService, +})); -import { credentialStoreFactory } from '../../lib/reindexing/credential_store'; +import { credentialStoreFactory } from '../lib/credential_store'; import { registerBatchReindexIndicesRoutes } from './batch_reindex_indices'; const logMock = loggingSystemMock.create().get(); @@ -62,6 +60,7 @@ describe('reindex API', () => { licensing: licensingMock.createSetup(), lib: { handleEsError }, getSecurityPlugin: () => securityMock.createStart(), + version: { getMajorVersion: () => 8 }, }; registerBatchReindexIndicesRoutes(routeDependencies, () => worker); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts b/x-pack/platform/plugins/private/reindex_service/server/src/routes/batch_reindex_indices.ts similarity index 81% rename from x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/routes/batch_reindex_indices.ts index c43d417d73e97..bf585073493bf 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/batch_reindex_indices.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/routes/batch_reindex_indices.ts @@ -8,15 +8,15 @@ import { schema } from '@kbn/config-schema'; import { errors } from '@elastic/elasticsearch'; -import { API_BASE_PATH } from '../../../common/constants'; -import { REINDEX_OP_TYPE, ReindexStatus } from '../../../common/types'; -import { versionCheckHandlerWrapper } from '../../lib/es_version_precheck'; -import { ReindexWorker } from '../../lib/reindexing'; -import { reindexActionsFactory } from '../../lib/reindexing/reindex_actions'; -import { sortAndOrderReindexOperations } from '../../lib/reindexing/op_utils'; +import { versionCheckHandlerWrapper, REINDEX_OP_TYPE } from '@kbn/upgrade-assistant-pkg-server'; +import { ReindexStatus } from '@kbn/upgrade-assistant-pkg-common'; +import { API_BASE_PATH_UPRGRADE_ASSISTANT } from '../constants'; +import { ReindexWorker } from '../lib'; +import { reindexActionsFactory } from '../lib/reindex_actions'; +import { sortAndOrderReindexOperations } from '../lib/op_utils'; import { RouteDependencies } from '../../types'; import { mapAnyErrorToKibanaHttpResponse } from './map_any_error_to_kibana_http_response'; -import { reindexHandler } from './reindex_handler'; +import { reindexHandler } from '../lib/reindex_handler'; import { GetBatchQueueResponse, PostBatchResponse } from './types'; export function registerBatchReindexIndicesRoutes( @@ -27,10 +27,11 @@ export function registerBatchReindexIndicesRoutes( log, getSecurityPlugin, lib: { handleEsError }, + version, }: RouteDependencies, getWorker: () => ReindexWorker ) { - const BASE_PATH = `${API_BASE_PATH}/reindex`; + const BASE_PATH = `${API_BASE_PATH_UPRGRADE_ASSISTANT}/reindex`; // Get the current batch queue router.get( @@ -44,7 +45,7 @@ export function registerBatchReindexIndicesRoutes( }, validate: {}, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(version.getMajorVersion())(async ({ core }, request, response) => { const { elasticsearch: { client: esClient }, savedObjects, @@ -54,7 +55,8 @@ export function registerBatchReindexIndicesRoutes( const reindexActions = reindexActionsFactory( getClient({ includedHiddenTypes: [REINDEX_OP_TYPE] }), callAsCurrentUser, - log + log, + version ); try { const inProgressOps = await reindexActions.findAllByStatus(ReindexStatus.inProgress); @@ -90,7 +92,7 @@ export function registerBatchReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(version.getMajorVersion())(async ({ core }, request, response) => { const { savedObjects: { getClient }, elasticsearch: { client: esClient }, @@ -114,6 +116,7 @@ export function registerBatchReindexIndicesRoutes( enqueue: true, }, security: getSecurityPlugin(), + version, }); results.enqueued.push(result); } catch (e) { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/index.ts b/x-pack/platform/plugins/private/reindex_service/server/src/routes/index.ts similarity index 86% rename from x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/index.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/routes/index.ts index 038f0c07c11fe..81f574f9872b8 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/index.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/routes/index.ts @@ -5,6 +5,5 @@ * 2.0. */ -export { createReindexWorker } from './create_reindex_worker'; export { registerReindexIndicesRoutes } from './reindex_indices'; export { registerBatchReindexIndicesRoutes } from './batch_reindex_indices'; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/map_any_error_to_kibana_http_response.ts b/x-pack/platform/plugins/private/reindex_service/server/src/routes/map_any_error_to_kibana_http_response.ts similarity index 92% rename from x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/map_any_error_to_kibana_http_response.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/routes/map_any_error_to_kibana_http_response.ts index 2f21e8cb80436..73b3c8b4d9d38 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/map_any_error_to_kibana_http_response.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/routes/map_any_error_to_kibana_http_response.ts @@ -16,8 +16,8 @@ import { ReindexCannotBeCancelled, ReindexTaskCannotBeDeleted, ReindexTaskFailed, -} from '../../lib/reindexing/error_symbols'; -import { ReindexError } from '../../lib/reindexing/error'; +} from '../lib/error_symbols'; +import { ReindexError } from '../lib/error'; export const mapAnyErrorToKibanaHttpResponse = (e: any) => { if (e instanceof ReindexError) { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts b/x-pack/platform/plugins/private/reindex_service/server/src/routes/reindex_indices.test.ts similarity index 94% rename from x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/routes/reindex_indices.test.ts index daf9daedf8b3a..c5aa377b35f06 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_indices.test.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/routes/reindex_indices.test.ts @@ -11,7 +11,7 @@ import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; import { securityMock } from '@kbn/security-plugin/server/mocks'; import { createMockRouter, MockRouter, routeHandlerContextMock } from '../__mocks__/routes.mock'; import { createRequestMock } from '../__mocks__/request.mock'; -import { handleEsError } from '../../shared_imports'; +import { handleEsError } from '@kbn/es-ui-shared-plugin/server'; import { errors as esErrors } from '@elastic/elasticsearch'; const mockReindexService = { @@ -26,19 +26,20 @@ const mockReindexService = { getIndexAliases: jest.fn().mockResolvedValue({}), getIndexInfo: jest.fn().mockResolvedValue({ aliases: {}, settings: {} }), }; -jest.mock('../../lib/es_version_precheck', () => ({ - versionCheckHandlerWrapper: (a: any) => a, +jest.mock('@kbn/upgrade-assistant-pkg-server/src/es_version_precheck', () => ({ + versionCheckHandlerWrapper: () => (a: any) => a, })); -jest.mock('../../lib/reindexing', () => { - return { - reindexServiceFactory: () => mockReindexService, - generateNewIndexName: () => 'reindexed-foo', - }; -}); +jest.mock('../lib/reindex_service', () => ({ + reindexServiceFactory: () => mockReindexService, +})); + +jest.mock('../lib/index_settings', () => ({ + generateNewIndexName: () => 'reindexed-foo', +})); -import { ReindexSavedObject, ReindexStatus } from '../../../common/types'; -import { credentialStoreFactory } from '../../lib/reindexing/credential_store'; +import { ReindexSavedObject, ReindexStatus } from '@kbn/upgrade-assistant-pkg-common'; +import { credentialStoreFactory } from '../lib/credential_store'; import { registerReindexIndicesRoutes } from './reindex_indices'; const logMock = loggingSystemMock.create().get(); @@ -66,6 +67,7 @@ describe('reindex API', () => { licensing: licensingMock.createSetup(), lib: { handleEsError }, getSecurityPlugin: () => securityMock.createStart(), + version: { getMajorVersion: () => 8, getMinorVersion: () => 7 }, }; registerReindexIndicesRoutes(routeDependencies, () => worker); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts b/x-pack/platform/plugins/private/reindex_service/server/src/routes/reindex_indices.ts similarity index 83% rename from x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/routes/reindex_indices.ts index bb6c0e47a599e..de91fd518c3dd 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/routes/reindex_indices.ts @@ -8,14 +8,14 @@ import { schema } from '@kbn/config-schema'; import { errors } from '@elastic/elasticsearch'; -import { API_BASE_PATH } from '../../../common/constants'; -import { ReindexStatusResponse, REINDEX_OP_TYPE } from '../../../common/types'; -import { versionCheckHandlerWrapper } from '../../lib/es_version_precheck'; -import { reindexServiceFactory, ReindexWorker, generateNewIndexName } from '../../lib/reindexing'; -import { reindexActionsFactory } from '../../lib/reindexing/reindex_actions'; +import { versionCheckHandlerWrapper, REINDEX_OP_TYPE } from '@kbn/upgrade-assistant-pkg-server'; +import { ReindexStatusResponse } from '@kbn/upgrade-assistant-pkg-common'; +import { API_BASE_PATH_UPRGRADE_ASSISTANT } from '../constants'; +import { reindexServiceFactory, ReindexWorker, generateNewIndexName } from '../lib'; +import { reindexActionsFactory } from '../lib/reindex_actions'; import { RouteDependencies } from '../../types'; import { mapAnyErrorToKibanaHttpResponse } from './map_any_error_to_kibana_http_response'; -import { reindexHandler } from './reindex_handler'; +import { reindexHandler } from '../lib/reindex_handler'; export function registerReindexIndicesRoutes( { @@ -25,10 +25,11 @@ export function registerReindexIndicesRoutes( log, getSecurityPlugin, lib: { handleEsError }, + version, }: RouteDependencies, getWorker: () => ReindexWorker ) { - const BASE_PATH = `${API_BASE_PATH}/reindex`; + const BASE_PATH = `${API_BASE_PATH_UPRGRADE_ASSISTANT}/reindex`; // Start reindex for an index router.post( @@ -46,7 +47,7 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(version.getMajorVersion())(async ({ core }, request, response) => { const { savedObjects: { getClient }, elasticsearch: { client: esClient }, @@ -62,6 +63,7 @@ export function registerReindexIndicesRoutes( request, credentialStore, security: getSecurityPlugin(), + version, }); // Kick the worker on this node to immediately pickup the new reindex operation. @@ -95,7 +97,7 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(version.getMajorVersion())(async ({ core }, request, response) => { const { savedObjects, elasticsearch: { client: esClient }, @@ -106,9 +108,16 @@ export function registerReindexIndicesRoutes( const reindexActions = reindexActionsFactory( getClient({ includedHiddenTypes: [REINDEX_OP_TYPE] }), asCurrentUser, - log + log, + version + ); + const reindexService = reindexServiceFactory( + asCurrentUser, + reindexActions, + log, + licensing, + version ); - const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); try { const hasRequiredPrivileges = await reindexService.hasRequiredPrivileges(indexName); @@ -128,7 +137,7 @@ export function registerReindexIndicesRoutes( hasRequiredPrivileges, meta: { indexName, - reindexName: generateNewIndexName(indexName), + reindexName: generateNewIndexName(indexName, version), aliases: Object.keys(aliases), isFrozen: isTruthy(settings?.frozen), isReadonly: isTruthy(settings?.verified_read_only), @@ -165,7 +174,7 @@ export function registerReindexIndicesRoutes( }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(version.getMajorVersion())(async ({ core }, request, response) => { const { savedObjects, elasticsearch: { client: esClient }, @@ -176,13 +185,15 @@ export function registerReindexIndicesRoutes( const reindexActions = reindexActionsFactory( getClient({ includedHiddenTypes: [REINDEX_OP_TYPE] }), callAsCurrentUser, - log + log, + version ); const reindexService = reindexServiceFactory( callAsCurrentUser, reindexActions, log, - licensing + licensing, + version ); try { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/types.ts b/x-pack/platform/plugins/private/reindex_service/server/src/routes/types.ts similarity index 89% rename from x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/types.ts rename to x-pack/platform/plugins/private/reindex_service/server/src/routes/types.ts index 3532bc20d98f0..0622864e5f4b4 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/types.ts +++ b/x-pack/platform/plugins/private/reindex_service/server/src/routes/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ReindexOperation } from '../../../common/types'; +import { ReindexOperation } from '@kbn/upgrade-assistant-pkg-common'; // These types represent contracts from the reindex RESTful API endpoints and // should be changed in a way that respects backwards compatibility. diff --git a/x-pack/platform/plugins/private/reindex_service/server/types.ts b/x-pack/platform/plugins/private/reindex_service/server/types.ts new file mode 100644 index 0000000000000..e57068f71f93f --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/server/types.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IRouter, Logger } from '@kbn/core/server'; +import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; +import { SecurityPluginStart } from '@kbn/security-plugin/server'; +import { handleEsError } from '@kbn/es-ui-shared-plugin/server'; +import type { Version } from '@kbn/upgrade-assistant-pkg-server'; +import { CredentialStore } from './src/lib/credential_store'; + +export interface RouteDependencies { + router: IRouter; + credentialStore: CredentialStore; + log: Logger; + getSecurityPlugin: () => SecurityPluginStart | undefined; + licensing: LicensingPluginSetup; + lib: { + handleEsError: typeof handleEsError; + }; + version: Version; +} + +export interface ReindexServiceServerPluginStart { + cleanupReindexOperations: (indexNames: string[]) => Promise; +} diff --git a/x-pack/platform/plugins/private/reindex_service/tsconfig.json b/x-pack/platform/plugins/private/reindex_service/tsconfig.json new file mode 100644 index 0000000000000..5abc0f383ca19 --- /dev/null +++ b/x-pack/platform/plugins/private/reindex_service/tsconfig.json @@ -0,0 +1,34 @@ +{ + "extends": "../../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + }, + "include": [ + "../../../../../typings/**/*", + "__jest__/**/*", + "common/**/*", + "public/**/*", + "server/**/*", + // have to declare *.json explicitly due to https://github.com/microsoft/TypeScript/issues/25636 + "public/**/*.json", + "server/**/*.json" + ], + "kbn_references": [ + "@kbn/security-plugin", + "@kbn/es-ui-shared-plugin", + "@kbn/licensing-plugin", + "@kbn/core", + "@kbn/upgrade-assistant-pkg-server", + "@kbn/utility-types", + "@kbn/config-schema", + "@kbn/core-http-server-utils", + "@kbn/core-logging-server-mocks", + "@kbn/core-http-server-mocks", + "@kbn/core-elasticsearch-client-server-mocks", + "@kbn/i18n", + "@kbn/upgrade-assistant-pkg-common", + ], + "exclude": [ + "target/**/*", + ] +} diff --git a/x-pack/platform/plugins/private/upgrade_assistant/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/platform/plugins/private/upgrade_assistant/__jest__/client_integration/helpers/setup_environment.tsx index 2f82655879d36..7855f2573fe45 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/platform/plugins/private/upgrade_assistant/__jest__/client_integration/helpers/setup_environment.tsx @@ -10,6 +10,7 @@ import SemVer from 'semver/classes/semver'; import { merge } from 'lodash'; import { HttpSetup } from '@kbn/core/public'; +import { ReindexService } from '@kbn/reindex-service-plugin/public'; import { AuthorizationContext, Authorization, Privileges } from '../../../public/shared_imports'; import { AppContextProvider } from '../../../public/application/app_context'; import { apiService } from '../../../public/application/lib/api'; @@ -33,7 +34,7 @@ const createAuthorizationContextValue = (privileges: Privileges) => { export const WithAppDependencies = (Comp: any, httpSetup: HttpSetup, { privileges, ...overrides }: Record = {}) => (props: Record) => { - apiService.setup(httpSetup); + apiService.setup(httpSetup, new ReindexService(httpSetup)); breadcrumbService.setup(() => ''); const appContextMock = getAppContextMock(kibanaVersion) as unknown as AppDependencies; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/common/types.ts b/x-pack/platform/plugins/private/upgrade_assistant/common/types.ts index 65995a86777fd..19da305081a0c 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/common/types.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/common/types.ts @@ -7,8 +7,13 @@ import { HealthReportImpact } from '@elastic/elasticsearch/lib/api/types'; import type * as estypes from '@elastic/elasticsearch/lib/api/types'; -import { SavedObject } from '@kbn/core/types'; import type { DataStreamsAction } from './data_stream_types'; +export type { + ReindexStatusResponse, + IndexWarning, + IndexWarningType, +} from '@kbn/upgrade-assistant-pkg-common'; +export { ReindexStep, ReindexStatus, REINDEX_OP_TYPE } from '@kbn/upgrade-assistant-pkg-common'; export * from './data_stream_types'; @@ -24,139 +29,6 @@ export interface ResponseError { }; } -export enum ReindexStep { - // Enum values are spaced out by 10 to give us room to insert steps in between. - created = 0, - readonly = 20, - newIndexCreated = 30, - reindexStarted = 40, - reindexCompleted = 50, - indexSettingsRestored = 55, - aliasCreated = 60, - originalIndexDeleted = 70, - existingAliasesUpdated = 80, -} - -export enum ReindexStatus { - inProgress, - completed, - failed, - paused, - cancelled, - // Used by the UI to differentiate if there was a failure retrieving - // the status from the server API - fetchFailed, -} - -export interface ReindexStatusResponse { - meta: { - indexName: string; - reindexName: string; - // Array of aliases pointing to the index being reindexed - aliases: string[]; - isReadonly: boolean; - isFrozen: boolean; - isInDataStream: boolean; - isFollowerIndex: boolean; - }; - warnings?: IndexWarning[]; - reindexOp?: ReindexOperation; - hasRequiredPrivileges?: boolean; -} - -export const REINDEX_OP_TYPE = 'upgrade-assistant-reindex-operation'; - -export interface QueueSettings { - /** - * A Unix timestamp of when the reindex operation was enqueued. - * - * @remark - * This is used by the reindexing scheduler to determine execution - * order. - */ - queuedAt: number; - - /** - * A Unix timestamp of when the reindex operation was started. - * - * @remark - * Updating this field is useful for _also_ updating the saved object "updated_at" field - * which is used to determine stale or abandoned reindex operations. - * - * For now this is used by the reindex worker scheduler to determine whether we have - * A queue item at the start of the queue. - * - */ - startedAt?: number; -} - -export interface ReindexOptions { - /** - * 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; - - /** - * Set this key to configure a reindex operation as part of a - * batch to be run in series. - */ - queueSettings?: QueueSettings; -} - -export interface ReindexOperation { - indexName: string; - newIndexName: string; - status: ReindexStatus; - lastCompletedStep: ReindexStep; - locked: string | null; - reindexTaskId: string | null; - reindexTaskPercComplete: number | null; - errorMessage: string | null; - // This field is only used for the singleton IndexConsumerType documents. - runningReindexCount: number | null; - rollupJob?: string; - - /** - * The original index settings to set after reindex is completed. - * The target index is created with other defaults to improve reindexing performance. - * https://github.com/elastic/kibana/issues/201605 - */ - backupSettings?: { - 'index.number_of_replicas'?: number; - 'index.refresh_interval'?: number; - }; - - /** - * 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; - -// 8.0 -> 9.0 warnings -export type IndexWarningType = 'indexSetting' | 'replaceIndexWithAlias' | 'makeIndexReadonly'; - -export interface IndexWarning { - warningType: IndexWarningType; - flow: 'reindex' | 'readonly' | 'all'; - /** - * Optional metadata for deprecations - * - * @remark - * For "indexSetting" we want to surface the deprecated settings. - */ - meta?: { - [key: string]: string | string[] | boolean; - }; -} - // Telemetry types export type UIOpenOption = 'overview' | 'elasticsearch' | 'kibana'; export type UIReindexOption = 'close' | 'open' | 'start' | 'stop'; @@ -290,21 +162,6 @@ export interface ESUpgradeStatus { enrichedHealthIndicators: EnrichedDeprecationInfo[]; } -export interface ResolveIndexResponseFromES { - indices: Array<{ - name: string; - // per https://github.com/elastic/elasticsearch/pull/57626 - attributes: Array<'open' | 'closed' | 'hidden' | 'frozen'>; - aliases?: string[]; - data_stream?: string; - }>; - aliases: Array<{ - name: string; - indices: string[]; - }>; - data_streams: Array<{ name: string; backing_indices: string[]; timestamp_field: string }>; -} - export const ML_UPGRADE_OP_TYPE = 'upgrade-assistant-ml-upgrade-operation'; export interface MlOperation { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/kibana.jsonc b/x-pack/platform/plugins/private/upgrade_assistant/kibana.jsonc index 55a08297937bb..4acb2200aef20 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/kibana.jsonc +++ b/x-pack/platform/plugins/private/upgrade_assistant/kibana.jsonc @@ -17,7 +17,8 @@ "data", "licensing", "features", - "share" + "share", + "reindexService" ], "optionalPlugins": [ "usageCollection", diff --git a/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/es_deprecations/deprecation_types/indices/use_reindex.tsx b/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/es_deprecations/deprecation_types/indices/use_reindex.tsx index e1c7ba6e5bfcf..4a35f787885b3 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/es_deprecations/deprecation_types/indices/use_reindex.tsx +++ b/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/es_deprecations/deprecation_types/indices/use_reindex.tsx @@ -259,7 +259,10 @@ export const useReindex = ({ } setReindexState((prevValue: ReindexState) => { - return getReindexState(prevValue, { reindexOp, meta: prevValue.meta }); + return getReindexState(prevValue, { + reindexOp: reindexOp || undefined, + meta: prevValue.meta, + }); }); updateStatus(); }, [api, indexName, updateStatus]); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/shared/index.ts b/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/shared/index.ts index 7803ed1145e26..3211479c4976f 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/shared/index.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/public/application/components/shared/index.ts @@ -7,7 +7,7 @@ export { NoDeprecationsPrompt } from './no_deprecations'; export { DeprecationCount } from './deprecation_count'; -export { DeprecationBadge } from '@kbn/upgrade-assistant'; +export { DeprecationBadge } from '@kbn/upgrade-assistant-pkg-public'; export { DeprecationsPageLoadingError } from './deprecations_page_loading_error'; export { DeprecationFlyoutLearnMoreLink } from './deprecation_flyout_learn_more_link'; export { LevelInfoTip } from './level_info_tip'; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/public/application/lib/api.ts b/x-pack/platform/plugins/private/upgrade_assistant/public/application/lib/api.ts index 80e6a88eec6f4..2492255deee6b 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/public/application/lib/api.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/public/application/lib/api.ts @@ -7,6 +7,7 @@ import type { HttpSetup } from '@kbn/core/public'; +import type { ReindexService } from '@kbn/reindex-service-plugin/public'; import type { UpdateIndexOperation } from '../../../common/update_index'; import type { ESUpgradeStatus, @@ -14,7 +15,6 @@ import type { ClusterUpgradeState, ResponseError, SystemIndicesMigrationStatus, - ReindexStatusResponse, DataStreamReindexStatusResponse, DataStreamMetadata, } from '../../../common/types'; @@ -36,6 +36,7 @@ type ClusterUpgradeStateListener = (clusterUpgradeState: ClusterUpgradeState) => export class ApiService { private client: HttpSetup | undefined; + private reindexService: ReindexService | undefined; private clusterUpgradeStateListeners: ClusterUpgradeStateListener[] = []; private handleClusterUpgradeError(error: ResponseError | null) { @@ -82,8 +83,9 @@ export class ApiService { return response; } - public setup(httpClient: HttpSetup): void { + public setup(httpClient: HttpSetup, reindexService: ReindexService): void { this.client = httpClient; + this.reindexService = reindexService; } public onClusterUpgradeStateChange(listener: ClusterUpgradeStateListener) { @@ -258,24 +260,13 @@ export class ApiService { */ public async getReindexStatus(indexName: string) { - return await this.sendRequest({ - path: `${API_BASE_PATH}/reindex/${indexName}`, - method: 'get', - }); + return this.reindexService!.getReindexStatus(indexName); } - public async startReindexTask(indexName: string) { - return await this.sendRequest({ - path: `${API_BASE_PATH}/reindex/${indexName}`, - method: 'post', - }); + return this.reindexService!.startReindex(indexName); } - public async cancelReindexTask(indexName: string) { - return await this.sendRequest({ - path: `${API_BASE_PATH}/reindex/${indexName}/cancel`, - method: 'post', - }); + return this.reindexService!.cancelReindex(indexName); } public async updateIndex(indexName: string, operations: UpdateIndexOperation[]) { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/public/application/mount_management_section.tsx b/x-pack/platform/plugins/private/upgrade_assistant/public/application/mount_management_section.tsx index 96ea2004d6e85..625bfc56e479e 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/public/application/mount_management_section.tsx +++ b/x-pack/platform/plugins/private/upgrade_assistant/public/application/mount_management_section.tsx @@ -21,7 +21,10 @@ export function mountManagementSection( ) { const { element, setBreadcrumbs } = params; - apiService.setup(dependencies.services.core.http); + apiService.setup( + dependencies.services.core.http, + dependencies.plugins.reindexService.reindexService + ); breadcrumbService.setup(setBreadcrumbs); render(, element); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/public/plugin.ts b/x-pack/platform/plugins/private/upgrade_assistant/public/plugin.ts index 5056277888290..3bcf775a2c405 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/public/plugin.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/public/plugin.ts @@ -53,7 +53,7 @@ export class UpgradeAssistantUIPlugin title: pluginName, order: 1, async mount(params) { - const [coreStart, { data }] = await coreSetup.getStartServices(); + const [coreStart, { data, reindexService }] = await coreSetup.getStartServices(); const { chrome: { docTitle }, @@ -67,6 +67,7 @@ export class UpgradeAssistantUIPlugin plugins: { cloud, share, + reindexService, }, services: { core: coreStart, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/public/types.ts b/x-pack/platform/plugins/private/upgrade_assistant/public/types.ts index 08aa04995dfee..b5090352a31f6 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/public/types.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/public/types.ts @@ -8,6 +8,7 @@ import { ManagementSetup } from '@kbn/management-plugin/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { SharePluginSetup } from '@kbn/share-plugin/public'; import { CoreStart, ScopedHistory } from '@kbn/core/public'; +import { ReindexServicePublicStart } from '@kbn/reindex-service-plugin/public'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import { CloudSetup } from '@kbn/cloud-plugin/public'; @@ -34,6 +35,7 @@ export interface SetupDependencies { export interface StartDependencies { licensing: LicensingPluginStart; data: DataPublicPluginStart; + reindexService: ReindexServicePublicStart; } export interface ClientConfigType { @@ -49,6 +51,7 @@ export interface AppDependencies { plugins: { cloud?: CloudSetup; share: SharePluginSetup; + reindexService: ReindexServicePublicStart; }; services: { core: CoreStart; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/config.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/config.ts index 61e41efe8cbb9..ce5dc21223767 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/config.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/config.ts @@ -7,6 +7,45 @@ import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema'; import { PluginConfigDescriptor } from '@kbn/core/server'; +export const dataSourceExclusionsSchema = schema.recordOf( + schema.string(), + schema.arrayOf(schema.oneOf([schema.literal('readOnly'), schema.literal('reindex')])), + { defaultValue: {} } +); + +export const featureSetSchema = schema.object({ + /** + * Ml Snapshot should only be enabled for major version upgrades. Currently this + * is manually set to `true` on every `x.last` version. + * ML Upgrade mode can be toggled from outside Kibana, the purpose + * of this feature guard is to hide all ML related deprecations from the end user + * until the next major upgrade. + * + * When we want to enable ML model snapshot deprecation warnings again we need + * to change the constant `MachineLearningField.MIN_CHECKED_SUPPORTED_SNAPSHOT_VERSION` + * to something higher than 7.0.0 in the Elasticsearch code. + */ + mlSnapshots: schema.boolean({ defaultValue: true }), + /** + * Migrating system indices should only be enabled for major version upgrades. + * Currently this is manually set to `true` on every `x.last` version. + */ + migrateSystemIndices: schema.boolean({ defaultValue: true }), + /** + * Deprecations with reindexing corrective actions are only enabled for major version upgrades. + * Currently this is manually set to `true` on every `x.last` version. + * + * The reindex action includes some logic that is specific to the 8.0 upgrade + * End users could get into a bad situation if this is enabled before this logic is fixed. + */ + reindexCorrectiveActions: schema.boolean({ defaultValue: true }), + /** + * Migrating deprecated data streams should only be enabled for major version upgrades. + * Currently this is manually set to `true` on every `x.last` version. + */ + migrateDataStreams: schema.boolean({ defaultValue: true }), +}); + // ------------------------------- // >= 8.6 UA is always enabled to guide stack upgrades // even for minor releases. @@ -31,44 +70,8 @@ const configSchema = schema.object({ * xpack.upgrade_assistant.dataSourceExclusions: * 7_17_data_stream: ["readOnly"] */ - dataSourceExclusions: schema.recordOf( - schema.string(), - schema.arrayOf(schema.oneOf([schema.literal('readOnly'), schema.literal('reindex')])), - { defaultValue: {} } - ), - - featureSet: schema.object({ - /** - * Ml Snapshot should only be enabled for major version upgrades. Currently this - * is manually set to `true` on every `x.last` version. - * ML Upgrade mode can be toggled from outside Kibana, the purpose - * of this feature guard is to hide all ML related deprecations from the end user - * until the next major upgrade. - * - * When we want to enable ML model snapshot deprecation warnings again we need - * to change the constant `MachineLearningField.MIN_CHECKED_SUPPORTED_SNAPSHOT_VERSION` - * to something higher than 7.0.0 in the Elasticsearch code. - */ - mlSnapshots: schema.boolean({ defaultValue: true }), - /** - * Migrating system indices should only be enabled for major version upgrades. - * Currently this is manually set to `true` on every `x.last` version. - */ - migrateSystemIndices: schema.boolean({ defaultValue: true }), - /** - * Deprecations with reindexing corrective actions are only enabled for major version upgrades. - * Currently this is manually set to `true` on every `x.last` version. - * - * The reindex action includes some logic that is specific to the 8.0 upgrade - * End users could get into a bad situation if this is enabled before this logic is fixed. - */ - reindexCorrectiveActions: schema.boolean({ defaultValue: true }), - /** - * Migrating deprecated data streams should only be enabled for major version upgrades. - * Currently this is manually set to `true` on every `x.last` version. - */ - migrateDataStreams: schema.boolean({ defaultValue: true }), - }), + dataSourceExclusions: dataSourceExclusionsSchema, + featureSet: featureSetSchema, /** * This config allows to hide the UI without disabling the plugin. */ diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_deprecations_status/migrations.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_deprecations_status/migrations.ts index 6ba9ba2c8ec1d..1b8ee5c0f80bb 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_deprecations_status/migrations.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/es_deprecations_status/migrations.ts @@ -11,6 +11,7 @@ import type { } from '@elastic/elasticsearch/lib/api/types'; import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { omit } from 'lodash'; +import { esIndicesStateCheck } from '@kbn/upgrade-assistant-pkg-server'; import type { CorrectiveAction, EnrichedDeprecationInfo } from '../../../common/types'; import { convertFeaturesToIndicesArray, @@ -21,7 +22,6 @@ import { getCorrectiveAction, isFrozenDeprecation, } from './get_corrective_actions'; -import { esIndicesStateCheck } from '../es_indices_state_check'; /** * Remove once the these keys are added to the `MigrationDeprecationsResponse` type diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/types.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/types.ts deleted file mode 100644 index d046fa5f22f92..0000000000000 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/reindexing/types.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import type * as estypes from '@elastic/elasticsearch/lib/api/types'; - -interface Mapping { - type?: string; - properties?: MappingProperties; -} - -export interface MappingProperties { - [key: string]: Mapping; -} - -interface MetaProperties { - [key: string]: string; -} - -export interface FlatSettings { - settings?: estypes.IndicesIndexState['settings']; - mappings?: { - properties?: MappingProperties; - _meta?: MetaProperties; - }; -} diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/update_index/index.test.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/update_index/index.test.ts index 3571ce4f06825..a90e08f43e80d 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/update_index/index.test.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/update_index/index.test.ts @@ -8,10 +8,13 @@ import { elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks'; import { updateIndex } from '.'; import { IndicesPutSettingsRequest } from '@elastic/elasticsearch/lib/api/types'; -import { getReindexWarnings } from '../reindexing/index_settings'; +import { type Version } from '@kbn/upgrade-assistant-pkg-server'; +import { getReindexWarnings } from '@kbn/upgrade-assistant-pkg-server/src/index_settings'; + +const versionService = { getMajorVersion: () => 8 } as unknown as Version; // Mock the getReindexWarnings function -jest.mock('../reindexing/index_settings', () => ({ +jest.mock('@kbn/upgrade-assistant-pkg-server/src/index_settings', () => ({ getReindexWarnings: jest.fn(), })); @@ -21,6 +24,8 @@ const ackResponseMock = { indices: [], }; +// const versionService = getMockVersionInfo(); + describe('updateIndex', () => { const mockGetReindexWarnings = getReindexWarnings as jest.Mock; const mockLogger = loggingSystemMock.create().get(); @@ -66,6 +71,7 @@ describe('updateIndex', () => { index: 'testIndex', operations: ['blockWrite'], log: mockLogger, + versionService, }); expect(mockClient.indices.addBlock).toHaveBeenCalledWith({ @@ -86,6 +92,7 @@ describe('updateIndex', () => { index: 'testIndex', operations: ['blockWrite'], log: mockLogger, + versionService, }) ).rejects.toThrow('Could not set apply blockWrite to testIndex.'); }); @@ -129,6 +136,7 @@ describe('updateIndex', () => { index: 'testIndex', operations: ['blockWrite'], log: mockLogger, + versionService, }); // Verify indices.addBlock was called @@ -197,6 +205,7 @@ describe('updateIndex', () => { index: 'testIndex', operations: ['blockWrite'], log: mockLogger, + versionService, }); // Verify indices.addBlock was called @@ -234,6 +243,7 @@ describe('updateIndex', () => { index: 'testIndex', operations: ['blockWrite'], log: mockLogger, + versionService, }); expect(mockClient.indices.addBlock).toHaveBeenCalledWith({ diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/update_index/index.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/update_index/index.ts index 02afb89e56574..ad0ad8ae193dc 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/update_index/index.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/update_index/index.ts @@ -6,15 +6,16 @@ */ import type { ElasticsearchClient, Logger } from '@kbn/core/server'; +import { getRollupJobByIndexName, getReindexWarnings } from '@kbn/upgrade-assistant-pkg-server'; +import type { Version } from '@kbn/upgrade-assistant-pkg-server'; import type { UpdateIndexOperation } from '../../../common/update_index'; -import { getReindexWarnings } from '../reindexing/index_settings'; -import { getRollupJobByIndexName } from '../rollup_job'; export interface UpdateIndexParams { esClient: ElasticsearchClient; index: string; operations: UpdateIndexOperation[]; log: Logger; + versionService: Version; } /** @@ -24,7 +25,13 @@ export interface UpdateIndexParams { * @param operations The operations to perform on the specified index * @param logger Optional logger to log information */ -export async function updateIndex({ esClient, index, operations, log }: UpdateIndexParams) { +export async function updateIndex({ + esClient, + index, + operations, + log, + versionService, +}: UpdateIndexParams) { for (const operation of operations) { let res; @@ -38,7 +45,7 @@ export async function updateIndex({ esClient, index, operations, log }: UpdateIn res = await esClient.indices.addBlock({ index, block: 'write' }); - await removeDeprecatedSettings(esClient, index, log); + await removeDeprecatedSettings(esClient, index, versionService, log); break; } case 'unfreeze': { @@ -60,6 +67,7 @@ export async function updateIndex({ esClient, index, operations, log }: UpdateIn async function removeDeprecatedSettings( esClient: ElasticsearchClient, index: string, + versionService: Version, log?: Logger ) { try { @@ -71,7 +79,9 @@ async function removeDeprecatedSettings( // Get the warnings for this index to check for deprecated settings const flatSettings = indexSettings[index] || {}; - const warnings = flatSettings ? getReindexWarnings(flatSettings) : undefined; + const warnings = flatSettings + ? getReindexWarnings(flatSettings, versionService.getMajorVersion()) + : undefined; const indexSettingsWarning = warnings?.find( (warning) => warning.warningType === 'indexSetting' && diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/version.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/version.ts index b67468ec2a572..50dc36b6a40a3 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/lib/version.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/lib/version.ts @@ -5,38 +5,8 @@ * 2.0. */ -import SemVer from 'semver/classes/semver'; +import { Version } from '@kbn/upgrade-assistant-pkg-server'; -export interface IVersion { - setup(version: string): void; - getCurrentVersion(): SemVer; - getMajorVersion(): number; - getNextMajorVersion(): number; - getPrevMajorVersion(): number; -} +const versionService = new Version(); -export class Version implements IVersion { - private version!: SemVer; - - public setup(version: string) { - this.version = new SemVer(version); - } - - public getCurrentVersion() { - return this.version; - } - - public getMajorVersion() { - return this.version?.major; - } - - public getNextMajorVersion() { - return this.version?.major + 1; - } - - public getPrevMajorVersion() { - return this.version?.major - 1; - } -} - -export const versionService = new Version(); +export { versionService }; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/plugin.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/plugin.ts index 019d83fc691de..7a084cb94b502 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/plugin.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/plugin.ts @@ -12,7 +12,6 @@ import { CoreStart, PluginInitializerContext, Logger, - SavedObjectsClient, SavedObjectsServiceStart, } from '@kbn/core/server'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; @@ -21,26 +20,20 @@ import { LogsSharedPluginSetup } from '@kbn/logs-shared-plugin/server'; import { FeaturesPluginSetup } from '@kbn/features-plugin/server'; import { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; +import { mlSavedObjectType } from '@kbn/upgrade-assistant-pkg-server'; +import { ReindexServiceServerPluginStart } from '@kbn/reindex-service-plugin/server'; +import type { DataSourceExclusions, FeatureSet } from '../common/types'; import { DEPRECATION_LOGS_SOURCE_ID, DEPRECATION_LOGS_INDEX } from '../common/constants'; -import { CredentialStore, credentialStoreFactory } from './lib/reindexing/credential_store'; -import { ReindexWorker } from './lib/reindexing'; import { registerUpgradeAssistantUsageCollector } from './lib/telemetry'; import { versionService } from './lib/version'; -import { createReindexWorker } from './routes/reindex_indices'; import { registerRoutes } from './routes/register_routes'; -import { - reindexOperationSavedObjectType, - mlSavedObjectType, - hiddenTypes, -} from './saved_object_types'; import { handleEsError } from './shared_imports'; import { RouteDependencies } from './types'; import type { UpgradeAssistantConfig } from './config'; -import type { DataSourceExclusions, FeatureSet } from '../common/types'; import { defaultExclusions } from './lib/data_source_exclusions'; -interface PluginsSetup { +interface UpgradeAssistantServerSetupDependencies { usageCollection: UsageCollectionSetup; licensing: LicensingPluginSetup; features: FeaturesPluginSetup; @@ -48,28 +41,30 @@ interface PluginsSetup { security?: SecurityPluginSetup; } -interface PluginsStart { +interface UpgradeAssistantServerStartDependencies { security: SecurityPluginStart; + reindexService: ReindexServiceServerPluginStart; } - -export class UpgradeAssistantServerPlugin implements Plugin { +export class UpgradeAssistantServerPlugin + implements + Plugin< + void, + void, + UpgradeAssistantServerSetupDependencies, + UpgradeAssistantServerStartDependencies + > +{ private readonly logger: Logger; - private readonly credentialStore: CredentialStore; private readonly kibanaVersion: string; private readonly initialFeatureSet: FeatureSet; private readonly initialDataSourceExclusions: DataSourceExclusions; - // Properties set at setup - private licensing?: LicensingPluginSetup; - // Properties set at start private savedObjectsServiceStart?: SavedObjectsServiceStart; private securityPluginStart?: SecurityPluginStart; - private worker?: ReindexWorker; constructor({ logger, env, config }: PluginInitializerContext) { this.logger = logger.get(); - this.credentialStore = credentialStoreFactory(this.logger); this.kibanaVersion = env.packageInfo.version; const { featureSet, dataSourceExclusions } = config.get(); @@ -77,20 +72,13 @@ export class UpgradeAssistantServerPlugin implements Plugin { this.initialDataSourceExclusions = Object.assign({}, defaultExclusions, dataSourceExclusions); } - private getWorker() { - if (!this.worker) { - throw new Error('Worker unavailable'); - } - return this.worker; - } - setup( - { http, deprecations, getStartServices, savedObjects, docLinks }: CoreSetup, - { usageCollection, features, licensing, logsShared, security }: PluginsSetup + coreSetup: CoreSetup, + pluginSetup: UpgradeAssistantServerSetupDependencies ) { - this.licensing = licensing; + const { http, getStartServices, savedObjects } = coreSetup; + const { usageCollection, features, licensing, logsShared, security } = pluginSetup; - savedObjects.registerType(reindexOperationSavedObjectType); savedObjects.registerType(mlSavedObjectType); features.registerElasticsearchFeature({ @@ -127,7 +115,6 @@ export class UpgradeAssistantServerPlugin implements Plugin { const dependencies: RouteDependencies = { router, - credentialStore: this.credentialStore, log: this.logger, licensing, getSavedObjectsService: () => { @@ -147,9 +134,15 @@ export class UpgradeAssistantServerPlugin implements Plugin { }, current: versionService.getCurrentVersion(), defaultTarget: versionService.getNextMajorVersion(), + version: versionService, + cleanupReindexOperations: async (indexNames: string[]) => { + const [, { reindexService }] = await getStartServices(); + + return reindexService.cleanupReindexOperations(indexNames); + }, }; - registerRoutes(dependencies, this.getWorker.bind(this)); + registerRoutes(dependencies); if (usageCollection) { void getStartServices().then(([{ elasticsearch }]) => { @@ -161,34 +154,10 @@ export class UpgradeAssistantServerPlugin implements Plugin { } } - start({ savedObjects, elasticsearch }: CoreStart, { security }: PluginsStart) { + start({ savedObjects }: CoreStart, { security }: UpgradeAssistantServerStartDependencies) { this.savedObjectsServiceStart = savedObjects; this.securityPluginStart = security; - - // The ReindexWorker uses a map of request headers that contain the authentication credentials - // for a given reindex. We cannot currently store these in an the .kibana index b/c we do not - // want to expose these credentials to any unauthenticated users. We also want to avoid any need - // to add a user for a special index just for upgrading. This in-memory cache allows us to - // process jobs without the browser staying on the page, but will require that jobs go into - // a paused state if no Kibana nodes have the required credentials. - - this.worker = createReindexWorker({ - credentialStore: this.credentialStore, - licensing: this.licensing!, - elasticsearchService: elasticsearch, - logger: this.logger, - savedObjects: new SavedObjectsClient( - this.savedObjectsServiceStart.createInternalRepository(hiddenTypes) - ), - security: this.securityPluginStart, - }); - - this.worker.start(); } - stop(): void { - if (this.worker) { - this.worker.stop(); - } - } + stop(): void {} } diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/app.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/app.ts index 12063ba382d6f..58c4886b39c64 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/app.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/app.ts @@ -5,13 +5,13 @@ * 2.0. */ +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH, DEPRECATION_LOGS_INDEX, APP_LOGS_COUNT_INDEX_PRIVILEGES, APP_LOGS_COUNT_CLUSTER_PRIVILEGES, } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { Privileges } from '../shared_imports'; import { RouteDependencies } from '../types'; @@ -39,6 +39,7 @@ export function registerAppRoutes({ router, lib: { handleEsError }, config: { isSecurityEnabled }, + current, }: RouteDependencies) { router.get( { @@ -51,7 +52,7 @@ export function registerAppRoutes({ }, validate: false, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { const { elasticsearch: { client }, } = await core; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cloud_backup_status.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cloud_backup_status.ts index 0ae3b03eb7618..958caa4ab49aa 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cloud_backup_status.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cloud_backup_status.ts @@ -5,13 +5,14 @@ * 2.0. */ +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH, CLOUD_SNAPSHOT_REPOSITORY } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; export function registerCloudBackupStatusRoutes({ router, lib: { handleEsError }, + current, }: RouteDependencies) { // GET most recent Cloud snapshot router.get( @@ -25,7 +26,7 @@ export function registerCloudBackupStatusRoutes({ }, validate: false, }, - versionCheckHandlerWrapper(async (context, request, response) => { + versionCheckHandlerWrapper(current.major)(async (context, request, response) => { const { client: clusterClient } = (await context.core).elasticsearch; try { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cluster_settings.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cluster_settings.ts index aae2b02267b93..6ac254d25571d 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cluster_settings.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cluster_settings.ts @@ -6,13 +6,14 @@ */ import { schema } from '@kbn/config-schema'; +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; export function registerClusterSettingsRoute({ router, lib: { handleEsError }, + current, }: RouteDependencies) { router.post( { @@ -29,7 +30,7 @@ export function registerClusterSettingsRoute({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cluster_upgrade_status.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cluster_upgrade_status.ts index 3f930ca0a67d0..f3e1fdfced578 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cluster_upgrade_status.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/cluster_upgrade_status.ts @@ -5,11 +5,11 @@ * 2.0. */ +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; -export function registerClusterUpgradeStatusRoutes({ router }: RouteDependencies) { +export function registerClusterUpgradeStatusRoutes({ router, current }: RouteDependencies) { router.get( { path: `${API_BASE_PATH}/cluster_upgrade_status`, @@ -23,7 +23,7 @@ export function registerClusterUpgradeStatusRoutes({ router }: RouteDependencies }, // We're just depending on the version check to return a 426. // Otherwise we just return a 200. - versionCheckHandlerWrapper(async (context, request, response) => { + versionCheckHandlerWrapper(current.major)(async (context, request, response) => { return response.ok(); }) ); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/deprecation_logging.test.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/deprecation_logging.test.ts index 8df95072f5ac5..6135979cd1dc5 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/deprecation_logging.test.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/deprecation_logging.test.ts @@ -10,8 +10,8 @@ import { createMockRouter, MockRouter, routeHandlerContextMock } from './__mocks import { createRequestMock } from './__mocks__/request.mock'; import { handleEsError } from '../shared_imports'; -jest.mock('../lib/es_version_precheck', () => ({ - versionCheckHandlerWrapper: (a: any) => a, +jest.mock('@kbn/upgrade-assistant-pkg-server', () => ({ + versionCheckHandlerWrapper: () => (a: any) => a, })); import { registerDeprecationLoggingRoutes } from './deprecation_logging'; @@ -30,6 +30,7 @@ describe('deprecation logging API', () => { routeDependencies = { router: mockRouter, lib: { handleEsError }, + current: { major: 8 }, }; registerDeprecationLoggingRoutes(routeDependencies); }); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/deprecation_logging.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/deprecation_logging.ts index 2a8841f041ab1..a689a3ed34b65 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/deprecation_logging.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/deprecation_logging.ts @@ -7,6 +7,7 @@ import moment from 'moment-timezone'; import { schema } from '@kbn/config-schema'; +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH, APPS_WITH_DEPRECATION_LOGS, @@ -17,13 +18,13 @@ import { getDeprecationLoggingStatus, setDeprecationLogging, } from '../lib/es_deprecation_logging_apis'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; import { DEPRECATION_LOGS_INDEX } from '../../common/constants'; export function registerDeprecationLoggingRoutes({ router, lib: { handleEsError }, + current, }: RouteDependencies) { router.get( { @@ -36,7 +37,7 @@ export function registerDeprecationLoggingRoutes({ }, validate: false, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, @@ -64,7 +65,7 @@ export function registerDeprecationLoggingRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, @@ -94,7 +95,7 @@ export function registerDeprecationLoggingRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, @@ -148,7 +149,7 @@ export function registerDeprecationLoggingRoutes({ }, validate: false, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/es_deprecations.test.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/es_deprecations.test.ts index a95f5ac984778..50bb63aaef263 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/es_deprecations.test.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/es_deprecations.test.ts @@ -11,8 +11,8 @@ import { handleEsError } from '../shared_imports'; import { createMockRouter, MockRouter, routeHandlerContextMock } from './__mocks__/routes.mock'; import { createRequestMock } from './__mocks__/request.mock'; -jest.mock('../lib/es_version_precheck', () => ({ - versionCheckHandlerWrapper: (a: any) => a, +jest.mock('@kbn/upgrade-assistant-pkg-server', () => ({ + versionCheckHandlerWrapper: () => (a: any) => a, })); // Need to require to get mock on named export to work. @@ -44,6 +44,8 @@ describe('ES deprecations API', () => { router: mockRouter, lib: { handleEsError }, log: { error: jest.fn() }, + current: { major: 8 }, + cleanupReindexOperations: jest.fn(), }; registerESDeprecationRoutes(routeDependencies); }); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/es_deprecations.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/es_deprecations.ts index b42ea170d2234..684ebdaa07e64 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/es_deprecations.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/es_deprecations.ts @@ -5,19 +5,18 @@ * 2.0. */ +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; import { getESUpgradeStatus } from '../lib/es_deprecations_status'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import type { RouteDependencies } from '../types'; -import { reindexActionsFactory } from '../lib/reindexing/reindex_actions'; -import { reindexServiceFactory } from '../lib/reindexing'; export function registerESDeprecationRoutes({ config: { featureSet, dataSourceExclusions }, router, lib: { handleEsError }, - licensing, log, + current, + cleanupReindexOperations, }: RouteDependencies) { router.get( { @@ -30,27 +29,91 @@ export function registerESDeprecationRoutes({ }, validate: false, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { - savedObjects: { client: savedObjectsClient }, elasticsearch: { client }, } = await core; const status = await getESUpgradeStatus(client.asCurrentUser, { featureSet, dataSourceExclusions, }); - const asCurrentUser = client.asCurrentUser; - const reindexActions = reindexActionsFactory(savedObjectsClient, asCurrentUser, log); - const reindexService = reindexServiceFactory(asCurrentUser, reindexActions, log, licensing); + const indexNames = [...status.migrationsDeprecations, ...status.enrichedHealthIndicators] .filter(({ index }) => typeof index !== 'undefined') .map(({ index }) => index as string); - await reindexService.cleanupReindexOperations(indexNames); + await cleanupReindexOperations(indexNames); return response.ok({ - body: status, + // body: status, + body: { + totalCriticalDeprecations: 3, + migrationsDeprecations: [ + { + index: 'kibana_sample_data_ecommerce', + type: 'index_settings', + details: 'This index has version: 7.17.28', + message: 'Old index with a compatibility version < 8.0', + url: 'https://ela.st/es-deprecation-9-index-version', + level: 'critical', + resolveDuringUpgrade: false, + correctiveAction: { + type: 'reindex', + metadata: { + isClosedIndex: false, + isFrozenIndex: false, + isInDataStream: false, + }, + excludedActions: ['readOnly'], + indexSizeInBytes: 4550530, + }, + }, + { + index: 'kibana_sample_data_logs', + type: 'data_streams', + details: + 'This data stream has backing indices that were created before Elasticsearch 8.0', + message: 'Old data stream with a compatibility version < 8.0', + url: 'https://ela.st/es-deprecation-ds-reindex', + level: 'critical', + resolveDuringUpgrade: false, + correctiveAction: { + type: 'dataStream', + metadata: { + ignoredIndicesRequiringUpgrade: [], + ignoredIndicesRequiringUpgradeCount: 0, + totalBackingIndices: 1, + indicesRequiringUpgradeCount: 1, + indicesRequiringUpgrade: ['.ds-kibana_sample_data_logs-2025.07.30-000001'], + reindexRequired: true, + excludedActions: [], + }, + }, + }, + { + index: 'kibana_sample_data_flights', + type: 'index_settings', + details: 'This index has version: 7.17.28', + message: 'Old index with a compatibility version < 8.0', + url: 'https://ela.st/es-deprecation-9-index-version', + level: 'critical', + resolveDuringUpgrade: false, + correctiveAction: { + type: 'reindex', + metadata: { + isClosedIndex: false, + isFrozenIndex: false, + isInDataStream: false, + }, + excludedActions: ['readOnly'], + indexSizeInBytes: 6391375, + }, + }, + ], + totalCriticalHealthIssues: 0, + enrichedHealthIndicators: [], + }, }); } catch (error) { log.error(error); @@ -59,3 +122,8 @@ export function registerESDeprecationRoutes({ }) ); } + +/** + * + {"dataStreamName":"my-data-stream","documentationUrl":"https://ela.st/es-deprecation-ds-reindex","allIndices":[".ds-my-data-stream-2025.07.30-000001"],"allIndicesCount":1,"indicesRequiringUpgrade":[".ds-my-data-stream-2025.07.30-000001"],"indicesRequiringUpgradeCount":1,"lastIndexRequiringUpgradeCreationDate":1753906213125,"indicesRequiringUpgradeDocsSize":8814,"indicesRequiringUpgradeDocsCount":3,"oldestIncompatibleDocTimestamp":4081767675000} + */ diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/migrate_data_streams/data_stream_routes.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/migrate_data_streams/data_stream_routes.ts index dbf377181f19e..025c94106fb0c 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/migrate_data_streams/data_stream_routes.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/migrate_data_streams/data_stream_routes.ts @@ -9,10 +9,10 @@ import { schema } from '@kbn/config-schema'; import { errors } from '@elastic/elasticsearch'; import { i18n } from '@kbn/i18n'; +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { error } from '../../lib/data_streams/error'; import { API_BASE_PATH } from '../../../common/constants'; import { DataStreamReindexStatusResponse } from '../../../common/types'; -import { versionCheckHandlerWrapper } from '../../lib/es_version_precheck'; import { dataStreamMigrationServiceFactory } from '../../lib/data_streams'; import { RouteDependencies } from '../../types'; @@ -23,6 +23,7 @@ export function registerMigrateDataStreamRoutes({ licensing, log, lib: { handleEsError }, + current, }: RouteDependencies) { const BASE_PATH = `${API_BASE_PATH}/migrate_data_stream`; @@ -41,7 +42,7 @@ export function registerMigrateDataStreamRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { const { elasticsearch: { client: esClient }, } = await core; @@ -92,7 +93,7 @@ export function registerMigrateDataStreamRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { const { elasticsearch: { client: esClient }, } = await core; @@ -141,7 +142,7 @@ export function registerMigrateDataStreamRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { const { elasticsearch: { client: esClient }, } = await core; @@ -155,12 +156,29 @@ export function registerMigrateDataStreamRoutes({ }); try { + return response.ok({ + body: { + dataStreamName: 'kibana_sample_data_logs', + documentationUrl: 'https://ela.st/es-deprecation-ds-reindex', + allIndices: ['.ds-kibana_sample_data_logs-2025.07.30-000001'], + allIndicesCount: 1, + indicesRequiringUpgrade: ['.ds-kibana_sample_data_logs-2025.07.30-000001'], + indicesRequiringUpgradeCount: 1, + lastIndexRequiringUpgradeCreationDate: 1753906213125, + indicesRequiringUpgradeDocsSize: 8814, + indicesRequiringUpgradeDocsCount: 3, + oldestIncompatibleDocTimestamp: 4081767675000, + }, + }); + /* const dataStreamMetadata = await migrationService.getDataStreamMetadata(dataStreamName); return response.ok({ body: dataStreamMetadata || undefined, }); + */ } catch (err) { + console.log(err); if (err instanceof errors.ResponseError) { return handleEsError({ error: err, response }); } @@ -184,7 +202,7 @@ export function registerMigrateDataStreamRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { const { elasticsearch: { client: esClient }, } = await core; @@ -242,7 +260,7 @@ export function registerMigrateDataStreamRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { const { elasticsearch: { client: esClient }, } = await core; diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/ml_snapshots.test.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/ml_snapshots.test.ts index a841f3042f964..b4b93b914ff5e 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/ml_snapshots.test.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/ml_snapshots.test.ts @@ -18,8 +18,11 @@ import { import { createRequestMock } from './__mocks__/request.mock'; import { registerMlSnapshotRoutes } from './ml_snapshots'; -jest.mock('../lib/es_version_precheck', () => ({ - versionCheckHandlerWrapper: (handler: RequestHandler) => handler, +jest.mock('@kbn/upgrade-assistant-pkg-server', () => ({ + versionCheckHandlerWrapper: + () => + (handler: RequestHandler) => + handler, })); const JOB_ID = 'job_id'; @@ -38,6 +41,7 @@ describe('ML snapshots APIs', () => { }, router: mockRouter, lib: { handleEsError }, + current: { major: 8 }, }; registerMlSnapshotRoutes(routeDependencies); } diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/ml_snapshots.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/ml_snapshots.ts index e00d545c07a1c..2501d8c4cb1b6 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/ml_snapshots.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/ml_snapshots.ts @@ -11,9 +11,9 @@ import type { TransportResult } from '@elastic/elasticsearch'; import { schema } from '@kbn/config-schema'; import { IScopedClusterClient, SavedObjectsClientContract } from '@kbn/core/server'; +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; import { MlOperation, ML_UPGRADE_OP_TYPE } from '../../common/types'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; const findMlOperation = async ( @@ -140,6 +140,7 @@ export function registerMlSnapshotRoutes({ router, log, lib: { handleEsError }, + current, }: RouteDependencies) { // Upgrade ML model snapshot router.post( @@ -158,7 +159,7 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { savedObjects: { getClient }, @@ -214,7 +215,7 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { savedObjects: { getClient }, @@ -353,7 +354,7 @@ export function registerMlSnapshotRoutes({ }, }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { /** * Always return false if featureSet.mlSnapshots is set to false @@ -406,7 +407,7 @@ export function registerMlSnapshotRoutes({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/node_disk_space.test.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/node_disk_space.test.ts index 315c2537afa15..89d3a6a83c80c 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/node_disk_space.test.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/node_disk_space.test.ts @@ -10,8 +10,8 @@ import { createMockRouter, MockRouter, routeHandlerContextMock } from './__mocks import { createRequestMock } from './__mocks__/request.mock'; import { handleEsError } from '../shared_imports'; -jest.mock('../lib/es_version_precheck', () => ({ - versionCheckHandlerWrapper: (a: any) => a, +jest.mock('@kbn/upgrade-assistant-pkg-server', () => ({ + versionCheckHandlerWrapper: () => (a: any) => a, })); import { registerNodeDiskSpaceRoute } from './node_disk_space'; @@ -25,6 +25,7 @@ describe('Disk space API', () => { routeDependencies = { router: mockRouter, lib: { handleEsError }, + current: { major: 8 }, }; registerNodeDiskSpaceRoute(routeDependencies); }); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/node_disk_space.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/node_disk_space.ts index 2d22fa8442835..81fc43712d7e5 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/node_disk_space.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/node_disk_space.ts @@ -7,8 +7,8 @@ import type { ClusterGetSettingsResponse } from '@elastic/elasticsearch/lib/api/types'; import { ByteSizeValue } from '@kbn/config-schema'; +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; interface NodeWithLowDiskSpace { @@ -43,7 +43,11 @@ const getLowDiskWatermarkSetting = ( return undefined; }; -export function registerNodeDiskSpaceRoute({ router, lib: { handleEsError } }: RouteDependencies) { +export function registerNodeDiskSpaceRoute({ + router, + current, + lib: { handleEsError }, +}: RouteDependencies) { router.get( { path: `${API_BASE_PATH}/node_disk_space`, @@ -55,7 +59,7 @@ export function registerNodeDiskSpaceRoute({ router, lib: { handleEsError } }: R }, validate: false, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/register_routes.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/register_routes.ts index c94a4a378a360..b1534ce0caa28 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/register_routes.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/register_routes.ts @@ -13,10 +13,8 @@ import { registerClusterUpgradeStatusRoutes } from './cluster_upgrade_status'; import { registerSystemIndicesMigrationRoutes } from './system_indices_migration'; import { registerESDeprecationRoutes } from './es_deprecations'; import { registerDeprecationLoggingRoutes } from './deprecation_logging'; -import { registerReindexIndicesRoutes, registerBatchReindexIndicesRoutes } from './reindex_indices'; import { registerUpdateSettingsRoute } from './update_index_settings'; import { registerMlSnapshotRoutes } from './ml_snapshots'; -import { ReindexWorker } from '../lib/reindexing'; import { registerUpgradeStatusRoute } from './status'; import { registerRemoteClustersRoute } from './remote_clusters'; import { registerNodeDiskSpaceRoute } from './node_disk_space'; @@ -24,7 +22,7 @@ import { registerClusterSettingsRoute } from './cluster_settings'; import { registerMigrateDataStreamRoutes } from './migrate_data_streams'; import { registerUpdateIndexRoute } from './update_index'; -export function registerRoutes(dependencies: RouteDependencies, getWorker: () => ReindexWorker) { +export function registerRoutes(dependencies: RouteDependencies) { registerAppRoutes(dependencies); registerCloudBackupStatusRoutes(dependencies); @@ -32,8 +30,6 @@ export function registerRoutes(dependencies: RouteDependencies, getWorker: () => registerSystemIndicesMigrationRoutes(dependencies); registerESDeprecationRoutes(dependencies); registerDeprecationLoggingRoutes(dependencies); - registerReindexIndicesRoutes(dependencies, getWorker); - registerBatchReindexIndicesRoutes(dependencies, getWorker); registerUpdateSettingsRoute(dependencies); registerMlSnapshotRoutes(dependencies); // Route for cloud to retrieve the upgrade status for ES and Kibana diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/create_reindex_worker.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/create_reindex_worker.ts deleted file mode 100644 index 81c65330d14b6..0000000000000 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/reindex_indices/create_reindex_worker.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ElasticsearchServiceStart, Logger, SavedObjectsClient } from '@kbn/core/server'; - -import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; -import { SecurityPluginStart } from '@kbn/security-plugin/server'; -import { ReindexWorker } from '../../lib/reindexing'; -import { CredentialStore } from '../../lib/reindexing/credential_store'; - -interface CreateReindexWorker { - logger: Logger; - elasticsearchService: ElasticsearchServiceStart; - credentialStore: CredentialStore; - savedObjects: SavedObjectsClient; - licensing: LicensingPluginSetup; - security: SecurityPluginStart; -} - -export function createReindexWorker({ - logger, - elasticsearchService, - credentialStore, - savedObjects, - licensing, - security, -}: CreateReindexWorker) { - const esClient = elasticsearchService.client; - return ReindexWorker.create(savedObjects, credentialStore, esClient, logger, licensing, security); -} diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/remote_clusters.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/remote_clusters.ts index 7b8ad1f046085..4f23b4e928dac 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/remote_clusters.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/remote_clusters.ts @@ -5,11 +5,15 @@ * 2.0. */ +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; -export function registerRemoteClustersRoute({ router, lib: { handleEsError } }: RouteDependencies) { +export function registerRemoteClustersRoute({ + router, + current, + lib: { handleEsError }, +}: RouteDependencies) { router.get( { path: `${API_BASE_PATH}/remote_clusters`, @@ -21,7 +25,7 @@ export function registerRemoteClustersRoute({ router, lib: { handleEsError } }: }, validate: false, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/status.test.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/status.test.ts index 79eaf9806feaa..6fdc4231c08ec 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/status.test.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/status.test.ts @@ -16,7 +16,6 @@ import { getKibanaUpgradeStatus } from '../lib/kibana_status'; import { getESSystemIndicesMigrationStatus } from '../lib/es_system_indices_migration'; import { getRecentEsDeprecationLogs } from '../lib/es_deprecation_logging_apis'; import type { FeatureSet } from '../../common/types'; -import { versionService } from '../lib/version'; import { getMockVersionInfo } from '../lib/__fixtures__/version'; const { currentVersion, nextMajor } = getMockVersionInfo(); @@ -29,8 +28,8 @@ const defaultApiResponseProperties = { }, kibanaApiDeprecations: undefined, }; -jest.mock('../lib/es_version_precheck', () => ({ - versionCheckHandlerWrapper: (a: any) => a, +jest.mock('@kbn/upgrade-assistant-pkg-server', () => ({ + versionCheckHandlerWrapper: () => (a: any) => a, })); jest.mock('../lib/es_deprecations_status', () => ({ @@ -113,10 +112,6 @@ const systemIndicesNoMigrationResponse = { }; describe('Status API', () => { - beforeAll(() => { - versionService.setup('8.17.0'); - }); - describe('GET /api/upgrade_assistant/status for major upgrade', () => { const registerRoutes = (featureSetOverrides: Partial = {}) => { const mockRouter = createMockRouter(); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/status.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/status.ts index acc8205b1b05b..667f11b797568 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/status.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/status.ts @@ -6,9 +6,9 @@ */ import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH, RECENT_DURATION_MS } from '../../common/constants'; import { getESUpgradeStatus } from '../lib/es_deprecations_status'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { getKibanaUpgradeStatus } from '../lib/kibana_status'; import { getESSystemIndicesMigrationStatus } from '../lib/es_system_indices_migration'; import { RouteDependencies } from '../types'; @@ -45,7 +45,7 @@ export function registerUpgradeStatusRoute({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { const targetVersion = request.query?.targetVersion || `${defaultTarget}`; const upgradeType = getUpgradeType({ current, target: targetVersion }); if (!upgradeType) return response.forbidden(); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/system_indices_migration.test.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/system_indices_migration.test.ts index 914008ccc079c..57c8395475a5d 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/system_indices_migration.test.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/system_indices_migration.test.ts @@ -10,8 +10,8 @@ import { createMockRouter, MockRouter, routeHandlerContextMock } from './__mocks import { createRequestMock } from './__mocks__/request.mock'; import { handleEsError } from '../shared_imports'; -jest.mock('../lib/es_version_precheck', () => ({ - versionCheckHandlerWrapper: (a: any) => a, +jest.mock('@kbn/upgrade-assistant-pkg-server', () => ({ + versionCheckHandlerWrapper: () => (a: any) => a, })); import { registerSystemIndicesMigrationRoutes } from './system_indices_migration'; @@ -57,6 +57,7 @@ describe('Migrate system indices API', () => { routeDependencies = { router: mockRouter, lib: { handleEsError }, + current: { major: 8 }, }; registerSystemIndicesMigrationRoutes(routeDependencies); }); diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/system_indices_migration.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/system_indices_migration.ts index 6c9790f55b908..c3b3874a83cdf 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/system_indices_migration.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/system_indices_migration.ts @@ -5,8 +5,8 @@ * 2.0. */ +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; import { getESSystemIndicesMigrationStatus, @@ -16,6 +16,7 @@ import { export function registerSystemIndicesMigrationRoutes({ router, lib: { handleEsError }, + current, }: RouteDependencies) { // GET status of the system indices migration router.get( @@ -29,7 +30,7 @@ export function registerSystemIndicesMigrationRoutes({ }, validate: false, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, @@ -62,7 +63,7 @@ export function registerSystemIndicesMigrationRoutes({ }, }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/update_index.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/update_index.ts index b60939c5b1c28..b840af9118ebc 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/update_index.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/update_index.ts @@ -8,15 +8,17 @@ import { schema } from '@kbn/config-schema'; import { errors } from '@elastic/elasticsearch'; +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import type { RouteDependencies } from '../types'; import { updateIndex } from '../lib/update_index'; +import { versionService } from '../lib/version'; export function registerUpdateIndexRoute({ router, lib: { handleEsError }, log, + current, }: RouteDependencies) { const BASE_PATH = `${API_BASE_PATH}/update_index`; router.post( @@ -43,7 +45,7 @@ export function registerUpdateIndexRoute({ }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { const { elasticsearch: { client }, } = await core; @@ -55,6 +57,7 @@ export function registerUpdateIndexRoute({ index, operations, log, + versionService, }); return response.ok(); } catch (err) { diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/update_index_settings.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/update_index_settings.ts index f037381a9f52a..54743007039d8 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/routes/update_index_settings.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/routes/update_index_settings.ts @@ -6,11 +6,11 @@ */ import { schema } from '@kbn/config-schema'; +import { versionCheckHandlerWrapper } from '@kbn/upgrade-assistant-pkg-server'; import { API_BASE_PATH } from '../../common/constants'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; import { RouteDependencies } from '../types'; -export function registerUpdateSettingsRoute({ router }: RouteDependencies) { +export function registerUpdateSettingsRoute({ router, current }: RouteDependencies) { router.post( { path: `${API_BASE_PATH}/{indexName}/index_settings`, @@ -29,7 +29,7 @@ export function registerUpdateSettingsRoute({ router }: RouteDependencies) { }), }, }, - versionCheckHandlerWrapper(async ({ core }, request, response) => { + versionCheckHandlerWrapper(current.major)(async ({ core }, request, response) => { try { const { elasticsearch: { client }, diff --git a/x-pack/platform/plugins/private/upgrade_assistant/server/types.ts b/x-pack/platform/plugins/private/upgrade_assistant/server/types.ts index 7210069f23df2..3d7335dd695bb 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/server/types.ts +++ b/x-pack/platform/plugins/private/upgrade_assistant/server/types.ts @@ -9,13 +9,12 @@ import { IRouter, Logger, SavedObjectsServiceStart } from '@kbn/core/server'; import { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; import { SecurityPluginStart } from '@kbn/security-plugin/server'; import SemVer from 'semver/classes/semver'; -import { CredentialStore } from './lib/reindexing/credential_store'; +import type { Version } from '@kbn/upgrade-assistant-pkg-server'; import { handleEsError } from './shared_imports'; import type { DataSourceExclusions, FeatureSet } from '../common/types'; export interface RouteDependencies { router: IRouter; - credentialStore: CredentialStore; log: Logger; getSavedObjectsService: () => SavedObjectsServiceStart; getSecurityPlugin: () => SecurityPluginStart | undefined; @@ -30,4 +29,6 @@ export interface RouteDependencies { }; current: SemVer; defaultTarget: number; + version: Version; + cleanupReindexOperations: (indexNames: string[]) => Promise; } diff --git a/x-pack/platform/plugins/private/upgrade_assistant/tsconfig.json b/x-pack/platform/plugins/private/upgrade_assistant/tsconfig.json index a0d60d983bf73..cae00bccee0d4 100644 --- a/x-pack/platform/plugins/private/upgrade_assistant/tsconfig.json +++ b/x-pack/platform/plugins/private/upgrade_assistant/tsconfig.json @@ -32,18 +32,17 @@ "@kbn/es-query", "@kbn/config-schema", "@kbn/security-plugin", - "@kbn/core-elasticsearch-client-server-mocks", "@kbn/utility-types", "@kbn/shared-ux-router", "@kbn/logs-shared-plugin", "@kbn/shared-ux-link-redirect-app", "@kbn/react-kibana-context-render", "@kbn/data-views-plugin", - "@kbn/core-logging-server-mocks", - "@kbn/core-http-server-mocks", - "@kbn/core-http-server-utils", "@kbn/core-elasticsearch-server", - "@kbn/upgrade-assistant", + "@kbn/upgrade-assistant-pkg-public", + "@kbn/upgrade-assistant-pkg-server", + "@kbn/upgrade-assistant-pkg-common", + "@kbn/reindex-service-plugin" ], "exclude": [ "target/**/*", diff --git a/x-pack/platform/test/tsconfig.json b/x-pack/platform/test/tsconfig.json index 06797c88be75b..8ab5101ec14b7 100644 --- a/x-pack/platform/test/tsconfig.json +++ b/x-pack/platform/test/tsconfig.json @@ -149,11 +149,14 @@ "@kbn/inference-common", "@kbn/rule-registry-plugin", "@kbn/controls-plugin", + "@kbn/upgrade-assistant-pkg-common", + "@kbn/upgrade-assistant-pkg-server", "@kbn/palettes", "@kbn/field-formats-plugin", "@kbn/visualizations-plugin", "@kbn/datemath", "@kbn/global-search-plugin", - "@kbn/global-search-test-plugin" + "@kbn/global-search-test-plugin", + "@kbn/reindex-service-plugin" ] } diff --git a/x-pack/platform/test/upgrade_assistant_integration/upgrade_assistant/reindexing.ts b/x-pack/platform/test/upgrade_assistant_integration/upgrade_assistant/reindexing.ts index 6dfe249fae9b7..f6b0adbc3d94b 100644 --- a/x-pack/platform/test/upgrade_assistant_integration/upgrade_assistant/reindexing.ts +++ b/x-pack/platform/test/upgrade_assistant_integration/upgrade_assistant/reindexing.ts @@ -7,13 +7,11 @@ import expect from '@kbn/expect'; -import { - ReindexStatus, - REINDEX_OP_TYPE, - type ResolveIndexResponseFromES, -} from '@kbn/upgrade-assistant-plugin/common/types'; -import { generateNewIndexName } from '@kbn/upgrade-assistant-plugin/server/lib/reindexing/index_settings'; -import { getIndexState } from '@kbn/upgrade-assistant-plugin/common/get_index_state'; +import { REINDEX_OP_TYPE } from '@kbn/upgrade-assistant-plugin/common/types'; +import { ReindexStatus } from '@kbn/upgrade-assistant-pkg-common'; +import { generateNewIndexName } from '@kbn/reindex-service-plugin/server'; +import { getIndexState, Version } from '@kbn/upgrade-assistant-pkg-server'; +import type { ResolveIndexResponseFromES } from '@kbn/upgrade-assistant-pkg-server'; import { sortBy } from 'lodash'; import { FtrProviderContext } from '../../common/ftr_provider_context'; @@ -22,6 +20,9 @@ export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const es = getService('es'); + const versionService = new Version(); + versionService.setup('8.0.0'); + // Utility function that keeps polling API until reindex operation has completed or failed. const waitForReindexToComplete = async (indexName: string) => { let lastState; @@ -268,7 +269,7 @@ export default function ({ getService }: FtrProviderContext) { const cleanupReindex = async (indexName: string) => { try { - await es.indices.delete({ index: generateNewIndexName(indexName) }); + await es.indices.delete({ index: generateNewIndexName(indexName, versionService) }); } catch (e) { try { await es.indices.delete({ index: indexName }); diff --git a/yarn.lock b/yarn.lock index 5f9eb54728072..08729759e157d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6934,6 +6934,10 @@ version "0.0.0" uid "" +"@kbn/reindex-service-plugin@link:x-pack/platform/plugins/private/reindex_service": + version "0.0.0" + uid "" + "@kbn/relocate@link:packages/kbn-relocate": version "0.0.0" uid "" @@ -8182,11 +8186,19 @@ version "0.0.0" uid "" -"@kbn/upgrade-assistant-plugin@link:x-pack/platform/plugins/private/upgrade_assistant": +"@kbn/upgrade-assistant-pkg-common@link:x-pack/platform/packages/private/upgrade-assistant/common": version "0.0.0" uid "" -"@kbn/upgrade-assistant@link:x-pack/platform/packages/private/upgrade-assistant": +"@kbn/upgrade-assistant-pkg-public@link:x-pack/platform/packages/private/upgrade-assistant/public": + version "0.0.0" + uid "" + +"@kbn/upgrade-assistant-pkg-server@link:x-pack/platform/packages/private/upgrade-assistant/server": + version "0.0.0" + uid "" + +"@kbn/upgrade-assistant-plugin@link:x-pack/platform/plugins/private/upgrade_assistant": version "0.0.0" uid ""