diff --git a/docs/dev-tools/console/console.asciidoc b/docs/dev-tools/console/console.asciidoc index 48fe936dd2db..21334c31011f 100644 --- a/docs/dev-tools/console/console.asciidoc +++ b/docs/dev-tools/console/console.asciidoc @@ -129,3 +129,12 @@ image::dev-tools/console/images/console-settings.png["Console Settings", width=6 For a list of available keyboard shortcuts, click *Help*. + +[float] +[[console-settings]] +=== Disable Console + +If you don’t want to use *Console*, you can disable it by setting `console.ui.enabled` +to `false` in your `kibana.yml` configuration file. Changing this setting +causes the server to regenerate assets on the next startup, +which might cause a delay before pages start being served. \ No newline at end of file diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 4802a4da8182..af22ad4ad157 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -20,6 +20,11 @@ configuration using `${MY_ENV_VAR}` syntax. [cols="2*<"] |=== +| `console.ui.enabled:` +Toggling this causes the server to regenerate assets on the next startup, +which may cause a delay before pages start being served. +Set to `false` to disable Console. *Default: `true`* + | `csp.rules:` | deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."] A https://w3c.github.io/webappsec-csp/[Content Security Policy] template @@ -681,6 +686,10 @@ out through *Advanced Settings*. *Default: `true`* | Set this value to true to allow Vega to use any URL to access external data sources and images. When false, Vega can only get data from {es}. *Default: `false`* +| `xpack.ccr.ui.enabled` +Set this value to false to disable the Cross-Cluster Replication UI. +*Default: `true`* + |[[settings-explore-data-in-context]] `xpack.discoverEnhanced.actions.` `exploreDataInContextMenu.enabled` | Enables the *Explore underlying data* option that allows you to open *Discover* from a dashboard panel and view the panel data. *Default: `false`* @@ -689,6 +698,31 @@ sources and images. When false, Vega can only get data from {es}. *Default: `fal `exploreDataInChart.enabled` | Enables you to view the underlying documents in a data series from a dashboard panel. *Default: `false`* +| `xpack.ilm.ui.enabled` +Set this value to false to disable the Index Lifecycle Policies UI. +*Default: `true`* + +| `xpack.index_management.ui.enabled` +Set this value to false to disable the Index Management UI. +*Default: `true`* + +| `xpack.license_management.ui.enabled` +Set this value to false to disable the License Management UI. +*Default: `true`* + +| `xpack.remote_clusters.ui.enabled` +Set this value to false to disable the Remote Clusters UI. +*Default: `true`* + +| `xpack.rollup.ui.enabled:` +Set this value to false to disable the Rollup Jobs UI. *Default: true* + +| `xpack.snapshot_restore.ui.enabled:` +Set this value to false to disable the Snapshot and Restore UI. *Default: true* + +| `xpack.upgrade_assistant.ui.enabled:` +Set this value to false to disable the Upgrade Assistant UI. *Default: true* + | `i18n.locale` {ess-icon} | Set this value to change the {kib} interface language. Valid locales are: `en`, `zh-CN`, `ja-JP`. *Default: `en`* diff --git a/src/plugins/console/public/index.ts b/src/plugins/console/public/index.ts index 8c4a10710856..9a9c5896cd26 100644 --- a/src/plugins/console/public/index.ts +++ b/src/plugins/console/public/index.ts @@ -7,13 +7,14 @@ */ import './index.scss'; +import { PluginInitializerContext } from 'src/core/public'; import { ConsoleUIPlugin } from './plugin'; -export type { ConsoleUILocatorParams } from './plugin'; +export type { ConsoleUILocatorParams, ConsolePluginSetup } from './types'; export { ConsoleUIPlugin as Plugin }; -export function plugin() { - return new ConsoleUIPlugin(); +export function plugin(ctx: PluginInitializerContext) { + return new ConsoleUIPlugin(ctx); } diff --git a/src/plugins/console/public/plugin.ts b/src/plugins/console/public/plugin.ts index e3791df6a2db..d61769c23dfe 100644 --- a/src/plugins/console/public/plugin.ts +++ b/src/plugins/console/public/plugin.ts @@ -7,77 +7,87 @@ */ import { i18n } from '@kbn/i18n'; -import { SerializableRecord } from '@kbn/utility-types'; -import { Plugin, CoreSetup } from 'src/core/public'; +import { Plugin, CoreSetup, PluginInitializerContext } from 'src/core/public'; import { FeatureCatalogueCategory } from '../../home/public'; -import { AppSetupUIPluginDependencies } from './types'; - -export interface ConsoleUILocatorParams extends SerializableRecord { - loadFrom?: string; -} +import { + AppSetupUIPluginDependencies, + ClientConfigType, + ConsolePluginSetup, + ConsoleUILocatorParams, +} from './types'; export class ConsoleUIPlugin implements Plugin { + constructor(private ctx: PluginInitializerContext) {} + public setup( { notifications, getStartServices, http }: CoreSetup, { devTools, home, share, usageCollection }: AppSetupUIPluginDependencies - ) { - if (home) { - home.featureCatalogue.register({ + ): ConsolePluginSetup { + const { + ui: { enabled: isConsoleUiEnabled }, + } = this.ctx.config.get(); + + if (isConsoleUiEnabled) { + if (home) { + home.featureCatalogue.register({ + id: 'console', + title: i18n.translate('console.devToolsTitle', { + defaultMessage: 'Interact with the Elasticsearch API', + }), + description: i18n.translate('console.devToolsDescription', { + defaultMessage: 'Skip cURL and use a JSON interface to work with your data in Console.', + }), + icon: 'consoleApp', + path: '/app/dev_tools#/console', + showOnHomePage: false, + category: FeatureCatalogueCategory.ADMIN, + }); + } + + devTools.register({ id: 'console', - title: i18n.translate('console.devToolsTitle', { - defaultMessage: 'Interact with the Elasticsearch API', + order: 1, + title: i18n.translate('console.consoleDisplayName', { + defaultMessage: 'Console', }), - description: i18n.translate('console.devToolsDescription', { - defaultMessage: 'Skip cURL and use a JSON interface to work with your data in Console.', - }), - icon: 'consoleApp', - path: '/app/dev_tools#/console', - showOnHomePage: false, - category: FeatureCatalogueCategory.ADMIN, + enableRouting: false, + mount: async ({ element }) => { + const [core] = await getStartServices(); + + const { + i18n: { Context: I18nContext }, + docLinks: { DOC_LINK_VERSION }, + } = core; + + const { renderApp } = await import('./application'); + + return renderApp({ + http, + docLinkVersion: DOC_LINK_VERSION, + I18nContext, + notifications, + usageCollection, + element, + }); + }, }); + + const locator = share.url.locators.create({ + id: 'CONSOLE_APP_LOCATOR', + getLocation: async ({ loadFrom }) => { + return { + app: 'dev_tools', + path: `#/console${loadFrom ? `?load_from=${loadFrom}` : ''}`, + state: { loadFrom }, + }; + }, + }); + + return { locator }; } - devTools.register({ - id: 'console', - order: 1, - title: i18n.translate('console.consoleDisplayName', { - defaultMessage: 'Console', - }), - enableRouting: false, - mount: async ({ element }) => { - const [core] = await getStartServices(); - - const { - i18n: { Context: I18nContext }, - docLinks: { DOC_LINK_VERSION }, - } = core; - - const { renderApp } = await import('./application'); - - return renderApp({ - http, - docLinkVersion: DOC_LINK_VERSION, - I18nContext, - notifications, - usageCollection, - element, - }); - }, - }); - - const locator = share.url.locators.create({ - id: 'CONSOLE_APP_LOCATOR', - getLocation: async ({ loadFrom }) => { - return { - app: 'dev_tools', - path: `#/console${loadFrom ? `?load_from=${loadFrom}` : ''}`, - state: { loadFrom }, - }; - }, - }); - - return { locator }; + return {}; } public start() {} diff --git a/src/plugins/console/public/types/config.ts b/src/plugins/console/public/types/config.ts new file mode 100644 index 000000000000..da41eef6f548 --- /dev/null +++ b/src/plugins/console/public/types/config.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export interface ClientConfigType { + ui: { + enabled: boolean; + }; +} diff --git a/src/plugins/console/public/types/index.ts b/src/plugins/console/public/types/index.ts index b98adbf5610c..d8b6aaf7b12c 100644 --- a/src/plugins/console/public/types/index.ts +++ b/src/plugins/console/public/types/index.ts @@ -11,3 +11,5 @@ export * from './core_editor'; export * from './token'; export * from './tokens_provider'; export * from './common'; +export { ClientConfigType } from './config'; +export { ConsoleUILocatorParams } from './locator'; diff --git a/src/plugins/console/public/types/locator.ts b/src/plugins/console/public/types/locator.ts new file mode 100644 index 000000000000..f3a42338aaad --- /dev/null +++ b/src/plugins/console/public/types/locator.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { SerializableRecord } from '@kbn/utility-types'; + +export interface ConsoleUILocatorParams extends SerializableRecord { + loadFrom?: string; +} diff --git a/src/plugins/console/public/types/plugin_dependencies.ts b/src/plugins/console/public/types/plugin_dependencies.ts index 444776f47ea1..afc49f9a5a98 100644 --- a/src/plugins/console/public/types/plugin_dependencies.ts +++ b/src/plugins/console/public/types/plugin_dependencies.ts @@ -9,7 +9,9 @@ import { HomePublicPluginSetup } from '../../../home/public'; import { DevToolsSetup } from '../../../dev_tools/public'; import { UsageCollectionSetup } from '../../../usage_collection/public'; -import { SharePluginSetup } from '../../../share/public'; +import { SharePluginSetup, LocatorPublic } from '../../../share/public'; + +import { ConsoleUILocatorParams } from './locator'; export interface AppSetupUIPluginDependencies { home?: HomePublicPluginSetup; @@ -17,3 +19,7 @@ export interface AppSetupUIPluginDependencies { share: SharePluginSetup; usageCollection?: UsageCollectionSetup; } + +export interface ConsolePluginSetup { + locator?: LocatorPublic; +} diff --git a/src/plugins/console/server/config.ts b/src/plugins/console/server/config.ts index 6d667fed081e..024777aa8d25 100644 --- a/src/plugins/console/server/config.ts +++ b/src/plugins/console/server/config.ts @@ -7,6 +7,8 @@ */ import { SemVer } from 'semver'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; import { PluginConfigDescriptor } from 'kibana/server'; @@ -14,62 +16,171 @@ import { MAJOR_VERSION } from '../common/constants'; const kibanaVersion = new SemVer(MAJOR_VERSION); -const baseSettings = { - enabled: schema.boolean({ defaultValue: true }), - ssl: schema.object({ verify: schema.boolean({ defaultValue: false }) }, {}), -}; - -// Settings only available in 7.x -const deprecatedSettings = { - proxyFilter: schema.arrayOf(schema.string(), { defaultValue: ['.*'] }), - proxyConfig: schema.arrayOf( - schema.object({ - match: schema.object({ - protocol: schema.string({ defaultValue: '*' }), - host: schema.string({ defaultValue: '*' }), - port: schema.string({ defaultValue: '*' }), - path: schema.string({ defaultValue: '*' }), - }), - - timeout: schema.number(), - ssl: schema.object( - { - verify: schema.boolean(), - ca: schema.arrayOf(schema.string()), - cert: schema.string(), - key: schema.string(), - }, - { defaultValue: undefined } - ), +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ssl: schema.object({ verify: schema.boolean({ defaultValue: false }) }, {}), + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), }), - { defaultValue: [] } - ), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schemaLatest, + deprecations: () => [], }; -const configSchema = schema.object( +export type ConsoleConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( { - ...baseSettings, + enabled: schema.boolean({ defaultValue: true }), + proxyFilter: schema.arrayOf(schema.string(), { defaultValue: ['.*'] }), + proxyConfig: schema.arrayOf( + schema.object({ + match: schema.object({ + protocol: schema.string({ defaultValue: '*' }), + host: schema.string({ defaultValue: '*' }), + port: schema.string({ defaultValue: '*' }), + path: schema.string({ defaultValue: '*' }), + }), + + timeout: schema.number(), + ssl: schema.object( + { + verify: schema.boolean(), + ca: schema.arrayOf(schema.string()), + cert: schema.string(), + key: schema.string(), + }, + { defaultValue: undefined } + ), + }), + { defaultValue: [] } + ), + ssl: schema.object({ verify: schema.boolean({ defaultValue: false }) }, {}), + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), }, { defaultValue: undefined } ); -const configSchema7x = schema.object( - { - ...baseSettings, - ...deprecatedSettings, +export type ConsoleConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, }, - { defaultValue: undefined } -); - -export type ConfigType = TypeOf; -export type ConfigType7x = TypeOf; - -export const config: PluginConfigDescriptor = { - schema: kibanaVersion.major < 8 ? configSchema7x : configSchema, + schema: schema7x, deprecations: ({ deprecate, unused }) => [ - deprecate('enabled', '8.0.0'), - deprecate('proxyFilter', '8.0.0'), - deprecate('proxyConfig', '8.0.0'), unused('ssl'), + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'console.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'console.enabled', + level: 'critical', + title: i18n.translate('console.deprecations.enabledTitle', { + defaultMessage: 'Setting "console.enabled" is deprecated', + }), + message: i18n.translate('console.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the Console UI, use the "console.ui.enabled" setting instead of "console.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate('console.deprecations.enabled.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('console.deprecations.enabled.manualStepTwoMessage', { + defaultMessage: 'Change the "console.enabled" setting to "console.ui.enabled".', + }), + ], + }, + }); + return completeConfig; + }, + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'console.proxyConfig') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'console.proxyConfig', + level: 'critical', + title: i18n.translate('console.deprecations.proxyConfigTitle', { + defaultMessage: 'Setting "console.proxyConfig" is deprecated', + }), + message: i18n.translate('console.deprecations.proxyConfigMessage', { + defaultMessage: + 'Configuring "console.proxyConfig" is deprecated and will be removed in 8.0.0. To secure your connection between Kibana and Elasticsearch use the standard "server.ssl.*" settings instead.', + }), + documentationUrl: 'https://ela.st/encrypt-kibana-browser', + correctiveActions: { + manualSteps: [ + i18n.translate('console.deprecations.proxyConfig.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('console.deprecations.proxyConfig.manualStepTwoMessage', { + defaultMessage: 'Remove the "console.proxyConfig" setting.', + }), + i18n.translate('console.deprecations.proxyConfig.manualStepThreeMessage', { + defaultMessage: + 'Configure the secure connection between Kibana and Elasticsearch using the "server.ssl.*" settings.', + }), + ], + }, + }); + return completeConfig; + }, + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'console.proxyFilter') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'console.proxyFilter', + level: 'critical', + title: i18n.translate('console.deprecations.proxyFilterTitle', { + defaultMessage: 'Setting "console.proxyFilter" is deprecated', + }), + message: i18n.translate('console.deprecations.proxyFilterMessage', { + defaultMessage: + 'Configuring "console.proxyFilter" is deprecated and will be removed in 8.0.0. To secure your connection between Kibana and Elasticsearch use the standard "server.ssl.*" settings instead.', + }), + documentationUrl: 'https://ela.st/encrypt-kibana-browser', + correctiveActions: { + manualSteps: [ + i18n.translate('console.deprecations.proxyFilter.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('console.deprecations.proxyFilter.manualStepTwoMessage', { + defaultMessage: 'Remove the "console.proxyFilter" setting.', + }), + i18n.translate('console.deprecations.proxyFilter.manualStepThreeMessage', { + defaultMessage: + 'Configure the secure connection between Kibana and Elasticsearch using the "server.ssl.*" settings.', + }), + ], + }, + }); + return completeConfig; + }, ], }; + +export const config: PluginConfigDescriptor = + kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/src/plugins/console/server/index.ts b/src/plugins/console/server/index.ts index 6ae518f5dc79..b270b89a3d45 100644 --- a/src/plugins/console/server/index.ts +++ b/src/plugins/console/server/index.ts @@ -11,6 +11,7 @@ import { PluginInitializerContext } from 'kibana/server'; import { ConsoleServerPlugin } from './plugin'; export { ConsoleSetup, ConsoleStart } from './types'; + export { config } from './config'; export const plugin = (ctx: PluginInitializerContext) => new ConsoleServerPlugin(ctx); diff --git a/src/plugins/console/server/plugin.ts b/src/plugins/console/server/plugin.ts index 613337b286fb..5543c40d03cb 100644 --- a/src/plugins/console/server/plugin.ts +++ b/src/plugins/console/server/plugin.ts @@ -11,7 +11,7 @@ import { SemVer } from 'semver'; import { ProxyConfigCollection } from './lib'; import { SpecDefinitionsService, EsLegacyConfigService } from './services'; -import { ConfigType, ConfigType7x } from './config'; +import { ConsoleConfig, ConsoleConfig7x } from './config'; import { registerRoutes } from './routes'; @@ -24,11 +24,11 @@ export class ConsoleServerPlugin implements Plugin { esLegacyConfigService = new EsLegacyConfigService(); - constructor(private readonly ctx: PluginInitializerContext) { + constructor(private readonly ctx: PluginInitializerContext) { this.log = this.ctx.logger.get(); } - setup({ http, capabilities, getStartServices, elasticsearch }: CoreSetup) { + setup({ http, capabilities, elasticsearch }: CoreSetup) { capabilities.registerProvider(() => ({ dev_tools: { show: true, @@ -43,8 +43,8 @@ export class ConsoleServerPlugin implements Plugin { let proxyConfigCollection: ProxyConfigCollection | undefined; if (kibanaVersion.major < 8) { // "pathFilters" and "proxyConfig" are only used in 7.x - pathFilters = (config as ConfigType7x).proxyFilter.map((str: string) => new RegExp(str)); - proxyConfigCollection = new ProxyConfigCollection((config as ConfigType7x).proxyConfig); + pathFilters = (config as ConsoleConfig7x).proxyFilter.map((str: string) => new RegExp(str)); + proxyConfigCollection = new ProxyConfigCollection((config as ConsoleConfig7x).proxyConfig); } this.esLegacyConfigService.setup(elasticsearch.legacy.config$); diff --git a/src/plugins/home/public/application/components/manage_data/manage_data.tsx b/src/plugins/home/public/application/components/manage_data/manage_data.tsx index b374bdd2e161..0f465dfcf965 100644 --- a/src/plugins/home/public/application/components/manage_data/manage_data.tsx +++ b/src/plugins/home/public/application/components/manage_data/manage_data.tsx @@ -61,7 +61,8 @@ export const ManageData: FC = ({ addBasePath, application, features }) => {isDevToolsEnabled || isManagementEnabled ? ( - {isDevToolsEnabled ? ( + {/* Check if both the Dev Tools UI and the Console UI are enabled. */} + {isDevToolsEnabled && consoleHref !== undefined ? ( (); const navigateToUrl = services.application?.navigateToUrl; - const canShowDevTools = services.application?.capabilities?.dev_tools.show; const devToolsDataUri = compressToEncodedURIComponent(`GET ${indexPattern}/_search\n${json}`); - const devToolsHref = services.share.url.locators + const consoleHref = services.share.url.locators .get('CONSOLE_APP_LOCATOR') ?.useUrl({ loadFrom: `data:text/plain,${devToolsDataUri}` }); + // Check if both the Dev Tools UI and the Console UI are enabled. + const canShowDevTools = + services.application?.capabilities?.dev_tools.show && consoleHref !== undefined; const shouldShowDevToolsLink = !!(indexPattern && canShowDevTools); const handleDevToolsLinkClick = useCallback( - () => devToolsHref && navigateToUrl && navigateToUrl(devToolsHref), - [devToolsHref, navigateToUrl] + () => consoleHref && navigateToUrl && navigateToUrl(consoleHref), + [consoleHref, navigateToUrl] ); return ( @@ -79,7 +81,7 @@ export const RequestCodeViewer = ({ indexPattern, json }: RequestCodeViewerProps size="xs" flush="right" iconType="wrench" - href={devToolsHref} + href={consoleHref} onClick={handleDevToolsLinkClick} data-test-subj="inspectorRequestOpenInConsoleButton" > diff --git a/x-pack/plugins/cross_cluster_replication/common/constants/index.ts b/x-pack/plugins/cross_cluster_replication/common/constants/index.ts index f1b327aed638..a800afcf77ae 100644 --- a/x-pack/plugins/cross_cluster_replication/common/constants/index.ts +++ b/x-pack/plugins/cross_cluster_replication/common/constants/index.ts @@ -19,6 +19,8 @@ export const PLUGIN = { minimumLicenseType: platinumLicense, }; +export const MAJOR_VERSION = '8.0.0'; + export const APPS = { CCR_APP: 'ccr', REMOTE_CLUSTER_APP: 'remote_cluster', diff --git a/x-pack/plugins/cross_cluster_replication/server/config.ts b/x-pack/plugins/cross_cluster_replication/server/config.ts index 50cca903f8a2..732137e308a0 100644 --- a/x-pack/plugins/cross_cluster_replication/server/config.ts +++ b/x-pack/plugins/cross_cluster_replication/server/config.ts @@ -4,14 +4,96 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { SemVer } from 'semver'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'src/core/server'; -export const configSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), - ui: schema.object({ +import { MAJOR_VERSION } from '../common/constants'; + +const kibanaVersion = new SemVer(MAJOR_VERSION); + +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schemaLatest, + deprecations: () => [], +}; + +export type CrossClusterReplicationConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( + { enabled: schema.boolean({ defaultValue: true }), - }), -}); + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); -export type CrossClusterReplicationConfig = TypeOf; +export type CrossClusterReplicationConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schema7x, + deprecations: () => [ + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'xpack.ccr.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'xpack.ccr.enabled', + level: 'critical', + title: i18n.translate('xpack.crossClusterReplication.deprecations.enabledTitle', { + defaultMessage: 'Setting "xpack.ccr.enabled" is deprecated', + }), + message: i18n.translate('xpack.crossClusterReplication.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the Cross-Cluster Replication UI, use the "xpack.ccr.ui.enabled" setting instead of "xpack.ccr.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate( + 'xpack.crossClusterReplication.deprecations.enabled.manualStepOneMessage', + { + defaultMessage: 'Open the kibana.yml config file.', + } + ), + i18n.translate( + 'xpack.crossClusterReplication.deprecations.enabled.manualStepTwoMessage', + { + defaultMessage: 'Change the "xpack.ccr.enabled" setting to "xpack.ccr.ui.enabled".', + } + ), + ], + }, + }); + return completeConfig; + }, + ], +}; + +export const config: PluginConfigDescriptor< + CrossClusterReplicationConfig | CrossClusterReplicationConfig7x +> = kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/x-pack/plugins/cross_cluster_replication/server/index.ts b/x-pack/plugins/cross_cluster_replication/server/index.ts index a6a3ec0fe575..7a0984a6117b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/index.ts +++ b/x-pack/plugins/cross_cluster_replication/server/index.ts @@ -5,17 +5,10 @@ * 2.0. */ -import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server'; +import { PluginInitializerContext } from 'src/core/server'; import { CrossClusterReplicationServerPlugin } from './plugin'; -import { configSchema, CrossClusterReplicationConfig } from './config'; + +export { config } from './config'; export const plugin = (pluginInitializerContext: PluginInitializerContext) => new CrossClusterReplicationServerPlugin(pluginInitializerContext); - -export const config: PluginConfigDescriptor = { - schema: configSchema, - exposeToBrowser: { - ui: true, - }, - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], -}; diff --git a/x-pack/plugins/index_lifecycle_management/common/constants/index.ts b/x-pack/plugins/index_lifecycle_management/common/constants/index.ts index 7107489f4e2b..329f479e128e 100644 --- a/x-pack/plugins/index_lifecycle_management/common/constants/index.ts +++ b/x-pack/plugins/index_lifecycle_management/common/constants/index.ts @@ -19,6 +19,8 @@ export const PLUGIN = { }), }; +export const MAJOR_VERSION = '8.0.0'; + export const API_BASE_PATH = '/api/index_lifecycle_management'; export { MIN_SEARCHABLE_SNAPSHOT_LICENSE, MIN_PLUGIN_LICENSE }; diff --git a/x-pack/plugins/index_lifecycle_management/server/config.ts b/x-pack/plugins/index_lifecycle_management/server/config.ts index f3fdf59cec55..691cc06708bb 100644 --- a/x-pack/plugins/index_lifecycle_management/server/config.ts +++ b/x-pack/plugins/index_lifecycle_management/server/config.ts @@ -4,16 +4,94 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { SemVer } from 'semver'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'src/core/server'; -export const configSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), - ui: schema.object({ +import { MAJOR_VERSION } from '../common/constants'; + +const kibanaVersion = new SemVer(MAJOR_VERSION); + +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + // Cloud requires the ability to hide internal node attributes from users. + filteredNodeAttributes: schema.arrayOf(schema.string(), { defaultValue: [] }), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schemaLatest, + deprecations: () => [], +}; + +export type IndexLifecycleManagementConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( + { enabled: schema.boolean({ defaultValue: true }), - }), - // Cloud requires the ability to hide internal node attributes from users. - filteredNodeAttributes: schema.arrayOf(schema.string(), { defaultValue: [] }), -}); + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + // Cloud requires the ability to hide internal node attributes from users. + filteredNodeAttributes: schema.arrayOf(schema.string(), { defaultValue: [] }), + }, + { defaultValue: undefined } +); -export type IndexLifecycleManagementConfig = TypeOf; +export type IndexLifecycleManagementConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schema7x, + deprecations: () => [ + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'xpack.ilm.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'xpack.ilm.enabled', + level: 'critical', + title: i18n.translate('xpack.indexLifecycleMgmt.deprecations.enabledTitle', { + defaultMessage: 'Setting "xpack.ilm.enabled" is deprecated', + }), + message: i18n.translate('xpack.indexLifecycleMgmt.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the Index Lifecycle Policies UI, use the "xpack.ilm.ui.enabled" setting instead of "xpack.ilm.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate('xpack.indexLifecycleMgmt.deprecations.enabled.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('xpack.indexLifecycleMgmt.deprecations.enabled.manualStepTwoMessage', { + defaultMessage: 'Change the "xpack.ilm.enabled" setting to "xpack.ilm.ui.enabled".', + }), + ], + }, + }); + return completeConfig; + }, + ], +}; + +export const config: PluginConfigDescriptor< + IndexLifecycleManagementConfig | IndexLifecycleManagementConfig7x +> = kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/x-pack/plugins/index_lifecycle_management/server/index.ts b/x-pack/plugins/index_lifecycle_management/server/index.ts index 1f8b01913fd3..6a74b4c80b2d 100644 --- a/x-pack/plugins/index_lifecycle_management/server/index.ts +++ b/x-pack/plugins/index_lifecycle_management/server/index.ts @@ -5,17 +5,10 @@ * 2.0. */ -import { PluginInitializerContext, PluginConfigDescriptor } from 'kibana/server'; +import { PluginInitializerContext } from 'kibana/server'; import { IndexLifecycleManagementServerPlugin } from './plugin'; -import { configSchema, IndexLifecycleManagementConfig } from './config'; + +export { config } from './config'; export const plugin = (ctx: PluginInitializerContext) => new IndexLifecycleManagementServerPlugin(ctx); - -export const config: PluginConfigDescriptor = { - schema: configSchema, - exposeToBrowser: { - ui: true, - }, - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], -}; diff --git a/x-pack/plugins/index_management/public/plugin.ts b/x-pack/plugins/index_management/public/plugin.ts index 4e123b6f474f..2394167ca61b 100644 --- a/x-pack/plugins/index_management/public/plugin.ts +++ b/x-pack/plugins/index_management/public/plugin.ts @@ -13,7 +13,12 @@ import { setExtensionsService } from './application/store/selectors/extension_se import { ExtensionsService } from './services'; -import { IndexManagementPluginSetup, SetupDependencies, StartDependencies } from './types'; +import { + IndexManagementPluginSetup, + SetupDependencies, + StartDependencies, + ClientConfigType, +} from './types'; // avoid import from index files in plugin.ts, use specific import paths import { PLUGIN } from '../common/constants/plugin'; @@ -31,25 +36,30 @@ export class IndexMgmtUIPlugin { coreSetup: CoreSetup, plugins: SetupDependencies ): IndexManagementPluginSetup { - const { fleet, usageCollection, management } = plugins; - const kibanaVersion = new SemVer(this.ctx.env.packageInfo.version); + const { + ui: { enabled: isIndexManagementUiEnabled }, + } = this.ctx.config.get(); - management.sections.section.data.registerApp({ - id: PLUGIN.id, - title: i18n.translate('xpack.idxMgmt.appTitle', { defaultMessage: 'Index Management' }), - order: 0, - mount: async (params) => { - const { mountManagementSection } = await import('./application/mount_management_section'); - return mountManagementSection( - coreSetup, - usageCollection, - params, - this.extensionsService, - Boolean(fleet), - kibanaVersion - ); - }, - }); + if (isIndexManagementUiEnabled) { + const { fleet, usageCollection, management } = plugins; + const kibanaVersion = new SemVer(this.ctx.env.packageInfo.version); + management.sections.section.data.registerApp({ + id: PLUGIN.id, + title: i18n.translate('xpack.idxMgmt.appTitle', { defaultMessage: 'Index Management' }), + order: 0, + mount: async (params) => { + const { mountManagementSection } = await import('./application/mount_management_section'); + return mountManagementSection( + coreSetup, + usageCollection, + params, + this.extensionsService, + Boolean(fleet), + kibanaVersion + ); + }, + }); + } return { extensionsService: this.extensionsService.setup(), diff --git a/x-pack/plugins/index_management/public/types.ts b/x-pack/plugins/index_management/public/types.ts index 05c486e299c7..e0af6b160cf1 100644 --- a/x-pack/plugins/index_management/public/types.ts +++ b/x-pack/plugins/index_management/public/types.ts @@ -23,3 +23,9 @@ export interface SetupDependencies { export interface StartDependencies { share: SharePluginStart; } + +export interface ClientConfigType { + ui: { + enabled: boolean; + }; +} diff --git a/x-pack/plugins/index_management/server/config.ts b/x-pack/plugins/index_management/server/config.ts index 0a314c7654b1..88a714db5edc 100644 --- a/x-pack/plugins/index_management/server/config.ts +++ b/x-pack/plugins/index_management/server/config.ts @@ -4,11 +4,90 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { SemVer } from 'semver'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'src/core/server'; -export const configSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), -}); +import { MAJOR_VERSION } from '../common/constants'; -export type IndexManagementConfig = TypeOf; +const kibanaVersion = new SemVer(MAJOR_VERSION); + +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schemaLatest, + deprecations: () => [], +}; + +export type IndexManagementConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( + { + enabled: schema.boolean({ defaultValue: true }), + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +export type IndexManagementConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schema7x, + deprecations: () => [ + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'xpack.index_management.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'xpack.index_management.enabled', + level: 'critical', + title: i18n.translate('xpack.idxMgmt.deprecations.enabledTitle', { + defaultMessage: 'Setting "xpack.index_management.enabled" is deprecated', + }), + message: i18n.translate('xpack.idxMgmt.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the Index Management UI, use the "xpack.index_management.ui.enabled" setting instead of "xpack.index_management.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate('xpack.idxMgmt.deprecations.enabled.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('xpack.idxMgmt.deprecations.enabled.manualStepTwoMessage', { + defaultMessage: + 'Change the "xpack.index_management.enabled" setting to "xpack.index_management.ui.enabled".', + }), + ], + }, + }); + return completeConfig; + }, + ], +}; + +export const config: PluginConfigDescriptor = + kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/x-pack/plugins/index_management/server/index.ts b/x-pack/plugins/index_management/server/index.ts index 14b67e2ffd58..29291116e44f 100644 --- a/x-pack/plugins/index_management/server/index.ts +++ b/x-pack/plugins/index_management/server/index.ts @@ -5,18 +5,14 @@ * 2.0. */ -import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server'; +import { PluginInitializerContext } from 'src/core/server'; import { IndexMgmtServerPlugin } from './plugin'; -import { configSchema } from './config'; + +export { config } from './config'; export const plugin = (context: PluginInitializerContext) => new IndexMgmtServerPlugin(context); -export const config: PluginConfigDescriptor = { - schema: configSchema, - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], -}; - /** @public */ export { Dependencies } from './types'; export { IndexManagementPluginSetup } from './plugin'; diff --git a/x-pack/plugins/license_management/common/constants/index.ts b/x-pack/plugins/license_management/common/constants/index.ts index 0567b0008f0c..9735eabeb1e4 100644 --- a/x-pack/plugins/license_management/common/constants/index.ts +++ b/x-pack/plugins/license_management/common/constants/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -export { PLUGIN } from './plugin'; +export { PLUGIN, MAJOR_VERSION } from './plugin'; export { API_BASE_PATH } from './base_path'; export { EXTERNAL_LINKS } from './external_links'; export { APP_PERMISSION } from './permissions'; diff --git a/x-pack/plugins/license_management/common/constants/plugin.ts b/x-pack/plugins/license_management/common/constants/plugin.ts index ae7fd0f6e8a2..76f4d94a0188 100644 --- a/x-pack/plugins/license_management/common/constants/plugin.ts +++ b/x-pack/plugins/license_management/common/constants/plugin.ts @@ -13,3 +13,5 @@ export const PLUGIN = { }), id: 'license_management', }; + +export const MAJOR_VERSION = '8.0.0'; diff --git a/x-pack/plugins/license_management/server/config.ts b/x-pack/plugins/license_management/server/config.ts index 0e4de29b718b..e378a1019168 100644 --- a/x-pack/plugins/license_management/server/config.ts +++ b/x-pack/plugins/license_management/server/config.ts @@ -4,14 +4,90 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { SemVer } from 'semver'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'src/core/server'; -export const configSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), - ui: schema.object({ +import { MAJOR_VERSION } from '../common/constants'; + +const kibanaVersion = new SemVer(MAJOR_VERSION); + +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schemaLatest, + deprecations: () => [], +}; + +export type LicenseManagementConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( + { enabled: schema.boolean({ defaultValue: true }), - }), -}); + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); -export type LicenseManagementConfig = TypeOf; +export type LicenseManagementConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schema7x, + deprecations: () => [ + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'xpack.license_management.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'xpack.license_management.enabled', + level: 'critical', + title: i18n.translate('xpack.licenseMgmt.deprecations.enabledTitle', { + defaultMessage: 'Setting "xpack.license_management.enabled" is deprecated', + }), + message: i18n.translate('xpack.licenseMgmt.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the License Management UI, use the "xpack.license_management.ui.enabled" setting instead of "xpack.license_management.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate('xpack.licenseMgmt.deprecations.enabled.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('xpack.licenseMgmt.deprecations.enabled.manualStepTwoMessage', { + defaultMessage: + 'Change the "xpack.license_management.enabled" setting to "xpack.license_management.ui.enabled".', + }), + ], + }, + }); + return completeConfig; + }, + ], +}; + +export const config: PluginConfigDescriptor = + kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/x-pack/plugins/license_management/server/index.ts b/x-pack/plugins/license_management/server/index.ts index e78ffe07b50c..7aa6bfb06d54 100644 --- a/x-pack/plugins/license_management/server/index.ts +++ b/x-pack/plugins/license_management/server/index.ts @@ -5,17 +5,10 @@ * 2.0. */ -import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server'; +import { PluginInitializerContext } from 'src/core/server'; import { LicenseManagementServerPlugin } from './plugin'; -import { configSchema, LicenseManagementConfig } from './config'; + +export { config } from './config'; export const plugin = (ctx: PluginInitializerContext) => new LicenseManagementServerPlugin(); - -export const config: PluginConfigDescriptor = { - schema: configSchema, - exposeToBrowser: { - ui: true, - }, - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], -}; diff --git a/x-pack/plugins/remote_clusters/common/constants.ts b/x-pack/plugins/remote_clusters/common/constants.ts index b11292141672..5a36924b2643 100644 --- a/x-pack/plugins/remote_clusters/common/constants.ts +++ b/x-pack/plugins/remote_clusters/common/constants.ts @@ -20,6 +20,8 @@ export const PLUGIN = { }, }; +export const MAJOR_VERSION = '8.0.0'; + export const API_BASE_PATH = '/api/remote_clusters'; export const SNIFF_MODE = 'sniff'; diff --git a/x-pack/plugins/remote_clusters/server/config.ts b/x-pack/plugins/remote_clusters/server/config.ts index 8f379ec5613c..5b4972f0a525 100644 --- a/x-pack/plugins/remote_clusters/server/config.ts +++ b/x-pack/plugins/remote_clusters/server/config.ts @@ -4,23 +4,90 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { SemVer } from 'semver'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; -import { PluginConfigDescriptor } from 'kibana/server'; +import { PluginConfigDescriptor } from 'src/core/server'; -export const configSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), - ui: schema.object({ - enabled: schema.boolean({ defaultValue: true }), - }), -}); +import { MAJOR_VERSION } from '../common/constants'; -export type ConfigType = TypeOf; +const kibanaVersion = new SemVer(MAJOR_VERSION); -export const config: PluginConfigDescriptor = { - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], - schema: configSchema, +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { exposeToBrowser: { ui: true, }, + schema: schemaLatest, + deprecations: () => [], }; + +export type RemoteClustersConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( + { + enabled: schema.boolean({ defaultValue: true }), + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +export type RemoteClustersConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schema7x, + deprecations: () => [ + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'xpack.remote_clusters.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'xpack.remote_clusters.enabled', + level: 'critical', + title: i18n.translate('xpack.remoteClusters.deprecations.enabledTitle', { + defaultMessage: 'Setting "xpack.remote_clusters.enabled" is deprecated', + }), + message: i18n.translate('xpack.remoteClusters.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the Remote Clusters UI, use the "xpack.remote_clusters.ui.enabled" setting instead of "xpack.remote_clusters.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate('xpack.remoteClusters.deprecations.enabled.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('xpack.remoteClusters.deprecations.enabled.manualStepTwoMessage', { + defaultMessage: + 'Change the "xpack.remote_clusters.enabled" setting to "xpack.remote_clusters.ui.enabled".', + }), + ], + }, + }); + return completeConfig; + }, + ], +}; + +export const config: PluginConfigDescriptor = + kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/x-pack/plugins/remote_clusters/server/plugin.ts b/x-pack/plugins/remote_clusters/server/plugin.ts index b13773c27034..fde71677b844 100644 --- a/x-pack/plugins/remote_clusters/server/plugin.ts +++ b/x-pack/plugins/remote_clusters/server/plugin.ts @@ -11,7 +11,7 @@ import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'src/core/se import { PLUGIN } from '../common/constants'; import { Dependencies, LicenseStatus, RouteDependencies } from './types'; -import { ConfigType } from './config'; +import { RemoteClustersConfig, RemoteClustersConfig7x } from './config'; import { registerGetRoute, registerAddRoute, @@ -30,7 +30,7 @@ export class RemoteClustersServerPlugin { licenseStatus: LicenseStatus; log: Logger; - config: ConfigType; + config: RemoteClustersConfig | RemoteClustersConfig7x; constructor({ logger, config }: PluginInitializerContext) { this.log = logger.get(); diff --git a/x-pack/plugins/rollup/common/index.ts b/x-pack/plugins/rollup/common/index.ts index dffbfbd18209..c912a905d061 100644 --- a/x-pack/plugins/rollup/common/index.ts +++ b/x-pack/plugins/rollup/common/index.ts @@ -14,6 +14,8 @@ export const PLUGIN = { minimumLicenseType: basicLicense, }; +export const MAJOR_VERSION = '8.0.0'; + export const CONFIG_ROLLUPS = 'rollups:enableIndexPatterns'; export const API_BASE_PATH = '/api/rollup'; diff --git a/x-pack/plugins/rollup/public/index.ts b/x-pack/plugins/rollup/public/index.ts index b70ce8649338..f740971b4bcb 100644 --- a/x-pack/plugins/rollup/public/index.ts +++ b/x-pack/plugins/rollup/public/index.ts @@ -4,7 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { PluginInitializerContext } from 'src/core/public'; import { RollupPlugin } from './plugin'; -export const plugin = () => new RollupPlugin(); +export const plugin = (ctx: PluginInitializerContext) => new RollupPlugin(ctx); diff --git a/x-pack/plugins/rollup/public/plugin.ts b/x-pack/plugins/rollup/public/plugin.ts index 0d345e326193..e458a13ee0e0 100644 --- a/x-pack/plugins/rollup/public/plugin.ts +++ b/x-pack/plugins/rollup/public/plugin.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import { CoreSetup, CoreStart, Plugin } from 'kibana/public'; +import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/public'; import { rollupBadgeExtension, rollupToggleExtension } from './extend_index_management'; // @ts-ignore import { RollupIndexPatternCreationConfig } from './index_pattern_creation/rollup_index_pattern_creation_config'; @@ -23,6 +23,7 @@ import { IndexManagementPluginSetup } from '../../index_management/public'; import { setHttp, init as initDocumentation } from './crud_app/services/index'; import { setNotifications, setFatalErrors, setUiStatsReporter } from './kibana_services'; import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; +import { ClientConfigType } from './types'; export interface RollupPluginSetupDependencies { home?: HomePublicPluginSetup; @@ -32,10 +33,16 @@ export interface RollupPluginSetupDependencies { } export class RollupPlugin implements Plugin { + constructor(private ctx: PluginInitializerContext) {} + setup( core: CoreSetup, { home, management, indexManagement, usageCollection }: RollupPluginSetupDependencies ) { + const { + ui: { enabled: isRollupUiEnabled }, + } = this.ctx.config.get(); + setFatalErrors(core.fatalErrors); if (usageCollection) { setUiStatsReporter(usageCollection.reportUiCounter.bind(usageCollection, UIM_APP_NAME)); @@ -46,7 +53,7 @@ export class RollupPlugin implements Plugin { indexManagement.extensionsService.addToggle(rollupToggleExtension); } - if (home) { + if (home && isRollupUiEnabled) { home.featureCatalogue.register({ id: 'rollup_jobs', title: 'Rollups', @@ -61,33 +68,35 @@ export class RollupPlugin implements Plugin { }); } - const pluginName = i18n.translate('xpack.rollupJobs.appTitle', { - defaultMessage: 'Rollup Jobs', - }); + if (isRollupUiEnabled) { + const pluginName = i18n.translate('xpack.rollupJobs.appTitle', { + defaultMessage: 'Rollup Jobs', + }); - management.sections.section.data.registerApp({ - id: 'rollup_jobs', - title: pluginName, - order: 4, - async mount(params) { - const [coreStart] = await core.getStartServices(); + management.sections.section.data.registerApp({ + id: 'rollup_jobs', + title: pluginName, + order: 4, + async mount(params) { + const [coreStart] = await core.getStartServices(); - const { - chrome: { docTitle }, - } = coreStart; + const { + chrome: { docTitle }, + } = coreStart; - docTitle.change(pluginName); - params.setBreadcrumbs([{ text: pluginName }]); + docTitle.change(pluginName); + params.setBreadcrumbs([{ text: pluginName }]); - const { renderApp } = await import('./application'); - const unmountAppCallback = await renderApp(core, params); + const { renderApp } = await import('./application'); + const unmountAppCallback = await renderApp(core, params); - return () => { - docTitle.reset(); - unmountAppCallback(); - }; - }, - }); + return () => { + docTitle.reset(); + unmountAppCallback(); + }; + }, + }); + } } start(core: CoreStart) { diff --git a/x-pack/plugins/rollup/public/types.ts b/x-pack/plugins/rollup/public/types.ts new file mode 100644 index 000000000000..dc5e55e9268f --- /dev/null +++ b/x-pack/plugins/rollup/public/types.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. + */ + +export interface ClientConfigType { + ui: { + enabled: boolean; + }; +} diff --git a/x-pack/plugins/rollup/server/config.ts b/x-pack/plugins/rollup/server/config.ts index d20b31742210..c0cca4bbb4d3 100644 --- a/x-pack/plugins/rollup/server/config.ts +++ b/x-pack/plugins/rollup/server/config.ts @@ -4,11 +4,90 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { SemVer } from 'semver'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'src/core/server'; -export const configSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), -}); +import { MAJOR_VERSION } from '../common'; -export type RollupConfig = TypeOf; +const kibanaVersion = new SemVer(MAJOR_VERSION); + +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schemaLatest, + deprecations: () => [], +}; + +export type RollupConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( + { + enabled: schema.boolean({ defaultValue: true }), + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +export type RollupConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, + schema: schema7x, + deprecations: () => [ + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'xpack.rollup.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'xpack.rollup.enabled', + level: 'critical', + title: i18n.translate('xpack.rollupJobs.deprecations.enabledTitle', { + defaultMessage: 'Setting "xpack.rollup.enabled" is deprecated', + }), + message: i18n.translate('xpack.rollupJobs.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the Rollup Jobs UI, use the "xpack.rollup.ui.enabled" setting instead of "xpack.rollup.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate('xpack.rollupJobs.deprecations.enabled.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('xpack.rollupJobs.deprecations.enabled.manualStepTwoMessage', { + defaultMessage: + 'Change the "xpack.rollup.enabled" setting to "xpack.rollup.ui.enabled".', + }), + ], + }, + }); + return completeConfig; + }, + ], +}; + +export const config: PluginConfigDescriptor = + kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/x-pack/plugins/rollup/server/index.ts b/x-pack/plugins/rollup/server/index.ts index e77e0e6f15d7..6ae1d9f24b8b 100644 --- a/x-pack/plugins/rollup/server/index.ts +++ b/x-pack/plugins/rollup/server/index.ts @@ -5,14 +5,10 @@ * 2.0. */ -import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server'; +import { PluginInitializerContext } from 'src/core/server'; import { RollupPlugin } from './plugin'; -import { configSchema, RollupConfig } from './config'; + +export { config } from './config'; export const plugin = (pluginInitializerContext: PluginInitializerContext) => new RollupPlugin(pluginInitializerContext); - -export const config: PluginConfigDescriptor = { - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], - schema: configSchema, -}; diff --git a/x-pack/plugins/snapshot_restore/common/constants.ts b/x-pack/plugins/snapshot_restore/common/constants.ts index b18e118dc5ff..df13bd4c2f1f 100644 --- a/x-pack/plugins/snapshot_restore/common/constants.ts +++ b/x-pack/plugins/snapshot_restore/common/constants.ts @@ -20,6 +20,8 @@ export const PLUGIN = { }, }; +export const MAJOR_VERSION = '8.0.0'; + export const API_BASE_PATH = '/api/snapshot_restore/'; export enum REPOSITORY_TYPES { diff --git a/x-pack/plugins/snapshot_restore/public/plugin.ts b/x-pack/plugins/snapshot_restore/public/plugin.ts index bb091a1fd183..0351716fad5b 100644 --- a/x-pack/plugins/snapshot_restore/public/plugin.ts +++ b/x-pack/plugins/snapshot_restore/public/plugin.ts @@ -42,52 +42,58 @@ export class SnapshotRestoreUIPlugin { public setup(coreSetup: CoreSetup, plugins: PluginsDependencies): void { const config = this.initializerContext.config.get(); - const { http } = coreSetup; - const { home, management, usageCollection } = plugins; + const { + ui: { enabled: isSnapshotRestoreUiEnabled }, + } = config; - // Initialize services - this.uiMetricService.setup(usageCollection); - textService.setup(i18n); - httpService.setup(http); + if (isSnapshotRestoreUiEnabled) { + const { http } = coreSetup; + const { home, management, usageCollection } = plugins; - management.sections.section.data.registerApp({ - id: PLUGIN.id, - title: i18n.translate('xpack.snapshotRestore.appTitle', { - defaultMessage: 'Snapshot and Restore', - }), - order: 3, - mount: async (params) => { - const { mountManagementSection } = await import('./application/mount_management_section'); - const services = { - uiMetricService: this.uiMetricService, - }; - return await mountManagementSection(coreSetup, services, config, params); - }, - }); + // Initialize services + this.uiMetricService.setup(usageCollection); + textService.setup(i18n); + httpService.setup(http); - if (home) { - home.featureCatalogue.register({ + management.sections.section.data.registerApp({ id: PLUGIN.id, - title: i18n.translate('xpack.snapshotRestore.featureCatalogueTitle', { - defaultMessage: 'Back up and restore', + title: i18n.translate('xpack.snapshotRestore.appTitle', { + defaultMessage: 'Snapshot and Restore', }), - description: i18n.translate('xpack.snapshotRestore.featureCatalogueDescription', { - defaultMessage: - 'Save snapshots to a backup repository, and restore to recover index and cluster state.', - }), - icon: 'storage', - path: '/app/management/data/snapshot_restore', - showOnHomePage: true, - category: FeatureCatalogueCategory.ADMIN, - order: 630, + order: 3, + mount: async (params) => { + const { mountManagementSection } = await import('./application/mount_management_section'); + const services = { + uiMetricService: this.uiMetricService, + }; + return await mountManagementSection(coreSetup, services, config, params); + }, }); - } - plugins.share.url.locators.create( - new SnapshotRestoreLocatorDefinition({ - managementAppLocator: plugins.management.locator, - }) - ); + if (home) { + home.featureCatalogue.register({ + id: PLUGIN.id, + title: i18n.translate('xpack.snapshotRestore.featureCatalogueTitle', { + defaultMessage: 'Back up and restore', + }), + description: i18n.translate('xpack.snapshotRestore.featureCatalogueDescription', { + defaultMessage: + 'Save snapshots to a backup repository, and restore to recover index and cluster state.', + }), + icon: 'storage', + path: '/app/management/data/snapshot_restore', + showOnHomePage: true, + category: FeatureCatalogueCategory.ADMIN, + order: 630, + }); + } + + plugins.share.url.locators.create( + new SnapshotRestoreLocatorDefinition({ + managementAppLocator: plugins.management.locator, + }) + ); + } } public start() {} diff --git a/x-pack/plugins/snapshot_restore/public/types.ts b/x-pack/plugins/snapshot_restore/public/types.ts index b73170ad9d57..c58c942b4bc1 100644 --- a/x-pack/plugins/snapshot_restore/public/types.ts +++ b/x-pack/plugins/snapshot_restore/public/types.ts @@ -7,4 +7,5 @@ export interface ClientConfigType { slm_ui: { enabled: boolean }; + ui: { enabled: boolean }; } diff --git a/x-pack/plugins/snapshot_restore/server/config.ts b/x-pack/plugins/snapshot_restore/server/config.ts index f0ca416ef203..cc430f475661 100644 --- a/x-pack/plugins/snapshot_restore/server/config.ts +++ b/x-pack/plugins/snapshot_restore/server/config.ts @@ -4,14 +4,98 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { SemVer } from 'semver'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'src/core/server'; -export const configSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), - slm_ui: schema.object({ +import { MAJOR_VERSION } from '../common/constants'; + +const kibanaVersion = new SemVer(MAJOR_VERSION); + +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + slm_ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + slm_ui: true, + }, + schema: schemaLatest, + deprecations: () => [], +}; + +export type SnapshotRestoreConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( + { enabled: schema.boolean({ defaultValue: true }), - }), -}); + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + slm_ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }, + { defaultValue: undefined } +); -export type SnapshotRestoreConfig = TypeOf; +export type SnapshotRestoreConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + slm_ui: true, + }, + schema: schema7x, + deprecations: () => [ + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'xpack.snapshot_restore.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'xpack.snapshot_restore.enabled', + level: 'critical', + title: i18n.translate('xpack.snapshotRestore.deprecations.enabledTitle', { + defaultMessage: 'Setting "xpack.snapshot_restore.enabled" is deprecated', + }), + message: i18n.translate('xpack.snapshotRestore.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the Snapshot and Restore UI, use the "xpack.snapshot_restore.ui.enabled" setting instead of "xpack.snapshot_restore.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate('xpack.snapshotRestore.deprecations.enabled.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('xpack.snapshotRestore.deprecations.enabled.manualStepTwoMessage', { + defaultMessage: + 'Change the "xpack.snapshot_restore.enabled" setting to "xpack.snapshot_restore.ui.enabled".', + }), + ], + }, + }); + return completeConfig; + }, + ], +}; + +export const config: PluginConfigDescriptor = + kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/x-pack/plugins/snapshot_restore/server/index.ts b/x-pack/plugins/snapshot_restore/server/index.ts index e10bffd6073d..1e9d2b55aa20 100644 --- a/x-pack/plugins/snapshot_restore/server/index.ts +++ b/x-pack/plugins/snapshot_restore/server/index.ts @@ -5,16 +5,9 @@ * 2.0. */ -import { PluginInitializerContext, PluginConfigDescriptor } from 'kibana/server'; +import { PluginInitializerContext } from 'kibana/server'; import { SnapshotRestoreServerPlugin } from './plugin'; -import { configSchema, SnapshotRestoreConfig } from './config'; + +export { config } from './config'; export const plugin = (ctx: PluginInitializerContext) => new SnapshotRestoreServerPlugin(ctx); - -export const config: PluginConfigDescriptor = { - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], - schema: configSchema, - exposeToBrowser: { - slm_ui: true, - }, -}; diff --git a/x-pack/plugins/snapshot_restore/server/plugin.ts b/x-pack/plugins/snapshot_restore/server/plugin.ts index 4414e3735959..d737807ec8da 100644 --- a/x-pack/plugins/snapshot_restore/server/plugin.ts +++ b/x-pack/plugins/snapshot_restore/server/plugin.ts @@ -28,16 +28,9 @@ export class SnapshotRestoreServerPlugin implements Plugin this.license = new License(); } - public setup( - { http, getStartServices }: CoreSetup, - { licensing, features, security, cloud }: Dependencies - ): void { + public setup({ http }: CoreSetup, { licensing, features, security, cloud }: Dependencies): void { const pluginConfig = this.context.config.get(); - if (!pluginConfig.enabled) { - return; - } - const router = http.createRouter(); this.license.setup( diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/index.ts index b19c8b3d0f08..b2a1c4e80ec7 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/index.ts @@ -9,4 +9,4 @@ export { setup as setupOverviewPage, OverviewTestBed } from './overview.helpers' export { setup as setupElasticsearchPage, ElasticsearchTestBed } from './elasticsearch.helpers'; export { setup as setupKibanaPage, KibanaTestBed } from './kibana.helpers'; -export { setupEnvironment } from './setup_environment'; +export { setupEnvironment, kibanaVersion } from './setup_environment'; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/setup_environment.tsx index a1cdfaa3446c..fbbbc0e07853 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/setup_environment.tsx @@ -9,7 +9,7 @@ import React from 'react'; import axios from 'axios'; // @ts-ignore import axiosXhrAdapter from 'axios/lib/adapters/xhr'; - +import SemVer from 'semver/classes/semver'; import { deprecationsServiceMock, docLinksServiceMock, @@ -19,7 +19,7 @@ import { import { HttpSetup } from 'src/core/public'; import { KibanaContextProvider } from '../../../public/shared_imports'; -import { mockKibanaSemverVersion } from '../../../common/constants'; +import { MAJOR_VERSION } from '../../../common/constants'; import { AppContextProvider } from '../../../public/application/app_context'; import { apiService } from '../../../public/application/lib/api'; import { breadcrumbService } from '../../../public/application/lib/breadcrumbs'; @@ -31,6 +31,8 @@ const { GlobalFlyoutProvider } = GlobalFlyout; const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); +export const kibanaVersion = new SemVer(MAJOR_VERSION); + export const WithAppDependencies = (Comp: any, overrides: Record = {}) => (props: Record) => { @@ -41,9 +43,9 @@ export const WithAppDependencies = http: mockHttpClient as unknown as HttpSetup, docLinks: docLinksServiceMock.createStartContract(), kibanaVersionInfo: { - currentMajor: mockKibanaSemverVersion.major, - prevMajor: mockKibanaSemverVersion.major - 1, - nextMajor: mockKibanaSemverVersion.major + 1, + currentMajor: kibanaVersion.major, + prevMajor: kibanaVersion.major - 1, + nextMajor: kibanaVersion.major + 1, }, notifications: notificationServiceMock.createStartContract(), isReadOnlyMode: false, diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/overview.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/overview.test.tsx index 0acf5ae65c6c..7831ab0110e4 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/overview.test.tsx +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/overview.test.tsx @@ -5,8 +5,7 @@ * 2.0. */ -import { mockKibanaSemverVersion } from '../../../common/constants'; -import { OverviewTestBed, setupOverviewPage, setupEnvironment } from '../helpers'; +import { OverviewTestBed, setupOverviewPage, setupEnvironment, kibanaVersion } from '../helpers'; describe('Overview Page', () => { let testBed: OverviewTestBed; @@ -24,7 +23,7 @@ describe('Overview Page', () => { describe('Documentation links', () => { test('Has a whatsNew link and it references nextMajor version', () => { const { exists, find } = testBed; - const nextMajor = mockKibanaSemverVersion.major + 1; + const nextMajor = kibanaVersion.major + 1; expect(exists('whatsNewLink')).toBe(true); expect(find('whatsNewLink').text()).toContain(`${nextMajor}.0`); diff --git a/x-pack/plugins/upgrade_assistant/common/config.ts b/x-pack/plugins/upgrade_assistant/common/config.ts deleted file mode 100644 index e74fe5cc1bf1..000000000000 --- a/x-pack/plugins/upgrade_assistant/common/config.ts +++ /dev/null @@ -1,20 +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 { schema, TypeOf } from '@kbn/config-schema'; - -export const configSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), - /* - * This will default to true up until the last minor before the next major. - * In readonly mode, the user will not be able to perform any actions in the UI - * and will be presented with a message indicating as such. - */ - readonly: schema.boolean({ defaultValue: true }), -}); - -export type Config = TypeOf; diff --git a/x-pack/plugins/upgrade_assistant/common/constants.ts b/x-pack/plugins/upgrade_assistant/common/constants.ts index 893d61d32953..68a6b9e9cdb8 100644 --- a/x-pack/plugins/upgrade_assistant/common/constants.ts +++ b/x-pack/plugins/upgrade_assistant/common/constants.ts @@ -4,15 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import SemVer from 'semver/classes/semver'; - /* - * These constants are used only in tests to add conditional logic based on Kibana version * On master, the version should represent the next major version (e.g., master --> 8.0.0) * The release branch should match the release version (e.g., 7.x --> 7.0.0) */ -export const mockKibanaVersion = '8.0.0'; -export const mockKibanaSemverVersion = new SemVer(mockKibanaVersion); +export const MAJOR_VERSION = '8.0.0'; /* * Map of 7.0 --> 8.0 index setting deprecation log messages and associated settings diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/deprecation_types/reindex/flyout/warning_step.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/deprecation_types/reindex/flyout/warning_step.test.tsx index ff11b9f1a845..d2cafd69e94e 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/deprecation_types/reindex/flyout/warning_step.test.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/es_deprecations/deprecation_types/reindex/flyout/warning_step.test.tsx @@ -8,12 +8,20 @@ import { I18nProvider } from '@kbn/i18n/react'; import { mount, shallow } from 'enzyme'; import React from 'react'; +import SemVer from 'semver/classes/semver'; import { ReindexWarning } from '../../../../../../../common/types'; -import { mockKibanaSemverVersion } from '../../../../../../../common/constants'; +import { MAJOR_VERSION } from '../../../../../../../common/constants'; import { idForWarning, WarningsFlyoutStep } from './warnings_step'; +const kibanaVersion = new SemVer(MAJOR_VERSION); +const mockKibanaVersionInfo = { + currentMajor: kibanaVersion.major, + prevMajor: kibanaVersion.major - 1, + nextMajor: kibanaVersion.major + 1, +}; + jest.mock('../../../../../app_context', () => { const { docLinksServiceMock } = jest.requireActual( '../../../../../../../../../../src/core/public/doc_links/doc_links_service.mock' @@ -23,11 +31,7 @@ jest.mock('../../../../../app_context', () => { useAppContext: () => { return { docLinks: docLinksServiceMock.createStartContract(), - kibanaVersionInfo: { - currentMajor: mockKibanaSemverVersion.major, - prevMajor: mockKibanaSemverVersion.major - 1, - nextMajor: mockKibanaSemverVersion.major + 1, - }, + kibanaVersionInfo: mockKibanaVersionInfo, }; }, }; @@ -45,7 +49,7 @@ describe('WarningsFlyoutStep', () => { expect(shallow()).toMatchSnapshot(); }); - if (mockKibanaSemverVersion.major === 7) { + if (kibanaVersion.major === 7) { it('does not allow proceeding until all are checked', () => { const defaultPropsWithWarnings = { ...defaultProps, diff --git a/x-pack/plugins/upgrade_assistant/public/plugin.ts b/x-pack/plugins/upgrade_assistant/public/plugin.ts index 5edb638e1bc5..32e825fbdc20 100644 --- a/x-pack/plugins/upgrade_assistant/public/plugin.ts +++ b/x-pack/plugins/upgrade_assistant/public/plugin.ts @@ -9,59 +9,69 @@ import SemVer from 'semver/classes/semver'; import { i18n } from '@kbn/i18n'; import { Plugin, CoreSetup, PluginInitializerContext } from 'src/core/public'; -import { SetupDependencies, StartDependencies, AppServicesContext } from './types'; -import { Config } from '../common/config'; +import { + SetupDependencies, + StartDependencies, + AppServicesContext, + ClientConfigType, +} from './types'; export class UpgradeAssistantUIPlugin implements Plugin { constructor(private ctx: PluginInitializerContext) {} + setup(coreSetup: CoreSetup, { management, cloud }: SetupDependencies) { - const { readonly } = this.ctx.config.get(); + const { + readonly, + ui: { enabled: isUpgradeAssistantUiEnabled }, + } = this.ctx.config.get(); - const appRegistrar = management.sections.section.stack; - const kibanaVersion = new SemVer(this.ctx.env.packageInfo.version); + if (isUpgradeAssistantUiEnabled) { + const appRegistrar = management.sections.section.stack; + const kibanaVersion = new SemVer(this.ctx.env.packageInfo.version); - const kibanaVersionInfo = { - currentMajor: kibanaVersion.major, - prevMajor: kibanaVersion.major - 1, - nextMajor: kibanaVersion.major + 1, - }; + const kibanaVersionInfo = { + currentMajor: kibanaVersion.major, + prevMajor: kibanaVersion.major - 1, + nextMajor: kibanaVersion.major + 1, + }; - const pluginName = i18n.translate('xpack.upgradeAssistant.appTitle', { - defaultMessage: '{version} Upgrade Assistant', - values: { version: `${kibanaVersionInfo.nextMajor}.0` }, - }); + const pluginName = i18n.translate('xpack.upgradeAssistant.appTitle', { + defaultMessage: '{version} Upgrade Assistant', + values: { version: `${kibanaVersionInfo.nextMajor}.0` }, + }); - appRegistrar.registerApp({ - id: 'upgrade_assistant', - title: pluginName, - order: 1, - async mount(params) { - const [coreStart, { discover, data }] = await coreSetup.getStartServices(); - const services: AppServicesContext = { discover, data, cloud }; + appRegistrar.registerApp({ + id: 'upgrade_assistant', + title: pluginName, + order: 1, + async mount(params) { + const [coreStart, { discover, data }] = await coreSetup.getStartServices(); + const services: AppServicesContext = { discover, data, cloud }; - const { - chrome: { docTitle }, - } = coreStart; + const { + chrome: { docTitle }, + } = coreStart; - docTitle.change(pluginName); + docTitle.change(pluginName); - const { mountManagementSection } = await import('./application/mount_management_section'); - const unmountAppCallback = await mountManagementSection( - coreSetup, - params, - kibanaVersionInfo, - readonly, - services - ); + const { mountManagementSection } = await import('./application/mount_management_section'); + const unmountAppCallback = await mountManagementSection( + coreSetup, + params, + kibanaVersionInfo, + readonly, + services + ); - return () => { - docTitle.reset(); - unmountAppCallback(); - }; - }, - }); + return () => { + docTitle.reset(); + unmountAppCallback(); + }; + }, + }); + } } start() {} diff --git a/x-pack/plugins/upgrade_assistant/public/types.ts b/x-pack/plugins/upgrade_assistant/public/types.ts index a2b49305c32d..cbeaf22bb095 100644 --- a/x-pack/plugins/upgrade_assistant/public/types.ts +++ b/x-pack/plugins/upgrade_assistant/public/types.ts @@ -26,3 +26,10 @@ export interface StartDependencies { discover: DiscoverStart; data: DataPublicPluginStart; } + +export interface ClientConfigType { + readonly: boolean; + ui: { + enabled: boolean; + }; +} diff --git a/x-pack/plugins/upgrade_assistant/server/config.ts b/x-pack/plugins/upgrade_assistant/server/config.ts new file mode 100644 index 000000000000..4183ea337def --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/config.ts @@ -0,0 +1,107 @@ +/* + * 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'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; +import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'src/core/server'; + +import { MAJOR_VERSION } from '../common/constants'; + +const kibanaVersion = new SemVer(MAJOR_VERSION); + +// ------------------------------- +// >= 8.x +// ------------------------------- +const schemaLatest = schema.object( + { + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + /* + * This will default to true up until the last minor before the next major. + * In readonly mode, the user will not be able to perform any actions in the UI + * and will be presented with a message indicating as such. + */ + readonly: schema.boolean({ defaultValue: true }), + }, + { defaultValue: undefined } +); + +const configLatest: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + readonly: true, + }, + schema: schemaLatest, + deprecations: () => [], +}; + +export type UpgradeAssistantConfig = TypeOf; + +// ------------------------------- +// 7.x +// ------------------------------- +const schema7x = schema.object( + { + enabled: schema.boolean({ defaultValue: true }), + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + /* + * This will default to true up until the last minor before the next major. + * In readonly mode, the user will not be able to perform any actions in the UI + * and will be presented with a message indicating as such. + */ + readonly: schema.boolean({ defaultValue: true }), + }, + { defaultValue: undefined } +); + +export type UpgradeAssistantConfig7x = TypeOf; + +const config7x: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + readonly: true, + }, + schema: schema7x, + deprecations: () => [ + (completeConfig, rootPath, addDeprecation) => { + if (get(completeConfig, 'xpack.upgrade_assistant.enabled') === undefined) { + return completeConfig; + } + + addDeprecation({ + configPath: 'xpack.upgrade_assistant.enabled', + level: 'critical', + title: i18n.translate('xpack.upgradeAssistant.deprecations.enabledTitle', { + defaultMessage: 'Setting "xpack.upgrade_assistant.enabled" is deprecated', + }), + message: i18n.translate('xpack.upgradeAssistant.deprecations.enabledMessage', { + defaultMessage: + 'To disallow users from accessing the Upgrade Assistant UI, use the "xpack.upgrade_assistant.ui.enabled" setting instead of "xpack.upgrade_assistant.enabled".', + }), + correctiveActions: { + manualSteps: [ + i18n.translate('xpack.upgradeAssistant.deprecations.enabled.manualStepOneMessage', { + defaultMessage: 'Open the kibana.yml config file.', + }), + i18n.translate('xpack.upgradeAssistant.deprecations.enabled.manualStepTwoMessage', { + defaultMessage: + 'Change the "xpack.upgrade_assistant.enabled" setting to "xpack.upgrade_assistant.ui.enabled".', + }), + ], + }, + }); + return completeConfig; + }, + ], +}; + +export const config: PluginConfigDescriptor = + kibanaVersion.major < 8 ? config7x : configLatest; diff --git a/x-pack/plugins/upgrade_assistant/server/index.ts b/x-pack/plugins/upgrade_assistant/server/index.ts index 5591276b2fa3..660aa107292e 100644 --- a/x-pack/plugins/upgrade_assistant/server/index.ts +++ b/x-pack/plugins/upgrade_assistant/server/index.ts @@ -5,18 +5,11 @@ * 2.0. */ -import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server'; +import { PluginInitializerContext } from 'src/core/server'; import { UpgradeAssistantServerPlugin } from './plugin'; -import { configSchema, Config } from '../common/config'; + +export { config } from './config'; export const plugin = (ctx: PluginInitializerContext) => { return new UpgradeAssistantServerPlugin(ctx); }; - -export const config: PluginConfigDescriptor = { - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], - schema: configSchema, - exposeToBrowser: { - readonly: true, - }, -}; diff --git a/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/version.ts b/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/version.ts index d93fe7920f1d..5f39e902c75d 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/version.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/version.ts @@ -4,14 +4,16 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { SemVer } from 'semver'; +import { MAJOR_VERSION } from '../../../common/constants'; -import { mockKibanaSemverVersion } from '../../../common/constants'; +const kibanaVersion = new SemVer(MAJOR_VERSION); export const getMockVersionInfo = () => { - const currentMajor = mockKibanaSemverVersion.major; + const currentMajor = kibanaVersion.major; return { - currentVersion: mockKibanaSemverVersion, + currentVersion: kibanaVersion, currentMajor, prevMajor: currentMajor - 1, nextMajor: currentMajor + 1, diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts index e1817ef63927..1785491e5da4 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts @@ -9,7 +9,7 @@ import { SemVer } from 'semver'; import { IScopedClusterClient, kibanaResponseFactory } from 'src/core/server'; import { coreMock } from 'src/core/server/mocks'; import { licensingMock } from '../../../../plugins/licensing/server/mocks'; -import { mockKibanaVersion } from '../../common/constants'; +import { MAJOR_VERSION } from '../../common/constants'; import { getMockVersionInfo } from './__fixtures__/version'; import { @@ -98,7 +98,7 @@ describe('verifyAllMatchKibanaVersion', () => { describe('EsVersionPrecheck', () => { beforeEach(() => { - versionService.setup(mockKibanaVersion); + versionService.setup(MAJOR_VERSION); }); it('returns a 403 when callCluster fails with a 403', async () => { diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.test.ts index 30093a9fb6e5..957198cde8da 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { mockKibanaSemverVersion, mockKibanaVersion } from '../../../common/constants'; +import { MAJOR_VERSION } from '../../../common/constants'; import { versionService } from '../version'; import { getMockVersionInfo } from '../__fixtures__/version'; @@ -131,7 +131,7 @@ describe('transformFlatSettings', () => { describe('sourceNameForIndex', () => { beforeEach(() => { - versionService.setup(mockKibanaVersion); + versionService.setup(MAJOR_VERSION); }); it('parses internal indices', () => { @@ -152,7 +152,7 @@ describe('transformFlatSettings', () => { describe('generateNewIndexName', () => { beforeEach(() => { - versionService.setup(mockKibanaVersion); + versionService.setup(MAJOR_VERSION); }); it('parses internal indices', () => { @@ -186,7 +186,7 @@ describe('transformFlatSettings', () => { ).toEqual([]); }); - if (mockKibanaSemverVersion.major === 7) { + if (currentMajor === 7) { describe('[7.x] customTypeName warning', () => { it('returns customTypeName warning for non-_doc mapping types', () => { expect( diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts index 3cfdb1fdd316..ce1e8e11eb2d 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts @@ -19,7 +19,7 @@ import { ReindexStatus, ReindexStep, } from '../../../common/types'; -import { mockKibanaVersion } from '../../../common/constants'; +import { MAJOR_VERSION } from '../../../common/constants'; import { versionService } from '../version'; import { LOCK_WINDOW, ReindexActions, reindexActionsFactory } from './reindex_actions'; import { getMockVersionInfo } from '../__fixtures__/version'; @@ -54,7 +54,7 @@ describe('ReindexActions', () => { describe('createReindexOp', () => { beforeEach(() => { - versionService.setup(mockKibanaVersion); + versionService.setup(MAJOR_VERSION); client.create.mockResolvedValue(); }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts index 7a5bf1c18769..6017691a9328 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts @@ -20,7 +20,7 @@ import { ReindexStatus, ReindexStep, } from '../../../common/types'; -import { mockKibanaVersion } from '../../../common/constants'; +import { MAJOR_VERSION } from '../../../common/constants'; import { licensingMock } from '../../../../licensing/server/mocks'; import { LicensingPluginSetup } from '../../../../licensing/server'; @@ -89,7 +89,7 @@ describe('reindexService', () => { licensingPluginSetup ); - versionService.setup(mockKibanaVersion); + versionService.setup(MAJOR_VERSION); }); describe('hasRequiredPrivileges', () => {