From d5852165b373ad8103a139dce224bcf007da3721 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 3 Apr 2020 09:44:13 +0200 Subject: [PATCH 1/4] add warnings for legacy 3rd party plugins --- .../legacy/legacy_service.test.mocks.ts | 7 +- src/core/server/legacy/legacy_service.test.ts | 37 +++++++- src/core/server/legacy/legacy_service.ts | 7 +- src/core/server/legacy/plugins/index.ts | 1 + .../log_legacy_plugins_warning.test.ts | 90 +++++++++++++++++++ .../plugins/log_legacy_plugins_warning.ts | 52 +++++++++++ src/core/server/legacy/types.ts | 1 + src/core/server/server.api.md | 10 +-- 8 files changed, 197 insertions(+), 8 deletions(-) create mode 100644 src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts create mode 100644 src/core/server/legacy/plugins/log_legacy_plugins_warning.ts diff --git a/src/core/server/legacy/legacy_service.test.mocks.ts b/src/core/server/legacy/legacy_service.test.mocks.ts index 451a75ced7ae29..9ad554d63add08 100644 --- a/src/core/server/legacy/legacy_service.test.mocks.ts +++ b/src/core/server/legacy/legacy_service.test.mocks.ts @@ -30,6 +30,11 @@ export const findLegacyPluginSpecsMock = jest.fn().mockImplementation((settings: uiExports: {}, navLinks: [], })); -jest.doMock('./plugins/find_legacy_plugin_specs.ts', () => ({ +jest.doMock('./plugins/find_legacy_plugin_specs', () => ({ findLegacyPluginSpecs: findLegacyPluginSpecsMock, })); + +export const logLegacyThirdPartyPluginDeprecationWarningMock = jest.fn(); +jest.doMock('./plugins/log_legacy_plugins_warning', () => ({ + logLegacyThirdPartyPluginDeprecationWarning: logLegacyThirdPartyPluginDeprecationWarningMock, +})); diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts index c6860086e77842..ebf873aa8f435c 100644 --- a/src/core/server/legacy/legacy_service.test.ts +++ b/src/core/server/legacy/legacy_service.test.ts @@ -22,7 +22,10 @@ jest.mock('../../../cli/cluster/cluster_manager'); jest.mock('./config/legacy_deprecation_adapters', () => ({ convertLegacyDeprecationProvider: (provider: any) => Promise.resolve(provider), })); -import { findLegacyPluginSpecsMock } from './legacy_service.test.mocks'; +import { + findLegacyPluginSpecsMock, + logLegacyThirdPartyPluginDeprecationWarningMock, +} from './legacy_service.test.mocks'; import { BehaviorSubject, throwError } from 'rxjs'; @@ -472,6 +475,38 @@ describe('#discoverPlugins()', () => { expect(configService.addDeprecationProvider).toHaveBeenCalledWith('', 'providerA'); expect(configService.addDeprecationProvider).toHaveBeenCalledWith('', 'providerB'); }); + + it(`logs deprecations for legacy third party plugins`, async () => { + const pluginSpecs = [ + { getId: () => 'pluginA', getDeprecationsProvider: () => undefined }, + { getId: () => 'pluginB', getDeprecationsProvider: () => undefined }, + ]; + findLegacyPluginSpecsMock.mockImplementation( + settings => + Promise.resolve({ + pluginSpecs, + pluginExtendedConfig: settings, + disabledPluginSpecs: [], + uiExports: {}, + navLinks: [], + }) as any + ); + + const legacyService = new LegacyService({ + coreId, + env, + logger, + configService: configService as any, + }); + + await legacyService.discoverPlugins(); + + expect(logLegacyThirdPartyPluginDeprecationWarningMock).toHaveBeenCalledTimes(1); + expect(logLegacyThirdPartyPluginDeprecationWarningMock).toHaveBeenCalledWith({ + specs: pluginSpecs, + log: expect.any(Object), + }); + }); }); test('Sets the server.uuid property on the legacy configuration', async () => { diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index bb5f6d5617aaea..ea9b2c4c496f99 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -28,7 +28,7 @@ import { DevConfig, DevConfigType, config as devConfig } from '../dev'; import { BasePathProxyServer, HttpConfig, HttpConfigType, config as httpConfig } from '../http'; import { Logger } from '../logging'; import { PathConfigType } from '../path'; -import { findLegacyPluginSpecs } from './plugins'; +import { findLegacyPluginSpecs, logLegacyThirdPartyPluginDeprecationWarning } from './plugins'; import { convertLegacyDeprecationProvider } from './config'; import { ILegacyInternals, @@ -133,6 +133,11 @@ export class LegacyService implements CoreService { this.coreContext.env.packageInfo ); + logLegacyThirdPartyPluginDeprecationWarning({ + specs: pluginSpecs, + log: this.log, + }); + this.legacyPlugins = { pluginSpecs, disabledPluginSpecs, diff --git a/src/core/server/legacy/plugins/index.ts b/src/core/server/legacy/plugins/index.ts index a6d55e1da78390..7ec5dbc1983ab9 100644 --- a/src/core/server/legacy/plugins/index.ts +++ b/src/core/server/legacy/plugins/index.ts @@ -18,3 +18,4 @@ */ export { findLegacyPluginSpecs } from './find_legacy_plugin_specs'; +export { logLegacyThirdPartyPluginDeprecationWarning } from './log_legacy_plugins_warning'; diff --git a/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts b/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts new file mode 100644 index 00000000000000..df479162d1e610 --- /dev/null +++ b/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts @@ -0,0 +1,90 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { loggerMock } from '../../logging/logger.mock'; +import { logLegacyThirdPartyPluginDeprecationWarning } from './log_legacy_plugins_warning'; +import { LegacyPluginSpec } from '../types'; + +const createPluginSpec = ({ id, path }: { id: string; path: string }): LegacyPluginSpec => { + return { + getId: () => id, + getExpectedKibanaVersion: () => 'kibana', + getConfigPrefix: () => 'plugin.config', + getDeprecationsProvider: () => undefined, + getPack: () => ({ + getPath: () => path, + }), + }; +}; + +describe('logLegacyThirdPartyPluginDeprecationWarning', () => { + let log: ReturnType; + + beforeEach(() => { + log = loggerMock.create(); + }); + + it('logs warning for third party plugins', () => { + logLegacyThirdPartyPluginDeprecationWarning({ + specs: [createPluginSpec({ id: 'plugin', path: '/some-external-path' })], + log, + }); + expect(log.warn).toHaveBeenCalledTimes(1); + expect(log.warn.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "Some installed third party plugin(s) [plugin] are using the legacy plugin format and will no longer work after version 8.0. Please refer to https://github.com/elastic/kibana/blob/master/docs/migration/migrate_8_0.asciidoc for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", + ] + `); + }); + + it('lists all the deprecated plugins and only log once', () => { + logLegacyThirdPartyPluginDeprecationWarning({ + specs: [ + createPluginSpec({ id: 'pluginA', path: '/abs/path/to/pluginA' }), + createPluginSpec({ id: 'pluginB', path: '/abs/path/to/pluginB' }), + createPluginSpec({ id: 'pluginC', path: '/abs/path/to/pluginC' }), + ], + log, + }); + expect(log.warn).toHaveBeenCalledTimes(1); + expect(log.warn.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "Some installed third party plugin(s) [pluginA, pluginB, pluginC] are using the legacy plugin format and will no longer work after version 8.0. Please refer to https://github.com/elastic/kibana/blob/master/docs/migration/migrate_8_0.asciidoc for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", + ] + `); + }); + + it('does not log warning for internal legacy plugins', () => { + logLegacyThirdPartyPluginDeprecationWarning({ + specs: [ + createPluginSpec({ + id: 'plugin', + path: '/absolute/path/to/kibana/src/legacy/core_plugins', + }), + createPluginSpec({ + id: 'plugin', + path: '/absolute/path/to/kibana/x-pack', + }), + ], + log, + }); + + expect(log.warn).not.toHaveBeenCalled(); + }); +}); diff --git a/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts b/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts new file mode 100644 index 00000000000000..8309e0e7cb7133 --- /dev/null +++ b/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts @@ -0,0 +1,52 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Logger } from '../../logging'; +import { LegacyPluginSpec } from '../types'; + +const internalPaths = ['/src/legacy/core_plugins', '/x-pack']; + +const breakingChangesUrl = + 'https://github.com/elastic/kibana/blob/master/docs/migration/migrate_8_0.asciidoc'; +const migrationGuideUrl = 'https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md'; + +export const logLegacyThirdPartyPluginDeprecationWarning = ({ + specs, + log, +}: { + specs: LegacyPluginSpec[]; + log: Logger; +}) => { + const thirdPartySpecs = specs.filter(isThirdPartyPluginSpec); + if (thirdPartySpecs.length > 0) { + const pluginIds = thirdPartySpecs.map(spec => spec.getId()); + log.warn( + `Some installed third party plugin(s) [${pluginIds.join( + ', ' + )}] are using the legacy plugin format and will no longer work after version 8.0. ` + + `Please refer to ${breakingChangesUrl} for a list of breaking changes ` + + `and ${migrationGuideUrl} for documentation on how to migrate legacy plugins.` + ); + } +}; + +const isThirdPartyPluginSpec = (spec: LegacyPluginSpec): boolean => { + const pluginPath = spec.getPack().getPath(); + return !internalPaths.some(internalPath => pluginPath.indexOf(internalPath) > -1); +}; diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts index 0c1a7730f92a77..b24e7389eff136 100644 --- a/src/core/server/legacy/types.ts +++ b/src/core/server/legacy/types.ts @@ -98,6 +98,7 @@ export interface LegacyPluginSpec { getExpectedKibanaVersion: () => string; getConfigPrefix: () => string; getDeprecationsProvider: () => LegacyConfigDeprecationProvider | undefined; + getPack: () => LegacyPluginPack; } /** diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index e4e2b8d7adbb77..678492e6fe2b76 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -2344,11 +2344,11 @@ export const validBodyOutput: readonly ["data", "stream"]; // Warnings were encountered during analysis: // // src/core/server/http/router/response.ts:316:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:162:3 - (ae-forgotten-export) The symbol "VarsProvider" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:163:3 - (ae-forgotten-export) The symbol "VarsReplacer" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:164:3 - (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:165:3 - (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts -// src/core/server/legacy/types.ts:166:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts +// src/core/server/legacy/types.ts:163:3 - (ae-forgotten-export) The symbol "VarsProvider" needs to be exported by the entry point index.d.ts +// src/core/server/legacy/types.ts:164:3 - (ae-forgotten-export) The symbol "VarsReplacer" needs to be exported by the entry point index.d.ts +// src/core/server/legacy/types.ts:165:3 - (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts +// src/core/server/legacy/types.ts:166:3 - (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts +// src/core/server/legacy/types.ts:167:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts // src/core/server/plugins/plugins_service.ts:47:5 - (ae-forgotten-export) The symbol "InternalPluginInfo" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:230:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:230:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts From ed8172288da111a9166236ec5ace81bd14d710f4 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Sat, 11 Apr 2020 11:27:55 +0200 Subject: [PATCH 2/4] use published doc page for 8.0 breaking changes --- .../server/legacy/plugins/log_legacy_plugins_warning.test.ts | 4 ++-- src/core/server/legacy/plugins/log_legacy_plugins_warning.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts b/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts index df479162d1e610..bf82803ffae25b 100644 --- a/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts +++ b/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts @@ -48,7 +48,7 @@ describe('logLegacyThirdPartyPluginDeprecationWarning', () => { expect(log.warn).toHaveBeenCalledTimes(1); expect(log.warn.mock.calls[0]).toMatchInlineSnapshot(` Array [ - "Some installed third party plugin(s) [plugin] are using the legacy plugin format and will no longer work after version 8.0. Please refer to https://github.com/elastic/kibana/blob/master/docs/migration/migrate_8_0.asciidoc for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", + "Some installed third party plugin(s) [plugin] are using the legacy plugin format and will no longer work after version 8.0. Please refer to https://www.elastic.co/guide/en/kibana/master/breaking-changes-8.0.html for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", ] `); }); @@ -65,7 +65,7 @@ describe('logLegacyThirdPartyPluginDeprecationWarning', () => { expect(log.warn).toHaveBeenCalledTimes(1); expect(log.warn.mock.calls[0]).toMatchInlineSnapshot(` Array [ - "Some installed third party plugin(s) [pluginA, pluginB, pluginC] are using the legacy plugin format and will no longer work after version 8.0. Please refer to https://github.com/elastic/kibana/blob/master/docs/migration/migrate_8_0.asciidoc for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", + "Some installed third party plugin(s) [pluginA, pluginB, pluginC] are using the legacy plugin format and will no longer work after version 8.0. Please refer to https://www.elastic.co/guide/en/kibana/master/breaking-changes-8.0.html for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", ] `); }); diff --git a/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts b/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts index 8309e0e7cb7133..d655dbbbfd67b7 100644 --- a/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts +++ b/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts @@ -23,7 +23,7 @@ import { LegacyPluginSpec } from '../types'; const internalPaths = ['/src/legacy/core_plugins', '/x-pack']; const breakingChangesUrl = - 'https://github.com/elastic/kibana/blob/master/docs/migration/migrate_8_0.asciidoc'; + 'https://www.elastic.co/guide/en/kibana/master/breaking-changes-8.0.html'; const migrationGuideUrl = 'https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md'; export const logLegacyThirdPartyPluginDeprecationWarning = ({ From 3eb038211bac91845276312b5cf77009cd55b504 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 14 Apr 2020 16:32:44 +0200 Subject: [PATCH 3/4] update message to remove fixed 8.0 version reference --- .../server/legacy/plugins/log_legacy_plugins_warning.test.ts | 4 ++-- src/core/server/legacy/plugins/log_legacy_plugins_warning.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts b/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts index bf82803ffae25b..1790b096a71aea 100644 --- a/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts +++ b/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts @@ -48,7 +48,7 @@ describe('logLegacyThirdPartyPluginDeprecationWarning', () => { expect(log.warn).toHaveBeenCalledTimes(1); expect(log.warn.mock.calls[0]).toMatchInlineSnapshot(` Array [ - "Some installed third party plugin(s) [plugin] are using the legacy plugin format and will no longer work after version 8.0. Please refer to https://www.elastic.co/guide/en/kibana/master/breaking-changes-8.0.html for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", + "Some installed third party plugin(s) [plugin] are using the legacy plugin format and will no longer work in a future Kibana release. Please refer to https://www.elastic.co/guide/en/kibana/master/breaking-changes-8.0.html for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", ] `); }); @@ -65,7 +65,7 @@ describe('logLegacyThirdPartyPluginDeprecationWarning', () => { expect(log.warn).toHaveBeenCalledTimes(1); expect(log.warn.mock.calls[0]).toMatchInlineSnapshot(` Array [ - "Some installed third party plugin(s) [pluginA, pluginB, pluginC] are using the legacy plugin format and will no longer work after version 8.0. Please refer to https://www.elastic.co/guide/en/kibana/master/breaking-changes-8.0.html for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", + "Some installed third party plugin(s) [pluginA, pluginB, pluginC] are using the legacy plugin format and will no longer work in a future Kibana release. Please refer to https://www.elastic.co/guide/en/kibana/master/breaking-changes-8.0.html for a list of breaking changes and https://github.com/elastic/kibana/blob/master/src/core/MIGRATION.md for documentation on how to migrate legacy plugins.", ] `); }); diff --git a/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts b/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts index d655dbbbfd67b7..f9c3dcbf554cb8 100644 --- a/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts +++ b/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts @@ -39,7 +39,7 @@ export const logLegacyThirdPartyPluginDeprecationWarning = ({ log.warn( `Some installed third party plugin(s) [${pluginIds.join( ', ' - )}] are using the legacy plugin format and will no longer work after version 8.0. ` + + )}] are using the legacy plugin format and will no longer work in a future Kibana release. ` + `Please refer to ${breakingChangesUrl} for a list of breaking changes ` + `and ${migrationGuideUrl} for documentation on how to migrate legacy plugins.` ); From 4cfab7d3481a7f94537c41477b29e3158d997de9 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 17 Apr 2020 09:10:02 +0200 Subject: [PATCH 4/4] fix generated doc --- src/core/server/server.api.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 61c0b8ea1f4f48..7ca5c75f19e8ff 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -2473,7 +2473,6 @@ export const validBodyOutput: readonly ["data", "stream"]; // src/core/server/legacy/types.ts:165:3 - (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts // src/core/server/legacy/types.ts:166:3 - (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts // src/core/server/legacy/types.ts:167:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/plugins_service.ts:47:5 - (ae-forgotten-export) The symbol "InternalPluginInfo" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:230:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:230:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:232:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts