Skip to content

Commit

Permalink
add deprecation warning for legacy 3rd party plugins (#62401)
Browse files Browse the repository at this point in the history
* add warnings for legacy 3rd party plugins

* use published doc page for 8.0 breaking changes

* update message to remove fixed 8.0 version reference

* fix generated doc
  • Loading branch information
pgayvallet committed Apr 17, 2020
1 parent 5f3595b commit b58c224
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 8 deletions.
7 changes: 6 additions & 1 deletion src/core/server/legacy/legacy_service.test.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}));
37 changes: 36 additions & 1 deletion src/core/server/legacy/legacy_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -476,6 +479,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 () => {
Expand Down
7 changes: 6 additions & 1 deletion src/core/server/legacy/legacy_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -133,6 +133,11 @@ export class LegacyService implements CoreService {
this.coreContext.env.packageInfo
);

logLegacyThirdPartyPluginDeprecationWarning({
specs: pluginSpecs,
log: this.log,
});

this.legacyPlugins = {
pluginSpecs,
disabledPluginSpecs,
Expand Down
1 change: 1 addition & 0 deletions src/core/server/legacy/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
*/

export { findLegacyPluginSpecs } from './find_legacy_plugin_specs';
export { logLegacyThirdPartyPluginDeprecationWarning } from './log_legacy_plugins_warning';
90 changes: 90 additions & 0 deletions src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts
Original file line number Diff line number Diff line change
@@ -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<typeof loggerMock.create>;

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 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.",
]
`);
});

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 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.",
]
`);
});

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();
});
});
52 changes: 52 additions & 0 deletions src/core/server/legacy/plugins/log_legacy_plugins_warning.ts
Original file line number Diff line number Diff line change
@@ -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://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 = ({
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 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.`
);
}
};

const isThirdPartyPluginSpec = (spec: LegacyPluginSpec): boolean => {
const pluginPath = spec.getPack().getPath();
return !internalPaths.some(internalPath => pluginPath.indexOf(internalPath) > -1);
};
1 change: 1 addition & 0 deletions src/core/server/legacy/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export interface LegacyPluginSpec {
getExpectedKibanaVersion: () => string;
getConfigPrefix: () => string;
getDeprecationsProvider: () => LegacyConfigDeprecationProvider | undefined;
getPack: () => LegacyPluginPack;
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/core/server/server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2468,11 +2468,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/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
Expand Down

0 comments on commit b58c224

Please sign in to comment.