diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 1f6b549c0110..88075b66ad04 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -198,6 +198,8 @@ export class DocLinksService { transportSettings: `${ELASTICSEARCH_DOCS}modules-network.html#common-network-settings`, typesRemoval: `${ELASTICSEARCH_DOCS}removal-of-types.html`, deprecationLogging: `${ELASTICSEARCH_DOCS}logging.html#deprecation-logging`, + setupUpgrade: `${ELASTICSEARCH_DOCS}setup-upgrade.html`, + releaseHighlights: `${ELASTICSEARCH_DOCS}release-highlights.html`, }, siem: { guide: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/index.html`, diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 68c8a957c3e5..68d4482afd92 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -24797,7 +24797,6 @@ "xpack.upgradeAssistant.deprecationListSearchBar.placeholderAriaLabel": "フィルター", "xpack.upgradeAssistant.deprecationListSearchBar.placeholderLabel": "フィルター", "xpack.upgradeAssistant.deprecationListSearchBar.reloadButtonLabel": "再読み込み", - "xpack.upgradeAssistant.deprecationLoggingDescription.deprecationLoggingLink": "廃止予定ログ", "xpack.upgradeAssistant.emptyPrompt.learnMoreDescription": "{nextMajor}への移行に関する詳細をご覧ください。", "xpack.upgradeAssistant.emptyPrompt.title": "{uaVersion} アップグレードアシスタント", "xpack.upgradeAssistant.emptyPrompt.upgradeAssistantDescription": "アップグレードアシスタントはクラスターの廃止予定の設定を特定し、アップグレード前に問題を解決できるようにします。Elastic {nextMajor}にアップグレードするときにここに戻って確認してください。", @@ -24819,9 +24818,7 @@ "xpack.upgradeAssistant.esDeprecationStats.criticalDeprecationsTitle": "重大", "xpack.upgradeAssistant.esDeprecationStats.loadingText": "Elasticsearchの廃止統計情報を読み込んでいます...", "xpack.upgradeAssistant.esDeprecationStats.statsTitle": "Elasticsearch", - "xpack.upgradeAssistant.esDeprecationStats.totalDeprecationsTitle": "廃止予定", "xpack.upgradeAssistant.esDeprecationStats.totalDeprecationsTooltip": "このクラスターは{clusterCount}個の廃止予定のクラスター設定と{indexCount}個の廃止予定のインデックス設定を使用しています。", - "xpack.upgradeAssistant.esDeprecationStats.viewDeprecationsLinkText": "廃止予定を表示", "xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorDescription": "エラーについては、Kibanaサーバーログを確認してください。", "xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorTitle": "Kibana廃止予定を取得できませんでした", "xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorDescription": "エラーについては、Kibanaサーバーログを確認してください。", @@ -24845,23 +24842,12 @@ "xpack.upgradeAssistant.kibanaDeprecationStats.loadingErrorMessage": "Kibana廃止予定の取得中にエラーが発生しました。", "xpack.upgradeAssistant.kibanaDeprecationStats.loadingText": "Kibana廃止予定統計情報を読み込んでいます…", "xpack.upgradeAssistant.kibanaDeprecationStats.statsTitle": "Kibana", - "xpack.upgradeAssistant.kibanaDeprecationStats.totalDeprecationsLabel": "Kibanaには合計{totalDeprecations}個の廃止予定があります", - "xpack.upgradeAssistant.kibanaDeprecationStats.totalDeprecationsTitle": "廃止予定", - "xpack.upgradeAssistant.kibanaDeprecationStats.viewDeprecationsLinkText": "廃止予定を表示", "xpack.upgradeAssistant.noDeprecationsPrompt.description": "構成は最新です。", "xpack.upgradeAssistant.noDeprecationsPrompt.nextStepsDescription": "他のスタック廃止予定については、{overviewButton}を確認してください。", "xpack.upgradeAssistant.noDeprecationsPrompt.overviewLinkText": "概要ページ", "xpack.upgradeAssistant.noDeprecationsPrompt.title": "アップグレードする準備ができました。", - "xpack.upgradeAssistant.overview.deprecationLogging.loadingLabel": "ロギング状態を取得しています", - "xpack.upgradeAssistant.overview.deprecationLoggingDescription": "{deprecationLoggingLink}を有効にすると、Elastic {nextMajor}にアップグレードした後に使用できない廃止予定の機能を使用しているかどうかがわかります。", - "xpack.upgradeAssistant.overview.deprecationLoggingTitle": "廃止ログ", - "xpack.upgradeAssistant.overview.deprecationLogs.disableButtonLabel": "廃止ログを無効にする", "xpack.upgradeAssistant.overview.deprecationLogs.disabledToastMessage": "廃止予定のアクションをログに出力しません。", - "xpack.upgradeAssistant.overview.deprecationLogs.disablingButtonLabel": "廃止ログを無効にしています", - "xpack.upgradeAssistant.overview.deprecationLogs.enableButtonLabel": "廃止ログを有効にする", "xpack.upgradeAssistant.overview.deprecationLogs.enabledToastMessage": "廃止予定のアクションをログに出力します。", - "xpack.upgradeAssistant.overview.deprecationLogs.enablingButtonLabel": "廃止ログを有効にしています", - "xpack.upgradeAssistant.overview.deprecationLogs.fetchErrorButtonLabel": "廃止ログがありません", "xpack.upgradeAssistant.overview.deprecationLogs.fetchErrorMessage": "ログ情報を取得できませんでした。", "xpack.upgradeAssistant.overview.deprecationLogs.reloadButtonLabel": "再試行", "xpack.upgradeAssistant.overview.deprecationLogs.updateErrorMessage": "ログ状態を更新できませんでした。", @@ -24869,9 +24855,6 @@ "xpack.upgradeAssistant.overview.pageDescription": "廃止予定の設定を特定し、構成を更新して、アップグレードの準備を行います。", "xpack.upgradeAssistant.overview.pageTitle": "アップグレードアシスタント", "xpack.upgradeAssistant.reindex.reindexPrivilegesErrorBatch": "「{indexName}」に再インデックスするための権限が不十分です。", - "xpack.upgradeAssistant.tabs.incompleteCallout.calloutBody.breackingChangesDocButtonLabel": "廃止と互換性を破る変更", - "xpack.upgradeAssistant.tabs.incompleteCallout.calloutBody.calloutDetail": "Elasticsearch {nextEsVersion} の {breakingChangesDocButton} の完全なリストは、最終の {currentEsVersion} マイナーリリースで確認できます。この警告は、リストがすべて解決されると消えます。", - "xpack.upgradeAssistant.tabs.incompleteCallout.calloutTitle": "リストの問題がすべて解決されていない可能性があります。", "xpack.uptime.addDataButtonLabel": "データの追加", "xpack.uptime.alerts.anomaly.criteriaExpression.ariaLabel": "選択したモニターの条件を表示する式。", "xpack.uptime.alerts.anomaly.criteriaExpression.description": "監視するとき", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 6b5b171de35b..fc0613e8b46e 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -25350,7 +25350,6 @@ "xpack.upgradeAssistant.deprecationListSearchBar.placeholderAriaLabel": "筛选", "xpack.upgradeAssistant.deprecationListSearchBar.placeholderLabel": "筛选", "xpack.upgradeAssistant.deprecationListSearchBar.reloadButtonLabel": "重新加载", - "xpack.upgradeAssistant.deprecationLoggingDescription.deprecationLoggingLink": "弃用日志记录", "xpack.upgradeAssistant.emptyPrompt.learnMoreDescription": "详细了解如何迁移到 {nextMajor}。", "xpack.upgradeAssistant.emptyPrompt.title": "{uaVersion} 升级助手", "xpack.upgradeAssistant.emptyPrompt.upgradeAssistantDescription": "升级助手识别集群中弃用的设置,帮助您在升级前解决问题。需要升级到 Elastic {nextMajor} 时,回到这里查看。", @@ -25372,9 +25371,7 @@ "xpack.upgradeAssistant.esDeprecationStats.criticalDeprecationsTitle": "紧急", "xpack.upgradeAssistant.esDeprecationStats.loadingText": "正在加载 Elasticsearch 弃用统计……", "xpack.upgradeAssistant.esDeprecationStats.statsTitle": "Elasticsearch", - "xpack.upgradeAssistant.esDeprecationStats.totalDeprecationsTitle": "弃用", "xpack.upgradeAssistant.esDeprecationStats.totalDeprecationsTooltip": "此集群正在使用 {clusterCount} 个已弃用集群设置和 {indexCount} 个已弃用的索引设置", - "xpack.upgradeAssistant.esDeprecationStats.viewDeprecationsLinkText": "查看弃用", "xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorDescription": "请在 Kibana 服务器日志中查看错误。", "xpack.upgradeAssistant.kibanaDeprecationErrors.loadingErrorTitle": "无法检索 Kibana 弃用", "xpack.upgradeAssistant.kibanaDeprecationErrors.pluginErrorDescription": "请在 Kibana 服务器日志中查看错误。", @@ -25398,23 +25395,12 @@ "xpack.upgradeAssistant.kibanaDeprecationStats.loadingErrorMessage": "检索 Kibana 弃用时发生错误。", "xpack.upgradeAssistant.kibanaDeprecationStats.loadingText": "正在加载 Kibana 弃用统计……", "xpack.upgradeAssistant.kibanaDeprecationStats.statsTitle": "Kibana", - "xpack.upgradeAssistant.kibanaDeprecationStats.totalDeprecationsLabel": "Kibana 总共有 {totalDeprecations} 个弃用", - "xpack.upgradeAssistant.kibanaDeprecationStats.totalDeprecationsTitle": "弃用", - "xpack.upgradeAssistant.kibanaDeprecationStats.viewDeprecationsLinkText": "查看弃用", "xpack.upgradeAssistant.noDeprecationsPrompt.description": "您的配置是最新的。", "xpack.upgradeAssistant.noDeprecationsPrompt.nextStepsDescription": "查看{overviewButton}以了解其他 Stack 弃用。", "xpack.upgradeAssistant.noDeprecationsPrompt.overviewLinkText": "“概览”页面", "xpack.upgradeAssistant.noDeprecationsPrompt.title": "准备好升级!", - "xpack.upgradeAssistant.overview.deprecationLogging.loadingLabel": "正在检索日志记录状态", - "xpack.upgradeAssistant.overview.deprecationLoggingDescription": "启用{deprecationLoggingLink}以查看是否正在使用升级到 Elastic {nextMajor} 后将不再可用的已弃用功能。", - "xpack.upgradeAssistant.overview.deprecationLoggingTitle": "弃用日志", - "xpack.upgradeAssistant.overview.deprecationLogs.disableButtonLabel": "禁用弃用日志记录", "xpack.upgradeAssistant.overview.deprecationLogs.disabledToastMessage": "不记录弃用的操作。", - "xpack.upgradeAssistant.overview.deprecationLogs.disablingButtonLabel": "正在禁用弃用日志记录", - "xpack.upgradeAssistant.overview.deprecationLogs.enableButtonLabel": "启用弃用日志记录", "xpack.upgradeAssistant.overview.deprecationLogs.enabledToastMessage": "记录弃用的操作。", - "xpack.upgradeAssistant.overview.deprecationLogs.enablingButtonLabel": "正在启用弃用日志记录", - "xpack.upgradeAssistant.overview.deprecationLogs.fetchErrorButtonLabel": "弃用日志记录不可用", "xpack.upgradeAssistant.overview.deprecationLogs.fetchErrorMessage": "无法检索日志记录信息。", "xpack.upgradeAssistant.overview.deprecationLogs.reloadButtonLabel": "重试", "xpack.upgradeAssistant.overview.deprecationLogs.updateErrorMessage": "无法更新日志记录状态。", @@ -25422,9 +25408,6 @@ "xpack.upgradeAssistant.overview.pageDescription": "通过识别弃用的设置并更新配置来准备升级。", "xpack.upgradeAssistant.overview.pageTitle": "升级助手", "xpack.upgradeAssistant.reindex.reindexPrivilegesErrorBatch": "您没有足够的权限重新索引“{indexName}”。", - "xpack.upgradeAssistant.tabs.incompleteCallout.calloutBody.breackingChangesDocButtonLabel": "弃用内容和重大更改", - "xpack.upgradeAssistant.tabs.incompleteCallout.calloutBody.calloutDetail": "Elasticsearch {nextEsVersion} 中的 {breakingChangesDocButton} 完整列表将在最终的 {currentEsVersion} 次要版本中提供。完成列表后,此警告将消失。", - "xpack.upgradeAssistant.tabs.incompleteCallout.calloutTitle": "问题列表可能不完整", "xpack.uptime.addDataButtonLabel": "添加数据", "xpack.uptime.alerts.anomaly.criteriaExpression.ariaLabel": "显示选定监测的条件的表达式。", "xpack.uptime.alerts.anomaly.criteriaExpression.description": "当监测", diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/cluster.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/cluster.test.ts index 6cbaf1cf9dc4..533a74842216 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/cluster.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/cluster.test.ts @@ -43,7 +43,10 @@ describe('Cluster tab', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadEsDeprecationsResponse(esDeprecationsMockResponse); - httpRequestsMockHelpers.setLoadDeprecationLoggingResponse({ isEnabled: true }); + httpRequestsMockHelpers.setLoadDeprecationLoggingResponse({ + isDeprecationLogIndexingEnabled: true, + isDeprecationLoggingEnabled: true, + }); await act(async () => { testBed = await setupClusterPage({ isReadOnlyMode: false }); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/http_requests.ts index f1f21b430d31..74fcf14fdf59 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/http_requests.ts @@ -7,7 +7,7 @@ import sinon, { SinonFakeServer } from 'sinon'; import { API_BASE_PATH } from '../../../common/constants'; -import { ESUpgradeStatus } from '../../../common/types'; +import { ESUpgradeStatus, DeprecationLoggingStatus } from '../../../common/types'; import { ResponseError } from '../../../public/application/lib/api'; // Register helpers to mock HTTP Requests @@ -24,7 +24,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { }; const setLoadDeprecationLoggingResponse = ( - response?: { isEnabled: boolean }, + response?: DeprecationLoggingStatus, error?: ResponseError ) => { const status = error ? error.statusCode || 400 : 200; @@ -38,7 +38,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { }; const setUpdateDeprecationLoggingResponse = ( - response?: { isEnabled: boolean }, + response?: DeprecationLoggingStatus, error?: ResponseError ) => { const status = error ? error.statusCode || 400 : 200; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/overview.helpers.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/overview.helpers.ts index 5c89b6230d85..93826497b863 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/overview.helpers.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/helpers/overview.helpers.ts @@ -7,7 +7,7 @@ import { act } from 'react-dom/test-utils'; import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test/jest'; -import { DeprecationsOverview } from '../../../public/application/components/overview'; +import { Overview } from '../../../public/application/components/overview'; import { WithAppDependencies } from './setup_environment'; const testBedConfig: TestBedConfig = { @@ -31,7 +31,7 @@ const createActions = (testBed: TestBed) => { const { find, component } = testBed; await act(async () => { - find('upgradeAssistantDeprecationToggle').simulate('click'); + find('deprecationLoggingToggle').simulate('click'); }); component.update(); @@ -43,10 +43,7 @@ const createActions = (testBed: TestBed) => { }; export const setup = async (overrides?: Record): Promise => { - const initTestBed = registerTestBed( - WithAppDependencies(DeprecationsOverview, overrides), - testBedConfig - ); + const initTestBed = registerTestBed(WithAppDependencies(Overview, overrides), testBedConfig); const testBed = await initTestBed(); return { @@ -56,21 +53,27 @@ export const setup = async (overrides?: Record): Promise + Promise.resolve({ + app: '/discover', + path: 'logs', + state: {}, + }) + ), + }, + }, +}; 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 aae550040332..53b4b5d75931 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 @@ -14,13 +14,16 @@ import { deprecationsServiceMock, docLinksServiceMock, notificationServiceMock, + applicationServiceMock, } from 'src/core/public/mocks'; import { HttpSetup } from 'src/core/public'; +import { KibanaContextProvider } from '../../../public/shared_imports'; import { mockKibanaSemverVersion } from '../../../common/constants'; import { AppContextProvider } from '../../../public/application/app_context'; import { apiService } from '../../../public/application/lib/api'; import { breadcrumbService } from '../../../public/application/lib/breadcrumbs'; +import { servicesMock } from './services_mock'; import { init as initHttpRequests } from './http_requests'; const mockHttpClient = axios.create({ adapter: axiosXhrAdapter }); @@ -39,18 +42,22 @@ export const WithAppDependencies = (Comp: any, overrides: Record '', + getUrlForApp: applicationServiceMock.createStartContract().getUrlForApp, deprecations: deprecationsServiceMock.createStartContract(), }; + const { servicesOverrides, ...contextOverrides } = overrides; + return ( - - - + + + + + ); }; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/indices.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/indices.test.ts index a959473bc4ec..89f648c98437 100644 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/indices.test.ts +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/indices.test.ts @@ -39,7 +39,10 @@ describe('Indices tab', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadEsDeprecationsResponse(esDeprecationsMockResponse); - httpRequestsMockHelpers.setLoadDeprecationLoggingResponse({ isEnabled: true }); + httpRequestsMockHelpers.setLoadDeprecationLoggingResponse({ + isDeprecationLogIndexingEnabled: true, + isDeprecationLoggingEnabled: true, + }); await act(async () => { testBed = await setupIndicesPage({ isReadOnlyMode: false }); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview.test.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview.test.ts deleted file mode 100644 index e86917dd4bd5..000000000000 --- a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview.test.ts +++ /dev/null @@ -1,270 +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 { DomainDeprecationDetails } from 'kibana/public'; -import { act } from 'react-dom/test-utils'; -import { deprecationsServiceMock } from 'src/core/public/mocks'; -import { ESUpgradeStatus } from '../../common/types'; - -import { OverviewTestBed, setupOverviewPage, setupEnvironment } from './helpers'; - -describe('Overview page', () => { - let testBed: OverviewTestBed; - const { server, httpRequestsMockHelpers } = setupEnvironment(); - - beforeEach(async () => { - const esDeprecationsMockResponse: ESUpgradeStatus = { - totalCriticalDeprecations: 1, - cluster: [ - { - level: 'critical', - message: 'Index Lifecycle Management poll interval is set too low', - url: - 'https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-8.0.html#ilm-poll-interval-limit', - details: - 'The Index Lifecycle Management poll interval setting [indices.lifecycle.poll_interval] is currently set to [500ms], but must be 1s or greater', - }, - ], - indices: [ - { - level: 'warning', - message: 'translog retention settings are ignored', - url: - 'https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-translog.html', - details: - 'translog retention settings [index.translog.retention.size] and [index.translog.retention.age] are ignored because translog is no longer used in peer recoveries with soft-deletes enabled (default in 7.0 or later)', - index: 'settings', - }, - ], - }; - - const kibanaDeprecationsMockResponse: DomainDeprecationDetails[] = [ - { - correctiveActions: { manualSteps: ['test-step'] }, - domainId: 'xpack.spaces', - level: 'critical', - message: - 'Disabling the Spaces plugin (xpack.spaces.enabled) will not be supported in the next major version (8.0)', - }, - ]; - - httpRequestsMockHelpers.setLoadEsDeprecationsResponse(esDeprecationsMockResponse); - httpRequestsMockHelpers.setLoadDeprecationLoggingResponse({ isEnabled: true }); - - await act(async () => { - const deprecationService = deprecationsServiceMock.createStartContract(); - deprecationService.getAllDeprecations = jest - .fn() - .mockReturnValue(kibanaDeprecationsMockResponse); - - testBed = await setupOverviewPage({ - deprecations: deprecationService, - }); - }); - - const { component } = testBed; - component.update(); - }); - - afterAll(() => { - server.restore(); - }); - - test('renders the overview page', () => { - const { exists, find } = testBed; - - expect(exists('overviewPageContent')).toBe(true); - - // Verify ES stats - expect(exists('esStatsPanel')).toBe(true); - expect(find('esStatsPanel.totalDeprecations').text()).toContain('2'); - expect(find('esStatsPanel.criticalDeprecations').text()).toContain('1'); - - // Verify Kibana stats - expect(exists('kibanaStatsPanel')).toBe(true); - expect(find('kibanaStatsPanel.totalDeprecations').text()).toContain('1'); - expect(find('kibanaStatsPanel.criticalDeprecations').text()).toContain('1'); - }); - - describe('Deprecation logging', () => { - test('toggles deprecation logging', async () => { - const { find, actions } = testBed; - - httpRequestsMockHelpers.setUpdateDeprecationLoggingResponse({ isEnabled: false }); - - expect(find('upgradeAssistantDeprecationToggle').text()).toEqual( - 'Disable deprecation logging' - ); - - await actions.clickDeprecationToggle(); - - const latestRequest = server.requests[server.requests.length - 1]; - expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual({ isEnabled: false }); - expect(find('upgradeAssistantDeprecationToggle').text()).toEqual( - 'Enable deprecation logging' - ); - }); - - test('handles network error when updating logging state', async () => { - const error = { - statusCode: 500, - error: 'Internal server error', - message: 'Internal server error', - }; - - const { actions, find, exists } = testBed; - - httpRequestsMockHelpers.setUpdateDeprecationLoggingResponse(undefined, error); - - expect(find('upgradeAssistantDeprecationToggle').text()).toEqual( - 'Disable deprecation logging' - ); - - await actions.clickDeprecationToggle(); - - // Logging state should not change since there was an error - expect(find('upgradeAssistantDeprecationToggle').text()).toEqual( - 'Disable deprecation logging' - ); - expect(exists('updateLoggingError')).toBe(true); - }); - - test('handles network error when fetching logging state', async () => { - const error = { - statusCode: 500, - error: 'Internal server error', - message: 'Internal server error', - }; - - httpRequestsMockHelpers.setLoadDeprecationLoggingResponse(undefined, error); - - await act(async () => { - testBed = await setupOverviewPage(); - }); - - const { component, exists, find } = testBed; - - component.update(); - - expect(find('upgradeAssistantDeprecationToggle').text()).toEqual( - 'Deprecation logging unavailable' - ); - expect(exists('fetchLoggingError')).toBe(true); - }); - }); - - describe('Error handling', () => { - describe('Kibana deprecations', () => { - test('handles network failure', async () => { - await act(async () => { - const deprecationService = deprecationsServiceMock.createStartContract(); - deprecationService.getAllDeprecations = jest - .fn() - .mockRejectedValue(new Error('Internal Server Error')); - - testBed = await setupOverviewPage({ - deprecations: deprecationService, - }); - }); - - const { component, exists } = testBed; - - component.update(); - - expect(exists('requestErrorIconTip')).toBe(true); - }); - }); - - describe('Elasticsearch deprecations', () => { - test('handles network failure', async () => { - const error = { - statusCode: 500, - error: 'Internal server error', - message: 'Internal server error', - }; - - httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); - - await act(async () => { - testBed = await setupOverviewPage(); - }); - - const { component, exists } = testBed; - - component.update(); - - expect(exists('requestErrorIconTip')).toBe(true); - }); - - test('handles unauthorized error', async () => { - const error = { - statusCode: 403, - error: 'Forbidden', - message: 'Forbidden', - }; - - httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); - - await act(async () => { - testBed = await setupOverviewPage(); - }); - - const { component, exists } = testBed; - - component.update(); - - expect(exists('unauthorizedErrorIconTip')).toBe(true); - }); - - test('handles partially upgraded error', async () => { - const error = { - statusCode: 426, - error: 'Upgrade required', - message: 'There are some nodes running a different version of Elasticsearch', - attributes: { - allNodesUpgraded: false, - }, - }; - - httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); - - await act(async () => { - testBed = await setupOverviewPage({ isReadOnlyMode: false }); - }); - - const { component, exists } = testBed; - - component.update(); - - expect(exists('partiallyUpgradedErrorIconTip')).toBe(true); - }); - - test('handles upgrade error', async () => { - const error = { - statusCode: 426, - error: 'Upgrade required', - message: 'There are some nodes running a different version of Elasticsearch', - attributes: { - allNodesUpgraded: true, - }, - }; - - httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); - - await act(async () => { - testBed = await setupOverviewPage({ isReadOnlyMode: false }); - }); - - const { component, exists } = testBed; - - component.update(); - - expect(exists('upgradedErrorIconTip')).toBe(true); - }); - }); - }); -}); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_deprecation_logs_step/fix_deprecation_logs_step.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_deprecation_logs_step/fix_deprecation_logs_step.test.tsx new file mode 100644 index 000000000000..3db75ba0a342 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/fix_deprecation_logs_step/fix_deprecation_logs_step.test.tsx @@ -0,0 +1,153 @@ +/* + * 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 { act } from 'react-dom/test-utils'; + +import { OverviewTestBed, setupOverviewPage, setupEnvironment } from '../../helpers'; +import { DeprecationLoggingStatus } from '../../../../common/types'; +import { DEPRECATION_LOGS_SOURCE_ID } from '../../../../common/constants'; + +const getLoggingResponse = (toggle: boolean): DeprecationLoggingStatus => ({ + isDeprecationLogIndexingEnabled: toggle, + isDeprecationLoggingEnabled: toggle, +}); + +describe('Overview - Fix deprecation logs step', () => { + let testBed: OverviewTestBed; + const { server, httpRequestsMockHelpers } = setupEnvironment(); + + beforeEach(async () => { + httpRequestsMockHelpers.setLoadDeprecationLoggingResponse(getLoggingResponse(true)); + testBed = await setupOverviewPage(); + + const { component } = testBed; + component.update(); + }); + + afterAll(() => { + server.restore(); + }); + + describe('Step 1 - Toggle log writing and collecting', () => { + test('toggles deprecation logging', async () => { + const { find, actions } = testBed; + + httpRequestsMockHelpers.setUpdateDeprecationLoggingResponse({ + isDeprecationLogIndexingEnabled: false, + isDeprecationLoggingEnabled: false, + }); + + expect(find('deprecationLoggingToggle').props()['aria-checked']).toBe(true); + + await actions.clickDeprecationToggle(); + + const latestRequest = server.requests[server.requests.length - 1]; + expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual({ isEnabled: false }); + expect(find('deprecationLoggingToggle').props()['aria-checked']).toBe(false); + }); + + test('shows callout when only loggerDeprecation is enabled', async () => { + httpRequestsMockHelpers.setLoadDeprecationLoggingResponse({ + isDeprecationLogIndexingEnabled: false, + isDeprecationLoggingEnabled: true, + }); + + await act(async () => { + testBed = await setupOverviewPage(); + }); + + const { exists, component } = testBed; + + component.update(); + + expect(exists('deprecationWarningCallout')).toBe(true); + }); + + test('handles network error when updating logging state', async () => { + const error = { + statusCode: 500, + error: 'Internal server error', + message: 'Internal server error', + }; + + const { actions, exists } = testBed; + + httpRequestsMockHelpers.setUpdateDeprecationLoggingResponse(undefined, error); + + await actions.clickDeprecationToggle(); + + expect(exists('updateLoggingError')).toBe(true); + }); + + test('handles network error when fetching logging state', async () => { + const error = { + statusCode: 500, + error: 'Internal server error', + message: 'Internal server error', + }; + + httpRequestsMockHelpers.setLoadDeprecationLoggingResponse(undefined, error); + + await act(async () => { + testBed = await setupOverviewPage(); + }); + + const { component, exists } = testBed; + + component.update(); + + expect(exists('fetchLoggingError')).toBe(true); + }); + }); + + describe('Step 2 - Analyze logs', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setLoadDeprecationLoggingResponse({ + isDeprecationLogIndexingEnabled: true, + isDeprecationLoggingEnabled: true, + }); + }); + + test('Has a link to see logs in observability app', async () => { + await act(async () => { + testBed = await setupOverviewPage({ + http: { + basePath: { + prepend: (url: string) => url, + }, + }, + }); + }); + + const { component, exists, find } = testBed; + + component.update(); + + expect(exists('viewObserveLogs')).toBe(true); + expect(find('viewObserveLogs').props().href).toBe( + `/app/logs/stream?sourceId=${DEPRECATION_LOGS_SOURCE_ID}` + ); + }); + + test('Has a link to see logs in discover app', async () => { + await act(async () => { + testBed = await setupOverviewPage({ + getUrlForApp: jest.fn((app, options) => { + return `${app}/${options.path}`; + }), + }); + }); + + const { exists, component, find } = testBed; + + component.update(); + + expect(exists('viewDiscoverLogs')).toBe(true); + expect(find('viewDiscoverLogs').props().href).toBe('/discover/logs'); + }); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/review_logs_step/mocked_responses.ts b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/review_logs_step/mocked_responses.ts new file mode 100644 index 000000000000..ba8f9f8b67d0 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/review_logs_step/mocked_responses.ts @@ -0,0 +1,56 @@ +/* + * 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 { DomainDeprecationDetails } from 'kibana/public'; +import { ESUpgradeStatus } from '../../../../common/types'; + +export const esDeprecations: ESUpgradeStatus = { + totalCriticalDeprecations: 1, + cluster: [ + { + level: 'critical', + message: 'Index Lifecycle Management poll interval is set too low', + url: + 'https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-8.0.html#ilm-poll-interval-limit', + details: + 'The Index Lifecycle Management poll interval setting [indices.lifecycle.poll_interval] is currently set to [500ms], but must be 1s or greater', + }, + ], + indices: [ + { + level: 'warning', + message: 'translog retention settings are ignored', + url: + 'https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-translog.html', + details: + 'translog retention settings [index.translog.retention.size] and [index.translog.retention.age] are ignored because translog is no longer used in peer recoveries with soft-deletes enabled (default in 7.0 or later)', + index: 'settings', + }, + ], +}; + +export const esDeprecationsEmpty: ESUpgradeStatus = { + totalCriticalDeprecations: 0, + cluster: [], + indices: [], +}; + +export const kibanaDeprecations: DomainDeprecationDetails[] = [ + { + correctiveActions: { manualSteps: ['test-step'] }, + domainId: 'xpack.spaces', + level: 'critical', + message: + 'Disabling the Spaces plugin (xpack.spaces.enabled) will not be supported in the next major version (8.0)', + }, + { + correctiveActions: { manualSteps: ['test-step'] }, + domainId: 'xpack.spaces', + level: 'warning', + message: 'Sample warning deprecation', + }, +]; diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/review_logs_step/review_logs_step.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/review_logs_step/review_logs_step.test.tsx new file mode 100644 index 000000000000..254242ab338a --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/review_logs_step/review_logs_step.test.tsx @@ -0,0 +1,233 @@ +/* + * 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 { act } from 'react-dom/test-utils'; +import { deprecationsServiceMock } from 'src/core/public/mocks'; + +import * as mockedResponses from './mocked_responses'; +import { OverviewTestBed, setupOverviewPage, setupEnvironment } from '../../helpers'; + +describe('Overview - Fix deprecated settings step', () => { + let testBed: OverviewTestBed; + const { server, httpRequestsMockHelpers } = setupEnvironment(); + + beforeEach(async () => { + httpRequestsMockHelpers.setLoadEsDeprecationsResponse(mockedResponses.esDeprecations); + + await act(async () => { + const deprecationService = deprecationsServiceMock.createStartContract(); + deprecationService.getAllDeprecations = jest + .fn() + .mockReturnValue(mockedResponses.kibanaDeprecations); + + testBed = await setupOverviewPage({ + deprecations: deprecationService, + }); + }); + + const { component } = testBed; + component.update(); + }); + + afterAll(() => { + server.restore(); + }); + + describe('ES deprecations', () => { + test('Shows deprecation warning and critical counts', () => { + const { exists, find } = testBed; + + expect(exists('esStatsPanel')).toBe(true); + expect(find('esStatsPanel.warningDeprecations').text()).toContain('1'); + expect(find('esStatsPanel.criticalDeprecations').text()).toContain('1'); + }); + + test('Handles network failure', async () => { + const error = { + statusCode: 500, + error: 'Cant retrieve deprecations error', + message: 'Cant retrieve deprecations error', + }; + + httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); + + await act(async () => { + testBed = await setupOverviewPage(); + }); + + const { component, exists } = testBed; + + component.update(); + + expect(exists('esRequestErrorIconTip')).toBe(true); + }); + + test('Hides deprecation counts if it doesnt have any', async () => { + httpRequestsMockHelpers.setLoadEsDeprecationsResponse(mockedResponses.esDeprecationsEmpty); + + await act(async () => { + testBed = await setupOverviewPage(); + }); + + const { exists } = testBed; + + expect(exists('noDeprecationsLabel')).toBe(true); + }); + + test('Stats panel navigates to deprecations list if clicked', () => { + const { component, exists, find } = testBed; + + component.update(); + + expect(exists('esStatsPanel')).toBe(true); + expect(find('esStatsPanel').find('a').props().href).toBe('/es_deprecations/cluster'); + }); + + describe('Renders ES errors', () => { + test('handles network failure', async () => { + const error = { + statusCode: 500, + error: 'Internal server error', + message: 'Internal server error', + }; + + httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); + + await act(async () => { + testBed = await setupOverviewPage(); + }); + + const { component, exists } = testBed; + + component.update(); + + expect(exists('esRequestErrorIconTip')).toBe(true); + }); + + test('handles unauthorized error', async () => { + const error = { + statusCode: 403, + error: 'Forbidden', + message: 'Forbidden', + }; + + httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); + + await act(async () => { + testBed = await setupOverviewPage(); + }); + + const { component, exists } = testBed; + + component.update(); + + expect(exists('unauthorizedErrorIconTip')).toBe(true); + }); + + test('handles partially upgraded error', async () => { + const error = { + statusCode: 426, + error: 'Upgrade required', + message: 'There are some nodes running a different version of Elasticsearch', + attributes: { + allNodesUpgraded: false, + }, + }; + + httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); + + await act(async () => { + testBed = await setupOverviewPage({ isReadOnlyMode: false }); + }); + + const { component, exists } = testBed; + + component.update(); + + expect(exists('partiallyUpgradedErrorIconTip')).toBe(true); + }); + + test('handles upgrade error', async () => { + const error = { + statusCode: 426, + error: 'Upgrade required', + message: 'There are some nodes running a different version of Elasticsearch', + attributes: { + allNodesUpgraded: true, + }, + }; + + httpRequestsMockHelpers.setLoadEsDeprecationsResponse(undefined, error); + + await act(async () => { + testBed = await setupOverviewPage({ isReadOnlyMode: false }); + }); + + const { component, exists } = testBed; + + component.update(); + + expect(exists('upgradedErrorIconTip')).toBe(true); + }); + }); + }); + + describe('Kibana deprecations', () => { + test('Show deprecation warning and critical counts', () => { + const { exists, find } = testBed; + + expect(exists('kibanaStatsPanel')).toBe(true); + expect(find('kibanaStatsPanel.warningDeprecations').text()).toContain('1'); + expect(find('kibanaStatsPanel.criticalDeprecations').text()).toContain('1'); + }); + + test('Handles network failure', async () => { + await act(async () => { + const deprecationService = deprecationsServiceMock.createStartContract(); + deprecationService.getAllDeprecations = jest + .fn() + .mockRejectedValue(new Error('Internal Server Error')); + + testBed = await setupOverviewPage({ + deprecations: deprecationService, + }); + }); + + const { component, exists } = testBed; + + component.update(); + + expect(exists('kibanaRequestErrorIconTip')).toBe(true); + }); + + test('Hides deprecation count if it doesnt have any', async () => { + await act(async () => { + const deprecationService = deprecationsServiceMock.createStartContract(); + deprecationService.getAllDeprecations = jest.fn().mockRejectedValue([]); + + testBed = await setupOverviewPage({ + deprecations: deprecationService, + }); + }); + + const { exists } = testBed; + + expect(exists('noDeprecationsLabel')).toBe(true); + expect(exists('kibanaStatsPanel.warningDeprecations')).toBe(false); + expect(exists('kibanaStatsPanel.criticalDeprecations')).toBe(false); + }); + + test('Stats panel navigates to deprecations list if clicked', () => { + const { component, exists, find } = testBed; + + component.update(); + + expect(exists('kibanaStatsPanel')).toBe(true); + expect(find('kibanaStatsPanel').find('a').props().href).toBe('/kibana_deprecations'); + }); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/upgrade_step/upgrade_step.test.tsx b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/upgrade_step/upgrade_step.test.tsx new file mode 100644 index 000000000000..21daed29acac --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/__jest__/client_integration/overview/upgrade_step/upgrade_step.test.tsx @@ -0,0 +1,55 @@ +/* + * 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 { act } from 'react-dom/test-utils'; + +import { OverviewTestBed, setupOverviewPage, setupEnvironment } from '../../helpers'; + +describe('Overview - Upgrade Step', () => { + let testBed: OverviewTestBed; + const { server } = setupEnvironment(); + + beforeEach(async () => { + testBed = await setupOverviewPage(); + testBed.component.update(); + }); + + afterAll(() => { + server.restore(); + }); + + describe('Step 3 - Upgrade stack', () => { + test('Shows link to setup upgrade docs for on-prem installations', () => { + const { exists } = testBed; + + expect(exists('upgradeSetupDocsLink')).toBe(true); + expect(exists('upgradeSetupCloudLink')).toBe(false); + }); + + test('Shows upgrade cta and link to docs for cloud installations', async () => { + await act(async () => { + testBed = await setupOverviewPage({ + servicesOverrides: { + cloud: { + isCloudEnabled: true, + baseUrl: 'https://test.com', + cloudId: '1234', + }, + }, + }); + }); + + const { component, exists, find } = testBed; + component.update(); + + expect(exists('upgradeSetupCloudLink')).toBe(true); + expect(exists('upgradeSetupDocsLink')).toBe(true); + + expect(find('upgradeSetupCloudLink').props().href).toBe('https://test.com/deployments/1234'); + }); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/common/constants.ts b/x-pack/plugins/upgrade_assistant/common/constants.ts index bab3d8c3fda8..893d61d32953 100644 --- a/x-pack/plugins/upgrade_assistant/common/constants.ts +++ b/x-pack/plugins/upgrade_assistant/common/constants.ts @@ -27,3 +27,7 @@ export const indexSettingDeprecations = { }; export const API_BASE_PATH = '/api/upgrade_assistant'; + +export const DEPRECATION_WARNING_UPPER_LIMIT = 999999; +export const DEPRECATION_LOGS_SOURCE_ID = 'deprecation_logs'; +export const DEPRECATION_LOGS_INDEX_PATTERN = '.logs-deprecation.elasticsearch-default'; diff --git a/x-pack/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts index 680e1e03dbbf..35c514a0a95b 100644 --- a/x-pack/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -248,3 +248,8 @@ export interface MlOperation extends SavedObjectAttributes { snapshotId: string; jobId: string; } + +export interface DeprecationLoggingStatus { + isDeprecationLogIndexingEnabled: boolean; + isDeprecationLoggingEnabled: boolean; +} diff --git a/x-pack/plugins/upgrade_assistant/kibana.json b/x-pack/plugins/upgrade_assistant/kibana.json index e69e352104f3..e66f25318a28 100644 --- a/x-pack/plugins/upgrade_assistant/kibana.json +++ b/x-pack/plugins/upgrade_assistant/kibana.json @@ -8,7 +8,7 @@ "githubTeam": "kibana-stack-management" }, "configPath": ["xpack", "upgrade_assistant"], - "requiredPlugins": ["management", "licensing", "features"], - "optionalPlugins": ["usageCollection"], + "requiredPlugins": ["management", "discover", "data", "licensing", "features", "infra"], + "optionalPlugins": ["usageCollection", "cloud"], "requiredBundles": ["esUiShared", "kibanaReact"] } diff --git a/x-pack/plugins/upgrade_assistant/public/application/app.tsx b/x-pack/plugins/upgrade_assistant/public/application/app.tsx index 8086d3322c0e..b1571b9e4546 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/app.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/app.tsx @@ -8,15 +8,22 @@ import React from 'react'; import { Router, Switch, Route, Redirect } from 'react-router-dom'; import { I18nStart, ScopedHistory } from 'src/core/public'; + +import { ApplicationStart } from 'kibana/public'; +import { KibanaContextProvider } from '../shared_imports'; +import { AppServicesContext } from '../types'; import { AppContextProvider, ContextValue, useAppContext } from './app_context'; import { ComingSoonPrompt } from './components/coming_soon_prompt'; import { EsDeprecationsContent } from './components/es_deprecations'; import { KibanaDeprecationsContent } from './components/kibana_deprecations'; -import { DeprecationsOverview } from './components/overview'; +import { Overview } from './components/overview'; +import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public'; export interface AppDependencies extends ContextValue { i18n: I18nStart; history: ScopedHistory; + application: ApplicationStart; + services: AppServicesContext; } const App: React.FunctionComponent = () => { @@ -29,7 +36,7 @@ const App: React.FunctionComponent = () => { return ( - + @@ -45,12 +52,22 @@ export const AppWithRouter = ({ history }: { history: ScopedHistory }) => { ); }; -export const RootComponent = ({ i18n, history, ...contextValue }: AppDependencies) => { +export const RootComponent = ({ + i18n, + history, + services, + application, + ...contextValue +}: AppDependencies) => { return ( - - - - - + + + + + + + + + ); }; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/latest_minor_banner.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/latest_minor_banner.tsx deleted file mode 100644 index 4fd62417c73e..000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/latest_minor_banner.tsx +++ /dev/null @@ -1,60 +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 React from 'react'; - -import { EuiCallOut, EuiLink } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { useAppContext } from '../app_context'; - -export const LatestMinorBanner: React.FunctionComponent = () => { - const { docLinks, kibanaVersionInfo } = useAppContext(); - - const { ELASTIC_WEBSITE_URL } = docLinks; - const esDocBasePath = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference`; - - const { currentMajor, nextMajor } = kibanaVersionInfo; - - return ( - - } - color="warning" - iconType="help" - > -

- - - - ), - nextEsVersion: `${nextMajor}.x`, - currentEsVersion: `${currentMajor}.x`, - }} - /> -

-
- ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/_index.scss b/x-pack/plugins/upgrade_assistant/public/application/components/overview/_index.scss index c64a8f5a5326..cbcfbff3bab6 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/_index.scss +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/_index.scss @@ -1 +1,2 @@ -@import 'steps'; +@import 'review_logs_step/index'; +@import 'fix_deprecation_logs_step/index'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/_steps.scss b/x-pack/plugins/upgrade_assistant/public/application/components/overview/_steps.scss deleted file mode 100644 index 789c22fe1c28..000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/_steps.scss +++ /dev/null @@ -1,6 +0,0 @@ -.upgSteps { - .euiStep:last-child .euiStep__content { - padding-bottom: 0; - margin-bottom: 0; - } -} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/deprecation_logging_toggle.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/deprecation_logging_toggle.tsx deleted file mode 100644 index ab2f94ee5824..000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/deprecation_logging_toggle.tsx +++ /dev/null @@ -1,201 +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 React, { useEffect, useState } from 'react'; - -import { - EuiButton, - EuiFlexItem, - EuiFlexGroup, - EuiText, - EuiTextColor, - EuiButtonEmpty, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import { useAppContext } from '../../app_context'; -import { ResponseError } from '../../lib/api'; - -const i18nTexts = { - fetchErrorMessage: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.fetchErrorMessage', - { - defaultMessage: 'Could not retrieve logging information.', - } - ), - reloadButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.reloadButtonLabel', - { - defaultMessage: 'Try again', - } - ), - updateErrorMessage: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.updateErrorMessage', - { - defaultMessage: 'Could not update logging state.', - } - ), - enabledMessage: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.enabledToastMessage', - { - defaultMessage: 'Log deprecated actions.', - } - ), - disabledMessage: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.disabledToastMessage', - { - defaultMessage: 'Do not log deprecated actions.', - } - ), - fetchButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogging.loadingLabel', - { - defaultMessage: 'Retrieving logging state', - } - ), - enablingButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.enablingButtonLabel', - { - defaultMessage: 'Enabling deprecation logging', - } - ), - disablingButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.disablingButtonLabel', - { - defaultMessage: 'Disabling deprecation logging', - } - ), - enableButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.enableButtonLabel', - { - defaultMessage: 'Enable deprecation logging', - } - ), - disableButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.disableButtonLabel', - { - defaultMessage: 'Disable deprecation logging', - } - ), - fetchErrorButtonLabel: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLogs.fetchErrorButtonLabel', - { - defaultMessage: 'Deprecation logging unavailable', - } - ), -}; - -export const DeprecationLoggingToggle: React.FunctionComponent = () => { - const { api, notifications } = useAppContext(); - - const { data, error: fetchError, isLoading, resendRequest } = api.useLoadDeprecationLogging(); - - const [isEnabled, setIsEnabled] = useState(undefined); - const [isUpdating, setIsUpdating] = useState(false); - const [updateError, setUpdateError] = useState(undefined); - - const getButtonLabel = () => { - if (isLoading) { - return i18nTexts.fetchButtonLabel; - } - - if (isUpdating) { - return isEnabled ? i18nTexts.disablingButtonLabel : i18nTexts.enablingButtonLabel; - } - - if (fetchError) { - return i18nTexts.fetchErrorButtonLabel; - } - - if (isEnabled) { - return i18nTexts.disableButtonLabel; - } - - return i18nTexts.enableButtonLabel; - }; - - useEffect(() => { - if (isLoading === false && data) { - setIsEnabled(data.isEnabled); - } - }, [data, isLoading]); - - const toggleLogging = async () => { - const newIsEnabledValue = !isEnabled; - - setIsUpdating(true); - - const { - data: updatedLoggingState, - error: updateDeprecationError, - } = await api.updateDeprecationLogging({ - isEnabled: newIsEnabledValue, - }); - - setIsUpdating(false); - - if (updateDeprecationError) { - setUpdateError(updateDeprecationError); - } else if (updatedLoggingState) { - setIsEnabled(updatedLoggingState.isEnabled); - notifications.toasts.addSuccess( - updatedLoggingState.isEnabled ? i18nTexts.enabledMessage : i18nTexts.disabledMessage - ); - } - }; - - return ( - - - - {getButtonLabel()} - - - - {fetchError && ( - - -

- {i18nTexts.fetchErrorMessage} - {fetchError.statusCode && fetchError.message && ( - <> - {' '} - {`${fetchError.statusCode}: ${fetchError.message}`} - - )}{' '} - - {i18nTexts.reloadButtonLabel} - -

-
-
- )} - - {updateError && ( - - -

- {i18nTexts.updateErrorMessage} - {updateError.statusCode && updateError.message && ( - <> - {' '} - {`${updateError.statusCode}: ${updateError.message}`} - - )} -

-
-
- )} -
- ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/es_stats.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/es_stats.tsx deleted file mode 100644 index 3152639d3f10..000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/es_stats.tsx +++ /dev/null @@ -1,166 +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 React, { FunctionComponent } from 'react'; - -import { - EuiLink, - EuiPanel, - EuiStat, - EuiTitle, - EuiSpacer, - EuiFlexGroup, - EuiFlexItem, - EuiIconTip, - EuiScreenReaderOnly, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import { RouteComponentProps } from 'react-router-dom'; -import { reactRouterNavigate } from '../../../../../../../src/plugins/kibana_react/public'; -import { useAppContext } from '../../app_context'; -import { EsStatsErrors } from './es_stats_error'; - -const i18nTexts = { - statsTitle: i18n.translate('xpack.upgradeAssistant.esDeprecationStats.statsTitle', { - defaultMessage: 'Elasticsearch', - }), - totalDeprecationsTitle: i18n.translate( - 'xpack.upgradeAssistant.esDeprecationStats.totalDeprecationsTitle', - { - defaultMessage: 'Deprecations', - } - ), - criticalDeprecationsTitle: i18n.translate( - 'xpack.upgradeAssistant.esDeprecationStats.criticalDeprecationsTitle', - { - defaultMessage: 'Critical', - } - ), - viewDeprecationsLink: i18n.translate( - 'xpack.upgradeAssistant.esDeprecationStats.viewDeprecationsLinkText', - { - defaultMessage: 'View deprecations', - } - ), - loadingText: i18n.translate('xpack.upgradeAssistant.esDeprecationStats.loadingText', { - defaultMessage: 'Loading Elasticsearch deprecation stats…', - }), - getCriticalDeprecationsMessage: (criticalDeprecations: number) => - i18n.translate('xpack.upgradeAssistant.esDeprecationStats.criticalDeprecationsLabel', { - defaultMessage: 'This cluster has {criticalDeprecations} critical deprecations', - values: { - criticalDeprecations, - }, - }), - getTotalDeprecationsTooltip: (clusterCount: number, indexCount: number) => - i18n.translate('xpack.upgradeAssistant.esDeprecationStats.totalDeprecationsTooltip', { - defaultMessage: - 'This cluster is using {clusterCount} deprecated cluster settings and {indexCount} deprecated index settings', - values: { - clusterCount, - indexCount, - }, - }), -}; - -interface Props { - history: RouteComponentProps['history']; -} - -export const ESDeprecationStats: FunctionComponent = ({ history }) => { - const { api } = useAppContext(); - - const { data: esDeprecations, isLoading, error } = api.useLoadUpgradeStatus(); - - const allDeprecations = esDeprecations?.cluster?.concat(esDeprecations?.indices) ?? []; - const criticalDeprecations = allDeprecations.filter( - (deprecation) => deprecation.level === 'critical' - ); - - return ( - - - - -

{i18nTexts.statsTitle}

-
-
- - - {i18nTexts.viewDeprecationsLink} - - -
- - - - - - - {i18nTexts.totalDeprecationsTitle}{' '} - - - } - isLoading={isLoading} - > - {error === null && ( - -

- {isLoading - ? i18nTexts.loadingText - : i18nTexts.getTotalDeprecationsTooltip( - esDeprecations?.cluster.length ?? 0, - esDeprecations?.indices.length ?? 0 - )} -

-
- )} -
-
- - - - {error === null && ( - -

- {isLoading - ? i18nTexts.loadingText - : i18nTexts.getCriticalDeprecationsMessage(criticalDeprecations.length)} -

-
- )} - - {error && } -
-
-
-
- ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/_index.scss b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/_index.scss new file mode 100644 index 000000000000..2299c08a4ac3 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/_index.scss @@ -0,0 +1 @@ +@import 'deprecation_logging_toggle/deprecation_logging_toggle'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/_deprecation_logging_toggle.scss b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/_deprecation_logging_toggle.scss new file mode 100644 index 000000000000..e8b6ec06ed7c --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/_deprecation_logging_toggle.scss @@ -0,0 +1,7 @@ +// When you have a flex item with an EuiSwitch and replace it with +// an EuiLoadingSpinner you end up with a slight 2px difference between +// them. With this selector we offset the difference so that the content +// of the page doesnt jump when toggling between states. +.upgToggleLoading > .upgLoadingItem { + margin: $euiSizeM / 2; +} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/deprecation_logging_toggle.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/deprecation_logging_toggle.tsx new file mode 100644 index 000000000000..42b9f073a52f --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/deprecation_logging_toggle.tsx @@ -0,0 +1,154 @@ +/* + * 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 React, { useState, FunctionComponent } from 'react'; + +import { + EuiSwitch, + EuiFlexItem, + EuiFlexGroup, + EuiText, + EuiPopover, + EuiLink, + EuiTextColor, + EuiButtonEmpty, + EuiLoadingSpinner, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { ResponseError } from '../../../../lib/api'; +import { DeprecationLoggingPreviewProps } from '../../../types'; + +const i18nTexts = { + fetchErrorMessage: i18n.translate( + 'xpack.upgradeAssistant.overview.deprecationLogs.fetchErrorMessage', + { + defaultMessage: 'Could not retrieve logging information.', + } + ), + reloadButtonLabel: i18n.translate( + 'xpack.upgradeAssistant.overview.deprecationLogs.reloadButtonLabel', + { + defaultMessage: 'Try again', + } + ), + updateErrorMessage: i18n.translate( + 'xpack.upgradeAssistant.overview.deprecationLogs.updateErrorMessage', + { + defaultMessage: 'Could not update logging state.', + } + ), + errorLabel: i18n.translate('xpack.upgradeAssistant.overview.deprecationLogs.errorLabel', { + defaultMessage: 'Error', + }), + buttonLabel: i18n.translate('xpack.upgradeAssistant.overview.deprecationLogs.buttonLabel', { + defaultMessage: 'Enable deprecation logging and indexing', + }), + loadingLogsLabel: i18n.translate('xpack.upgradeAssistant.overview.loadingLogsLabel', { + defaultMessage: 'Loading log collection state…', + }), +}; + +const ErrorDetailsLink = ({ error }: { error: ResponseError }) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const onButtonClick = () => setIsPopoverOpen(!isPopoverOpen); + const closePopover = () => setIsPopoverOpen(false); + + if (!error.statusCode || !error.message) { + return null; + } + + const button = ( + + {i18nTexts.errorLabel} {error.statusCode} + + ); + + return ( + + +

{error.message}

+
+
+ ); +}; + +export const DeprecationLoggingToggle: FunctionComponent = ({ + isDeprecationLogIndexingEnabled, + isLoading, + isUpdating, + fetchError, + updateError, + resendRequest, + toggleLogging, +}) => { + if (isLoading) { + return ( + + + + + {i18nTexts.loadingLogsLabel} + + ); + } + + if (fetchError) { + return ( + + + + + {i18nTexts.fetchErrorMessage} + + + + + + + + + {i18nTexts.reloadButtonLabel} + + + + ); + } + + return ( + + + + + + {updateError && ( + + + + {i18nTexts.updateErrorMessage} + + + + + + + )} + + {isUpdating && ( + + + + )} + + ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/index.ts new file mode 100644 index 000000000000..f41ab454f894 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/deprecation_logging_toggle/index.ts @@ -0,0 +1,8 @@ +/* + * 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 { DeprecationLoggingToggle } from './deprecation_logging_toggle'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/external_links.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/external_links.tsx new file mode 100644 index 000000000000..0cd5ad5bfdb2 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/external_links.tsx @@ -0,0 +1,120 @@ +/* + * 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 React, { FunctionComponent, useState, useEffect } from 'react'; + +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiLink, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiPanel, EuiText } from '@elastic/eui'; + +import { useAppContext } from '../../../app_context'; +import { useKibana, DataPublicPluginStart } from '../../../../shared_imports'; +import { + DEPRECATION_LOGS_INDEX_PATTERN, + DEPRECATION_LOGS_SOURCE_ID, +} from '../../../../../common/constants'; + +const getDeprecationIndexPatternId = async (dataService: DataPublicPluginStart) => { + const { indexPatterns: indexPatternService } = dataService; + + const results = await indexPatternService.find(DEPRECATION_LOGS_INDEX_PATTERN); + // Since the find might return also results with wildcard matchers we need to find the + // index pattern that has an exact match with our title. + const deprecationIndexPattern = results.find( + (result) => result.title === DEPRECATION_LOGS_INDEX_PATTERN + ); + + if (deprecationIndexPattern) { + return deprecationIndexPattern.id; + } else { + const newIndexPattern = await indexPatternService.createAndSave({ + title: DEPRECATION_LOGS_INDEX_PATTERN, + allowNoIndex: true, + }); + return newIndexPattern.id; + } +}; + +const DiscoverAppLink: FunctionComponent = () => { + const { getUrlForApp } = useAppContext(); + const { data: dataService, discover: discoverService } = useKibana().services; + + const [discoveryUrl, setDiscoveryUrl] = useState(); + + useEffect(() => { + const getDiscoveryUrl = async () => { + const indexPatternId = await getDeprecationIndexPatternId(dataService); + const appLocation = await discoverService?.locator?.getLocation({ indexPatternId }); + + const result = getUrlForApp(appLocation?.app as string, { + path: appLocation?.path, + }); + setDiscoveryUrl(result); + }; + + getDiscoveryUrl(); + }, [dataService, discoverService, getUrlForApp]); + + return ( + + + + ); +}; + +const ObservabilityAppLink: FunctionComponent = () => { + const { http } = useAppContext(); + const logStreamUrl = http?.basePath?.prepend( + `/app/logs/stream?sourceId=${DEPRECATION_LOGS_SOURCE_ID}` + ); + + return ( + + + + ); +}; + +export const ExternalLinks: FunctionComponent = () => { + return ( + + + + +

+ +

+
+ + +
+
+ + + +

+ +

+
+ + +
+
+
+ ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/fix_deprecation_logs_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/fix_deprecation_logs_step.tsx new file mode 100644 index 000000000000..a2f1feae4979 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/fix_deprecation_logs_step.tsx @@ -0,0 +1,90 @@ +/* + * 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 React, { FunctionComponent } from 'react'; + +import { i18n } from '@kbn/i18n'; +import { EuiText, EuiSpacer, EuiPanel, EuiCallOut } from '@elastic/eui'; +import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; + +import { ExternalLinks } from './external_links'; +import { useDeprecationLogging } from './use_deprecation_logging'; +import { DeprecationLoggingToggle } from './deprecation_logging_toggle'; + +const i18nTexts = { + identifyStepTitle: i18n.translate('xpack.upgradeAssistant.overview.identifyStepTitle', { + defaultMessage: 'Identify deprecated API use and update your applications', + }), + toggleTitle: i18n.translate('xpack.upgradeAssistant.overview.toggleTitle', { + defaultMessage: 'Log Elasticsearch deprecation warnings', + }), + analyzeTitle: i18n.translate('xpack.upgradeAssistant.overview.analyzeTitle', { + defaultMessage: 'Analyze deprecation logs', + }), + onlyLogWritingEnabledTitle: i18n.translate( + 'xpack.upgradeAssistant.overview.deprecationLogs.deprecationWarningTitle', + { + defaultMessage: 'Your logs are being written to the logs directory', + } + ), + onlyLogWritingEnabledBody: i18n.translate( + 'xpack.upgradeAssistant.overview.deprecationLogs.deprecationWarningBody', + { + defaultMessage: + 'Go to your logs directory to view the deprecation logs or enable log collecting to see them in the UI.', + } + ), +}; + +const DeprecationLogsPreview: FunctionComponent = () => { + const state = useDeprecationLogging(); + + return ( + <> + +

{i18nTexts.toggleTitle}

+
+ + + + + + {state.onlyDeprecationLogWritingEnabled && ( + <> + + +

{i18nTexts.onlyLogWritingEnabledBody}

+
+ + )} + + {state.isDeprecationLogIndexingEnabled && ( + <> + + +

{i18nTexts.analyzeTitle}

+
+ + + + )} + + ); +}; + +export const getFixDeprecationLogsStep = (): EuiStepProps => { + return { + title: i18nTexts.identifyStepTitle, + status: 'incomplete', + children: , + }; +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/index.ts new file mode 100644 index 000000000000..d4794623d8a9 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/index.ts @@ -0,0 +1,8 @@ +/* + * 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 { getFixDeprecationLogsStep } from './fix_deprecation_logs_step'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/use_deprecation_logging.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/use_deprecation_logging.ts new file mode 100644 index 000000000000..5545eb035374 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/fix_deprecation_logs_step/use_deprecation_logging.ts @@ -0,0 +1,89 @@ +/* + * 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 { useState, useEffect } from 'react'; + +import { i18n } from '@kbn/i18n'; + +import { useAppContext } from '../../../app_context'; +import { ResponseError } from '../../../lib/api'; +import { DeprecationLoggingPreviewProps } from '../../types'; + +const i18nTexts = { + enabledMessage: i18n.translate( + 'xpack.upgradeAssistant.overview.deprecationLogs.enabledToastMessage', + { + defaultMessage: 'Deprecated API requests will be logged and indexed.', + } + ), + disabledMessage: i18n.translate( + 'xpack.upgradeAssistant.overview.deprecationLogs.disabledToastMessage', + { + defaultMessage: 'Deprecated API requests will not be logged.', + } + ), +}; + +export const useDeprecationLogging = (): DeprecationLoggingPreviewProps => { + const { api, notifications } = useAppContext(); + const { data, error: fetchError, isLoading, resendRequest } = api.useLoadDeprecationLogging(); + + const [isDeprecationLogIndexingEnabled, setIsDeprecationLogIndexingEnabled] = useState(false); + const [isUpdating, setIsUpdating] = useState(false); + const [onlyDeprecationLogWritingEnabled, setOnlyDeprecationLogWritingEnabled] = useState(false); + const [updateError, setUpdateError] = useState(); + + useEffect(() => { + if (!isLoading && data) { + const { + isDeprecationLogIndexingEnabled: isIndexingEnabled, + isDeprecationLoggingEnabled, + } = data; + setIsDeprecationLogIndexingEnabled(isIndexingEnabled); + + if (!isIndexingEnabled && isDeprecationLoggingEnabled) { + setOnlyDeprecationLogWritingEnabled(true); + } + } + }, [data, isLoading]); + + const toggleLogging = async () => { + setIsUpdating(true); + + const { + data: updatedLoggingState, + error: updateDeprecationError, + } = await api.updateDeprecationLogging({ + isEnabled: !isDeprecationLogIndexingEnabled, + }); + + setIsUpdating(false); + setOnlyDeprecationLogWritingEnabled(false); + + if (updateDeprecationError) { + setUpdateError(updateDeprecationError); + } else if (updatedLoggingState) { + setIsDeprecationLogIndexingEnabled(updatedLoggingState.isDeprecationLogIndexingEnabled); + notifications.toasts.addSuccess( + updatedLoggingState.isDeprecationLogIndexingEnabled + ? i18nTexts.enabledMessage + : i18nTexts.disabledMessage + ); + } + }; + + return { + isDeprecationLogIndexingEnabled, + isLoading, + isUpdating, + toggleLogging, + fetchError, + updateError, + resendRequest, + onlyDeprecationLogWritingEnabled, + }; +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/index.ts index a64d7b0d4491..69c843fe3821 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/index.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { DeprecationsOverview } from './overview'; +export { Overview } from './overview'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/kibana_stats.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/kibana_stats.tsx deleted file mode 100644 index 28941d1305ad..000000000000 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/kibana_stats.tsx +++ /dev/null @@ -1,194 +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 React, { FunctionComponent, useEffect, useState } from 'react'; - -import { - EuiLink, - EuiPanel, - EuiStat, - EuiTitle, - EuiSpacer, - EuiFlexGroup, - EuiFlexItem, - EuiIconTip, - EuiScreenReaderOnly, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -import { RouteComponentProps } from 'react-router-dom'; -import type { DomainDeprecationDetails } from 'kibana/public'; -import { reactRouterNavigate } from '../../../../../../../src/plugins/kibana_react/public'; -import { useAppContext } from '../../app_context'; - -const i18nTexts = { - statsTitle: i18n.translate('xpack.upgradeAssistant.kibanaDeprecationStats.statsTitle', { - defaultMessage: 'Kibana', - }), - totalDeprecationsTitle: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecationStats.totalDeprecationsTitle', - { - defaultMessage: 'Deprecations', - } - ), - criticalDeprecationsTitle: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecationStats.criticalDeprecationsTitle', - { - defaultMessage: 'Critical', - } - ), - viewDeprecationsLink: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecationStats.viewDeprecationsLinkText', - { - defaultMessage: 'View deprecations', - } - ), - loadingError: i18n.translate( - 'xpack.upgradeAssistant.kibanaDeprecationStats.loadingErrorMessage', - { - defaultMessage: 'An error occurred while retrieving Kibana deprecations.', - } - ), - loadingText: i18n.translate('xpack.upgradeAssistant.kibanaDeprecationStats.loadingText', { - defaultMessage: 'Loading Kibana deprecation stats…', - }), - getCriticalDeprecationsMessage: (criticalDeprecations: number) => - i18n.translate('xpack.upgradeAssistant.kibanaDeprecationStats.criticalDeprecationsLabel', { - defaultMessage: 'Kibana has {criticalDeprecations} critical deprecations', - values: { - criticalDeprecations, - }, - }), - getTotalDeprecationsMessage: (totalDeprecations: number) => - i18n.translate('xpack.upgradeAssistant.kibanaDeprecationStats.totalDeprecationsLabel', { - defaultMessage: 'Kibana has {totalDeprecations} total deprecations', - values: { - totalDeprecations, - }, - }), -}; - -interface Props { - history: RouteComponentProps['history']; -} - -export const KibanaDeprecationStats: FunctionComponent = ({ history }) => { - const { deprecations } = useAppContext(); - - const [kibanaDeprecations, setKibanaDeprecations] = useState< - DomainDeprecationDetails[] | undefined - >(undefined); - const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(undefined); - - useEffect(() => { - async function getAllDeprecations() { - setIsLoading(true); - - try { - const response = await deprecations.getAllDeprecations(); - setKibanaDeprecations(response); - } catch (e) { - setError(e); - } - - setIsLoading(false); - } - - getAllDeprecations(); - }, [deprecations]); - - return ( - - - - -

{i18nTexts.statsTitle}

-
-
- - - {i18nTexts.viewDeprecationsLink} - - -
- - - - - - - {error === undefined && ( - -

- {isLoading - ? i18nTexts.loadingText - : i18nTexts.getTotalDeprecationsMessage(kibanaDeprecations?.length ?? 0)} -

-
- )} -
-
- - - deprecation.level === 'critical') - ?.length ?? '0' - : '--' - } - description={i18nTexts.criticalDeprecationsTitle} - titleColor="danger" - isLoading={isLoading} - > - {error === undefined && ( - -

- {isLoading - ? i18nTexts.loadingText - : i18nTexts.getCriticalDeprecationsMessage( - kibanaDeprecations - ? kibanaDeprecations.filter( - (deprecation) => deprecation.level === 'critical' - )?.length ?? 0 - : 0 - )} -

-
- )} - - {error && ( - <> - - - - - )} -
-
-
-
- ); -}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx index b77d4a337295..bd076dd60021 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/overview.tsx @@ -8,71 +8,26 @@ import React, { FunctionComponent, useEffect } from 'react'; import { - EuiPageContentBody, + EuiSteps, EuiText, EuiPageHeader, EuiButtonEmpty, - EuiFlexItem, - EuiFlexGroup, EuiSpacer, - EuiTitle, EuiLink, + EuiPageBody, + EuiPageContent, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { RouteComponentProps } from 'react-router-dom'; import { useAppContext } from '../../app_context'; -import { LatestMinorBanner } from '../latest_minor_banner'; -import { ESDeprecationStats } from './es_stats'; -import { KibanaDeprecationStats } from './kibana_stats'; -import { DeprecationLoggingToggle } from './deprecation_logging_toggle'; +import { getReviewLogsStep } from './review_logs_step'; +import { getFixDeprecationLogsStep } from './fix_deprecation_logs_step'; +import { getUpgradeStep } from './upgrade_step'; -const i18nTexts = { - pageTitle: i18n.translate('xpack.upgradeAssistant.overview.pageTitle', { - defaultMessage: 'Upgrade Assistant', - }), - pageDescription: i18n.translate('xpack.upgradeAssistant.overview.pageDescription', { - defaultMessage: - 'Prepare to upgrade by identifying deprecated settings and updating your configuration.', - }), - docLink: i18n.translate('xpack.upgradeAssistant.overview.documentationLinkText', { - defaultMessage: 'Documentation', - }), - deprecationLoggingTitle: i18n.translate( - 'xpack.upgradeAssistant.overview.deprecationLoggingTitle', - { - defaultMessage: 'Deprecation logs', - } - ), - getDeprecationLoggingDescription: (nextMajor: string, href: string) => ( - - {i18n.translate( - 'xpack.upgradeAssistant.deprecationLoggingDescription.deprecationLoggingLink', - { - defaultMessage: 'deprecation logging', - } - )} - - ), - }} - /> - ), -}; - -interface Props { - history: RouteComponentProps['history']; -} - -export const DeprecationsOverview: FunctionComponent = ({ history }) => { +export const Overview: FunctionComponent = () => { const { kibanaVersionInfo, breadcrumbs, docLinks, api } = useAppContext(); - const { nextMajor } = kibanaVersionInfo; + const { currentMajor } = kibanaVersionInfo; useEffect(() => { async function sendTelemetryData() { @@ -89,68 +44,51 @@ export const DeprecationsOverview: FunctionComponent = ({ history }) => { }, [breadcrumbs]); return ( -
- - {i18nTexts.docLink} - , - ]} - /> + + + + + , + ]} + > + + + + + + - + - - <> - {/* Remove this in last minor of the current major (e.g., 7.15) */} - - - - - {/* Deprecation stats */} - - - - - - - - - - - - - {/* Deprecation logging */} - - - -

{i18nTexts.deprecationLoggingTitle}

-
- - -

- {i18nTexts.getDeprecationLoggingDescription( - `${nextMajor}.x`, - docLinks.links.elasticsearch.deprecationLogging - )} -

-
- - - - -
-
- -
-
+ + + ); }; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/_index.scss b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/_index.scss new file mode 100644 index 000000000000..7eea518d5698 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/_index.scss @@ -0,0 +1,2 @@ +@import 'stats_panel'; +@import 'no_deprecations/no_deprecations'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/_stats_panel.scss b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/_stats_panel.scss new file mode 100644 index 000000000000..b32f3eb9ddbd --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/_stats_panel.scss @@ -0,0 +1,6 @@ +// Used by both es_stats and kibana_stats panel for having the EuiPopover Icon +// for errors shown next to the title without having to resort to wrapping everything +// with EuiFlexGroups. +.upgWarningIcon { + margin-left: $euiSizeS; +} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/es_stats.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/es_stats.tsx new file mode 100644 index 000000000000..97306dac287b --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/es_stats.tsx @@ -0,0 +1,153 @@ +/* + * 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 React, { FunctionComponent } from 'react'; +import { useHistory } from 'react-router-dom'; + +import { + EuiStat, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiCard, + EuiScreenReaderOnly, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { reactRouterNavigate } from '../../../../../../../../../src/plugins/kibana_react/public'; +import { getDeprecationsUpperLimit } from '../../../../lib/utils'; +import { useAppContext } from '../../../../app_context'; +import { EsStatsErrors } from './es_stats_error'; +import { NoDeprecations } from '../no_deprecations'; + +const i18nTexts = { + statsTitle: i18n.translate('xpack.upgradeAssistant.esDeprecationStats.statsTitle', { + defaultMessage: 'Elasticsearch', + }), + warningDeprecationsTitle: i18n.translate( + 'xpack.upgradeAssistant.esDeprecationStats.warningDeprecationsTitle', + { + defaultMessage: 'Warning', + } + ), + criticalDeprecationsTitle: i18n.translate( + 'xpack.upgradeAssistant.esDeprecationStats.criticalDeprecationsTitle', + { + defaultMessage: 'Critical', + } + ), + loadingText: i18n.translate('xpack.upgradeAssistant.esDeprecationStats.loadingText', { + defaultMessage: 'Loading Elasticsearch deprecation stats…', + }), + getCriticalDeprecationsMessage: (criticalDeprecations: number) => + i18n.translate('xpack.upgradeAssistant.esDeprecationStats.criticalDeprecationsLabel', { + defaultMessage: 'This cluster has {criticalDeprecations} critical deprecations', + values: { + criticalDeprecations, + }, + }), + getWarningDeprecationMessage: (clusterCount: number, indexCount: number) => + i18n.translate('xpack.upgradeAssistant.esDeprecationStats.totalDeprecationsTooltip', { + defaultMessage: + 'This cluster is using {clusterCount} deprecated cluster settings and {indexCount} deprecated index settings', + values: { + clusterCount, + indexCount, + }, + }), +}; + +export const ESDeprecationStats: FunctionComponent = () => { + const history = useHistory(); + const { api } = useAppContext(); + + const { data: esDeprecations, isLoading, error } = api.useLoadUpgradeStatus(); + + const allDeprecations = esDeprecations?.cluster?.concat(esDeprecations?.indices) ?? []; + const warningDeprecations = allDeprecations.filter( + (deprecation) => deprecation.level === 'warning' + ); + const criticalDeprecations = allDeprecations.filter( + (deprecation) => deprecation.level === 'critical' + ); + + const hasWarnings = warningDeprecations.length > 0; + const hasCritical = criticalDeprecations.length > 0; + const hasNoDeprecations = !isLoading && !error && !hasWarnings && !hasCritical; + const shouldRenderStat = (forSection: boolean) => error || isLoading || forSection; + + return ( + + {i18nTexts.statsTitle} + {error && } + + } + {...(!hasNoDeprecations && reactRouterNavigate(history, '/es_deprecations/cluster'))} + > + + + {hasNoDeprecations && ( + + + + )} + + {shouldRenderStat(hasCritical) && ( + + + {error === null && ( + +

+ {isLoading + ? i18nTexts.loadingText + : i18nTexts.getCriticalDeprecationsMessage(criticalDeprecations.length)} +

+
+ )} +
+
+ )} + + {shouldRenderStat(hasWarnings) && ( + + + {!error && ( + +

+ {isLoading + ? i18nTexts.loadingText + : i18nTexts.getWarningDeprecationMessage( + esDeprecations?.cluster.length ?? 0, + esDeprecations?.indices.length ?? 0 + )} +

+
+ )} +
+
+ )} +
+
+ ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/es_stats_error.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/es_stats_error.tsx similarity index 80% rename from x-pack/plugins/upgrade_assistant/public/application/components/overview/es_stats_error.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/es_stats_error.tsx index dda7d16599e0..5db5b80cc42e 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/overview/es_stats_error.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/es_stats_error.tsx @@ -7,9 +7,9 @@ import React from 'react'; -import { EuiIconTip, EuiSpacer } from '@elastic/eui'; -import { ResponseError } from '../../lib/api'; -import { getEsDeprecationError } from '../../lib/es_deprecation_errors'; +import { EuiIconTip } from '@elastic/eui'; +import { ResponseError } from '../../../../lib/api'; +import { getEsDeprecationError } from '../../../../lib/es_deprecation_errors'; interface Props { error: ResponseError; @@ -26,7 +26,7 @@ export const EsStatsErrors: React.FunctionComponent = ({ error }) => { = ({ error }) => { = ({ error }) => { = ({ error }) => { ); } - return ( - <> - - {iconContent} - - ); + return {iconContent}; }; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/index.ts new file mode 100644 index 000000000000..daf2644c2477 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/es_stats/index.ts @@ -0,0 +1,8 @@ +/* + * 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 { ESDeprecationStats } from './es_stats'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/index.ts new file mode 100644 index 000000000000..231b8ba2d777 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/index.ts @@ -0,0 +1,8 @@ +/* + * 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 { getReviewLogsStep } from './review_logs_step'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/kibana_stats/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/kibana_stats/index.ts new file mode 100644 index 000000000000..185ec5f2540c --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/kibana_stats/index.ts @@ -0,0 +1,8 @@ +/* + * 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 { KibanaDeprecationStats } from './kibana_stats'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/kibana_stats/kibana_stats.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/kibana_stats/kibana_stats.tsx new file mode 100644 index 000000000000..d7b820aa4a48 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/kibana_stats/kibana_stats.tsx @@ -0,0 +1,188 @@ +/* + * 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 React, { FunctionComponent, useEffect, useState } from 'react'; +import { useHistory } from 'react-router-dom'; + +import { + EuiCard, + EuiStat, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiIconTip, + EuiScreenReaderOnly, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import type { DomainDeprecationDetails } from 'kibana/public'; +import { reactRouterNavigate } from '../../../../../../../../../src/plugins/kibana_react/public'; +import { getDeprecationsUpperLimit } from '../../../../lib/utils'; +import { useAppContext } from '../../../../app_context'; +import { NoDeprecations } from '../no_deprecations'; + +const i18nTexts = { + statsTitle: i18n.translate('xpack.upgradeAssistant.kibanaDeprecationStats.statsTitle', { + defaultMessage: 'Kibana', + }), + warningDeprecationsTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecationStats.warningDeprecationsTitle', + { + defaultMessage: 'Warning', + } + ), + criticalDeprecationsTitle: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecationStats.criticalDeprecationsTitle', + { + defaultMessage: 'Critical', + } + ), + loadingError: i18n.translate( + 'xpack.upgradeAssistant.kibanaDeprecationStats.loadingErrorMessage', + { + defaultMessage: 'An error occurred while retrieving Kibana deprecations.', + } + ), + loadingText: i18n.translate('xpack.upgradeAssistant.kibanaDeprecationStats.loadingText', { + defaultMessage: 'Loading Kibana deprecation stats…', + }), + getCriticalDeprecationsMessage: (criticalDeprecations: number) => + i18n.translate('xpack.upgradeAssistant.kibanaDeprecationStats.criticalDeprecationsLabel', { + defaultMessage: + 'Kibana has {criticalDeprecations} critical {criticalDeprecations, plural, one {deprecation} other {deprecations}}', + values: { + criticalDeprecations, + }, + }), + getWarningDeprecationsMessage: (warningDeprecations: number) => + i18n.translate('xpack.upgradeAssistant.kibanaDeprecationStats.getWarningDeprecationsMessage', { + defaultMessage: + 'Kibana has {warningDeprecations} warning {warningDeprecations, plural, one {deprecation} other {deprecations}}', + values: { + warningDeprecations, + }, + }), +}; + +export const KibanaDeprecationStats: FunctionComponent = () => { + const history = useHistory(); + const { deprecations } = useAppContext(); + + const [kibanaDeprecations, setKibanaDeprecations] = useState< + DomainDeprecationDetails[] | undefined + >(undefined); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(undefined); + + useEffect(() => { + async function getAllDeprecations() { + setIsLoading(true); + + try { + const response = await deprecations.getAllDeprecations(); + setKibanaDeprecations(response); + } catch (e) { + setError(e); + } + + setIsLoading(false); + } + + getAllDeprecations(); + }, [deprecations]); + + const warningDeprecationsCount = + kibanaDeprecations?.filter((deprecation) => deprecation.level === 'warning')?.length ?? 0; + const criticalDeprecationsCount = + kibanaDeprecations?.filter((deprecation) => deprecation.level === 'critical')?.length ?? 0; + + const hasCritical = criticalDeprecationsCount > 0; + const hasWarnings = warningDeprecationsCount > 0; + const hasNoDeprecations = !isLoading && !error && !hasWarnings && !hasCritical; + const shouldRenderStat = (forSection: boolean) => error || isLoading || forSection; + + return ( + + {i18nTexts.statsTitle} + {error && ( + + )} + + } + {...(!hasNoDeprecations && reactRouterNavigate(history, '/kibana_deprecations'))} + > + + + {hasNoDeprecations && ( + + + + )} + + {shouldRenderStat(hasCritical) && ( + + + {error === undefined && ( + +

+ {isLoading + ? i18nTexts.loadingText + : i18nTexts.getCriticalDeprecationsMessage(criticalDeprecationsCount)} +

+
+ )} +
+
+ )} + + {shouldRenderStat(hasWarnings) && ( + + + {!error && ( + +

+ {isLoading + ? i18nTexts.loadingText + : i18nTexts.getWarningDeprecationsMessage(warningDeprecationsCount)} +

+
+ )} +
+
+ )} +
+
+ ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/_no_deprecations.scss b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/_no_deprecations.scss new file mode 100644 index 000000000000..0697efbd6ee3 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/_no_deprecations.scss @@ -0,0 +1,3 @@ +.upgRenderSuccessMessage { + margin-top: $euiSizeL; +} diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/index.ts new file mode 100644 index 000000000000..a2684505eb9c --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/index.ts @@ -0,0 +1,8 @@ +/* + * 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 { NoDeprecations } from './no_deprecations'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/no_deprecations.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/no_deprecations.tsx new file mode 100644 index 000000000000..06fea677aa0a --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/no_deprecations/no_deprecations.tsx @@ -0,0 +1,35 @@ +/* + * 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 React, { FunctionComponent } from 'react'; + +import { EuiFlexGroup, EuiFlexItem, EuiText, EuiIcon } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +const i18nTexts = { + noDeprecationsText: i18n.translate( + 'xpack.upgradeAssistant.esDeprecationStats.noDeprecationsText', + { + defaultMessage: 'No warnings. Good to go!', + } + ), +}; + +export const NoDeprecations: FunctionComponent = () => { + return ( + + + + + + + {i18nTexts.noDeprecationsText} + + + + ); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/review_logs_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/review_logs_step.tsx new file mode 100644 index 000000000000..2da31a3801dd --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/review_logs_step/review_logs_step.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiText, EuiFlexItem, EuiFlexGroup, EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; +import { ESDeprecationStats } from './es_stats'; +import { KibanaDeprecationStats } from './kibana_stats'; + +const i18nTexts = { + reviewStepTitle: i18n.translate('xpack.upgradeAssistant.overview.reviewStepTitle', { + defaultMessage: 'Review deprecated settings and resolve issues', + }), +}; + +export const getReviewLogsStep = ({ currentMajor }: { currentMajor: number }): EuiStepProps => { + return { + title: i18nTexts.reviewStepTitle, + status: 'incomplete', + children: ( + <> + +

+ +

+
+ + + + + + + + + + + + + + ), + }; +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/index.ts b/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/index.ts new file mode 100644 index 000000000000..5f74bed47c34 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/index.ts @@ -0,0 +1,8 @@ +/* + * 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 { getUpgradeStep } from './upgrade_step'; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/upgrade_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/upgrade_step.tsx new file mode 100644 index 000000000000..9b66a28e81cd --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/components/overview/upgrade_step/upgrade_step.tsx @@ -0,0 +1,129 @@ +/* + * 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 React from 'react'; + +import { + EuiText, + EuiFlexItem, + EuiFlexGroup, + EuiSpacer, + EuiButton, + EuiButtonEmpty, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import type { EuiStepProps } from '@elastic/eui/src/components/steps/step'; +import type { DocLinksStart } from 'src/core/public'; +import { useKibana } from '../../../../shared_imports'; + +const i18nTexts = { + upgradeStepTitle: (currentMajor: number) => + i18n.translate('xpack.upgradeAssistant.overview.upgradeStepTitle', { + defaultMessage: 'Install {currentMajor}.0', + values: { currentMajor }, + }), + upgradeStepDescription: i18n.translate('xpack.upgradeAssistant.overview.upgradeStepDescription', { + defaultMessage: + "Once you've resolved all critical issues and verified that your applications are ready, you can upgrade the Elastic Stack.", + }), + upgradeStepDescriptionForCloud: i18n.translate( + 'xpack.upgradeAssistant.overview.upgradeStepDescriptionForCloud', + { + defaultMessage: + "Once you've resolved all critical issues and verified that your applications are ready, you can upgrade the Elastic Stack. Upgrade your deployment on Elastic Cloud.", + } + ), + upgradeStepLink: i18n.translate('xpack.upgradeAssistant.overview.upgradeStepLink', { + defaultMessage: 'Learn more', + }), + upgradeStepCloudLink: i18n.translate('xpack.upgradeAssistant.overview.upgradeStepCloudLink', { + defaultMessage: 'Upgrade on Cloud', + }), + upgradeGuideLink: i18n.translate('xpack.upgradeAssistant.overview.upgradeGuideLink', { + defaultMessage: 'View upgrade guide', + }), +}; + +const UpgradeStep = ({ docLinks }: { docLinks: DocLinksStart }) => { + const { cloud } = useKibana().services; + + const isCloudEnabled: boolean = Boolean(cloud?.isCloudEnabled); + const cloudDeploymentUrl: string = `${cloud?.baseUrl ?? ''}/deployments/${cloud?.cloudId ?? ''}`; + + let callToAction; + + if (isCloudEnabled) { + callToAction = ( + + + + {i18nTexts.upgradeStepCloudLink} + + + + + + {i18nTexts.upgradeGuideLink} + + + + ); + } else { + callToAction = ( + + {i18nTexts.upgradeStepLink} + + ); + } + + return ( + <> + +

+ {isCloudEnabled + ? i18nTexts.upgradeStepDescriptionForCloud + : i18nTexts.upgradeStepDescription} +

+
+ + + + {callToAction} + + ); +}; + +interface Props { + docLinks: DocLinksStart; + currentMajor: number; +} + +export const getUpgradeStep = ({ docLinks, currentMajor }: Props): EuiStepProps => { + return { + title: i18nTexts.upgradeStepTitle(currentMajor), + status: 'incomplete', + children: , + }; +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/types.ts b/x-pack/plugins/upgrade_assistant/public/application/components/types.ts index e3ba609026a8..b4fd78252b2f 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/types.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/types.ts @@ -46,3 +46,14 @@ export enum TelemetryState { } export type EsTabs = 'cluster' | 'indices'; + +export interface DeprecationLoggingPreviewProps { + isDeprecationLogIndexingEnabled: boolean; + onlyDeprecationLogWritingEnabled: boolean; + isLoading: boolean; + isUpdating: boolean; + fetchError: ResponseError | null; + updateError: ResponseError | undefined; + resendRequest: () => void; + toggleLogging: () => void; +} diff --git a/x-pack/plugins/upgrade_assistant/public/application/lib/api.ts b/x-pack/plugins/upgrade_assistant/public/application/lib/api.ts index 063b53fecb98..1b22d26ea721 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/lib/api.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/lib/api.ts @@ -63,7 +63,10 @@ export class ApiService { } public useLoadDeprecationLogging() { - return this.useRequest<{ isEnabled: boolean }>({ + return this.useRequest<{ + isDeprecationLogIndexingEnabled: boolean; + isDeprecationLoggingEnabled: boolean; + }>({ path: `${API_BASE_PATH}/deprecation_logging`, method: 'get', }); diff --git a/x-pack/plugins/upgrade_assistant/public/application/lib/utils.test.ts b/x-pack/plugins/upgrade_assistant/public/application/lib/utils.test.ts index deee019f2d13..83fc9cabbbec 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/lib/utils.test.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/lib/utils.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { validateRegExpString } from './utils'; +import { DEPRECATION_WARNING_UPPER_LIMIT } from '../../../common/constants'; +import { validateRegExpString, getDeprecationsUpperLimit } from './utils'; describe('validRegExpString', () => { it('correctly returns false for invalid strings', () => { @@ -20,3 +21,17 @@ describe('validRegExpString', () => { expect(validateRegExpString('')).toBe(''); }); }); + +describe('getDeprecationsUpperLimit', () => { + it('correctly returns capped number if it goes above limit', () => { + expect(getDeprecationsUpperLimit(1000000)).toBe(`${DEPRECATION_WARNING_UPPER_LIMIT}+`); + expect(getDeprecationsUpperLimit(2000000)).toBe(`${DEPRECATION_WARNING_UPPER_LIMIT}+`); + }); + + it('correctly returns true for valid strings', () => { + expect(getDeprecationsUpperLimit(10)).toBe('10'); + expect(getDeprecationsUpperLimit(DEPRECATION_WARNING_UPPER_LIMIT)).toBe( + DEPRECATION_WARNING_UPPER_LIMIT.toString() + ); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/public/application/lib/utils.ts b/x-pack/plugins/upgrade_assistant/public/application/lib/utils.ts index b7fe435cb254..b90038e1166a 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/lib/utils.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/lib/utils.ts @@ -8,6 +8,8 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { tryCatch, fold } from 'fp-ts/lib/Either'; +import { DEPRECATION_WARNING_UPPER_LIMIT } from '../../../common/constants'; + export const validateRegExpString = (s: string) => pipe( tryCatch( @@ -19,3 +21,16 @@ export const validateRegExpString = (s: string) => () => '' ) ); + +/* + * There isnt much difference between having 1M or 1.1M deprecation warnings, the number is + * so big it beats the purpose of having a little preview of the count. With this we can also + * prevent the container of the value to grow due to the value being so large. + */ +export const getDeprecationsUpperLimit = (count: number) => { + if (count > DEPRECATION_WARNING_UPPER_LIMIT) { + return `${DEPRECATION_WARNING_UPPER_LIMIT}+`; + } + + return count.toString(); +}; diff --git a/x-pack/plugins/upgrade_assistant/public/application/mount_management_section.ts b/x-pack/plugins/upgrade_assistant/public/application/mount_management_section.ts index 8cd9f8b6591e..9fa52e90c9d0 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/mount_management_section.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/mount_management_section.ts @@ -11,12 +11,14 @@ import { renderApp } from './render_app'; import { KibanaVersionContext } from './app_context'; import { apiService } from './lib/api'; import { breadcrumbService } from './lib/breadcrumbs'; +import { AppServicesContext } from '../types'; export async function mountManagementSection( coreSetup: CoreSetup, params: ManagementAppMountParams, kibanaVersionInfo: KibanaVersionContext, - readonly: boolean + readonly: boolean, + services: AppServicesContext ) { const [ { i18n, docLinks, notifications, application, deprecations }, @@ -41,5 +43,7 @@ export async function mountManagementSection( breadcrumbs: breadcrumbService, getUrlForApp: application.getUrlForApp, deprecations, + application, + services, }); } diff --git a/x-pack/plugins/upgrade_assistant/public/plugin.ts b/x-pack/plugins/upgrade_assistant/public/plugin.ts index 4cffd40faf38..558deffe43d9 100644 --- a/x-pack/plugins/upgrade_assistant/public/plugin.ts +++ b/x-pack/plugins/upgrade_assistant/public/plugin.ts @@ -9,17 +9,13 @@ import SemVer from 'semver/classes/semver'; import { i18n } from '@kbn/i18n'; import { Plugin, CoreSetup, PluginInitializerContext } from 'src/core/public'; -import { ManagementSetup } from '../../../../src/plugins/management/public'; - +import { SetupDependencies, StartDependencies, AppServicesContext } from './types'; import { Config } from '../common/config'; -interface Dependencies { - management: ManagementSetup; -} - -export class UpgradeAssistantUIPlugin implements Plugin { +export class UpgradeAssistantUIPlugin + implements Plugin { constructor(private ctx: PluginInitializerContext) {} - setup(coreSetup: CoreSetup, { management }: Dependencies) { + setup(coreSetup: CoreSetup, { management, cloud }: SetupDependencies) { const { enabled, readonly } = this.ctx.config.get(); if (!enabled) { @@ -45,7 +41,8 @@ export class UpgradeAssistantUIPlugin implements Plugin { title: pluginName, order: 1, async mount(params) { - const [coreStart] = await coreSetup.getStartServices(); + const [coreStart, { discover, data }] = await coreSetup.getStartServices(); + const services: AppServicesContext = { discover, data, cloud }; const { chrome: { docTitle }, @@ -58,7 +55,8 @@ export class UpgradeAssistantUIPlugin implements Plugin { coreSetup, params, kibanaVersionInfo, - readonly + readonly, + services ); return () => { diff --git a/x-pack/plugins/upgrade_assistant/public/shared_imports.ts b/x-pack/plugins/upgrade_assistant/public/shared_imports.ts index 9007fdc5db04..c3ffd44662ec 100644 --- a/x-pack/plugins/upgrade_assistant/public/shared_imports.ts +++ b/x-pack/plugins/upgrade_assistant/public/shared_imports.ts @@ -5,6 +5,9 @@ * 2.0. */ +import { useKibana as _useKibana } from '../../../../src/plugins/kibana_react/public'; +import { AppServicesContext } from './types'; + export { sendRequest, SendRequestConfig, @@ -13,3 +16,9 @@ export { UseRequestConfig, SectionLoading, } from '../../../../src/plugins/es_ui_shared/public/'; + +export { KibanaContextProvider } from '../../../../src/plugins/kibana_react/public'; + +export { DataPublicPluginStart } from '../../../../src/plugins/data/public'; + +export const useKibana = () => _useKibana(); diff --git a/x-pack/plugins/upgrade_assistant/public/types.ts b/x-pack/plugins/upgrade_assistant/public/types.ts new file mode 100644 index 000000000000..a2b49305c32d --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/types.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DiscoverStart } from 'src/plugins/discover/public'; +import { ManagementSetup } from 'src/plugins/management/public'; +import { DataPublicPluginStart } from 'src/plugins/data/public'; +import { CloudSetup } from '../../cloud/public'; +import { LicensingPluginStart } from '../../licensing/public'; + +export interface AppServicesContext { + cloud?: CloudSetup; + discover: DiscoverStart; + data: DataPublicPluginStart; +} + +export interface SetupDependencies { + management: ManagementSetup; + cloud?: CloudSetup; +} +export interface StartDependencies { + licensing: LicensingPluginStart; + discover: DiscoverStart; + data: DataPublicPluginStart; +} diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts index b9595d2b0bb6..0e01d8d6a345 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts @@ -10,6 +10,7 @@ import { getDeprecationLoggingStatus, isDeprecationLoggingEnabled, setDeprecationLogging, + isDeprecationLogIndexingEnabled, } from './es_deprecation_logging_apis'; describe('getDeprecationLoggingStatus', () => { @@ -28,7 +29,16 @@ describe('setDeprecationLogging', () => { const dataClient = elasticsearchServiceMock.createScopedClusterClient(); await setDeprecationLogging(dataClient, true); expect(dataClient.asCurrentUser.cluster.putSettings).toHaveBeenCalledWith({ - body: { transient: { 'logger.deprecation': 'WARN' } }, + body: { + persistent: { + 'logger.deprecation': 'WARN', + 'cluster.deprecation_indexing.enabled': true, + }, + transient: { + 'logger.deprecation': 'WARN', + 'cluster.deprecation_indexing.enabled': true, + }, + }, }); }); }); @@ -38,7 +48,16 @@ describe('setDeprecationLogging', () => { const dataClient = elasticsearchServiceMock.createScopedClusterClient(); await setDeprecationLogging(dataClient, false); expect(dataClient.asCurrentUser.cluster.putSettings).toHaveBeenCalledWith({ - body: { transient: { 'logger.deprecation': 'ERROR' } }, + body: { + persistent: { + 'logger.deprecation': 'ERROR', + 'cluster.deprecation_indexing.enabled': false, + }, + transient: { + 'logger.deprecation': 'ERROR', + 'cluster.deprecation_indexing.enabled': false, + }, + }, }); }); }); @@ -84,3 +103,24 @@ describe('isDeprecationLoggingEnabled', () => { ).toBe(true); }); }); + +describe('isDeprecationLogIndexingEnabled', () => { + it('allows transient to override persistent and default', () => { + expect( + isDeprecationLogIndexingEnabled({ + default: { cluster: { deprecation_indexing: { enabled: 'false' } } }, + persistent: { cluster: { deprecation_indexing: { enabled: 'false' } } }, + transient: { cluster: { deprecation_indexing: { enabled: 'true' } } }, + }) + ).toBe(true); + }); + + it('allows persistent to override default', () => { + expect( + isDeprecationLogIndexingEnabled({ + default: { cluster: { deprecation_indexing: { enabled: 'false' } } }, + persistent: { cluster: { deprecation_indexing: { enabled: 'true' } } }, + }) + ).toBe(true); + }); +}); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts index 5b1900b881d4..214aabb98992 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts @@ -7,10 +7,7 @@ import { get } from 'lodash'; import { IScopedClusterClient } from 'src/core/server'; - -interface DeprecationLoggingStatus { - isEnabled: boolean; -} +import { DeprecationLoggingStatus } from '../../common/types'; export async function getDeprecationLoggingStatus( dataClient: IScopedClusterClient @@ -20,7 +17,8 @@ export async function getDeprecationLoggingStatus( }); return { - isEnabled: isDeprecationLoggingEnabled(response), + isDeprecationLogIndexingEnabled: isDeprecationLogIndexingEnabled(response), + isDeprecationLoggingEnabled: isDeprecationLoggingEnabled(response), }; } @@ -30,17 +28,38 @@ export async function setDeprecationLogging( ): Promise { const { body: response } = await dataClient.asCurrentUser.cluster.putSettings({ body: { + persistent: { + 'logger.deprecation': isEnabled ? 'WARN' : 'ERROR', + 'cluster.deprecation_indexing.enabled': isEnabled, + }, + /* + * If we only set the persistent setting, we can end up in a situation in which a user has + * set transient on/off. And when toggling and reloading the page the transient setting will + * have priority over it thus "overriding" whatever the user selected. + */ transient: { 'logger.deprecation': isEnabled ? 'WARN' : 'ERROR', + 'cluster.deprecation_indexing.enabled': isEnabled, }, }, }); return { - isEnabled: isDeprecationLoggingEnabled(response), + isDeprecationLogIndexingEnabled: isEnabled, + isDeprecationLoggingEnabled: isDeprecationLoggingEnabled(response), }; } +export function isDeprecationLogIndexingEnabled(settings: any) { + const clusterDeprecationLoggingEnabled = ['default', 'persistent', 'transient'].reduce( + (currentLogLevel, settingsTier) => + get(settings, [settingsTier, 'cluster', 'deprecation_indexing', 'enabled'], currentLogLevel), + 'false' + ); + + return clusterDeprecationLoggingEnabled === 'true'; +} + export function isDeprecationLoggingEnabled(settings: any) { const deprecationLogLevel = ['default', 'persistent', 'transient'].reduce( (currentLogLevel, settingsTier) => diff --git a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts index 30195f6652fb..2227139c53cd 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts @@ -31,6 +31,11 @@ describe('Upgrade Assistant Usage Collector', () => { logger: { deprecation: 'WARN', }, + cluster: { + deprecation_indexing: { + enabled: 'true', + }, + }, }, }, }); diff --git a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts index 564cd69c042b..a6253ab1091d 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts @@ -20,7 +20,10 @@ import { UpgradeAssistantTelemetrySavedObject, UpgradeAssistantTelemetrySavedObjectAttributes, } from '../../../common/types'; -import { isDeprecationLoggingEnabled } from '../es_deprecation_logging_apis'; +import { + isDeprecationLogIndexingEnabled, + isDeprecationLoggingEnabled, +} from '../es_deprecation_logging_apis'; async function getSavedObjectAttributesFromRepo( savedObjectsRepository: ISavedObjectsRepository, @@ -45,7 +48,10 @@ async function getDeprecationLoggingStatusValue(esClient: ElasticsearchClient): include_defaults: true, }); - return isDeprecationLoggingEnabled(loggerDeprecationCallResult); + return ( + isDeprecationLogIndexingEnabled(loggerDeprecationCallResult) && + isDeprecationLoggingEnabled(loggerDeprecationCallResult) + ); } catch (e) { return false; } diff --git a/x-pack/plugins/upgrade_assistant/server/plugin.ts b/x-pack/plugins/upgrade_assistant/server/plugin.ts index 8fb677feabd1..870bd6b98566 100644 --- a/x-pack/plugins/upgrade_assistant/server/plugin.ts +++ b/x-pack/plugins/upgrade_assistant/server/plugin.ts @@ -16,6 +16,7 @@ import { SavedObjectsClient, SavedObjectsServiceStart, } from '../../../../src/core/server'; +import { InfraPluginSetup } from '../../infra/server'; import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; import { LicensingPluginSetup } from '../../licensing/server'; @@ -31,6 +32,7 @@ import { reindexOperationSavedObjectType, mlSavedObjectType, } from './saved_object_types'; +import { DEPRECATION_LOGS_SOURCE_ID, DEPRECATION_LOGS_INDEX_PATTERN } from '../common/constants'; import { RouteDependencies } from './types'; @@ -38,6 +40,7 @@ interface PluginsSetup { usageCollection: UsageCollectionSetup; licensing: LicensingPluginSetup; features: FeaturesPluginSetup; + infra: InfraPluginSetup; } export class UpgradeAssistantServerPlugin implements Plugin { @@ -66,8 +69,8 @@ export class UpgradeAssistantServerPlugin implements Plugin { } setup( - { http, getStartServices, capabilities, savedObjects }: CoreSetup, - { usageCollection, features, licensing }: PluginsSetup + { http, getStartServices, savedObjects }: CoreSetup, + { usageCollection, features, licensing, infra }: PluginsSetup ) { this.licensing = licensing; @@ -88,6 +91,21 @@ export class UpgradeAssistantServerPlugin implements Plugin { ], }); + // We need to initialize the deprecation logs plugin so that we can + // navigate from this app to the observability app using a source_id. + infra.defineInternalSourceConfiguration(DEPRECATION_LOGS_SOURCE_ID, { + name: 'deprecationLogs', + description: 'deprecation logs', + logIndices: { + type: 'index_name', + indexName: DEPRECATION_LOGS_INDEX_PATTERN, + }, + logColumns: [ + { timestampColumn: { id: 'timestampField' } }, + { messageColumn: { id: 'messageField' } }, + ], + }); + const router = http.createRouter(); const dependencies: RouteDependencies = { diff --git a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts index 0b595df0dc8c..e146415b1ccf 100644 --- a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts @@ -37,18 +37,26 @@ describe('deprecation logging API', () => { }); describe('GET /api/upgrade_assistant/deprecation_logging', () => { - it('returns isEnabled', async () => { + it('returns that indexing and writing logs is enabled', async () => { (routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.cluster .getSettings as jest.Mock).mockResolvedValue({ - body: { default: { logger: { deprecation: 'WARN' } } }, + body: { + default: { + cluster: { deprecation_indexing: { enabled: 'true' } }, + }, + }, }); + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/deprecation_logging', })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); expect(resp.status).toEqual(200); - expect(resp.payload).toEqual({ isEnabled: true }); + expect(resp.payload).toEqual({ + isDeprecationLogIndexingEnabled: true, + isDeprecationLoggingEnabled: true, + }); }); it('returns an error if it throws', async () => { @@ -64,17 +72,26 @@ describe('deprecation logging API', () => { }); describe('PUT /api/upgrade_assistant/deprecation_logging', () => { - it('returns isEnabled', async () => { + it('returns that indexing and writing logs is enabled', async () => { (routeHandlerContextMock.core.elasticsearch.client.asCurrentUser.cluster .putSettings as jest.Mock).mockResolvedValue({ - body: { default: { logger: { deprecation: 'ERROR' } } }, + body: { + default: { + logger: { deprecation: 'WARN' }, + cluster: { deprecation_indexing: { enabled: 'true' } }, + }, + }, }); + const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/deprecation_logging', })(routeHandlerContextMock, { body: { isEnabled: true } }, kibanaResponseFactory); - expect(resp.payload).toEqual({ isEnabled: false }); + expect(resp.payload).toEqual({ + isDeprecationLogIndexingEnabled: true, + isDeprecationLoggingEnabled: true, + }); }); it('returns an error if it throws', async () => { diff --git a/x-pack/plugins/upgrade_assistant/tsconfig.json b/x-pack/plugins/upgrade_assistant/tsconfig.json index 33a1421fbb0c..39d7404ebea9 100644 --- a/x-pack/plugins/upgrade_assistant/tsconfig.json +++ b/x-pack/plugins/upgrade_assistant/tsconfig.json @@ -22,5 +22,7 @@ { "path": "../features/tsconfig.json" }, { "path": "../licensing/tsconfig.json" }, { "path": "../../../src/plugins/es_ui_shared/tsconfig.json" }, + { "path": "../infra/tsconfig.json" }, + { "path": "../cloud/tsconfig.json" }, ] }