From 0ac0df23b43747eee53ce77f89fff5db92016b37 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 16 Sep 2020 11:16:58 +0200 Subject: [PATCH 01/29] remove ALL the things. --- src/core/server/index.ts | 1 - .../config/ensure_valid_configuration.test.ts | 75 --- .../config/ensure_valid_configuration.ts | 50 -- .../config/get_unused_config_keys.test.ts | 220 -------- .../legacy/config/get_unused_config_keys.ts | 63 --- src/core/server/legacy/config/index.ts | 1 - src/core/server/legacy/index.ts | 2 +- src/core/server/legacy/legacy_internals.ts | 42 +- src/core/server/legacy/legacy_service.mock.ts | 17 +- .../legacy/legacy_service.test.mocks.ts | 40 -- src/core/server/legacy/legacy_service.test.ts | 91 +--- src/core/server/legacy/legacy_service.ts | 156 ++---- .../legacy/plugins/collect_ui_exports.js | 21 - .../plugins/find_legacy_plugin_specs.ts | 135 ----- src/core/server/legacy/plugins/index.ts | 21 - .../log_legacy_plugins_warning.test.ts | 89 ---- .../plugins/log_legacy_plugins_warning.ts | 53 -- src/core/server/legacy/types.ts | 50 -- .../server/rendering/rendering_service.tsx | 2 - src/core/server/rendering/types.ts | 3 - src/core/server/server.ts | 11 +- src/legacy/plugin_discovery/README.md | 148 ------ .../__tests__/find_plugin_specs.js | 219 -------- .../__tests__/fixtures/conflicts/foo/index.js | 27 - .../fixtures/conflicts/foo/package.json | 4 - .../__tests__/fixtures/plugins/bar/index.js | 29 - .../fixtures/plugins/bar/package.json | 4 - .../fixtures/plugins/broken/index.js | 22 - .../fixtures/plugins/broken/package1.json | 4 - .../__tests__/fixtures/plugins/foo/index.js | 24 - .../fixtures/plugins/foo/package.json | 4 - src/legacy/plugin_discovery/errors.js | 84 --- .../plugin_discovery/find_plugin_specs.js | 234 --------- src/legacy/plugin_discovery/index.js | 22 - .../__tests__/extend_config_service.js | 162 ------ .../plugin_config/__tests__/schema.js | 92 ---- .../plugin_config/__tests__/settings.js | 61 --- .../plugin_config/extend_config_service.js | 50 -- .../plugin_discovery/plugin_config/index.js | 20 - .../plugin_discovery/plugin_config/schema.js | 46 -- .../plugin_config/settings.js | 34 -- .../__tests__/reduce_export_specs.js | 75 --- .../plugin_discovery/plugin_exports/index.js | 20 - .../plugin_exports/reduce_export_specs.js | 47 -- .../plugin_pack/__tests__/create_pack.js | 85 --- .../fixtures/plugins/broken/package.json | 3 - .../fixtures/plugins/broken_code/index.js | 7 - .../fixtures/plugins/broken_code/package.json | 4 - .../fixtures/plugins/exports_number/index.js | 20 - .../plugins/exports_number/package.json | 4 - .../fixtures/plugins/exports_object/index.js | 22 - .../plugins/exports_object/package.json | 4 - .../fixtures/plugins/exports_string/index.js | 20 - .../plugins/exports_string/package.json | 4 - .../__tests__/fixtures/plugins/foo/index.js | 24 - .../fixtures/plugins/foo/package.json | 4 - .../__tests__/fixtures/plugins/index.js | 20 - .../__tests__/fixtures/plugins/lib/index.js | 20 - .../__tests__/fixtures/plugins/lib/my_lib.js | 22 - .../fixtures/plugins/prebuilt/index.js | 14 - .../fixtures/plugins/prebuilt/package.json | 3 - .../__tests__/package_json_at_path.js | 88 ---- .../__tests__/package_jsons_in_directory.js | 83 --- .../plugin_pack/__tests__/plugin_pack.js | 126 ----- .../plugin_pack/__tests__/utils.js | 37 -- .../plugin_pack/create_pack.js | 54 -- .../plugin_discovery/plugin_pack/index.js | 23 - .../plugin_discovery/plugin_pack/lib/fs.js | 85 --- .../plugin_discovery/plugin_pack/lib/index.js | 20 - .../plugin_pack/package_json_at_path.js | 62 --- .../plugin_pack/package_jsons_in_directory.js | 52 -- .../plugin_pack/plugin_pack.js | 74 --- .../__tests__/is_version_compatible.js | 48 -- .../plugin_spec/__tests__/plugin_spec.js | 496 ------------------ .../plugin_discovery/plugin_spec/index.js | 20 - .../plugin_spec/is_version_compatible.js | 30 -- .../plugin_spec/plugin_spec.js | 210 -------- .../plugin_spec/plugin_spec_options.d.ts | 35 -- src/legacy/plugin_discovery/types.ts | 107 ---- src/legacy/server/kbn_server.d.ts | 13 +- src/legacy/server/kbn_server.js | 21 +- src/legacy/server/plugins/index.js | 22 - src/legacy/server/plugins/initialize_mixin.js | 47 -- .../server/plugins/lib/call_plugin_hook.js | 50 -- .../plugins/lib/call_plugin_hook.test.js | 101 ---- src/legacy/server/plugins/lib/index.js | 21 - src/legacy/server/plugins/lib/plugin.js | 125 ----- src/legacy/server/plugins/scan_mixin.js | 23 - .../server/plugins/wait_for_plugins_init.js | 53 -- src/legacy/ui/index.js | 1 - src/legacy/ui/ui_exports/README.md | 95 ---- .../ui/ui_exports/collect_ui_exports.ts | 31 -- src/legacy/ui/ui_exports/index.js | 20 - .../ui/ui_exports/ui_export_defaults.js | 20 - .../ui/ui_exports/ui_export_types/index.js | 36 -- .../ui_export_types/modify_injected_vars.js | 32 -- .../ui_export_types/modify_reduce/alias.js | 28 - .../ui_export_types/modify_reduce/debug.js | 31 -- .../ui_export_types/modify_reduce/index.js | 24 - .../ui_export_types/modify_reduce/map_spec.js | 29 - .../modify_reduce/unique_keys.js | 32 -- .../ui_export_types/modify_reduce/wrap.js | 45 -- .../reduce/flat_concat_at_type.js | 28 - .../reduce/flat_concat_values_at_type.js | 30 -- .../ui_export_types/reduce/index.js | 22 - .../reduce/lib/create_type_reducer.js | 32 -- .../ui_export_types/reduce/lib/flat_concat.js | 27 - .../ui_export_types/reduce/lib/index.js | 22 - .../ui_export_types/reduce/lib/merge_with.js | 38 -- .../ui_export_types/reduce/merge_at_type.js | 25 - .../ui_export_types/saved_object.js | 65 --- .../ui_export_types/task_definitions.js | 24 - .../ui_export_types/ui_nav_links.js | 24 - .../ui_exports/ui_export_types/ui_settings.js | 23 - .../ui/ui_exports/ui_export_types/unknown.js | 23 - 115 files changed, 77 insertions(+), 5711 deletions(-) delete mode 100644 src/core/server/legacy/config/ensure_valid_configuration.test.ts delete mode 100644 src/core/server/legacy/config/ensure_valid_configuration.ts delete mode 100644 src/core/server/legacy/config/get_unused_config_keys.test.ts delete mode 100644 src/core/server/legacy/config/get_unused_config_keys.ts delete mode 100644 src/core/server/legacy/legacy_service.test.mocks.ts delete mode 100644 src/core/server/legacy/plugins/collect_ui_exports.js delete mode 100644 src/core/server/legacy/plugins/find_legacy_plugin_specs.ts delete mode 100644 src/core/server/legacy/plugins/index.ts delete mode 100644 src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts delete mode 100644 src/core/server/legacy/plugins/log_legacy_plugins_warning.ts delete mode 100644 src/legacy/plugin_discovery/README.md delete mode 100644 src/legacy/plugin_discovery/__tests__/find_plugin_specs.js delete mode 100644 src/legacy/plugin_discovery/__tests__/fixtures/conflicts/foo/index.js delete mode 100644 src/legacy/plugin_discovery/__tests__/fixtures/conflicts/foo/package.json delete mode 100644 src/legacy/plugin_discovery/__tests__/fixtures/plugins/bar/index.js delete mode 100644 src/legacy/plugin_discovery/__tests__/fixtures/plugins/bar/package.json delete mode 100644 src/legacy/plugin_discovery/__tests__/fixtures/plugins/broken/index.js delete mode 100644 src/legacy/plugin_discovery/__tests__/fixtures/plugins/broken/package1.json delete mode 100644 src/legacy/plugin_discovery/__tests__/fixtures/plugins/foo/index.js delete mode 100644 src/legacy/plugin_discovery/__tests__/fixtures/plugins/foo/package.json delete mode 100644 src/legacy/plugin_discovery/errors.js delete mode 100644 src/legacy/plugin_discovery/find_plugin_specs.js delete mode 100644 src/legacy/plugin_discovery/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_config/__tests__/extend_config_service.js delete mode 100644 src/legacy/plugin_discovery/plugin_config/__tests__/schema.js delete mode 100644 src/legacy/plugin_discovery/plugin_config/__tests__/settings.js delete mode 100644 src/legacy/plugin_discovery/plugin_config/extend_config_service.js delete mode 100644 src/legacy/plugin_discovery/plugin_config/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_config/schema.js delete mode 100644 src/legacy/plugin_discovery/plugin_config/settings.js delete mode 100644 src/legacy/plugin_discovery/plugin_exports/__tests__/reduce_export_specs.js delete mode 100644 src/legacy/plugin_discovery/plugin_exports/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_exports/reduce_export_specs.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/create_pack.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken/package.json delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken_code/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken_code/package.json delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_number/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_number/package.json delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_object/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_object/package.json delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_string/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_string/package.json delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/foo/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/foo/package.json delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/lib/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/lib/my_lib.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/prebuilt/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/prebuilt/package.json delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/package_json_at_path.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/package_jsons_in_directory.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/plugin_pack.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/__tests__/utils.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/create_pack.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/lib/fs.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/lib/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/package_json_at_path.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/package_jsons_in_directory.js delete mode 100644 src/legacy/plugin_discovery/plugin_pack/plugin_pack.js delete mode 100644 src/legacy/plugin_discovery/plugin_spec/__tests__/is_version_compatible.js delete mode 100644 src/legacy/plugin_discovery/plugin_spec/__tests__/plugin_spec.js delete mode 100644 src/legacy/plugin_discovery/plugin_spec/index.js delete mode 100644 src/legacy/plugin_discovery/plugin_spec/is_version_compatible.js delete mode 100644 src/legacy/plugin_discovery/plugin_spec/plugin_spec.js delete mode 100644 src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts delete mode 100644 src/legacy/plugin_discovery/types.ts delete mode 100644 src/legacy/server/plugins/index.js delete mode 100644 src/legacy/server/plugins/initialize_mixin.js delete mode 100644 src/legacy/server/plugins/lib/call_plugin_hook.js delete mode 100644 src/legacy/server/plugins/lib/call_plugin_hook.test.js delete mode 100644 src/legacy/server/plugins/lib/index.js delete mode 100644 src/legacy/server/plugins/lib/plugin.js delete mode 100644 src/legacy/server/plugins/scan_mixin.js delete mode 100644 src/legacy/server/plugins/wait_for_plugins_init.js delete mode 100644 src/legacy/ui/ui_exports/README.md delete mode 100644 src/legacy/ui/ui_exports/collect_ui_exports.ts delete mode 100644 src/legacy/ui/ui_exports/index.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_defaults.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/index.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/modify_injected_vars.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/modify_reduce/alias.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/modify_reduce/debug.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/modify_reduce/index.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/modify_reduce/map_spec.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/modify_reduce/unique_keys.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/modify_reduce/wrap.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/reduce/flat_concat_at_type.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/reduce/flat_concat_values_at_type.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/reduce/index.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/reduce/lib/create_type_reducer.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/reduce/lib/flat_concat.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/reduce/lib/index.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/reduce/lib/merge_with.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/reduce/merge_at_type.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/saved_object.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/task_definitions.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/ui_nav_links.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/ui_settings.js delete mode 100644 src/legacy/ui/ui_exports/ui_export_types/unknown.js diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 01797d073ae2e..605958be39b6d 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -340,7 +340,6 @@ export { export { LegacyServiceSetupDeps, LegacyServiceStartDeps, - LegacyServiceDiscoverPlugins, LegacyConfig, LegacyUiExports, LegacyInternals, diff --git a/src/core/server/legacy/config/ensure_valid_configuration.test.ts b/src/core/server/legacy/config/ensure_valid_configuration.test.ts deleted file mode 100644 index d8917b46eba62..0000000000000 --- a/src/core/server/legacy/config/ensure_valid_configuration.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 { ensureValidConfiguration } from './ensure_valid_configuration'; -import { getUnusedConfigKeys } from './get_unused_config_keys'; -import { configServiceMock } from '../../config/config_service.mock'; - -jest.mock('./get_unused_config_keys'); - -describe('ensureValidConfiguration', () => { - let configService: ReturnType; - - beforeEach(() => { - jest.clearAllMocks(); - configService = configServiceMock.create(); - configService.getUsedPaths.mockReturnValue(Promise.resolve(['core', 'elastic'])); - - (getUnusedConfigKeys as any).mockImplementation(() => []); - }); - - it('calls getUnusedConfigKeys with correct parameters', async () => { - await ensureValidConfiguration( - configService as any, - { - settings: 'settings', - pluginSpecs: 'pluginSpecs', - disabledPluginSpecs: 'disabledPluginSpecs', - pluginExtendedConfig: 'pluginExtendedConfig', - uiExports: 'uiExports', - } as any - ); - expect(getUnusedConfigKeys).toHaveBeenCalledTimes(1); - expect(getUnusedConfigKeys).toHaveBeenCalledWith({ - coreHandledConfigPaths: ['core', 'elastic'], - pluginSpecs: 'pluginSpecs', - disabledPluginSpecs: 'disabledPluginSpecs', - settings: 'settings', - legacyConfig: 'pluginExtendedConfig', - }); - }); - - it('returns normally when there is no unused keys', async () => { - await expect( - ensureValidConfiguration(configService as any, {} as any) - ).resolves.toBeUndefined(); - - expect(getUnusedConfigKeys).toHaveBeenCalledTimes(1); - }); - - it('throws when there are some unused keys', async () => { - (getUnusedConfigKeys as any).mockImplementation(() => ['some.key', 'some.other.key']); - - await expect( - ensureValidConfiguration(configService as any, {} as any) - ).rejects.toMatchInlineSnapshot( - `[Error: Unknown configuration key(s): "some.key", "some.other.key". Check for spelling errors and ensure that expected plugins are installed.]` - ); - }); -}); diff --git a/src/core/server/legacy/config/ensure_valid_configuration.ts b/src/core/server/legacy/config/ensure_valid_configuration.ts deleted file mode 100644 index 5cd1603ea65fb..0000000000000 --- a/src/core/server/legacy/config/ensure_valid_configuration.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 { getUnusedConfigKeys } from './get_unused_config_keys'; -import { ConfigService } from '../../config'; -import { LegacyServiceDiscoverPlugins } from '../types'; -import { CriticalError } from '../../errors'; - -export async function ensureValidConfiguration( - configService: ConfigService, - { pluginSpecs, disabledPluginSpecs, pluginExtendedConfig, settings }: LegacyServiceDiscoverPlugins -) { - const unusedConfigKeys = await getUnusedConfigKeys({ - coreHandledConfigPaths: await configService.getUsedPaths(), - pluginSpecs, - disabledPluginSpecs, - settings, - legacyConfig: pluginExtendedConfig, - }); - - if (unusedConfigKeys.length > 0) { - const message = `Unknown configuration key(s): ${unusedConfigKeys - .map((key) => `"${key}"`) - .join(', ')}. Check for spelling errors and ensure that expected plugins are installed.`; - throw new InvalidConfigurationError(message); - } -} - -class InvalidConfigurationError extends CriticalError { - constructor(message: string) { - super(message, 'InvalidConfig', 64); - Object.setPrototypeOf(this, InvalidConfigurationError.prototype); - } -} diff --git a/src/core/server/legacy/config/get_unused_config_keys.test.ts b/src/core/server/legacy/config/get_unused_config_keys.test.ts deleted file mode 100644 index f8506b5744030..0000000000000 --- a/src/core/server/legacy/config/get_unused_config_keys.test.ts +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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 { LegacyPluginSpec, LegacyConfig, LegacyVars } from '../types'; -import { getUnusedConfigKeys } from './get_unused_config_keys'; - -describe('getUnusedConfigKeys', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - const getConfig = (values: LegacyVars = {}): LegacyConfig => - ({ - get: () => values as any, - } as LegacyConfig); - - describe('not using core or plugin specs', () => { - it('should return an empty list for empty parameters', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: [], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: {}, - legacyConfig: getConfig(), - }) - ).toEqual([]); - }); - - it('returns empty list when config and settings have the same properties', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: [], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: { - presentInBoth: true, - alsoInBoth: 'someValue', - }, - legacyConfig: getConfig({ - presentInBoth: true, - alsoInBoth: 'someValue', - }), - }) - ).toEqual([]); - }); - - it('returns empty list when config has entries not present in settings', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: [], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: { - presentInBoth: true, - }, - legacyConfig: getConfig({ - presentInBoth: true, - onlyInConfig: 'someValue', - }), - }) - ).toEqual([]); - }); - - it('returns the list of properties from settings not present in config', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: [], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: { - presentInBoth: true, - onlyInSetting: 'value', - }, - legacyConfig: getConfig({ - presentInBoth: true, - }), - }) - ).toEqual(['onlyInSetting']); - }); - - it('correctly handle nested properties', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: [], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: { - elasticsearch: { - username: 'foo', - password: 'bar', - }, - }, - legacyConfig: getConfig({ - elasticsearch: { - username: 'foo', - onlyInConfig: 'default', - }, - }), - }) - ).toEqual(['elasticsearch.password']); - }); - - it('correctly handle "env" specific case', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: [], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: { - env: 'development', - }, - legacyConfig: getConfig({ - env: { - name: 'development', - }, - }), - }) - ).toEqual([]); - }); - - it('correctly handle array properties', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: [], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: { - prop: ['a', 'b', 'c'], - }, - legacyConfig: getConfig({ - prop: ['a'], - }), - }) - ).toEqual([]); - }); - }); - - it('ignores config for plugins that are disabled', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: [], - pluginSpecs: [], - disabledPluginSpecs: [ - ({ - id: 'foo', - getConfigPrefix: () => 'foo.bar', - } as unknown) as LegacyPluginSpec, - ], - settings: { - foo: { - bar: { - unused: true, - }, - }, - plugin: { - missingProp: false, - }, - }, - legacyConfig: getConfig({ - prop: 'a', - }), - }) - ).toEqual(['plugin.missingProp']); - }); - - it('ignores properties managed by the new platform', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: ['core', 'foo.bar'], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: { - core: { - prop: 'value', - }, - foo: { - bar: true, - dolly: true, - }, - }, - legacyConfig: getConfig({}), - }) - ).toEqual(['foo.dolly']); - }); - - it('handles array values', async () => { - expect( - await getUnusedConfigKeys({ - coreHandledConfigPaths: ['core', 'array'], - pluginSpecs: [], - disabledPluginSpecs: [], - settings: { - core: { - prop: 'value', - array: [1, 2, 3], - }, - array: ['some', 'values'], - }, - legacyConfig: getConfig({}), - }) - ).toEqual([]); - }); -}); diff --git a/src/core/server/legacy/config/get_unused_config_keys.ts b/src/core/server/legacy/config/get_unused_config_keys.ts deleted file mode 100644 index c15c3b270df05..0000000000000 --- a/src/core/server/legacy/config/get_unused_config_keys.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 { difference } from 'lodash'; -import { getFlattenedObject } from '@kbn/std'; -import { unset } from '../../../../legacy/utils'; -import { hasConfigPathIntersection } from '../../config'; -import { LegacyPluginSpec, LegacyConfig, LegacyVars } from '../types'; - -const getFlattenedKeys = (object: object) => Object.keys(getFlattenedObject(object)); - -export async function getUnusedConfigKeys({ - coreHandledConfigPaths, - pluginSpecs, - disabledPluginSpecs, - settings, - legacyConfig, -}: { - coreHandledConfigPaths: string[]; - pluginSpecs: LegacyPluginSpec[]; - disabledPluginSpecs: LegacyPluginSpec[]; - settings: LegacyVars; - legacyConfig: LegacyConfig; -}) { - // remove config values from disabled plugins - for (const spec of disabledPluginSpecs) { - unset(settings, spec.getConfigPrefix()); - } - - const inputKeys = getFlattenedKeys(settings); - const appliedKeys = getFlattenedKeys(legacyConfig.get()); - - if (inputKeys.includes('env')) { - // env is a special case key, see https://github.com/elastic/kibana/blob/848bf17b/src/legacy/server/config/config.js#L74 - // where it is deleted from the settings before being injected into the schema via context and - // then renamed to `env.name` https://github.com/elastic/kibana/blob/848bf17/src/legacy/server/config/schema.js#L17 - inputKeys[inputKeys.indexOf('env')] = 'env.name'; - } - - // Filter out keys that are marked as used in the core (e.g. by new core plugins). - return difference(inputKeys, appliedKeys).filter( - (unusedConfigKey) => - !coreHandledConfigPaths.some((usedInCoreConfigKey) => - hasConfigPathIntersection(unusedConfigKey, usedInCoreConfigKey) - ) - ); -} diff --git a/src/core/server/legacy/config/index.ts b/src/core/server/legacy/config/index.ts index b56b83ca324cb..784a6be8906fa 100644 --- a/src/core/server/legacy/config/index.ts +++ b/src/core/server/legacy/config/index.ts @@ -17,5 +17,4 @@ * under the License. */ -export { ensureValidConfiguration } from './ensure_valid_configuration'; export { LegacyObjectToConfigAdapter } from './legacy_object_to_config_adapter'; diff --git a/src/core/server/legacy/index.ts b/src/core/server/legacy/index.ts index 208e9b1167253..ea812d2d887dd 100644 --- a/src/core/server/legacy/index.ts +++ b/src/core/server/legacy/index.ts @@ -18,7 +18,7 @@ */ /** @internal */ -export { LegacyObjectToConfigAdapter, ensureValidConfiguration } from './config'; +export { LegacyObjectToConfigAdapter } from './config'; /** @internal */ export { LegacyInternals } from './legacy_internals'; /** @internal */ diff --git a/src/core/server/legacy/legacy_internals.ts b/src/core/server/legacy/legacy_internals.ts index 628ca4ed12f6b..9f161e19fbd9c 100644 --- a/src/core/server/legacy/legacy_internals.ts +++ b/src/core/server/legacy/legacy_internals.ts @@ -17,12 +17,8 @@ * under the License. */ -import { Server } from 'hapi'; - import { KibanaRequest, LegacyRequest } from '../http'; -import { ensureRawRequest } from '../http/router'; -import { mergeVars } from './merge_vars'; -import { ILegacyInternals, LegacyVars, VarsInjector, LegacyConfig, LegacyUiExports } from './types'; +import { ILegacyInternals, LegacyVars, VarsInjector } from './types'; /** * @internal @@ -30,37 +26,8 @@ import { ILegacyInternals, LegacyVars, VarsInjector, LegacyConfig, LegacyUiExpor */ export class LegacyInternals implements ILegacyInternals { private readonly injectors = new Map>(); - private cachedDefaultVars?: LegacyVars; - - constructor( - private readonly uiExports: LegacyUiExports, - private readonly config: LegacyConfig, - private readonly server: Server - ) {} - - private get defaultVars(): LegacyVars { - if (this.cachedDefaultVars) { - return this.cachedDefaultVars; - } - - const { defaultInjectedVarProviders = [] } = this.uiExports; - return (this.cachedDefaultVars = defaultInjectedVarProviders.reduce( - (vars, { fn, pluginSpec }) => - mergeVars(vars, fn(this.server, pluginSpec.readConfigValue(this.config, []))), - {} - )); - } - - private replaceVars(vars: LegacyVars, request: KibanaRequest | LegacyRequest) { - const { injectedVarsReplacers = [] } = this.uiExports; - - return injectedVarsReplacers.reduce( - async (injected, replacer) => - replacer(await injected, ensureRawRequest(request), this.server), - Promise.resolve(vars) - ); - } + constructor() {} public injectUiAppVars(id: string, injector: VarsInjector) { if (!this.injectors.has(id)) { @@ -85,9 +52,6 @@ export class LegacyInternals implements ILegacyInternals { request: KibanaRequest | LegacyRequest, injected: LegacyVars = {} ) { - return this.replaceVars( - mergeVars(this.defaultVars, await this.getInjectedUiAppVars(id), injected), - request - ); + return Promise.resolve(injected); } } diff --git a/src/core/server/legacy/legacy_service.mock.ts b/src/core/server/legacy/legacy_service.mock.ts index ab501bd6bb53b..81f5799f17d42 100644 --- a/src/core/server/legacy/legacy_service.mock.ts +++ b/src/core/server/legacy/legacy_service.mock.ts @@ -18,26 +18,12 @@ */ import type { PublicMethodsOf } from '@kbn/utility-types'; import { LegacyService } from './legacy_service'; -import { LegacyConfig, LegacyServiceDiscoverPlugins, LegacyServiceSetupDeps } from './types'; +import { LegacyConfig, LegacyServiceSetupDeps } from './types'; type LegacyServiceMock = jest.Mocked & { legacyId: symbol }>; -const createDiscoverPluginsMock = (): LegacyServiceDiscoverPlugins => ({ - pluginSpecs: [], - uiExports: {}, - navLinks: [], - pluginExtendedConfig: { - get: jest.fn(), - has: jest.fn(), - set: jest.fn(), - }, - disabledPluginSpecs: [], - settings: {}, -}); - const createLegacyServiceMock = (): LegacyServiceMock => ({ legacyId: Symbol(), - discoverPlugins: jest.fn().mockResolvedValue(createDiscoverPluginsMock()), setup: jest.fn(), start: jest.fn(), stop: jest.fn(), @@ -52,6 +38,5 @@ const createLegacyConfigMock = (): jest.Mocked => ({ export const legacyServiceMock = { create: createLegacyServiceMock, createSetupContract: (deps: LegacyServiceSetupDeps) => createLegacyServiceMock().setup(deps), - createDiscoverPlugins: createDiscoverPluginsMock, createLegacyConfig: createLegacyConfigMock, }; diff --git a/src/core/server/legacy/legacy_service.test.mocks.ts b/src/core/server/legacy/legacy_service.test.mocks.ts deleted file mode 100644 index 9ad554d63add0..0000000000000 --- a/src/core/server/legacy/legacy_service.test.mocks.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 { LegacyVars } from './types'; - -export const findLegacyPluginSpecsMock = jest.fn().mockImplementation((settings: LegacyVars) => ({ - pluginSpecs: [], - pluginExtendedConfig: { - has: jest.fn(), - get: jest.fn().mockReturnValue(settings), - set: jest.fn(), - }, - disabledPluginSpecs: [], - uiExports: {}, - navLinks: [], -})); -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 f3ce89f83a610..7fef50861817a 100644 --- a/src/core/server/legacy/legacy_service.test.ts +++ b/src/core/server/legacy/legacy_service.test.ts @@ -19,10 +19,6 @@ jest.mock('../../../legacy/server/kbn_server'); jest.mock('./cluster_manager'); -import { - findLegacyPluginSpecsMock, - logLegacyThirdPartyPluginDeprecationWarningMock, -} from './legacy_service.test.mocks'; import { BehaviorSubject, throwError } from 'rxjs'; @@ -44,8 +40,7 @@ import { capabilitiesServiceMock } from '../capabilities/capabilities_service.mo import { httpResourcesMock } from '../http_resources/http_resources_service.mock'; import { setupMock as renderingServiceMock } from '../rendering/__mocks__/rendering_service'; import { environmentServiceMock } from '../environment/environment_service.mock'; -import { findLegacyPluginSpecs } from './plugins'; -import { LegacyVars, LegacyServiceSetupDeps, LegacyServiceStartDeps } from './types'; +import { LegacyServiceSetupDeps, LegacyServiceStartDeps } from './types'; import { LegacyService } from './legacy_service'; import { coreMock } from '../mocks'; import { statusServiceMock } from '../status/status_service.mock'; @@ -72,7 +67,6 @@ beforeEach(() => { configService = configServiceMock.create(); environmentSetup = environmentServiceMock.createSetupContract(); - findLegacyPluginSpecsMock.mockClear(); MockKbnServer.prototype.ready = jest.fn().mockReturnValue(Promise.resolve()); MockKbnServer.prototype.listen = jest.fn(); @@ -150,7 +144,6 @@ describe('once LegacyService is set up with connection info', () => { configService: configService as any, }); - await legacyService.discoverPlugins(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -180,7 +173,6 @@ describe('once LegacyService is set up with connection info', () => { logger, configService: configService as any, }); - await legacyService.discoverPlugins(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -212,7 +204,6 @@ describe('once LegacyService is set up with connection info', () => { configService: configService as any, }); - await legacyService.discoverPlugins(); await legacyService.setup(setupDeps); await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingInlineSnapshot( `"something failed"` @@ -232,9 +223,6 @@ describe('once LegacyService is set up with connection info', () => { configService: configService as any, }); - await expect(legacyService.discoverPlugins()).rejects.toThrowErrorMatchingInlineSnapshot( - `"something failed"` - ); await expect(legacyService.setup(setupDeps)).rejects.toThrowErrorMatchingInlineSnapshot( `"Legacy service has not discovered legacy plugins yet. Ensure LegacyService.discoverPlugins() is called before LegacyService.setup()"` ); @@ -253,7 +241,6 @@ describe('once LegacyService is set up with connection info', () => { logger, configService: configService as any, }); - await legacyService.discoverPlugins(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -274,7 +261,6 @@ describe('once LegacyService is set up with connection info', () => { logger, configService: configService as any, }); - await legacyService.discoverPlugins(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -299,7 +285,6 @@ describe('once LegacyService is set up with connection info', () => { logger, configService: configService as any, }); - await legacyService.discoverPlugins(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -319,7 +304,6 @@ describe('once LegacyService is set up without connection info', () => { let legacyService: LegacyService; beforeEach(async () => { legacyService = new LegacyService({ coreId, env, logger, configService: configService as any }); - await legacyService.discoverPlugins(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); }); @@ -372,7 +356,6 @@ describe('once LegacyService is set up in `devClusterMaster` mode', () => { configService: configService as any, }); - await devClusterLegacyService.discoverPlugins(); await devClusterLegacyService.setup(setupDeps); await devClusterLegacyService.start(startDeps); @@ -400,7 +383,6 @@ describe('once LegacyService is set up in `devClusterMaster` mode', () => { configService: configService as any, }); - await devClusterLegacyService.discoverPlugins(); await devClusterLegacyService.setup(setupDeps); await devClusterLegacyService.start(startDeps); @@ -430,50 +412,6 @@ describe('start', () => { }); }); -describe('#discoverPlugins()', () => { - it('calls findLegacyPluginSpecs with correct parameters', async () => { - const legacyService = new LegacyService({ - coreId, - env, - logger, - configService: configService as any, - }); - - await legacyService.discoverPlugins(); - expect(findLegacyPluginSpecs).toHaveBeenCalledTimes(1); - expect(findLegacyPluginSpecs).toHaveBeenCalledWith(expect.any(Object), logger, env.packageInfo); - }); - - it(`logs deprecations for legacy third party plugins`, async () => { - const pluginSpecs = [{ getId: () => 'pluginA' }, { getId: () => 'pluginB' }]; - 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 () => { configService.atPath.mockReturnValue(new BehaviorSubject({ autoListen: true })); const legacyService = new LegacyService({ @@ -487,21 +425,22 @@ test('Sets the server.uuid property on the legacy configuration', async () => { const configSetMock = jest.fn(); - findLegacyPluginSpecsMock.mockImplementation((settings: LegacyVars) => ({ - pluginSpecs: [], - pluginExtendedConfig: { - has: jest.fn(), - get: jest.fn().mockReturnValue(settings), - set: configSetMock, - }, - disabledPluginSpecs: [], - uiExports: {}, - navLinks: [], - })); - - await legacyService.discoverPlugins(); await legacyService.setup(setupDeps); expect(configSetMock).toHaveBeenCalledTimes(1); expect(configSetMock).toHaveBeenCalledWith('server.uuid', 'UUID_FROM_SERVICE'); + + /* + expect(MockKbnServer).toHaveBeenCalledTimes(1); + expect(MockKbnServer).toHaveBeenCalledWith( + { path: {}, server: { autoListen: true } }, + expect.objectContaining({ get: expect.any(Function) }), + expect.any(Object), + { disabledPluginSpecs: [], pluginSpecs: [], uiExports: {}, navLinks: [] } + ); + expect(MockKbnServer.mock.calls[0][1].get()).toEqual({ + path: {}, + server: { autoListen: true }, + }); + */ }); diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index fd3e3a694e6ae..effbcdb5ebe20 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -16,11 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -import type { PublicMethodsOf } from '@kbn/utility-types'; + import { combineLatest, ConnectableObservable, EMPTY, Observable, Subscription } from 'rxjs'; import { first, map, publishReplay, tap } from 'rxjs/operators'; - +import type { PublicMethodsOf } from '@kbn/utility-types'; import { PathConfigType } from '@kbn/utils'; + +// @ts-expect-error legacy config class +import { Config as LegacyConfigClass } from '../../../legacy/server/config'; import { CoreService } from '../../types'; import { Config } from '../config'; import { CoreContext } from '../core_context'; @@ -28,13 +31,10 @@ import { CspConfigType, config as cspConfig } from '../csp'; import { DevConfig, DevConfigType, config as devConfig } from '../dev'; import { BasePathProxyServer, HttpConfig, HttpConfigType, config as httpConfig } from '../http'; import { Logger } from '../logging'; -import { findLegacyPluginSpecs, logLegacyThirdPartyPluginDeprecationWarning } from './plugins'; import { ILegacyInternals, LegacyServiceSetupDeps, LegacyServiceStartDeps, - LegacyPlugins, - LegacyServiceDiscoverPlugins, LegacyConfig, LegacyVars, } from './types'; @@ -48,7 +48,7 @@ interface LegacyKbnServer { close: () => Promise; } -function getLegacyRawConfig(config: Config, pathConfig: PathConfigType) { +function getLegacyRawConfig(config: Config, pathConfig: PathConfigType, serverUuid: string) { const rawConfig = config.toRaw(); // Elasticsearch config is solely handled by the core and legacy platform @@ -59,6 +59,10 @@ function getLegacyRawConfig(config: Config, pathConfig: PathConfigType) { return { ...rawConfig, + server: { + ...rawConfig.server, + uuid: serverUuid, + }, // We rely heavily in the default value of 'path.data' in the legacy world and, // since it has been moved to NP, it won't show up in RawConfig. path: pathConfig, @@ -80,7 +84,6 @@ export class LegacyService implements CoreService { private setupDeps?: LegacyServiceSetupDeps; private update$?: ConnectableObservable<[Config, PathConfigType]>; private legacyRawConfig?: LegacyConfig; - private legacyPlugins?: LegacyPlugins; private settings?: LegacyVars; public legacyInternals?: ILegacyInternals; @@ -97,14 +100,20 @@ export class LegacyService implements CoreService { ).pipe(map(([http, csp]) => new HttpConfig(http, csp))); } - public async discoverPlugins(): Promise { - this.update$ = combineLatest( + public async setup(setupDeps: LegacyServiceSetupDeps) { + this.log.debug('setting up legacy service'); + + const serverUuid = setupDeps.core.environment.instanceUuid; + + this.update$ = combineLatest([ this.coreContext.configService.getConfig$(), - this.coreContext.configService.atPath('path') - ).pipe( + this.coreContext.configService.atPath('path'), + ]).pipe( tap(([config, pathConfig]) => { if (this.kbnServer !== undefined) { - this.kbnServer.applyLoggingConfiguration(getLegacyRawConfig(config, pathConfig)); + this.kbnServer.applyLoggingConfiguration( + getLegacyRawConfig(config, pathConfig, serverUuid) + ); } }), tap({ error: (err) => this.log.error(err) }), @@ -116,78 +125,20 @@ export class LegacyService implements CoreService { this.settings = await this.update$ .pipe( first(), - map(([config, pathConfig]) => getLegacyRawConfig(config, pathConfig)) + map(([config, pathConfig]) => getLegacyRawConfig(config, pathConfig, serverUuid)) ) .toPromise(); - const { - pluginSpecs, - pluginExtendedConfig, - disabledPluginSpecs, - uiExports, - navLinks, - } = await findLegacyPluginSpecs( - this.settings, - this.coreContext.logger, - this.coreContext.env.packageInfo - ); + this.legacyRawConfig = LegacyConfigClass.withDefaultSchema(this.settings); - logLegacyThirdPartyPluginDeprecationWarning({ - specs: pluginSpecs, - log: this.log, - }); - - this.legacyPlugins = { - pluginSpecs, - disabledPluginSpecs, - uiExports, - navLinks, - }; - - this.legacyRawConfig = pluginExtendedConfig; - - // check for unknown uiExport types - if (uiExports.unknown && uiExports.unknown.length > 0) { - throw new Error( - `Unknown uiExport types: ${uiExports.unknown - .map(({ pluginSpec, type }) => `${type} from ${pluginSpec.getId()}`) - .join(', ')}` - ); - } - - return { - pluginSpecs, - disabledPluginSpecs, - uiExports, - navLinks, - pluginExtendedConfig, - settings: this.settings, - }; - } - - public async setup(setupDeps: LegacyServiceSetupDeps) { - this.log.debug('setting up legacy service'); - - if (!this.legacyPlugins) { - throw new Error( - 'Legacy service has not discovered legacy plugins yet. Ensure LegacyService.discoverPlugins() is called before LegacyService.setup()' - ); - } - - // propagate the instance uuid to the legacy config, as it was the legacy way to access it. - this.legacyRawConfig!.set('server.uuid', setupDeps.core.environment.instanceUuid); this.setupDeps = setupDeps; - this.legacyInternals = new LegacyInternals( - this.legacyPlugins.uiExports, - this.legacyRawConfig!, - setupDeps.core.http.server - ); + this.legacyInternals = new LegacyInternals(); } public async start(startDeps: LegacyServiceStartDeps) { const { setupDeps } = this; - if (!setupDeps || !this.legacyPlugins) { + if (!setupDeps) { throw new Error('Legacy service is not setup yet.'); } @@ -201,8 +152,7 @@ export class LegacyService implements CoreService { this.settings!, this.legacyRawConfig!, setupDeps, - startDeps, - this.legacyPlugins! + startDeps ); } } @@ -245,8 +195,7 @@ export class LegacyService implements CoreService { settings: LegacyVars, config: LegacyConfig, setupDeps: LegacyServiceSetupDeps, - startDeps: LegacyServiceStartDeps, - legacyPlugins: LegacyPlugins + startDeps: LegacyServiceStartDeps ) { const coreStart: CoreStart = { capabilities: startDeps.core.capabilities, @@ -332,36 +281,31 @@ export class LegacyService implements CoreService { // eslint-disable-next-line @typescript-eslint/no-var-requires const KbnServer = require('../../../legacy/server/kbn_server'); - const kbnServer: LegacyKbnServer = new KbnServer( - settings, - config, - { - env: { - mode: this.coreContext.env.mode, - packageInfo: this.coreContext.env.packageInfo, - }, - setupDeps: { - core: coreSetup, - plugins: setupDeps.plugins, - }, - startDeps: { - core: coreStart, - plugins: startDeps.plugins, - }, - __internals: { - http: { - registerStaticDir: setupDeps.core.http.registerStaticDir, - }, - hapiServer: setupDeps.core.http.server, - uiPlugins: setupDeps.uiPlugins, - elasticsearch: setupDeps.core.elasticsearch, - rendering: setupDeps.core.rendering, - legacy: this.legacyInternals, + const kbnServer: LegacyKbnServer = new KbnServer(settings, config, { + env: { + mode: this.coreContext.env.mode, + packageInfo: this.coreContext.env.packageInfo, + }, + setupDeps: { + core: coreSetup, + plugins: setupDeps.plugins, + }, + startDeps: { + core: coreStart, + plugins: startDeps.plugins, + }, + __internals: { + http: { + registerStaticDir: setupDeps.core.http.registerStaticDir, }, - logger: this.coreContext.logger, + hapiServer: setupDeps.core.http.server, + uiPlugins: setupDeps.uiPlugins, + elasticsearch: setupDeps.core.elasticsearch, + rendering: setupDeps.core.rendering, + legacy: this.legacyInternals, }, - legacyPlugins - ); + logger: this.coreContext.logger, + }); // The kbnWorkerType check is necessary to prevent the repl // from being started multiple times in different processes. diff --git a/src/core/server/legacy/plugins/collect_ui_exports.js b/src/core/server/legacy/plugins/collect_ui_exports.js deleted file mode 100644 index 842ab554d79d1..0000000000000 --- a/src/core/server/legacy/plugins/collect_ui_exports.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -export { collectUiExports } from '../../../../legacy/ui/ui_exports/collect_ui_exports'; diff --git a/src/core/server/legacy/plugins/find_legacy_plugin_specs.ts b/src/core/server/legacy/plugins/find_legacy_plugin_specs.ts deleted file mode 100644 index cb4277b130a88..0000000000000 --- a/src/core/server/legacy/plugins/find_legacy_plugin_specs.ts +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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 { Observable, merge, forkJoin } from 'rxjs'; -import { toArray, tap, distinct, map } from 'rxjs/operators'; - -import { - findPluginSpecs, - defaultConfig, - // @ts-expect-error -} from '../../../../legacy/plugin_discovery/find_plugin_specs.js'; -// @ts-expect-error -import { collectUiExports as collectLegacyUiExports } from './collect_ui_exports'; - -import { LoggerFactory } from '../../logging'; -import { PackageInfo } from '../../config'; -import { LegacyUiExports, LegacyPluginSpec, LegacyPluginPack, LegacyConfig } from '../types'; - -export async function findLegacyPluginSpecs( - settings: unknown, - loggerFactory: LoggerFactory, - packageInfo: PackageInfo -) { - const configToMutate: LegacyConfig = defaultConfig(settings); - const { - pack$, - invalidDirectoryError$, - invalidPackError$, - otherError$, - deprecation$, - invalidVersionSpec$, - spec$, - disabledSpec$, - }: { - pack$: Observable; - invalidDirectoryError$: Observable<{ path: string }>; - invalidPackError$: Observable<{ path: string }>; - otherError$: Observable; - deprecation$: Observable<{ spec: LegacyPluginSpec; message: string }>; - invalidVersionSpec$: Observable; - spec$: Observable; - disabledSpec$: Observable; - } = findPluginSpecs(settings, configToMutate) as any; - - const logger = loggerFactory.get('legacy-plugins'); - - const log$ = merge( - pack$.pipe( - tap((definition) => { - const path = definition.getPath(); - logger.debug(`Found plugin at ${path}`, { path }); - }) - ), - - invalidDirectoryError$.pipe( - tap((error) => { - logger.warn(`Unable to scan directory for plugins "${error.path}"`, { - err: error, - dir: error.path, - }); - }) - ), - - invalidPackError$.pipe( - tap((error) => { - logger.warn(`Skipping non-plugin directory at ${error.path}`, { - path: error.path, - }); - }) - ), - - otherError$.pipe( - tap((error) => { - // rethrow unhandled errors, which will fail the server - throw error; - }) - ), - - invalidVersionSpec$.pipe( - map((spec) => { - const name = spec.getId(); - const pluginVersion = spec.getExpectedKibanaVersion(); - const kibanaVersion = packageInfo.version; - return `Plugin "${name}" was disabled because it expected Kibana version "${pluginVersion}", and found "${kibanaVersion}".`; - }), - distinct(), - tap((message) => { - logger.warn(message); - }) - ), - - deprecation$.pipe( - tap(({ spec, message }) => { - const deprecationLogger = loggerFactory.get( - 'plugins', - spec.getConfigPrefix(), - 'config', - 'deprecation' - ); - deprecationLogger.warn(message); - }) - ) - ); - - const [disabledPluginSpecs, pluginSpecs] = await forkJoin( - disabledSpec$.pipe(toArray()), - spec$.pipe(toArray()), - log$.pipe(toArray()) - ).toPromise(); - const uiExports: LegacyUiExports = collectLegacyUiExports(pluginSpecs); - - return { - disabledPluginSpecs, - pluginSpecs, - pluginExtendedConfig: configToMutate, - uiExports, - navLinks: [], - }; -} diff --git a/src/core/server/legacy/plugins/index.ts b/src/core/server/legacy/plugins/index.ts deleted file mode 100644 index 7ec5dbc1983ab..0000000000000 --- a/src/core/server/legacy/plugins/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -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 deleted file mode 100644 index 2317f1036ce42..0000000000000 --- a/src/core/server/legacy/plugins/log_legacy_plugins_warning.test.ts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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', - 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 in a future Kibana release. Please refer to https://ela.st/kibana-breaking-changes-8-0 for a list of breaking changes and https://ela.st/kibana-platform-migration 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://ela.st/kibana-breaking-changes-8-0 for a list of breaking changes and https://ela.st/kibana-platform-migration 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 deleted file mode 100644 index 4a4a1b1b0e60b..0000000000000 --- a/src/core/server/legacy/plugins/log_legacy_plugins_warning.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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']; - -// Use shortened URLs so destinations can be updated if/when documentation moves -// All platform team members have access to edit these -const breakingChangesUrl = 'https://ela.st/kibana-breaking-changes-8-0'; -const migrationGuideUrl = 'https://ela.st/kibana-platform-migration'; - -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); -}; diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts index 1105308fd44cf..3d167014d0168 100644 --- a/src/core/server/legacy/types.ts +++ b/src/core/server/legacy/types.ts @@ -19,7 +19,6 @@ import { Server } from 'hapi'; -import { ChromeNavLink } from '../../public'; import { KibanaRequest, LegacyRequest } from '../http'; import { InternalCoreSetup, InternalCoreStart } from '../internal_types'; import { PluginsServiceSetup, PluginsServiceStart, UiPlugins } from '../plugins'; @@ -96,33 +95,6 @@ export type VarsReplacer = ( server: Server ) => LegacyVars | Promise; -/** - * @internal - * @deprecated - */ -export type LegacyNavLinkSpec = Partial & { - id: string; - title: string; - url: string; -}; - -/** - * @internal - * @deprecated - */ -export type LegacyAppSpec = Partial & { - pluginId?: string; - listed?: boolean; -}; - -/** - * @internal - * @deprecated - */ -export type LegacyNavLink = Omit & { - order: number; -}; - /** * @internal * @deprecated @@ -130,8 +102,6 @@ export type LegacyNavLink = Omit; unknown?: [{ pluginSpec: LegacyPluginSpec; type: unknown }]; } @@ -178,23 +148,3 @@ export interface ILegacyInternals { injected?: LegacyVars ): Promise; } - -/** - * @internal - * @deprecated - */ -export interface LegacyPlugins { - disabledPluginSpecs: LegacyPluginSpec[]; - pluginSpecs: LegacyPluginSpec[]; - uiExports: LegacyUiExports; - navLinks: LegacyNavLink[]; -} - -/** - * @internal - * @deprecated - */ -export interface LegacyServiceDiscoverPlugins extends LegacyPlugins { - pluginExtendedConfig: LegacyConfig; - settings: LegacyVars; -} diff --git a/src/core/server/rendering/rendering_service.tsx b/src/core/server/rendering/rendering_service.tsx index 7761c89044f6f..7997afd83d350 100644 --- a/src/core/server/rendering/rendering_service.tsx +++ b/src/core/server/rendering/rendering_service.tsx @@ -43,7 +43,6 @@ export class RenderingService implements CoreService { return { @@ -98,7 +97,6 @@ export class RenderingService implements CoreService`: emits [`InvalidDirectoryError`][Errors]s caused by `settings.plugins.scanDirs` values that don't point to actual directories. `findPluginSpecs()` will not abort when this error is encountered. - - `invalidPackError$: Observable`: emits [`InvalidPackError`][Errors]s caused by children of `settings.plugins.scanDirs` or `settings.plugins.paths` values which don't meet the requirements of a [`PluginPack`][PluginPack] (probably missing a `package.json`). `findPluginSpecs()` will not abort when this error is encountered. - - `deprecation$: Observable`: emits deprecation warnings that are produces when reading each [`PluginPack`][PluginPack]'s configuration - - `extendedConfig$: Observable`: emits the [`Config`][Config] service that was passed to `findPluginSpecs()` (or created internally if none was passed) after it has been extended with the configuration from each plugin - - `spec$: Observable`: emits every *enabled* [`PluginSpec`][PluginSpec] defined by the discovered [`PluginPack`][PluginPack]s - - `disabledSpec$: Observable`: emits every *disabled* [`PluginSpec`][PluginSpec] defined by the discovered [`PluginPack`][PluginPack]s - - `invalidVersionSpec$: Observable`: emits every [`PluginSpec`][PluginSpec] who's required kibana version does not match the version exposed by `config.get('pkg.version')` - -### example - -Just get the plugin specs, only fail if there is an uncaught error of some sort: -```js -const { pack$ } = findPluginSpecs(settings); -const packs = await pack$.pipe(toArray()).toPromise() -``` - -Just log the deprecation messages: -```js -const { deprecation$ } = findPluginSpecs(settings); -for (const warning of await deprecation$.pipe(toArray()).toPromise()) { - console.log('DEPRECATION:', warning) -} -``` - -Get the packs but fail if any packs are invalid: -```js -const { pack$, invalidDirectoryError$ } = findPluginSpecs(settings); -const packs = await Rx.merge( - pack$.pipe(toArray()), - - // if we ever get an InvalidDirectoryError, throw it - // into the stream so that all streams are unsubscribed, - // the discovery process is aborted, and the promise rejects - invalidDirectoryError$.pipe( - map(error => { throw error }) - ), -).toPromise() -``` - -Handle everything -```js -const { - pack$, - invalidDirectoryError$, - invalidPackError$, - deprecation$, - extendedConfig$, - spec$, - disabledSpecs$, - invalidVersionSpec$, -} = findPluginSpecs(settings); - -Rx.merge( - pack$.pipe( - tap(pluginPack => console.log('Found plugin pack', pluginPack)) - ), - - invalidDirectoryError$.pipe( - tap(error => console.log('Invalid directory error', error)) - ), - - invalidPackError$.pipe( - tap(error => console.log('Invalid plugin pack error', error)) - ), - - deprecation$.pipe( - tap(msg => console.log('DEPRECATION:', msg)) - ), - - extendedConfig$.pipe( - tap(config => console.log('config service extended by plugins', config)) - ), - - spec$.pipe( - tap(pluginSpec => console.log('enabled plugin spec found', spec)) - ), - - disabledSpec$.pipe( - tap(pluginSpec => console.log('disabled plugin spec found', spec)) - ), - - invalidVersionSpec$.pipe( - tap(pluginSpec => console.log('plugin spec with invalid version found', spec)) - ), -) -.toPromise() -.then(() => { - console.log('plugin discovery complete') -}) -.catch((error) => { - console.log('plugin discovery failed', error) -}) - -``` - -## `reduceExportSpecs(pluginSpecs, reducers, [defaults={}])` - -Reduces every value exported by the [`PluginSpec`][PluginSpec]s to produce a single value. If an exported value is an array each item in the array will be reduced individually. If the exported value is `undefined` it will be ignored. The reducer is called with the signature: - -```js -reducer( - // the result of the previous reducer call, or `defaults` - acc: any, - // the exported value, found at `uiExports[type]` or `uiExports[type][i]` - // in the PluginSpec config. - spec: any, - // the key in `uiExports` where this export was found - type: string, - // the PluginSpec which exported this spec - pluginSpec: PluginSpec -) -``` - -## `new PluginPack(options)` class - -Only exported so that `PluginPack` instances can be created in tests and used in place of on-disk plugin fixtures. Use `findPluginSpecs()`, or the cached result of a call to `findPluginSpecs()` (like `kbnServer.pluginSpecs`) any time you might need access to `PluginPack` objects in distributed code. - -### params - - - `options.path`: absolute path to where this plugin pack was found, this is normally a direct child of `./src/legacy/core_plugins` or `./plugins` - - `options.pkg`: the parsed `package.json` for this pack, used for defaults in `PluginSpec` objects defined by this pack - - `options.provider`: the default export of the pack, a function which is called with the `PluginSpec` class which should return one or more `PluginSpec` objects. - -[PluginPack]: ./plugin_pack/plugin_pack.js "PluginPath class definition" -[PluginSpec]: ./plugin_spec/plugin_spec.js "PluginSpec class definition" -[Errors]: ./errors.js "PluginDiscover specific error types" -[KbnServer]: ../server/kbn_server.js "KbnServer class definition" -[Config]: ../server/config/config.js "KbnServer/Config class definition" diff --git a/src/legacy/plugin_discovery/__tests__/find_plugin_specs.js b/src/legacy/plugin_discovery/__tests__/find_plugin_specs.js deleted file mode 100644 index e6af23d69c549..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/find_plugin_specs.js +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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 { resolve } from 'path'; -import { toArray } from 'rxjs/operators'; - -import expect from '@kbn/expect'; -import { isEqual } from 'lodash'; -import { findPluginSpecs } from '../find_plugin_specs'; -import { PluginSpec } from '../plugin_spec'; - -const PLUGIN_FIXTURES = resolve(__dirname, 'fixtures/plugins'); -const CONFLICT_FIXTURES = resolve(__dirname, 'fixtures/conflicts'); - -describe('plugin discovery', () => { - describe('findPluginSpecs()', function () { - this.timeout(10000); - - describe('spec$', () => { - it('finds specs for specified plugin paths', async () => { - const { spec$ } = findPluginSpecs({ - plugins: { - paths: [ - resolve(PLUGIN_FIXTURES, 'foo'), - resolve(PLUGIN_FIXTURES, 'bar'), - resolve(PLUGIN_FIXTURES, 'broken'), - ], - }, - }); - - const specs = await spec$.pipe(toArray()).toPromise(); - expect(specs).to.have.length(3); - specs.forEach((spec) => { - expect(spec).to.be.a(PluginSpec); - }); - expect(specs.map((s) => s.getId()).sort()).to.eql(['bar:one', 'bar:two', 'foo']); - }); - - it('finds all specs in scanDirs', async () => { - const { spec$ } = findPluginSpecs({ - // used to ensure the dev_mode plugin is enabled - env: 'development', - - plugins: { - scanDirs: [PLUGIN_FIXTURES], - }, - }); - - const specs = await spec$.pipe(toArray()).toPromise(); - expect(specs).to.have.length(3); - specs.forEach((spec) => { - expect(spec).to.be.a(PluginSpec); - }); - expect(specs.map((s) => s.getId()).sort()).to.eql(['bar:one', 'bar:two', 'foo']); - }); - - it('does not find disabled plugins', async () => { - const { spec$ } = findPluginSpecs({ - 'bar:one': { - enabled: false, - }, - - plugins: { - paths: [ - resolve(PLUGIN_FIXTURES, 'foo'), - resolve(PLUGIN_FIXTURES, 'bar'), - resolve(PLUGIN_FIXTURES, 'broken'), - ], - }, - }); - - const specs = await spec$.pipe(toArray()).toPromise(); - expect(specs).to.have.length(2); - specs.forEach((spec) => { - expect(spec).to.be.a(PluginSpec); - }); - expect(specs.map((s) => s.getId()).sort()).to.eql(['bar:two', 'foo']); - }); - - it('dedupes duplicate packs', async () => { - const { spec$ } = findPluginSpecs({ - plugins: { - scanDirs: [PLUGIN_FIXTURES], - paths: [ - resolve(PLUGIN_FIXTURES, 'foo'), - resolve(PLUGIN_FIXTURES, 'foo'), - resolve(PLUGIN_FIXTURES, 'bar'), - resolve(PLUGIN_FIXTURES, 'bar'), - resolve(PLUGIN_FIXTURES, 'broken'), - resolve(PLUGIN_FIXTURES, 'broken'), - ], - }, - }); - - const specs = await spec$.pipe(toArray()).toPromise(); - expect(specs).to.have.length(3); - specs.forEach((spec) => { - expect(spec).to.be.a(PluginSpec); - }); - expect(specs.map((s) => s.getId()).sort()).to.eql(['bar:one', 'bar:two', 'foo']); - }); - - describe('conflicting plugin spec ids', () => { - it('fails with informative message', async () => { - const { spec$ } = findPluginSpecs({ - plugins: { - scanDirs: [], - paths: [resolve(CONFLICT_FIXTURES, 'foo')], - }, - }); - - try { - await spec$.pipe(toArray()).toPromise(); - throw new Error('expected spec$ to throw an error'); - } catch (error) { - expect(error.message).to.contain('Multiple plugins found with the id "foo"'); - expect(error.message).to.contain(CONFLICT_FIXTURES); - } - }); - }); - }); - - describe('packageJson$', () => { - const checkPackageJsons = (packageJsons) => { - expect(packageJsons).to.have.length(2); - const package1 = packageJsons.find((packageJson) => - isEqual( - { - directoryPath: resolve(PLUGIN_FIXTURES, 'foo'), - contents: { - name: 'foo', - version: 'kibana', - }, - }, - packageJson - ) - ); - expect(package1).to.be.an(Object); - const package2 = packageJsons.find((packageJson) => - isEqual( - { - directoryPath: resolve(PLUGIN_FIXTURES, 'bar'), - contents: { - name: 'foo', - version: 'kibana', - }, - }, - packageJson - ) - ); - expect(package2).to.be.an(Object); - }; - - it('finds packageJson for specified plugin paths', async () => { - const { packageJson$ } = findPluginSpecs({ - plugins: { - paths: [ - resolve(PLUGIN_FIXTURES, 'foo'), - resolve(PLUGIN_FIXTURES, 'bar'), - resolve(PLUGIN_FIXTURES, 'broken'), - ], - }, - }); - - const packageJsons = await packageJson$.pipe(toArray()).toPromise(); - checkPackageJsons(packageJsons); - }); - - it('finds all packageJsons in scanDirs', async () => { - const { packageJson$ } = findPluginSpecs({ - // used to ensure the dev_mode plugin is enabled - env: 'development', - - plugins: { - scanDirs: [PLUGIN_FIXTURES], - }, - }); - - const packageJsons = await packageJson$.pipe(toArray()).toPromise(); - checkPackageJsons(packageJsons); - }); - - it('dedupes duplicate packageJson', async () => { - const { packageJson$ } = findPluginSpecs({ - plugins: { - scanDirs: [PLUGIN_FIXTURES], - paths: [ - resolve(PLUGIN_FIXTURES, 'foo'), - resolve(PLUGIN_FIXTURES, 'foo'), - resolve(PLUGIN_FIXTURES, 'bar'), - resolve(PLUGIN_FIXTURES, 'bar'), - resolve(PLUGIN_FIXTURES, 'broken'), - resolve(PLUGIN_FIXTURES, 'broken'), - ], - }, - }); - - const packageJsons = await packageJson$.pipe(toArray()).toPromise(); - checkPackageJsons(packageJsons); - }); - }); - }); -}); diff --git a/src/legacy/plugin_discovery/__tests__/fixtures/conflicts/foo/index.js b/src/legacy/plugin_discovery/__tests__/fixtures/conflicts/foo/index.js deleted file mode 100644 index fcbe3487463b7..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/fixtures/conflicts/foo/index.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - */ - -export default function (kibana) { - return [ - // two plugins exported without ids will both inherit - // the id of the pack and conflict - new kibana.Plugin({}), - new kibana.Plugin({}), - ]; -} diff --git a/src/legacy/plugin_discovery/__tests__/fixtures/conflicts/foo/package.json b/src/legacy/plugin_discovery/__tests__/fixtures/conflicts/foo/package.json deleted file mode 100644 index e43c2f0bc984c..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/fixtures/conflicts/foo/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/bar/index.js b/src/legacy/plugin_discovery/__tests__/fixtures/plugins/bar/index.js deleted file mode 100644 index 0eef126f2255a..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/bar/index.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ - -export default function (kibana) { - return [ - new kibana.Plugin({ - id: 'bar:one', - }), - new kibana.Plugin({ - id: 'bar:two', - }), - ]; -} diff --git a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/bar/package.json b/src/legacy/plugin_discovery/__tests__/fixtures/plugins/bar/package.json deleted file mode 100644 index e43c2f0bc984c..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/bar/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/broken/index.js b/src/legacy/plugin_discovery/__tests__/fixtures/plugins/broken/index.js deleted file mode 100644 index 59f4a2649f019..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/broken/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -export default { - foo: 'bar', -}; diff --git a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/broken/package1.json b/src/legacy/plugin_discovery/__tests__/fixtures/plugins/broken/package1.json deleted file mode 100644 index 81ddb6221d515..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/broken/package1.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "baz", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/foo/index.js b/src/legacy/plugin_discovery/__tests__/fixtures/plugins/foo/index.js deleted file mode 100644 index e43a1dcedb372..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/foo/index.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - */ - -module.exports = function (kibana) { - return new kibana.Plugin({ - id: 'foo', - }); -}; diff --git a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/foo/package.json b/src/legacy/plugin_discovery/__tests__/fixtures/plugins/foo/package.json deleted file mode 100644 index e43c2f0bc984c..0000000000000 --- a/src/legacy/plugin_discovery/__tests__/fixtures/plugins/foo/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/errors.js b/src/legacy/plugin_discovery/errors.js deleted file mode 100644 index 02d81b32d1fd1..0000000000000 --- a/src/legacy/plugin_discovery/errors.js +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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. - */ - -const errorCodeProperty = Symbol('pluginDiscovery/errorCode'); - -/** - * Thrown when reading a plugin directory fails, wraps failure - * @type {String} - */ -const ERROR_INVALID_DIRECTORY = 'ERROR_INVALID_DIRECTORY'; -export function createInvalidDirectoryError(sourceError, path) { - sourceError[errorCodeProperty] = ERROR_INVALID_DIRECTORY; - sourceError.path = path; - return sourceError; -} -export function isInvalidDirectoryError(error) { - return error && error[errorCodeProperty] === ERROR_INVALID_DIRECTORY; -} - -/** - * Thrown when trying to create a PluginPack for a path that - * is not a valid plugin definition - * @type {String} - */ -const ERROR_INVALID_PACK = 'ERROR_INVALID_PACK'; -export function createInvalidPackError(path, reason) { - const error = new Error(`PluginPack${path ? ` at "${path}"` : ''} ${reason}`); - error[errorCodeProperty] = ERROR_INVALID_PACK; - error.path = path; - return error; -} -export function isInvalidPackError(error) { - return error && error[errorCodeProperty] === ERROR_INVALID_PACK; -} - -/** - * Thrown when trying to load a PluginSpec that is invalid for some reason - * @type {String} - */ -const ERROR_INVALID_PLUGIN = 'ERROR_INVALID_PLUGIN'; -export function createInvalidPluginError(spec, reason) { - const error = new Error( - `Plugin from ${spec.getId()} at ${spec.getPack().getPath()} is invalid because ${reason}` - ); - error[errorCodeProperty] = ERROR_INVALID_PLUGIN; - error.spec = spec; - return error; -} -export function isInvalidPluginError(error) { - return error && error[errorCodeProperty] === ERROR_INVALID_PLUGIN; -} - -/** - * Thrown when trying to load a PluginSpec whose version is incompatible - * @type {String} - */ -const ERROR_INCOMPATIBLE_PLUGIN_VERSION = 'ERROR_INCOMPATIBLE_PLUGIN_VERSION'; -export function createIncompatiblePluginVersionError(spec) { - const error = new Error( - `Plugin ${spec.getId()} is only compatible with Kibana version ${spec.getExpectedKibanaVersion()}` - ); - error[errorCodeProperty] = ERROR_INCOMPATIBLE_PLUGIN_VERSION; - error.spec = spec; - return error; -} -export function isIncompatiblePluginVersionError(error) { - return error && error[errorCodeProperty] === ERROR_INCOMPATIBLE_PLUGIN_VERSION; -} diff --git a/src/legacy/plugin_discovery/find_plugin_specs.js b/src/legacy/plugin_discovery/find_plugin_specs.js deleted file mode 100644 index b97476bb456a5..0000000000000 --- a/src/legacy/plugin_discovery/find_plugin_specs.js +++ /dev/null @@ -1,234 +0,0 @@ -/* - * 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 * as Rx from 'rxjs'; -import { - distinct, - toArray, - mergeMap, - share, - shareReplay, - filter, - last, - map, - tap, -} from 'rxjs/operators'; -import { realpathSync } from 'fs'; - -import { Config } from '../server/config'; - -import { extendConfigService, disableConfigExtension } from './plugin_config'; - -import { - createPack$, - createPackageJsonAtPath$, - createPackageJsonsInDirectory$, -} from './plugin_pack'; - -import { isInvalidDirectoryError, isInvalidPackError } from './errors'; - -export function defaultConfig(settings) { - return Config.withDefaultSchema(settings); -} - -function bufferAllResults(observable) { - return observable.pipe( - // buffer all results into a single array - toArray(), - // merge the array back into the stream when complete - mergeMap((array) => array) - ); -} - -/** - * Determine a distinct value for each result from find$ - * so they can be deduplicated - * @param {{error?,pack?}} result - * @return {Any} - */ -function getDistinctKeyForFindResult(result) { - // errors are distinct by their message - if (result.error) { - return result.error.message; - } - - // packs are distinct by their absolute and real path - if (result.packageJson) { - return realpathSync(result.packageJson.directoryPath); - } - - // non error/pack results shouldn't exist, but if they do they are all unique - return result; -} - -function groupSpecsById(specs) { - const specsById = new Map(); - for (const spec of specs) { - const id = spec.getId(); - if (specsById.has(id)) { - specsById.get(id).push(spec); - } else { - specsById.set(id, [spec]); - } - } - return specsById; -} - -/** - * Creates a collection of observables for discovering pluginSpecs - * using Kibana's defaults, settings, and config service - * - * @param {Object} settings - * @param {ConfigService} [configToMutate] when supplied **it is mutated** to - * include the config from discovered plugin specs - * @return {Object} - */ -export function findPluginSpecs(settings, configToMutate) { - const config$ = Rx.defer(async () => { - if (configToMutate) { - return configToMutate; - } - - return defaultConfig(settings); - }).pipe(shareReplay()); - - // find plugin packs in configured paths/dirs - const packageJson$ = config$.pipe( - mergeMap((config) => - Rx.merge( - ...config.get('plugins.paths').map(createPackageJsonAtPath$), - ...config.get('plugins.scanDirs').map(createPackageJsonsInDirectory$) - ) - ), - distinct(getDistinctKeyForFindResult), - share() - ); - - const pack$ = createPack$(packageJson$).pipe(share()); - - const extendConfig$ = config$.pipe( - mergeMap((config) => - pack$.pipe( - // get the specs for each found plugin pack - mergeMap(({ pack }) => (pack ? pack.getPluginSpecs() : [])), - // make sure that none of the plugin specs have conflicting ids, fail - // early if conflicts detected or merge the specs back into the stream - toArray(), - mergeMap((allSpecs) => { - for (const [id, specs] of groupSpecsById(allSpecs)) { - if (specs.length > 1) { - throw new Error( - `Multiple plugins found with the id "${id}":\n${specs - .map((spec) => ` - ${id} at ${spec.getPath()}`) - .join('\n')}` - ); - } - } - - return allSpecs; - }), - mergeMap(async (spec) => { - // extend the config service with this plugin spec and - // collect its deprecations messages if some of its - // settings are outdated - const deprecations = []; - await extendConfigService(spec, config, settings, (message) => { - deprecations.push({ spec, message }); - }); - - return { - spec, - deprecations, - }; - }), - // extend the config with all plugins before determining enabled status - bufferAllResults, - map(({ spec, deprecations }) => { - const isRightVersion = spec.isVersionCompatible(config.get('pkg.version')); - const enabled = isRightVersion && spec.isEnabled(config); - return { - config, - spec, - deprecations, - enabledSpecs: enabled ? [spec] : [], - disabledSpecs: enabled ? [] : [spec], - invalidVersionSpecs: isRightVersion ? [] : [spec], - }; - }), - // determine which plugins are disabled before actually removing things from the config - bufferAllResults, - tap((result) => { - for (const spec of result.disabledSpecs) { - disableConfigExtension(spec, config); - } - }) - ) - ), - share() - ); - - return { - // package JSONs found when searching configure paths - packageJson$: packageJson$.pipe( - mergeMap((result) => (result.packageJson ? [result.packageJson] : [])) - ), - - // plugin packs found when searching configured paths - pack$: pack$.pipe(mergeMap((result) => (result.pack ? [result.pack] : []))), - - // errors caused by invalid directories of plugin directories - invalidDirectoryError$: pack$.pipe( - mergeMap((result) => (isInvalidDirectoryError(result.error) ? [result.error] : [])) - ), - - // errors caused by directories that we expected to be plugin but were invalid - invalidPackError$: pack$.pipe( - mergeMap((result) => (isInvalidPackError(result.error) ? [result.error] : [])) - ), - - otherError$: pack$.pipe( - mergeMap((result) => (isUnhandledError(result.error) ? [result.error] : [])) - ), - - // { spec, message } objects produced when transforming deprecated - // settings for a plugin spec - deprecation$: extendConfig$.pipe(mergeMap((result) => result.deprecations)), - - // the config service we extended with all of the plugin specs, - // only emitted once it is fully extended by all - extendedConfig$: extendConfig$.pipe( - mergeMap((result) => result.config), - filter(Boolean), - last() - ), - - // all enabled PluginSpec objects - spec$: extendConfig$.pipe(mergeMap((result) => result.enabledSpecs)), - - // all disabled PluginSpec objects - disabledSpec$: extendConfig$.pipe(mergeMap((result) => result.disabledSpecs)), - - // all PluginSpec objects that were disabled because their version was incompatible - invalidVersionSpec$: extendConfig$.pipe(mergeMap((result) => result.invalidVersionSpecs)), - }; -} - -function isUnhandledError(error) { - return error != null && !isInvalidDirectoryError(error) && !isInvalidPackError(error); -} diff --git a/src/legacy/plugin_discovery/index.js b/src/legacy/plugin_discovery/index.js deleted file mode 100644 index b60806f6cbc23..0000000000000 --- a/src/legacy/plugin_discovery/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -export { findPluginSpecs } from './find_plugin_specs'; -export { reduceExportSpecs } from './plugin_exports'; -export { PluginPack } from './plugin_pack'; diff --git a/src/legacy/plugin_discovery/plugin_config/__tests__/extend_config_service.js b/src/legacy/plugin_discovery/plugin_config/__tests__/extend_config_service.js deleted file mode 100644 index 40f84f6f54b3b..0000000000000 --- a/src/legacy/plugin_discovery/plugin_config/__tests__/extend_config_service.js +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 sinon from 'sinon'; -import expect from '@kbn/expect'; - -import { Config } from '../../../server/config'; -import { PluginPack } from '../../plugin_pack'; -import { extendConfigService, disableConfigExtension } from '../extend_config_service'; -import * as SchemaNS from '../schema'; -import * as SettingsNS from '../settings'; - -describe('plugin discovery/extend config service', () => { - const sandbox = sinon.createSandbox(); - afterEach(() => sandbox.restore()); - - const pluginSpec = new PluginPack({ - path: '/dev/null', - pkg: { - name: 'test', - version: 'kibana', - }, - provider: ({ Plugin }) => - new Plugin({ - configPrefix: 'foo.bar.baz', - - config: (Joi) => - Joi.object({ - enabled: Joi.boolean().default(true), - test: Joi.string().default('bonk'), - }).default(), - }), - }) - .getPluginSpecs() - .pop(); - - describe('extendConfigService()', () => { - it('calls getSettings, getSchema, and Config.extendSchema() correctly', async () => { - const rootSettings = { - foo: { - bar: { - enabled: false, - }, - }, - }; - const schema = { - validate: () => {}, - }; - const configPrefix = 'foo.bar'; - const config = { - extendSchema: sandbox.stub(), - }; - const pluginSpec = { - getConfigPrefix: sandbox.stub().returns(configPrefix), - }; - - const getSettings = sandbox.stub(SettingsNS, 'getSettings').returns(rootSettings.foo.bar); - - const getSchema = sandbox.stub(SchemaNS, 'getSchema').returns(schema); - - await extendConfigService(pluginSpec, config, rootSettings); - - sinon.assert.calledOnce(getSettings); - sinon.assert.calledWithExactly(getSettings, pluginSpec, rootSettings); - - sinon.assert.calledOnce(getSchema); - sinon.assert.calledWithExactly(getSchema, pluginSpec); - - sinon.assert.calledOnce(config.extendSchema); - sinon.assert.calledWithExactly( - config.extendSchema, - schema, - rootSettings.foo.bar, - configPrefix - ); - }); - - it('adds the schema for a plugin spec to its config prefix', async () => { - const config = Config.withDefaultSchema(); - expect(config.has('foo.bar.baz')).to.be(false); - await extendConfigService(pluginSpec, config); - expect(config.has('foo.bar.baz')).to.be(true); - }); - - it('initializes it with the default settings', async () => { - const config = Config.withDefaultSchema(); - await extendConfigService(pluginSpec, config); - expect(config.get('foo.bar.baz.enabled')).to.be(true); - expect(config.get('foo.bar.baz.test')).to.be('bonk'); - }); - - it('initializes it with values from root settings if defined', async () => { - const config = Config.withDefaultSchema(); - await extendConfigService(pluginSpec, config, { - foo: { - bar: { - baz: { - test: 'hello world', - }, - }, - }, - }); - - expect(config.get('foo.bar.baz.test')).to.be('hello world'); - }); - - it('throws if root settings are invalid', async () => { - const config = Config.withDefaultSchema(); - try { - await extendConfigService(pluginSpec, config, { - foo: { - bar: { - baz: { - test: { - 'not a string': true, - }, - }, - }, - }, - }); - throw new Error('Expected extendConfigService() to throw because of bad settings'); - } catch (error) { - expect(error.message).to.contain('"test" must be a string'); - } - }); - }); - - describe('disableConfigExtension()', () => { - it('removes added config', async () => { - const config = Config.withDefaultSchema(); - await extendConfigService(pluginSpec, config); - expect(config.has('foo.bar.baz.test')).to.be(true); - await disableConfigExtension(pluginSpec, config); - expect(config.has('foo.bar.baz.test')).to.be(false); - }); - - it('leaves {configPrefix}.enabled config', async () => { - const config = Config.withDefaultSchema(); - expect(config.has('foo.bar.baz.enabled')).to.be(false); - await extendConfigService(pluginSpec, config); - expect(config.get('foo.bar.baz.enabled')).to.be(true); - await disableConfigExtension(pluginSpec, config); - expect(config.get('foo.bar.baz.enabled')).to.be(false); - }); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_config/__tests__/schema.js b/src/legacy/plugin_discovery/plugin_config/__tests__/schema.js deleted file mode 100644 index 78adb1e680e20..0000000000000 --- a/src/legacy/plugin_discovery/plugin_config/__tests__/schema.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 expect from '@kbn/expect'; - -import { PluginPack } from '../../plugin_pack'; -import { getSchema, getStubSchema } from '../schema'; - -describe('plugin discovery/schema', () => { - function createPluginSpec(configProvider) { - return new PluginPack({ - path: '/dev/null', - pkg: { - name: 'test', - version: 'kibana', - }, - provider: ({ Plugin }) => - new Plugin({ - configPrefix: 'foo.bar.baz', - config: configProvider, - }), - }) - .getPluginSpecs() - .pop(); - } - - describe('getSchema()', () => { - it('calls the config provider and returns its return value', async () => { - const pluginSpec = createPluginSpec(() => 'foo'); - expect(await getSchema(pluginSpec)).to.be('foo'); - }); - - it('supports config provider that returns a promise', async () => { - const pluginSpec = createPluginSpec(() => Promise.resolve('foo')); - expect(await getSchema(pluginSpec)).to.be('foo'); - }); - - it('uses default schema when no config provider', async () => { - const schema = await getSchema(createPluginSpec()); - expect(schema).to.be.an('object'); - expect(schema).to.have.property('validate').a('function'); - expect(schema.validate({}).value).to.eql({ - enabled: true, - }); - }); - - it('uses default schema when config returns falsy value', async () => { - const schema = await getSchema(createPluginSpec(() => null)); - expect(schema).to.be.an('object'); - expect(schema).to.have.property('validate').a('function'); - expect(schema.validate({}).value).to.eql({ - enabled: true, - }); - }); - - it('uses default schema when config promise resolves to falsy value', async () => { - const schema = await getSchema(createPluginSpec(() => Promise.resolve(null))); - expect(schema).to.be.an('object'); - expect(schema).to.have.property('validate').a('function'); - expect(schema.validate({}).value).to.eql({ - enabled: true, - }); - }); - }); - - describe('getStubSchema()', () => { - it('returns schema with enabled: false', async () => { - const schema = await getStubSchema(); - expect(schema).to.be.an('object'); - expect(schema).to.have.property('validate').a('function'); - expect(schema.validate({}).value).to.eql({ - enabled: false, - }); - }); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_config/__tests__/settings.js b/src/legacy/plugin_discovery/plugin_config/__tests__/settings.js deleted file mode 100644 index 750c5ee6c6f50..0000000000000 --- a/src/legacy/plugin_discovery/plugin_config/__tests__/settings.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 expect from '@kbn/expect'; - -import { PluginPack } from '../../plugin_pack'; -import { getSettings } from '../settings'; - -describe('plugin_discovery/settings', () => { - const pluginSpec = new PluginPack({ - path: '/dev/null', - pkg: { - name: 'test', - version: 'kibana', - }, - provider: ({ Plugin }) => - new Plugin({ - configPrefix: 'a.b.c', - }), - }) - .getPluginSpecs() - .pop(); - - describe('getSettings()', () => { - it('reads settings from config prefix', async () => { - const rootSettings = { - a: { - b: { - c: { - enabled: false, - }, - }, - }, - }; - - expect(await getSettings(pluginSpec, rootSettings)).to.eql({ - enabled: false, - }); - }); - - it('allows rootSettings to be undefined', async () => { - expect(await getSettings(pluginSpec)).to.eql(undefined); - }); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_config/extend_config_service.js b/src/legacy/plugin_discovery/plugin_config/extend_config_service.js deleted file mode 100644 index a6d5d4ae5f990..0000000000000 --- a/src/legacy/plugin_discovery/plugin_config/extend_config_service.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 { getSettings } from './settings'; -import { getSchema, getStubSchema } from './schema'; - -/** - * Extend a config service with the schema and settings for a - * plugin spec and optionally call logDeprecation with warning - * messages about deprecated settings that are used - * @param {PluginSpec} spec - * @param {Server.Config} config - * @param {Object} rootSettings - * @param {Function} [logDeprecation] - * @return {Promise} - */ -export async function extendConfigService(spec, config, rootSettings) { - const settings = await getSettings(spec, rootSettings); - const schema = await getSchema(spec); - config.extendSchema(schema, settings, spec.getConfigPrefix()); -} - -/** - * Disable the schema and settings applied to a config service for - * a plugin spec - * @param {PluginSpec} spec - * @param {Server.Config} config - * @return {undefined} - */ -export function disableConfigExtension(spec, config) { - const prefix = spec.getConfigPrefix(); - config.removeSchema(prefix); - config.extendSchema(getStubSchema(), { enabled: false }, prefix); -} diff --git a/src/legacy/plugin_discovery/plugin_config/index.js b/src/legacy/plugin_discovery/plugin_config/index.js deleted file mode 100644 index a27463bc9c7f5..0000000000000 --- a/src/legacy/plugin_discovery/plugin_config/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export { extendConfigService, disableConfigExtension } from './extend_config_service'; diff --git a/src/legacy/plugin_discovery/plugin_config/schema.js b/src/legacy/plugin_discovery/plugin_config/schema.js deleted file mode 100644 index 14d10aa5568da..0000000000000 --- a/src/legacy/plugin_discovery/plugin_config/schema.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 Joi from 'joi'; - -const STUB_CONFIG_SCHEMA = Joi.object() - .keys({ - enabled: Joi.valid(false).default(false), - }) - .default(); - -const DEFAULT_CONFIG_SCHEMA = Joi.object() - .keys({ - enabled: Joi.boolean().default(true), - }) - .default(); - -/** - * Get the config schema for a plugin spec - * @param {PluginSpec} spec - * @return {Promise} - */ -export async function getSchema(spec) { - const provider = spec.getConfigSchemaProvider(); - return (provider && (await provider(Joi))) || DEFAULT_CONFIG_SCHEMA; -} - -export function getStubSchema() { - return STUB_CONFIG_SCHEMA; -} diff --git a/src/legacy/plugin_discovery/plugin_config/settings.js b/src/legacy/plugin_discovery/plugin_config/settings.js deleted file mode 100644 index e6a4741d76eca..0000000000000 --- a/src/legacy/plugin_discovery/plugin_config/settings.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 { get } from 'lodash'; - -/** - * Get the settings for a pluginSpec from the raw root settings while - * optionally calling logDeprecation() with warnings about deprecated - * settings that were used - * @param {PluginSpec} spec - * @param {Object} rootSettings - * @return {Promise} - */ -export async function getSettings(spec, rootSettings) { - const prefix = spec.getConfigPrefix(); - const rawSettings = get(rootSettings, prefix); - return rawSettings; -} diff --git a/src/legacy/plugin_discovery/plugin_exports/__tests__/reduce_export_specs.js b/src/legacy/plugin_discovery/plugin_exports/__tests__/reduce_export_specs.js deleted file mode 100644 index 3beaacc1a8293..0000000000000 --- a/src/legacy/plugin_discovery/plugin_exports/__tests__/reduce_export_specs.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 expect from '@kbn/expect'; - -import { PluginPack } from '../../plugin_pack'; -import { reduceExportSpecs } from '../reduce_export_specs'; - -const PLUGIN = new PluginPack({ - path: __dirname, - pkg: { - name: 'foo', - version: 'kibana', - }, - provider: ({ Plugin }) => - new Plugin({ - uiExports: { - concatNames: { - name: 'export1', - }, - - concat: ['export2', 'export3'], - }, - }), -}); - -const REDUCERS = { - concatNames(acc, spec, type, pluginSpec) { - return { - names: [].concat(acc.names || [], `${pluginSpec.getId()}:${spec.name}`), - }; - }, - concat(acc, spec, type, pluginSpec) { - return { - names: [].concat(acc.names || [], `${pluginSpec.getId()}:${spec}`), - }; - }, -}; - -const PLUGIN_SPECS = PLUGIN.getPluginSpecs(); - -describe('reduceExportSpecs', () => { - it('combines ui exports from a list of plugin definitions', () => { - const exports = reduceExportSpecs(PLUGIN_SPECS, REDUCERS); - expect(exports).to.eql({ - names: ['foo:export1', 'foo:export2', 'foo:export3'], - }); - }); - - it('starts with the defaults', () => { - const exports = reduceExportSpecs(PLUGIN_SPECS, REDUCERS, { - names: ['default'], - }); - - expect(exports).to.eql({ - names: ['default', 'foo:export1', 'foo:export2', 'foo:export3'], - }); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_exports/index.js b/src/legacy/plugin_discovery/plugin_exports/index.js deleted file mode 100644 index 0e3511ea85dd4..0000000000000 --- a/src/legacy/plugin_discovery/plugin_exports/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export { reduceExportSpecs } from './reduce_export_specs'; diff --git a/src/legacy/plugin_discovery/plugin_exports/reduce_export_specs.js b/src/legacy/plugin_discovery/plugin_exports/reduce_export_specs.js deleted file mode 100644 index a3adc3091085d..0000000000000 --- a/src/legacy/plugin_discovery/plugin_exports/reduce_export_specs.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - */ - -/** - * Combine the exportSpecs from a list of pluginSpecs - * by calling the reducers for each export type - * @param {Array} pluginSpecs - * @param {Object} reducers - * @param {Object} [defaults={}] - * @return {Object} - */ -export function reduceExportSpecs(pluginSpecs, reducers, defaults = {}) { - return pluginSpecs.reduce((acc, pluginSpec) => { - const specsByType = pluginSpec.getExportSpecs() || {}; - const types = Object.keys(specsByType); - - return types.reduce((acc, type) => { - const reducer = reducers[type] || reducers.unknown; - - if (!reducer) { - throw new Error(`Unknown export type ${type}`); - } - - // convert specs to an array if not already one or - // ignore the spec if it is undefined - const specs = [].concat(specsByType[type] === undefined ? [] : specsByType[type]); - - return specs.reduce((acc, spec) => reducer(acc, spec, type, pluginSpec), acc); - }, acc); - }, defaults); -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/create_pack.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/create_pack.js deleted file mode 100644 index b17bd69479ffa..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/create_pack.js +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 { resolve } from 'path'; -import * as Rx from 'rxjs'; -import { toArray } from 'rxjs/operators'; -import expect from '@kbn/expect'; - -import { createPack$ } from '../create_pack'; -import { PluginPack } from '../plugin_pack'; - -import { PLUGINS_DIR, assertInvalidPackError } from './utils'; - -describe('plugin discovery/create pack', () => { - it('creates PluginPack', async () => { - const packageJson$ = Rx.from([ - { - packageJson: { - directoryPath: resolve(PLUGINS_DIR, 'prebuilt'), - contents: { - name: 'prebuilt', - }, - }, - }, - ]); - const results = await createPack$(packageJson$).pipe(toArray()).toPromise(); - expect(results).to.have.length(1); - expect(results[0]).to.only.have.keys(['pack']); - const { pack } = results[0]; - expect(pack).to.be.a(PluginPack); - }); - - describe('errors thrown', () => { - async function checkError(path, check) { - const packageJson$ = Rx.from([ - { - packageJson: { - directoryPath: path, - }, - }, - ]); - - const results = await createPack$(packageJson$).pipe(toArray()).toPromise(); - expect(results).to.have.length(1); - expect(results[0]).to.only.have.keys(['error']); - const { error } = results[0]; - await check(error); - } - it('default export is an object', () => - checkError(resolve(PLUGINS_DIR, 'exports_object'), (error) => { - assertInvalidPackError(error); - expect(error.message).to.contain('must export a function'); - })); - it('default export is an number', () => - checkError(resolve(PLUGINS_DIR, 'exports_number'), (error) => { - assertInvalidPackError(error); - expect(error.message).to.contain('must export a function'); - })); - it('default export is an string', () => - checkError(resolve(PLUGINS_DIR, 'exports_string'), (error) => { - assertInvalidPackError(error); - expect(error.message).to.contain('must export a function'); - })); - it('directory with code that fails when required', () => - checkError(resolve(PLUGINS_DIR, 'broken_code'), (error) => { - expect(error.message).to.contain("Cannot find module 'does-not-exist'"); - })); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken/package.json b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken/package.json deleted file mode 100644 index f830e8b60c02d..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken_code/index.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken_code/index.js deleted file mode 100644 index bdb26504d6b6e..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken_code/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const brokenRequire = require('does-not-exist'); // eslint-disable-line - -module.exports = function (kibana) { - return new kibana.Plugin({ - id: 'foo', - }); -}; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken_code/package.json b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken_code/package.json deleted file mode 100644 index e43c2f0bc984c..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/broken_code/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_number/index.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_number/index.js deleted file mode 100644 index f24fc54e38d9a..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_number/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export default 1; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_number/package.json b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_number/package.json deleted file mode 100644 index e43c2f0bc984c..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_number/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_object/index.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_object/index.js deleted file mode 100644 index 59f4a2649f019..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_object/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -export default { - foo: 'bar', -}; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_object/package.json b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_object/package.json deleted file mode 100644 index e43c2f0bc984c..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_object/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_string/index.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_string/index.js deleted file mode 100644 index 8900db15321ae..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_string/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export default 'foo'; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_string/package.json b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_string/package.json deleted file mode 100644 index e43c2f0bc984c..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/exports_string/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/foo/index.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/foo/index.js deleted file mode 100644 index e43a1dcedb372..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/foo/index.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - */ - -module.exports = function (kibana) { - return new kibana.Plugin({ - id: 'foo', - }); -}; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/foo/package.json b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/foo/package.json deleted file mode 100644 index e43c2f0bc984c..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/foo/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "version": "kibana" -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/index.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/index.js deleted file mode 100644 index edb1dd15673da..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -console.log('hello world'); diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/lib/index.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/lib/index.js deleted file mode 100644 index 050ffdfbde9ea..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/lib/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export { myLib } from './my_lib'; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/lib/my_lib.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/lib/my_lib.js deleted file mode 100644 index 94e511632d9a6..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/lib/my_lib.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -export function myLib() { - console.log('lib'); -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/prebuilt/index.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/prebuilt/index.js deleted file mode 100644 index 89744b2dd3fd9..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/prebuilt/index.js +++ /dev/null @@ -1,14 +0,0 @@ -/* eslint-disable */ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -exports.default = function (_ref) { - var Plugin = _ref.Plugin; - - return new Plugin({ - id: 'foo' - }); -}; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/prebuilt/package.json b/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/prebuilt/package.json deleted file mode 100644 index b1b74e0e76b12..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/fixtures/plugins/prebuilt/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "prebuilt" -} diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/package_json_at_path.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/package_json_at_path.js deleted file mode 100644 index fa1033180954e..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/package_json_at_path.js +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 { resolve } from 'path'; -import { toArray } from 'rxjs/operators'; - -import expect from '@kbn/expect'; - -import { createPackageJsonAtPath$ } from '../package_json_at_path'; -import { PLUGINS_DIR, assertInvalidPackError, assertInvalidDirectoryError } from './utils'; - -describe('plugin discovery/plugin_pack', () => { - describe('createPackageJsonAtPath$()', () => { - it('returns an observable', () => { - expect(createPackageJsonAtPath$()).to.have.property('subscribe').a('function'); - }); - it('gets the default provider from prebuilt babel modules', async () => { - const results = await createPackageJsonAtPath$(resolve(PLUGINS_DIR, 'prebuilt')) - .pipe(toArray()) - .toPromise(); - expect(results).to.have.length(1); - expect(results[0]).to.only.have.keys(['packageJson']); - expect(results[0].packageJson).to.be.an(Object); - expect(results[0].packageJson.directoryPath).to.be(resolve(PLUGINS_DIR, 'prebuilt')); - expect(results[0].packageJson.contents).to.eql({ name: 'prebuilt' }); - }); - describe('errors emitted as { error } results', () => { - async function checkError(path, check) { - const results = await createPackageJsonAtPath$(path).pipe(toArray()).toPromise(); - expect(results).to.have.length(1); - expect(results[0]).to.only.have.keys(['error']); - const { error } = results[0]; - await check(error); - } - it('undefined path', () => - checkError(undefined, (error) => { - assertInvalidDirectoryError(error); - expect(error.message).to.contain('path must be a string'); - })); - it('relative path', () => - checkError('plugins/foo', (error) => { - assertInvalidDirectoryError(error); - expect(error.message).to.contain('path must be absolute'); - })); - it('./relative path', () => - checkError('./plugins/foo', (error) => { - assertInvalidDirectoryError(error); - expect(error.message).to.contain('path must be absolute'); - })); - it('non-existent path', () => - checkError(resolve(PLUGINS_DIR, 'baz'), (error) => { - assertInvalidPackError(error); - expect(error.message).to.contain('must be a directory'); - })); - it('path to a file', () => - checkError(resolve(PLUGINS_DIR, 'index.js'), (error) => { - assertInvalidPackError(error); - expect(error.message).to.contain('must be a directory'); - })); - it('directory without a package.json', () => - checkError(resolve(PLUGINS_DIR, 'lib'), (error) => { - assertInvalidPackError(error); - expect(error.message).to.contain('must have a package.json file'); - })); - it('directory with an invalid package.json', () => - checkError(resolve(PLUGINS_DIR, 'broken'), (error) => { - assertInvalidPackError(error); - expect(error.message).to.contain('must have a valid package.json file'); - })); - }); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/package_jsons_in_directory.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/package_jsons_in_directory.js deleted file mode 100644 index 37cb4cc064da7..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/package_jsons_in_directory.js +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 { resolve } from 'path'; - -import { toArray } from 'rxjs/operators'; -import expect from '@kbn/expect'; - -import { createPackageJsonsInDirectory$ } from '../package_jsons_in_directory'; - -import { PLUGINS_DIR, assertInvalidDirectoryError } from './utils'; - -describe('plugin discovery/packs in directory', () => { - describe('createPackageJsonsInDirectory$()', () => { - describe('errors emitted as { error } results', () => { - async function checkError(path, check) { - const results = await createPackageJsonsInDirectory$(path).pipe(toArray()).toPromise(); - expect(results).to.have.length(1); - expect(results[0]).to.only.have.keys('error'); - const { error } = results[0]; - await check(error); - } - - it('undefined path', () => - checkError(undefined, (error) => { - assertInvalidDirectoryError(error); - expect(error.message).to.contain('path must be a string'); - })); - it('relative path', () => - checkError('my/plugins', (error) => { - assertInvalidDirectoryError(error); - expect(error.message).to.contain('path must be absolute'); - })); - it('./relative path', () => - checkError('./my/pluginsd', (error) => { - assertInvalidDirectoryError(error); - expect(error.message).to.contain('path must be absolute'); - })); - it('non-existent path', () => - checkError(resolve(PLUGINS_DIR, 'notreal'), (error) => { - assertInvalidDirectoryError(error); - expect(error.message).to.contain('no such file or directory'); - })); - it('path to a file', () => - checkError(resolve(PLUGINS_DIR, 'index.js'), (error) => { - assertInvalidDirectoryError(error); - expect(error.message).to.contain('not a directory'); - })); - }); - - it('includes child errors for invalid packageJsons within a valid directory', async () => { - const results = await createPackageJsonsInDirectory$(PLUGINS_DIR).pipe(toArray()).toPromise(); - - const errors = results.map((result) => result.error).filter(Boolean); - - const packageJsons = results.map((result) => result.packageJson).filter(Boolean); - - packageJsons.forEach((pack) => expect(pack).to.be.an(Object)); - // there should be one result for each item in PLUGINS_DIR - expect(results).to.have.length(8); - // three of the fixtures are errors of some sort - expect(errors).to.have.length(2); - // six of them are valid - expect(packageJsons).to.have.length(6); - }); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/plugin_pack.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/plugin_pack.js deleted file mode 100644 index 769fcd74ce6fb..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/plugin_pack.js +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 expect from '@kbn/expect'; -import sinon from 'sinon'; - -import { PluginPack } from '../plugin_pack'; -import { PluginSpec } from '../../plugin_spec'; - -describe('plugin discovery/plugin pack', () => { - describe('constructor', () => { - it('requires an object', () => { - expect(() => { - new PluginPack(); - }).to.throwError(); - }); - }); - describe('#getPkg()', () => { - it('returns the `pkg` constructor argument', () => { - const pkg = {}; - const pack = new PluginPack({ pkg }); - expect(pack.getPkg()).to.be(pkg); - }); - }); - describe('#getPath()', () => { - it('returns the `path` constructor argument', () => { - const path = {}; - const pack = new PluginPack({ path }); - expect(pack.getPath()).to.be(path); - }); - }); - describe('#getPluginSpecs()', () => { - it('calls the `provider` constructor argument with an api including a single sub class of PluginSpec', () => { - const provider = sinon.stub(); - const pack = new PluginPack({ provider }); - sinon.assert.notCalled(provider); - pack.getPluginSpecs(); - sinon.assert.calledOnce(provider); - sinon.assert.calledWithExactly(provider, { - Plugin: sinon.match((Class) => { - return Class.prototype instanceof PluginSpec; - }, 'Subclass of PluginSpec'), - }); - }); - - it('casts undefined return value to array', () => { - const pack = new PluginPack({ provider: () => undefined }); - expect(pack.getPluginSpecs()).to.eql([]); - }); - - it('casts single PluginSpec to an array', () => { - const pack = new PluginPack({ - path: '/dev/null', - pkg: { name: 'foo', version: 'kibana' }, - provider: ({ Plugin }) => new Plugin({}), - }); - - const specs = pack.getPluginSpecs(); - expect(specs).to.be.an('array'); - expect(specs).to.have.length(1); - expect(specs[0]).to.be.a(PluginSpec); - }); - - it('returns an array of PluginSpec', () => { - const pack = new PluginPack({ - path: '/dev/null', - pkg: { name: 'foo', version: 'kibana' }, - provider: ({ Plugin }) => [new Plugin({}), new Plugin({})], - }); - - const specs = pack.getPluginSpecs(); - expect(specs).to.be.an('array'); - expect(specs).to.have.length(2); - expect(specs[0]).to.be.a(PluginSpec); - expect(specs[1]).to.be.a(PluginSpec); - }); - - it('throws if non-undefined return value is not an instance of api.Plugin', () => { - let OtherPluginSpecClass; - const otherPack = new PluginPack({ - path: '/dev/null', - pkg: { name: 'foo', version: 'kibana' }, - provider: (api) => { - OtherPluginSpecClass = api.Plugin; - }, - }); - - // call getPluginSpecs() on other pack to get it's api.Plugin class - otherPack.getPluginSpecs(); - - const badPacks = [ - new PluginPack({ provider: () => false }), - new PluginPack({ provider: () => null }), - new PluginPack({ provider: () => 1 }), - new PluginPack({ provider: () => 'true' }), - new PluginPack({ provider: () => true }), - new PluginPack({ provider: () => new Date() }), - new PluginPack({ provider: () => /foo.*bar/ }), - new PluginPack({ provider: () => function () {} }), - new PluginPack({ provider: () => new OtherPluginSpecClass({}) }), - ]; - - for (const pack of badPacks) { - expect(() => pack.getPluginSpecs()).to.throwError((error) => { - expect(error.message).to.contain('unexpected plugin export'); - }); - } - }); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/utils.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/utils.js deleted file mode 100644 index adcf60d809ff7..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/utils.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 { resolve } from 'path'; -import { inspect } from 'util'; - -import { isInvalidPackError, isInvalidDirectoryError } from '../../errors'; - -export const PLUGINS_DIR = resolve(__dirname, 'fixtures/plugins'); - -export function assertInvalidDirectoryError(error) { - if (!isInvalidDirectoryError(error)) { - throw new Error(`Expected ${inspect(error)} to be an 'InvalidDirectoryError'`); - } -} - -export function assertInvalidPackError(error) { - if (!isInvalidPackError(error)) { - throw new Error(`Expected ${inspect(error)} to be an 'InvalidPackError'`); - } -} diff --git a/src/legacy/plugin_discovery/plugin_pack/create_pack.js b/src/legacy/plugin_discovery/plugin_pack/create_pack.js deleted file mode 100644 index 189c2ea324103..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/create_pack.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 { PluginPack } from './plugin_pack'; -import { map, catchError } from 'rxjs/operators'; -import { createInvalidPackError } from '../errors'; - -function createPack(packageJson) { - let provider = require(packageJson.directoryPath); // eslint-disable-line import/no-dynamic-require - if (provider.__esModule) { - provider = provider.default; - } - if (typeof provider !== 'function') { - throw createInvalidPackError(packageJson.directoryPath, 'must export a function'); - } - - return new PluginPack({ path: packageJson.directoryPath, pkg: packageJson.contents, provider }); -} - -export const createPack$ = (packageJson$) => - packageJson$.pipe( - map(({ error, packageJson }) => { - if (error) { - return { error }; - } - - if (!packageJson) { - throw new Error('packageJson is required to create the pack'); - } - - return { - pack: createPack(packageJson), - }; - }), - // createPack can throw errors, and we want them to be represented - // like the errors we consume from createPackageJsonAtPath/Directory - catchError((error) => [{ error }]) - ); diff --git a/src/legacy/plugin_discovery/plugin_pack/index.js b/src/legacy/plugin_discovery/plugin_pack/index.js deleted file mode 100644 index 69e55baee660b..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/index.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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. - */ - -export { createPack$ } from './create_pack'; -export { createPackageJsonAtPath$ } from './package_json_at_path'; -export { createPackageJsonsInDirectory$ } from './package_jsons_in_directory'; -export { PluginPack } from './plugin_pack'; diff --git a/src/legacy/plugin_discovery/plugin_pack/lib/fs.js b/src/legacy/plugin_discovery/plugin_pack/lib/fs.js deleted file mode 100644 index 2b531e314df52..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/lib/fs.js +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 { stat, readdir } from 'fs'; -import { resolve, isAbsolute } from 'path'; - -import { fromNode as fcb } from 'bluebird'; -import * as Rx from 'rxjs'; -import { catchError, mergeAll, filter, map, mergeMap } from 'rxjs/operators'; - -import { createInvalidDirectoryError } from '../../errors'; - -function assertAbsolutePath(path) { - if (typeof path !== 'string') { - throw createInvalidDirectoryError(new TypeError('path must be a string'), path); - } - - if (!isAbsolute(path)) { - throw createInvalidDirectoryError(new TypeError('path must be absolute'), path); - } -} - -async function statTest(path, test) { - try { - const stats = await fcb((cb) => stat(path, cb)); - return Boolean(test(stats)); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } - return false; -} - -/** - * Determine if a path currently points to a directory - * @param {String} path - * @return {Promise} - */ -export async function isDirectory(path) { - assertAbsolutePath(path); - return await statTest(path, (stat) => stat.isDirectory()); -} - -/** - * Get absolute paths for child directories within a path - * @param {string} path - * @return {Promise>} - */ -export const createChildDirectory$ = (path) => - Rx.defer(() => { - assertAbsolutePath(path); - return fcb((cb) => readdir(path, cb)); - }).pipe( - catchError((error) => { - throw createInvalidDirectoryError(error, path); - }), - mergeAll(), - filter((name) => !name.startsWith('.')), - map((name) => resolve(path, name)), - mergeMap(async (absolute) => { - if (await isDirectory(absolute)) { - return [absolute]; - } else { - return []; - } - }), - mergeAll() - ); diff --git a/src/legacy/plugin_discovery/plugin_pack/lib/index.js b/src/legacy/plugin_discovery/plugin_pack/lib/index.js deleted file mode 100644 index 491deeda27516..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/lib/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export { isDirectory, createChildDirectory$ } from './fs'; diff --git a/src/legacy/plugin_discovery/plugin_pack/package_json_at_path.js b/src/legacy/plugin_discovery/plugin_pack/package_json_at_path.js deleted file mode 100644 index 18629ef3ea802..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/package_json_at_path.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 { readFileSync } from 'fs'; -import * as Rx from 'rxjs'; -import { map, mergeMap, catchError } from 'rxjs/operators'; -import { resolve } from 'path'; -import { createInvalidPackError } from '../errors'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { isNewPlatformPlugin } from '../../../core/server/plugins'; - -import { isDirectory } from './lib'; - -async function createPackageJsonAtPath(path) { - if (!(await isDirectory(path))) { - throw createInvalidPackError(path, 'must be a directory'); - } - - let str; - try { - str = readFileSync(resolve(path, 'package.json')); - } catch (err) { - throw createInvalidPackError(path, 'must have a package.json file'); - } - - let pkg; - try { - pkg = JSON.parse(str); - } catch (err) { - throw createInvalidPackError(path, 'must have a valid package.json file'); - } - - return { - directoryPath: path, - contents: pkg, - }; -} - -export const createPackageJsonAtPath$ = (path) => - // If plugin directory contains manifest file, we should skip it since it - // should have been handled by the core plugin system already. - Rx.defer(() => isNewPlatformPlugin(path)).pipe( - mergeMap((isNewPlatformPlugin) => (isNewPlatformPlugin ? [] : createPackageJsonAtPath(path))), - map((packageJson) => ({ packageJson })), - catchError((error) => [{ error }]) - ); diff --git a/src/legacy/plugin_discovery/plugin_pack/package_jsons_in_directory.js b/src/legacy/plugin_discovery/plugin_pack/package_jsons_in_directory.js deleted file mode 100644 index 5f0977f4829b8..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/package_jsons_in_directory.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 { mergeMap, catchError } from 'rxjs/operators'; -import { isInvalidDirectoryError } from '../errors'; - -import { createChildDirectory$ } from './lib'; -import { createPackageJsonAtPath$ } from './package_json_at_path'; - -/** - * Finds the plugins within a directory. Results are - * an array of objects with either `pack` or `error` - * keys. - * - * - `{ error }` results are provided when the path is not - * a directory, or one of the child directories is not a - * valid plugin pack. - * - `{ pack }` results are for discovered plugins defs - * - * @param {String} path - * @return {Array<{pack}|{error}>} - */ -export const createPackageJsonsInDirectory$ = (path) => - createChildDirectory$(path).pipe( - mergeMap(createPackageJsonAtPath$), - catchError((error) => { - // this error is produced by createChildDirectory$() when the path - // is invalid, we return them as an error result similar to how - // createPackAtPath$ works when it finds invalid packs in a directory - if (isInvalidDirectoryError(error)) { - return [{ error }]; - } - - throw error; - }) - ); diff --git a/src/legacy/plugin_discovery/plugin_pack/plugin_pack.js b/src/legacy/plugin_discovery/plugin_pack/plugin_pack.js deleted file mode 100644 index 1baf3d104ca84..0000000000000 --- a/src/legacy/plugin_discovery/plugin_pack/plugin_pack.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 { inspect } from 'util'; - -import { PluginSpec } from '../plugin_spec'; - -export class PluginPack { - constructor({ path, pkg, provider }) { - this._path = path; - this._pkg = pkg; - this._provider = provider; - } - - /** - * Get the contents of this plugin pack's package.json file - * @return {Object} - */ - getPkg() { - return this._pkg; - } - - /** - * Get the absolute path to this plugin pack on disk - * @return {String} - */ - getPath() { - return this._path; - } - - /** - * Invoke the plugin pack's provider to get the list - * of specs defined in this plugin. - * @return {Array} - */ - getPluginSpecs() { - const pack = this; - const api = { - Plugin: class ScopedPluginSpec extends PluginSpec { - constructor(options) { - super(pack, options); - } - }, - }; - - const result = this._provider(api); - const specs = [].concat(result === undefined ? [] : result); - - // verify that all specs are instances of passed "Plugin" class - specs.forEach((spec) => { - if (!(spec instanceof api.Plugin)) { - throw new TypeError('unexpected plugin export ' + inspect(spec)); - } - }); - - return specs; - } -} diff --git a/src/legacy/plugin_discovery/plugin_spec/__tests__/is_version_compatible.js b/src/legacy/plugin_discovery/plugin_spec/__tests__/is_version_compatible.js deleted file mode 100644 index 897184496af37..0000000000000 --- a/src/legacy/plugin_discovery/plugin_spec/__tests__/is_version_compatible.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 expect from '@kbn/expect'; - -import { isVersionCompatible } from '../is_version_compatible'; - -describe('plugin discovery/plugin spec', () => { - describe('isVersionCompatible()', () => { - const tests = [ - ['kibana', '6.0.0', true], - ['kibana', '6.0.0-rc1', true], - ['6.0.0-rc1', '6.0.0', true], - ['6.0.0', '6.0.0-rc1', true], - ['6.0.0-rc2', '6.0.0-rc1', true], - ['6.0.0-rc2', '6.0.0-rc3', true], - ['foo', 'bar', false], - ['6.0.0', '5.1.4', false], - ['5.1.4', '6.0.0', false], - ['5.1.4-SNAPSHOT', '6.0.0-rc2-SNAPSHOT', false], - ['5.1.4', '6.0.0-rc2-SNAPSHOT', false], - ['5.1.4-SNAPSHOT', '6.0.0', false], - ['5.1.4-SNAPSHOT', '6.0.0-rc2', false], - ]; - - for (const [plugin, kibana, shouldPass] of tests) { - it(`${shouldPass ? 'should' : `shouldn't`} allow plugin: ${plugin} kibana: ${kibana}`, () => { - expect(isVersionCompatible(plugin, kibana)).to.be(shouldPass); - }); - } - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_spec/__tests__/plugin_spec.js b/src/legacy/plugin_discovery/plugin_spec/__tests__/plugin_spec.js deleted file mode 100644 index 02675f0bd60f8..0000000000000 --- a/src/legacy/plugin_discovery/plugin_spec/__tests__/plugin_spec.js +++ /dev/null @@ -1,496 +0,0 @@ -/* - * 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 { resolve } from 'path'; - -import expect from '@kbn/expect'; -import sinon from 'sinon'; - -import { PluginPack } from '../../plugin_pack'; -import { PluginSpec } from '../plugin_spec'; -import * as IsVersionCompatibleNS from '../is_version_compatible'; - -const fooPack = new PluginPack({ - path: '/dev/null', - pkg: { name: 'foo', version: 'kibana' }, -}); - -describe('plugin discovery/plugin spec', () => { - describe('PluginSpec', () => { - describe('validation', () => { - it('throws if missing spec.id AND Pack has no name', () => { - const pack = new PluginPack({ pkg: {} }); - expect(() => new PluginSpec(pack, {})).to.throwError((error) => { - expect(error.message).to.contain('Unable to determine plugin id'); - }); - }); - - it('throws if missing spec.kibanaVersion AND Pack has no version', () => { - const pack = new PluginPack({ pkg: { name: 'foo' } }); - expect(() => new PluginSpec(pack, {})).to.throwError((error) => { - expect(error.message).to.contain('Unable to determine plugin version'); - }); - }); - - it('throws if spec.require is defined, but not an array', () => { - function assert(require) { - expect(() => new PluginSpec(fooPack, { require })).to.throwError((error) => { - expect(error.message).to.contain('"plugin.require" must be an array of plugin ids'); - }); - } - - assert(null); - assert(''); - assert('kibana'); - assert(1); - assert(0); - assert(/a.*b/); - }); - - it('throws if spec.publicDir is truthy and not a string', () => { - function assert(publicDir) { - expect(() => new PluginSpec(fooPack, { publicDir })).to.throwError((error) => { - expect(error.message).to.contain( - `The "path" argument must be of type string. Received type ${typeof publicDir}` - ); - }); - } - - assert(1); - assert(function () {}); - assert([]); - assert(/a.*b/); - }); - - it('throws if spec.publicDir is not an absolute path', () => { - function assert(publicDir) { - expect(() => new PluginSpec(fooPack, { publicDir })).to.throwError((error) => { - expect(error.message).to.contain('plugin.publicDir must be an absolute path'); - }); - } - - assert('relative/path'); - assert('./relative/path'); - }); - - it('throws if spec.publicDir basename is not `public`', () => { - function assert(publicDir) { - expect(() => new PluginSpec(fooPack, { publicDir })).to.throwError((error) => { - expect(error.message).to.contain('must end with a "public" directory'); - }); - } - - assert('/www'); - assert('/www/'); - assert('/www/public/my_plugin'); - assert('/www/public/my_plugin/'); - }); - }); - - describe('#getPack()', () => { - it('returns the pack', () => { - const spec = new PluginSpec(fooPack, {}); - expect(spec.getPack()).to.be(fooPack); - }); - }); - - describe('#getPkg()', () => { - it('returns the pkg from the pack', () => { - const spec = new PluginSpec(fooPack, {}); - expect(spec.getPkg()).to.be(fooPack.getPkg()); - }); - }); - - describe('#getPath()', () => { - it('returns the path from the pack', () => { - const spec = new PluginSpec(fooPack, {}); - expect(spec.getPath()).to.be(fooPack.getPath()); - }); - }); - - describe('#getId()', () => { - it('uses spec.id', () => { - const spec = new PluginSpec(fooPack, { - id: 'bar', - }); - - expect(spec.getId()).to.be('bar'); - }); - - it('defaults to pack.pkg.name', () => { - const spec = new PluginSpec(fooPack, {}); - - expect(spec.getId()).to.be('foo'); - }); - }); - - describe('#getVersion()', () => { - it('uses spec.version', () => { - const spec = new PluginSpec(fooPack, { - version: 'bar', - }); - - expect(spec.getVersion()).to.be('bar'); - }); - - it('defaults to pack.pkg.version', () => { - const spec = new PluginSpec(fooPack, {}); - - expect(spec.getVersion()).to.be('kibana'); - }); - }); - - describe('#isEnabled()', () => { - describe('spec.isEnabled is not defined', () => { - function setup(configPrefix, configGetImpl) { - const spec = new PluginSpec(fooPack, { configPrefix }); - const config = { - get: sinon.spy(configGetImpl), - has: sinon.stub(), - }; - - return { spec, config }; - } - - it('throws if not passed a config service', () => { - const { spec } = setup('a.b.c', () => true); - - expect(() => spec.isEnabled()).to.throwError((error) => { - expect(error.message).to.contain('must be called with a config service'); - }); - expect(() => spec.isEnabled(null)).to.throwError((error) => { - expect(error.message).to.contain('must be called with a config service'); - }); - expect(() => spec.isEnabled({ get: () => {} })).to.throwError((error) => { - expect(error.message).to.contain('must be called with a config service'); - }); - }); - - it('returns true when config.get([...configPrefix, "enabled"]) returns true', () => { - const { spec, config } = setup('d.e.f', () => true); - - expect(spec.isEnabled(config)).to.be(true); - sinon.assert.calledOnce(config.get); - sinon.assert.calledWithExactly(config.get, ['d', 'e', 'f', 'enabled']); - }); - - it('returns false when config.get([...configPrefix, "enabled"]) returns false', () => { - const { spec, config } = setup('g.h.i', () => false); - - expect(spec.isEnabled(config)).to.be(false); - sinon.assert.calledOnce(config.get); - sinon.assert.calledWithExactly(config.get, ['g', 'h', 'i', 'enabled']); - }); - }); - - describe('spec.isEnabled is defined', () => { - function setup(isEnabledImpl) { - const isEnabled = sinon.spy(isEnabledImpl); - const spec = new PluginSpec(fooPack, { isEnabled }); - const config = { - get: sinon.stub(), - has: sinon.stub(), - }; - - return { isEnabled, spec, config }; - } - - it('throws if not passed a config service', () => { - const { spec } = setup(() => true); - - expect(() => spec.isEnabled()).to.throwError((error) => { - expect(error.message).to.contain('must be called with a config service'); - }); - expect(() => spec.isEnabled(null)).to.throwError((error) => { - expect(error.message).to.contain('must be called with a config service'); - }); - expect(() => spec.isEnabled({ get: () => {} })).to.throwError((error) => { - expect(error.message).to.contain('must be called with a config service'); - }); - }); - - it('does not check config if spec.isEnabled returns true', () => { - const { spec, isEnabled, config } = setup(() => true); - - expect(spec.isEnabled(config)).to.be(true); - sinon.assert.calledOnce(isEnabled); - sinon.assert.notCalled(config.get); - }); - - it('does not check config if spec.isEnabled returns false', () => { - const { spec, isEnabled, config } = setup(() => false); - - expect(spec.isEnabled(config)).to.be(false); - sinon.assert.calledOnce(isEnabled); - sinon.assert.notCalled(config.get); - }); - }); - }); - - describe('#getExpectedKibanaVersion()', () => { - describe('has: spec.kibanaVersion,pkg.kibana.version,spec.version,pkg.version', () => { - it('uses spec.kibanaVersion', () => { - const pack = new PluginPack({ - path: '/dev/null', - pkg: { - name: 'expkv', - version: '1.0.0', - kibana: { - version: '6.0.0', - }, - }, - }); - - const spec = new PluginSpec(pack, { - version: '2.0.0', - kibanaVersion: '5.0.0', - }); - - expect(spec.getExpectedKibanaVersion()).to.be('5.0.0'); - }); - }); - describe('missing: spec.kibanaVersion, has: pkg.kibana.version,spec.version,pkg.version', () => { - it('uses pkg.kibana.version', () => { - const pack = new PluginPack({ - path: '/dev/null', - pkg: { - name: 'expkv', - version: '1.0.0', - kibana: { - version: '6.0.0', - }, - }, - }); - - const spec = new PluginSpec(pack, { - version: '2.0.0', - }); - - expect(spec.getExpectedKibanaVersion()).to.be('6.0.0'); - }); - }); - describe('missing: spec.kibanaVersion,pkg.kibana.version, has: spec.version,pkg.version', () => { - it('uses spec.version', () => { - const pack = new PluginPack({ - path: '/dev/null', - pkg: { - name: 'expkv', - version: '1.0.0', - }, - }); - - const spec = new PluginSpec(pack, { - version: '2.0.0', - }); - - expect(spec.getExpectedKibanaVersion()).to.be('2.0.0'); - }); - }); - describe('missing: spec.kibanaVersion,pkg.kibana.version,spec.version, has: pkg.version', () => { - it('uses pkg.version', () => { - const pack = new PluginPack({ - path: '/dev/null', - pkg: { - name: 'expkv', - version: '1.0.0', - }, - }); - - const spec = new PluginSpec(pack, {}); - - expect(spec.getExpectedKibanaVersion()).to.be('1.0.0'); - }); - }); - }); - - describe('#isVersionCompatible()', () => { - it('passes this.getExpectedKibanaVersion() and arg to isVersionCompatible(), returns its result', () => { - const spec = new PluginSpec(fooPack, { version: '1.0.0' }); - sinon.stub(spec, 'getExpectedKibanaVersion').returns('foo'); - const isVersionCompatible = sinon - .stub(IsVersionCompatibleNS, 'isVersionCompatible') - .returns('bar'); - expect(spec.isVersionCompatible('baz')).to.be('bar'); - - sinon.assert.calledOnce(spec.getExpectedKibanaVersion); - sinon.assert.calledWithExactly(spec.getExpectedKibanaVersion); - - sinon.assert.calledOnce(isVersionCompatible); - sinon.assert.calledWithExactly(isVersionCompatible, 'foo', 'baz'); - }); - }); - - describe('#getRequiredPluginIds()', () => { - it('returns spec.require', () => { - const spec = new PluginSpec(fooPack, { require: [1, 2, 3] }); - expect(spec.getRequiredPluginIds()).to.eql([1, 2, 3]); - }); - }); - - describe('#getPublicDir()', () => { - describe('spec.publicDir === false', () => { - it('returns null', () => { - const spec = new PluginSpec(fooPack, { publicDir: false }); - expect(spec.getPublicDir()).to.be(null); - }); - }); - - describe('spec.publicDir is falsy', () => { - it('returns public child of pack path', () => { - function assert(publicDir) { - const spec = new PluginSpec(fooPack, { publicDir }); - expect(spec.getPublicDir()).to.be(resolve('/dev/null/public')); - } - - assert(0); - assert(''); - assert(null); - assert(undefined); - assert(NaN); - }); - }); - - describe('spec.publicDir is an absolute path', () => { - it('returns the path', () => { - const spec = new PluginSpec(fooPack, { - publicDir: '/var/www/public', - }); - - expect(spec.getPublicDir()).to.be('/var/www/public'); - }); - }); - - // NOTE: see constructor tests for other truthy-tests that throw in constructor - }); - - describe('#getExportSpecs()', () => { - it('returns spec.uiExports', () => { - const spec = new PluginSpec(fooPack, { - uiExports: 'foo', - }); - - expect(spec.getExportSpecs()).to.be('foo'); - }); - }); - - describe('#getPreInitHandler()', () => { - it('returns spec.preInit', () => { - const spec = new PluginSpec(fooPack, { - preInit: 'foo', - }); - - expect(spec.getPreInitHandler()).to.be('foo'); - }); - }); - - describe('#getInitHandler()', () => { - it('returns spec.init', () => { - const spec = new PluginSpec(fooPack, { - init: 'foo', - }); - - expect(spec.getInitHandler()).to.be('foo'); - }); - }); - - describe('#getConfigPrefix()', () => { - describe('spec.configPrefix is truthy', () => { - it('returns spec.configPrefix', () => { - const spec = new PluginSpec(fooPack, { - configPrefix: 'foo.bar.baz', - }); - - expect(spec.getConfigPrefix()).to.be('foo.bar.baz'); - }); - }); - describe('spec.configPrefix is falsy', () => { - it('returns spec.getId()', () => { - function assert(configPrefix) { - const spec = new PluginSpec(fooPack, { configPrefix }); - sinon.stub(spec, 'getId').returns('foo'); - expect(spec.getConfigPrefix()).to.be('foo'); - sinon.assert.calledOnce(spec.getId); - } - - assert(false); - assert(null); - assert(undefined); - assert(''); - assert(0); - }); - }); - }); - - describe('#getConfigSchemaProvider()', () => { - it('returns spec.config', () => { - const spec = new PluginSpec(fooPack, { - config: 'foo', - }); - - expect(spec.getConfigSchemaProvider()).to.be('foo'); - }); - }); - - describe('#readConfigValue()', () => { - const spec = new PluginSpec(fooPack, { - configPrefix: 'foo.bar', - }); - - const config = { - get: sinon.stub(), - }; - - afterEach(() => config.get.resetHistory()); - - describe('key = "foo"', () => { - it('passes key as own array item', () => { - spec.readConfigValue(config, 'foo'); - sinon.assert.calledOnce(config.get); - sinon.assert.calledWithExactly(config.get, ['foo', 'bar', 'foo']); - }); - }); - - describe('key = "foo.bar"', () => { - it('passes key as two array items', () => { - spec.readConfigValue(config, 'foo.bar'); - sinon.assert.calledOnce(config.get); - sinon.assert.calledWithExactly(config.get, ['foo', 'bar', 'foo', 'bar']); - }); - }); - - describe('key = ["foo", "bar"]', () => { - it('merged keys into array', () => { - spec.readConfigValue(config, ['foo', 'bar']); - sinon.assert.calledOnce(config.get); - sinon.assert.calledWithExactly(config.get, ['foo', 'bar', 'foo', 'bar']); - }); - }); - }); - - describe('#getDeprecationsProvider()', () => { - it('returns spec.deprecations', () => { - const spec = new PluginSpec(fooPack, { - deprecations: 'foo', - }); - - expect(spec.getDeprecationsProvider()).to.be('foo'); - }); - }); - }); -}); diff --git a/src/legacy/plugin_discovery/plugin_spec/index.js b/src/legacy/plugin_discovery/plugin_spec/index.js deleted file mode 100644 index 671d311b152e2..0000000000000 --- a/src/legacy/plugin_discovery/plugin_spec/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export { PluginSpec } from './plugin_spec'; diff --git a/src/legacy/plugin_discovery/plugin_spec/is_version_compatible.js b/src/legacy/plugin_discovery/plugin_spec/is_version_compatible.js deleted file mode 100644 index 6822c168f368d..0000000000000 --- a/src/legacy/plugin_discovery/plugin_spec/is_version_compatible.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 { cleanVersion, versionSatisfies } from '../../utils/version'; - -export function isVersionCompatible(version, compatibleWith) { - // the special "kibana" version can be used to always be compatible, - // but is intentionally not supported by the plugin installer - if (version === 'kibana') { - return true; - } - - return versionSatisfies(cleanVersion(version), cleanVersion(compatibleWith)); -} diff --git a/src/legacy/plugin_discovery/plugin_spec/plugin_spec.js b/src/legacy/plugin_discovery/plugin_spec/plugin_spec.js deleted file mode 100644 index db1ec425f2ce5..0000000000000 --- a/src/legacy/plugin_discovery/plugin_spec/plugin_spec.js +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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 { resolve, basename, isAbsolute as isAbsolutePath } from 'path'; - -import { get, toPath } from 'lodash'; - -import { createInvalidPluginError } from '../errors'; -import { isVersionCompatible } from './is_version_compatible'; - -export class PluginSpec { - /** - * @param {PluginPack} pack The plugin pack that produced this spec - * @param {Object} opts the options for this plugin - * @param {String} [opts.id=pkg.name] the id for this plugin. - * @param {Object} [opts.uiExports] a mapping of UiExport types to - * UI modules or metadata about the UI module - * @param {Array} [opts.require] the other plugins that this plugin - * requires. These plugins must exist and be enabled for this plugin - * to function. The require'd plugins will also be initialized first, - * in order to make sure that dependencies provided by these plugins - * are available - * @param {String} [opts.version=pkg.version] the version of this plugin - * @param {Function} [opts.init] A function that will be called to initialize - * this plugin at the appropriate time. - * @param {Function} [opts.configPrefix=this.id] The prefix to use for - * configuration values in the main configuration service - * @param {Function} [opts.config] A function that produces a configuration - * schema using Joi, which is passed as its first argument. - * @param {String|False} [opts.publicDir=path + '/public'] the public - * directory for this plugin. The final directory must have the name "public", - * though it can be located somewhere besides the root of the plugin. Set - * this to false to disable exposure of a public directory - */ - constructor(pack, options) { - const { - id, - require, - version, - kibanaVersion, - uiExports, - uiCapabilities, - publicDir, - configPrefix, - config, - deprecations, - preInit, - init, - postInit, - isEnabled, - } = options; - - this._id = id; - this._pack = pack; - this._version = version; - this._kibanaVersion = kibanaVersion; - this._require = require; - - this._publicDir = publicDir; - this._uiExports = uiExports; - this._uiCapabilities = uiCapabilities; - - this._configPrefix = configPrefix; - this._configSchemaProvider = config; - this._configDeprecationsProvider = deprecations; - - this._isEnabled = isEnabled; - this._preInit = preInit; - this._init = init; - this._postInit = postInit; - - if (!this.getId()) { - throw createInvalidPluginError(this, 'Unable to determine plugin id'); - } - - if (!this.getVersion()) { - throw createInvalidPluginError(this, 'Unable to determine plugin version'); - } - - if (this.getRequiredPluginIds() !== undefined && !Array.isArray(this.getRequiredPluginIds())) { - throw createInvalidPluginError(this, '"plugin.require" must be an array of plugin ids'); - } - - if (this._publicDir) { - if (!isAbsolutePath(this._publicDir)) { - throw createInvalidPluginError(this, 'plugin.publicDir must be an absolute path'); - } - if (basename(this._publicDir) !== 'public') { - throw createInvalidPluginError( - this, - `publicDir for plugin ${this.getId()} must end with a "public" directory.` - ); - } - } - } - - getPack() { - return this._pack; - } - - getPkg() { - return this._pack.getPkg(); - } - - getPath() { - return this._pack.getPath(); - } - - getId() { - return this._id || this.getPkg().name; - } - - getVersion() { - return this._version || this.getPkg().version; - } - - isEnabled(config) { - if (!config || typeof config.get !== 'function' || typeof config.has !== 'function') { - throw new TypeError('PluginSpec#isEnabled() must be called with a config service'); - } - - if (this._isEnabled) { - return this._isEnabled(config); - } - - return Boolean(this.readConfigValue(config, 'enabled')); - } - - getExpectedKibanaVersion() { - // Plugins must specify their version, and by default that version should match - // the version of kibana down to the patch level. If these two versions need - // to diverge, they can specify a kibana.version in the package to indicate the - // version of kibana the plugin is intended to work with. - return ( - this._kibanaVersion || get(this.getPack().getPkg(), 'kibana.version') || this.getVersion() - ); - } - - isVersionCompatible(actualKibanaVersion) { - return isVersionCompatible(this.getExpectedKibanaVersion(), actualKibanaVersion); - } - - getRequiredPluginIds() { - return this._require; - } - - getPublicDir() { - if (this._publicDir === false) { - return null; - } - - if (!this._publicDir) { - return resolve(this.getPack().getPath(), 'public'); - } - - return this._publicDir; - } - - getExportSpecs() { - return this._uiExports; - } - - getUiCapabilitiesProvider() { - return this._uiCapabilities; - } - - getPreInitHandler() { - return this._preInit; - } - - getInitHandler() { - return this._init; - } - - getPostInitHandler() { - return this._postInit; - } - - getConfigPrefix() { - return this._configPrefix || this.getId(); - } - - getConfigSchemaProvider() { - return this._configSchemaProvider; - } - - readConfigValue(config, key) { - return config.get([...toPath(this.getConfigPrefix()), ...toPath(key)]); - } - - getDeprecationsProvider() { - return this._configDeprecationsProvider; - } -} diff --git a/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts b/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts deleted file mode 100644 index e1ed2f57375a4..0000000000000 --- a/src/legacy/plugin_discovery/plugin_spec/plugin_spec_options.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 { Server } from '../../server/kbn_server'; -import { Capabilities } from '../../../core/server'; - -export type InitPluginFunction = (server: Server) => void; -export interface UiExports { - injectDefaultVars?: (server: Server) => { [key: string]: any }; -} - -export interface PluginSpecOptions { - id: string; - require?: string[]; - publicDir?: string; - uiExports?: UiExports; - uiCapabilities?: Capabilities; - init?: InitPluginFunction; - config?: any; -} diff --git a/src/legacy/plugin_discovery/types.ts b/src/legacy/plugin_discovery/types.ts deleted file mode 100644 index 700ca6fa68c95..0000000000000 --- a/src/legacy/plugin_discovery/types.ts +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 { Server } from '../server/kbn_server'; -import { Capabilities } from '../../core/server'; -import { AppCategory } from '../../core/types'; - -/** - * Usage - * - * ``` - * const apmOss: LegacyPlugin = (kibana) => { - * return new kibana.Plugin({ - * id: 'apm_oss', - * // ... - * }); - * }; - * ``` - */ -export type LegacyPluginInitializer = (kibana: LegacyPluginApi) => ArrayOrItem; - -export type ArrayOrItem = T | T[]; - -export interface LegacyPluginApi { - Plugin: new (options: Partial) => LegacyPluginSpec; -} - -export interface LegacyPluginOptions { - id: string; - require: string[]; - version: string; - kibanaVersion: 'kibana'; - uiExports: Partial<{ - app: Partial<{ - title: string; - category?: AppCategory; - description: string; - main: string; - icon: string; - euiIconType: string; - order: number; - listed: boolean; - }>; - apps: any; - hacks: string[]; - visualize: string[]; - devTools: string[]; - injectDefaultVars: (server: Server) => Record; - home: string[]; - mappings: any; - migrations: any; - visTypes: string[]; - embeddableActions?: string[]; - embeddableFactories?: string[]; - uiSettingDefaults?: Record; - interpreter: string | string[]; - }>; - uiCapabilities?: Capabilities; - publicDir: any; - configPrefix: any; - config: any; - deprecations: any; - preInit: any; - init: InitPluginFunction; - postInit: any; - isEnabled: boolean; -} - -export type InitPluginFunction = (server: Server) => void; - -export interface LegacyPluginSpec { - getPack(): any; - getPkg(): any; - getPath(): string; - getId(): string; - getVersion(): string; - isEnabled(config: any): boolean; - getExpectedKibanaVersion(): string; - isVersionCompatible(actualKibanaVersion: any): boolean; - getRequiredPluginIds(): string[]; - getPublicDir(): string | null; - getExportSpecs(): any; - getUiCapabilitiesProvider(): any; - getPreInitHandler(): any; - getInitHandler(): any; - getPostInitHandler(): any; - getConfigPrefix(): string; - getConfigSchemaProvider(): any; - readConfigValue(config: any, key: string): any; - getDeprecationsProvider(): any; -} diff --git a/src/legacy/server/kbn_server.d.ts b/src/legacy/server/kbn_server.d.ts index 8827dc53c5275..bbbfa624562e2 100644 --- a/src/legacy/server/kbn_server.d.ts +++ b/src/legacy/server/kbn_server.d.ts @@ -26,7 +26,6 @@ import { LoggerFactory, PackageInfo, LegacyServiceSetupDeps, - LegacyServiceDiscoverPlugins, } from '../../core/server'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths @@ -94,11 +93,6 @@ export interface NewPlatform { stop: null; } -export type LegacyPlugins = Pick< - LegacyServiceDiscoverPlugins, - 'pluginSpecs' | 'disabledPluginSpecs' | 'uiExports' ->; - // eslint-disable-next-line import/no-default-export export default class KbnServer { public readonly newPlatform: NewPlatform; @@ -107,12 +101,7 @@ export default class KbnServer { public pluginSpecs: any[]; public uiBundles: any; - constructor( - settings: Record, - config: KibanaConfig, - core: KibanaCore, - legacyPlugins: LegacyPlugins - ); + constructor(settings: Record, config: KibanaConfig, core: KibanaCore); public ready(): Promise; public mixin(...fns: KbnMixinFunc[]): Promise; diff --git a/src/legacy/server/kbn_server.js b/src/legacy/server/kbn_server.js index 24d00abb99a05..928930a4e7189 100644 --- a/src/legacy/server/kbn_server.js +++ b/src/legacy/server/kbn_server.js @@ -31,7 +31,6 @@ import warningsMixin from './warnings'; import { statusMixin } from './status'; import configCompleteMixin from './config/complete'; import { optimizeMixin } from '../../optimize'; -import * as Plugins from './plugins'; import { uiMixin } from '../ui'; import { i18nMixin } from './i18n'; @@ -48,9 +47,8 @@ export default class KbnServer { * @param {Record} settings * @param {KibanaConfig} config * @param {KibanaCore} core - * @param {LegacyPlugins} legacyPlugins */ - constructor(settings, config, core, legacyPlugins) { + constructor(settings, config, core) { this.name = pkg.name; this.version = pkg.version; this.build = pkg.build || false; @@ -75,14 +73,8 @@ export default class KbnServer { stop: null, }; - this.uiExports = legacyPlugins.uiExports; - this.pluginSpecs = legacyPlugins.pluginSpecs; - this.disabledPluginSpecs = legacyPlugins.disabledPluginSpecs; - this.ready = constant( this.mixin( - Plugins.waitForInitSetupMixin, - // Sets global HTTP behaviors httpMixin, @@ -95,22 +87,13 @@ export default class KbnServer { // scan translations dirs, register locale files and initialize i18n engine. i18nMixin, - // find plugins and set this.plugins and this.pluginSpecs - Plugins.scanMixin, - // tell the config we are done loading plugins configCompleteMixin, uiMixin, // setup routes that serve the @kbn/optimizer output - optimizeMixin, - - // initialize the plugins - Plugins.initializeMixin, - - // notify any deferred setup logic that plugins have initialized - Plugins.waitForInitResolveMixin + optimizeMixin ) ); diff --git a/src/legacy/server/plugins/index.js b/src/legacy/server/plugins/index.js deleted file mode 100644 index 1511b63b519ae..0000000000000 --- a/src/legacy/server/plugins/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -export { scanMixin } from './scan_mixin'; -export { initializeMixin } from './initialize_mixin'; -export { waitForInitSetupMixin, waitForInitResolveMixin } from './wait_for_plugins_init'; diff --git a/src/legacy/server/plugins/initialize_mixin.js b/src/legacy/server/plugins/initialize_mixin.js deleted file mode 100644 index ccf4cd1c1a404..0000000000000 --- a/src/legacy/server/plugins/initialize_mixin.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 { callPluginHook } from './lib'; - -/** - * KbnServer mixin that initializes all plugins found in ./scan mixin - * @param {KbnServer} kbnServer - * @param {Hapi.Server} server - * @param {Config} config - * @return {Promise} - */ -export async function initializeMixin(kbnServer, server, config) { - if (!config.get('plugins.initialize')) { - server.log(['info'], 'Plugin initialization disabled.'); - return; - } - - async function callHookOnPlugins(hookName) { - const { plugins } = kbnServer; - const ids = plugins.map((p) => p.id); - - for (const id of ids) { - await callPluginHook(hookName, plugins, id, []); - } - } - - await callHookOnPlugins('preInit'); - await callHookOnPlugins('init'); - await callHookOnPlugins('postInit'); -} diff --git a/src/legacy/server/plugins/lib/call_plugin_hook.js b/src/legacy/server/plugins/lib/call_plugin_hook.js deleted file mode 100644 index b665869f5d25f..0000000000000 --- a/src/legacy/server/plugins/lib/call_plugin_hook.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 { last } from 'lodash'; - -export async function callPluginHook(hookName, plugins, id, history) { - const plugin = plugins.find((plugin) => plugin.id === id); - - // make sure this is a valid plugin id - if (!plugin) { - if (history.length) { - throw new Error(`Unmet requirement "${id}" for plugin "${last(history)}"`); - } else { - throw new Error(`Unknown plugin "${id}"`); - } - } - - const circleStart = history.indexOf(id); - const path = [...history, id]; - - // make sure we are not trying to load a dependency within itself - if (circleStart > -1) { - const circle = path.slice(circleStart); - throw new Error(`circular dependency found: "${circle.join(' -> ')}"`); - } - - // call hook on all dependencies - for (const req of plugin.requiredIds) { - await callPluginHook(hookName, plugins, req, path); - } - - // call hook on this plugin - await plugin[hookName](); -} diff --git a/src/legacy/server/plugins/lib/call_plugin_hook.test.js b/src/legacy/server/plugins/lib/call_plugin_hook.test.js deleted file mode 100644 index 30dc2d91a9ab2..0000000000000 --- a/src/legacy/server/plugins/lib/call_plugin_hook.test.js +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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 sinon from 'sinon'; -import { callPluginHook } from './call_plugin_hook'; - -describe('server/plugins/callPluginHook', () => { - it('should call in correct order based on requirements', async () => { - const plugins = [ - { - id: 'foo', - init: sinon.spy(), - preInit: sinon.spy(), - requiredIds: ['bar', 'baz'], - }, - { - id: 'bar', - init: sinon.spy(), - preInit: sinon.spy(), - requiredIds: [], - }, - { - id: 'baz', - init: sinon.spy(), - preInit: sinon.spy(), - requiredIds: ['bar'], - }, - ]; - - await callPluginHook('init', plugins, 'foo', []); - const [foo, bar, baz] = plugins; - sinon.assert.calledOnce(foo.init); - sinon.assert.calledTwice(bar.init); - sinon.assert.calledOnce(baz.init); - sinon.assert.callOrder(bar.init, baz.init, foo.init); - }); - - it('throws meaningful error when required plugin is missing', async () => { - const plugins = [ - { - id: 'foo', - init: sinon.spy(), - preInit: sinon.spy(), - requiredIds: ['bar'], - }, - ]; - - try { - await callPluginHook('init', plugins, 'foo', []); - throw new Error('expected callPluginHook to throw'); - } catch (error) { - expect(error.message).toContain('"bar" for plugin "foo"'); - } - }); - - it('throws meaningful error when dependencies are circular', async () => { - const plugins = [ - { - id: 'foo', - init: sinon.spy(), - preInit: sinon.spy(), - requiredIds: ['bar'], - }, - { - id: 'bar', - init: sinon.spy(), - preInit: sinon.spy(), - requiredIds: ['baz'], - }, - { - id: 'baz', - init: sinon.spy(), - preInit: sinon.spy(), - requiredIds: ['foo'], - }, - ]; - - try { - await callPluginHook('init', plugins, 'foo', []); - throw new Error('expected callPluginHook to throw'); - } catch (error) { - expect(error.message).toContain('foo -> bar -> baz -> foo'); - } - }); -}); diff --git a/src/legacy/server/plugins/lib/index.js b/src/legacy/server/plugins/lib/index.js deleted file mode 100644 index 2329d24498b6b..0000000000000 --- a/src/legacy/server/plugins/lib/index.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -export { callPluginHook } from './call_plugin_hook'; -export { Plugin } from './plugin'; diff --git a/src/legacy/server/plugins/lib/plugin.js b/src/legacy/server/plugins/lib/plugin.js deleted file mode 100644 index 2b392d13d595a..0000000000000 --- a/src/legacy/server/plugins/lib/plugin.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 { once } from 'lodash'; - -/** - * The server plugin class, used to extend the server - * and add custom behavior. A "scoped" plugin class is - * created by the PluginApi class and provided to plugin - * providers that automatically binds all but the `opts` - * arguments. - * - * @class Plugin - * @param {KbnServer} kbnServer - the KbnServer this plugin - * belongs to. - * @param {PluginDefinition} def - * @param {PluginSpec} spec - */ -export class Plugin { - constructor(kbnServer, spec) { - this.kbnServer = kbnServer; - this.spec = spec; - this.pkg = spec.getPkg(); - this.path = spec.getPath(); - this.id = spec.getId(); - this.version = spec.getVersion(); - this.requiredIds = spec.getRequiredPluginIds() || []; - this.externalPreInit = spec.getPreInitHandler(); - this.externalInit = spec.getInitHandler(); - this.externalPostInit = spec.getPostInitHandler(); - this.enabled = spec.isEnabled(kbnServer.config); - this.configPrefix = spec.getConfigPrefix(); - this.publicDir = spec.getPublicDir(); - - this.preInit = once(this.preInit); - this.init = once(this.init); - this.postInit = once(this.postInit); - } - - async preInit() { - if (this.externalPreInit) { - return await this.externalPreInit(this.kbnServer.server); - } - } - - async init() { - const { id, version, kbnServer, configPrefix } = this; - const { config } = kbnServer; - - // setup the hapi register function and get on with it - const register = async (server, options) => { - this._server = server; - this._options = options; - - server.logWithMetadata(['plugins', 'debug'], `Initializing plugin ${this.toString()}`, { - plugin: this, - }); - - if (this.publicDir) { - server.newPlatform.__internals.http.registerStaticDir( - `/plugins/${id}/{path*}`, - this.publicDir - ); - } - - // Many of the plugins are simply adding static assets to the server and we don't need - // to track their "status". Since plugins must have an init() function to even set its status - // we shouldn't even create a status unless the plugin can use it. - if (this.externalInit) { - this.status = kbnServer.status.createForPlugin(this); - server.expose('status', this.status); - await this.externalInit(server, options); - } - }; - - await kbnServer.server.register({ - plugin: { register, name: id, version }, - options: config.has(configPrefix) ? config.get(configPrefix) : null, - }); - - // Only change the plugin status to green if the - // initial status has not been changed - if (this.status && this.status.state === 'uninitialized') { - this.status.green('Ready'); - } - } - - async postInit() { - if (this.externalPostInit) { - return await this.externalPostInit(this.kbnServer.server); - } - } - - getServer() { - return this._server; - } - - getOptions() { - return this._options; - } - - toJSON() { - return this.pkg; - } - - toString() { - return `${this.id}@${this.version}`; - } -} diff --git a/src/legacy/server/plugins/scan_mixin.js b/src/legacy/server/plugins/scan_mixin.js deleted file mode 100644 index 89ebaf920d9d1..0000000000000 --- a/src/legacy/server/plugins/scan_mixin.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 { Plugin } from './lib'; - -export async function scanMixin(kbnServer) { - kbnServer.plugins = kbnServer.pluginSpecs.map((spec) => new Plugin(kbnServer, spec)); -} diff --git a/src/legacy/server/plugins/wait_for_plugins_init.js b/src/legacy/server/plugins/wait_for_plugins_init.js deleted file mode 100644 index 144eb5ef803cc..0000000000000 --- a/src/legacy/server/plugins/wait_for_plugins_init.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - */ - -/** - * Tracks the individual queue for each kbnServer, rather than attaching - * it to the kbnServer object via a property or something - * @type {WeakMap} - */ -const queues = new WeakMap(); - -export function waitForInitSetupMixin(kbnServer) { - queues.set(kbnServer, []); - - kbnServer.afterPluginsInit = function (callback) { - const queue = queues.get(kbnServer); - - if (!queue) { - throw new Error( - 'Plugins have already initialized. Only use this method for setup logic that must wait for plugins to initialize.' - ); - } - - queue.push(callback); - }; -} - -export async function waitForInitResolveMixin(kbnServer, server, config) { - const queue = queues.get(kbnServer); - queues.set(kbnServer, null); - - // only actually call the callbacks if we are really initializing - if (config.get('plugins.initialize')) { - for (const cb of queue) { - await cb(); - } - } -} diff --git a/src/legacy/ui/index.js b/src/legacy/ui/index.js index 05373fa5d1964..5c06cb4677347 100644 --- a/src/legacy/ui/index.js +++ b/src/legacy/ui/index.js @@ -18,4 +18,3 @@ */ export { uiMixin } from './ui_mixin'; -export { collectUiExports } from './ui_exports'; diff --git a/src/legacy/ui/ui_exports/README.md b/src/legacy/ui/ui_exports/README.md deleted file mode 100644 index 7fb117b1c25b9..0000000000000 --- a/src/legacy/ui/ui_exports/README.md +++ /dev/null @@ -1,95 +0,0 @@ -# UI Exports - -When defining a Plugin, the `uiExports` key can be used to define a map of export types to values that will be used to configure the UI system. A common use for `uiExports` is `uiExports.app`, which defines the configuration of a [`UiApp`][UiApp] and teaches the UI System how to render, bundle and tell the user about an application. - - -## `collectUiExports(pluginSpecs): { [type: string]: any }` - -This function produces the object commonly found at `kbnServer.uiExports`. This object is created by calling `collectPluginExports()` with a standard set of export type reducers and defaults for the UI System. - -### export type reducers - -The [`ui_export_types` module][UiExportTypes] defines the reducer used for each uiExports key (or `type`). The name of every export in [./ui_export_types/index.js][UiExportTypes] is a key that plugins can define in their `uiExports` specification and the value of those exports are reducers that `collectPluginExports()` will call to produce the merged result of all export specs. - -### example - UiApps - -Plugin authors can define a new UiApp in their plugin specification like so: - -```js -// a single app export -export default function (kibana) { - return new kibana.Plugin({ - //... - uiExports: { - app: { - // uiApp spec options go here - } - } - }) -} - -// apps can also export multiple apps -export default function (kibana) { - return new kibana.Plugin({ - //... - uiExports: { - apps: [ - { /* uiApp spec options */ }, - { /* second uiApp spec options */ }, - ] - } - }) -} -``` - -To handle this export type, the [ui_export_types][UiExportTypes] module exports two reducers, one named `app` and the other `apps`. - -```js -export const app = ... -export const apps = ... -``` - -These reducers are defined in [`ui_export_types/ui_apps`][UiAppExportType] and have the exact same definition: - -```js -// `wrap()` produces a reducer by wrapping a base reducer with modifiers. -// All but the last argument are modifiers that take a reducer and return -// an alternate reducer to use in it's place. -// -// Most wrappers call their target reducer with slightly different -// arguments. This allows composing standard reducer modifications for -// reuse, consistency, and easy reference (once you get the hang of it). -wrap( - // calls the next reducer with the `type` set to `uiAppSpecs`, ignoring - // the key the plugin author used to define this spec ("app" or "apps" - // in this example) - alias('uiAppSpecs'), - - // calls the next reducer with the `spec` set to the result of calling - // `applySpecDefaults(spec, type, pluginSpec)` which merges some defaults - // from the `PluginSpec` because we want uiAppSpecs to be useful individually - mapSpec(applySpecDefaults), - - // writes this spec to `acc[type]` (`acc.uiAppSpecs` in this example since - // the type was set to `uiAppSpecs` by `alias()`). It does this by concatenating - // the current value and the spec into an array. If either item is already - // an array its items are added to the result individually. If either item - // is undefined it is ignored. - // - // NOTE: since flatConcatAtType is last it isn't a wrapper, it's - // just a normal reducer - flatConcatAtType -) -``` - -This reducer format was chosen so that it will be easier to look back at these reducers and see that `app` and `apps` export specs are written to `kbnServer.uiExports.uiAppSpecs`, with defaults applied, in an array. - -### defaults - -The [`ui_exports/ui_export_defaults`][UiExportDefaults] module defines the default shape of the uiExports object produced by `collectUiExports()`. The defaults generally describe the `uiExports` from the UI System itself, like default visTypes and such. - -[UiExportDefaults]: ./ui_export_defaults.js "uiExport defaults definition" -[UiExportTypes]: ./ui_export_types/index.js "Index of default ui_export_types module" -[UiAppExportType]: ./ui_export_types/ui_apps.js "UiApp extension type definition" -[PluginSpec]: ../../plugin_discovery/plugin_spec/plugin_spec.js "PluginSpec class definition" -[PluginDiscovery]: '../../plugin_discovery' "plugin_discovery module" \ No newline at end of file diff --git a/src/legacy/ui/ui_exports/collect_ui_exports.ts b/src/legacy/ui/ui_exports/collect_ui_exports.ts deleted file mode 100644 index edb2a11dc0527..0000000000000 --- a/src/legacy/ui/ui_exports/collect_ui_exports.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 { LegacyUiExports } from '../../../core/server'; - -// @ts-ignore -import { UI_EXPORT_DEFAULTS } from './ui_export_defaults'; -// @ts-ignore -import * as uiExportTypeReducers from './ui_export_types'; -// @ts-ignore -import { reduceExportSpecs } from '../../plugin_discovery'; - -export function collectUiExports(pluginSpecs: unknown[]): LegacyUiExports { - return reduceExportSpecs(pluginSpecs, uiExportTypeReducers, UI_EXPORT_DEFAULTS); -} diff --git a/src/legacy/ui/ui_exports/index.js b/src/legacy/ui/ui_exports/index.js deleted file mode 100644 index 56db698dc7b03..0000000000000 --- a/src/legacy/ui/ui_exports/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export { collectUiExports } from './collect_ui_exports'; diff --git a/src/legacy/ui/ui_exports/ui_export_defaults.js b/src/legacy/ui/ui_exports/ui_export_defaults.js deleted file mode 100644 index 227954155ce88..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_defaults.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export const UI_EXPORT_DEFAULTS = {}; diff --git a/src/legacy/ui/ui_exports/ui_export_types/index.js b/src/legacy/ui/ui_exports/ui_export_types/index.js deleted file mode 100644 index 9ff6a53f4afb9..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/index.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ - -export { injectDefaultVars, replaceInjectedVars } from './modify_injected_vars'; - -export { - mappings, - migrations, - savedObjectSchemas, - savedObjectsManagement, - validations, -} from './saved_object'; - -export { taskDefinitions } from './task_definitions'; - -export { link, links } from './ui_nav_links'; - -export { uiSettingDefaults } from './ui_settings'; - -export { unknown } from './unknown'; diff --git a/src/legacy/ui/ui_exports/ui_export_types/modify_injected_vars.js b/src/legacy/ui/ui_exports/ui_export_types/modify_injected_vars.js deleted file mode 100644 index 4bb9f350bd959..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/modify_injected_vars.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 { flatConcatAtType } from './reduce'; -import { wrap, alias, mapSpec } from './modify_reduce'; - -export const replaceInjectedVars = wrap(alias('injectedVarsReplacers'), flatConcatAtType); - -export const injectDefaultVars = wrap( - alias('defaultInjectedVarProviders'), - mapSpec((spec, type, pluginSpec) => ({ - pluginSpec, - fn: spec, - })), - flatConcatAtType -); diff --git a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/alias.js b/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/alias.js deleted file mode 100644 index a894e59a03c81..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/alias.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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. - */ - -/** - * Creates a reducer wrapper which, when called with a reducer, creates a new - * reducer that replaces the `type` value with `newType` before delegating to - * the wrapped reducer - * @param {String} newType - * @return {Function} - */ -export const alias = (newType) => (next) => (acc, spec, type, pluginSpec) => - next(acc, spec, newType, pluginSpec); diff --git a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/debug.js b/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/debug.js deleted file mode 100644 index c40bca59fe14c..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/debug.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 { mapSpec } from './map_spec'; - -/** - * Reducer wrapper which, replaces the `spec` with the details about the definition - * of that spec - * @type {Function} - */ -export const debug = mapSpec((spec, type, pluginSpec) => ({ - spec, - type, - pluginSpec, -})); diff --git a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/index.js b/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/index.js deleted file mode 100644 index 54c81fefdd08a..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/index.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - */ - -export { alias } from './alias'; -export { debug } from './debug'; -export { mapSpec } from './map_spec'; -export { wrap } from './wrap'; -export { uniqueKeys } from './unique_keys'; diff --git a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/map_spec.js b/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/map_spec.js deleted file mode 100644 index 5970c45e7445e..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/map_spec.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ - -/** - * Creates a reducer wrapper which, when called with a reducer, creates a new - * reducer that replaces the `specs` value with the result of calling - * `mapFn(spec, type, pluginSpec)` before delegating to the wrapped - * reducer - * @param {Function} mapFn receives `(specs, type, pluginSpec)` - * @return {Function} - */ -export const mapSpec = (mapFn) => (next) => (acc, spec, type, pluginSpec) => - next(acc, mapFn(spec, type, pluginSpec), type, pluginSpec); diff --git a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/unique_keys.js b/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/unique_keys.js deleted file mode 100644 index dedcd057b09e3..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/unique_keys.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - */ - -const pluginId = (pluginSpec) => (pluginSpec.id ? pluginSpec.id() : pluginSpec.getId()); - -export const uniqueKeys = (sourceType) => (next) => (acc, spec, type, pluginSpec) => { - const duplicates = Object.keys(spec).filter((key) => acc[type] && acc[type].hasOwnProperty(key)); - - if (duplicates.length) { - throw new Error( - `${pluginId(pluginSpec)} defined duplicate ${sourceType || type} values: ${duplicates}` - ); - } - - return next(acc, spec, type, pluginSpec); -}; diff --git a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/wrap.js b/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/wrap.js deleted file mode 100644 index f84d83ed7c845..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/modify_reduce/wrap.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - */ - -/** - * Wrap a function with any number of wrappers. Wrappers - * are functions that take a reducer and return a reducer - * that should be called in its place. The wrappers will - * be called in reverse order for setup and then in the - * order they are defined when the resulting reducer is - * executed. - * - * const reducer = wrap( - * next => (acc) => acc[1] = 'a', - * next => (acc) => acc[1] = 'b', - * next => (acc) => acc[1] = 'c' - * ) - * - * reducer('foo') //=> 'fco' - * - * @param {Function} ...wrappers - * @param {Function} reducer - * @return {Function} - */ -export function wrap(...args) { - const reducer = args[args.length - 1]; - const wrappers = args.slice(0, -1); - - return wrappers.reverse().reduce((acc, wrapper) => wrapper(acc), reducer); -} diff --git a/src/legacy/ui/ui_exports/ui_export_types/reduce/flat_concat_at_type.js b/src/legacy/ui/ui_exports/ui_export_types/reduce/flat_concat_at_type.js deleted file mode 100644 index 5fcbcac463392..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/reduce/flat_concat_at_type.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 { createTypeReducer, flatConcat } from './lib'; - -/** - * Reducer that merges two values concatenating all values - * into a flattened array - * @param {Any} [initial] - * @return {Function} - */ -export const flatConcatAtType = createTypeReducer(flatConcat); diff --git a/src/legacy/ui/ui_exports/ui_export_types/reduce/flat_concat_values_at_type.js b/src/legacy/ui/ui_exports/ui_export_types/reduce/flat_concat_values_at_type.js deleted file mode 100644 index 229c5be24aac5..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/reduce/flat_concat_values_at_type.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 { createTypeReducer, flatConcat, mergeWith } from './lib'; - -/** - * Reducer that merges specs by concatenating the values of - * all keys in accumulator and spec with the same logic as concat - * @param {[type]} initial [description] - * @return {[type]} [description] - */ -export const flatConcatValuesAtType = createTypeReducer((objectA, objectB) => - mergeWith(objectA || {}, objectB || {}, flatConcat) -); diff --git a/src/legacy/ui/ui_exports/ui_export_types/reduce/index.js b/src/legacy/ui/ui_exports/ui_export_types/reduce/index.js deleted file mode 100644 index 7dc1ba60fb3cb..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/reduce/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -export { mergeAtType } from './merge_at_type'; -export { flatConcatValuesAtType } from './flat_concat_values_at_type'; -export { flatConcatAtType } from './flat_concat_at_type'; diff --git a/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/create_type_reducer.js b/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/create_type_reducer.js deleted file mode 100644 index bf4793c208308..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/create_type_reducer.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - */ - -/** - * Creates a reducer that reduces the values within `acc[type]` by calling - * reducer with signature: - * - * reducer(acc[type], spec, type, pluginSpec) - * - * @param {Function} reducer - * @return {Function} - */ -export const createTypeReducer = (reducer) => (acc, spec, type, pluginSpec) => ({ - ...acc, - [type]: reducer(acc[type], spec, type, pluginSpec), -}); diff --git a/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/flat_concat.js b/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/flat_concat.js deleted file mode 100644 index 1337c8a85d5b4..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/flat_concat.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - */ - -/** - * Concatenate two values into a single array, ignoring either - * value if it is undefined and flattening the value if it is an array - * @param {Array|T} a - * @param {Array} b - * @return {Array} - */ -export const flatConcat = (a, b) => [].concat(a === undefined ? [] : a, b === undefined ? [] : b); diff --git a/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/index.js b/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/index.js deleted file mode 100644 index e4281caebe245..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -export { flatConcat } from './flat_concat'; -export { mergeWith } from './merge_with'; -export { createTypeReducer } from './create_type_reducer'; diff --git a/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/merge_with.js b/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/merge_with.js deleted file mode 100644 index 6c7d31e6fd74d..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/reduce/lib/merge_with.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - */ - -const uniqueConcat = (arrayA, arrayB) => - arrayB.reduce((acc, key) => (acc.includes(key) ? acc : acc.concat(key)), arrayA); - -/** - * Assign the keys from both objA and objB to target after passing the - * current and new value through merge as `(target[key], source[key])` - * @param {Object} objA - * @param {Object} objB - * @param {Function} merge - * @return {Object} target - */ -export function mergeWith(objA, objB, merge) { - const target = {}; - const keys = uniqueConcat(Object.keys(objA), Object.keys(objB)); - for (const key of keys) { - target[key] = merge(objA[key], objB[key]); - } - return target; -} diff --git a/src/legacy/ui/ui_exports/ui_export_types/reduce/merge_at_type.js b/src/legacy/ui/ui_exports/ui_export_types/reduce/merge_at_type.js deleted file mode 100644 index 4f5a501253851..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/reduce/merge_at_type.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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 { createTypeReducer } from './lib'; - -export const mergeAtType = createTypeReducer((a, b) => ({ - ...a, - ...b, -})); diff --git a/src/legacy/ui/ui_exports/ui_export_types/saved_object.js b/src/legacy/ui/ui_exports/ui_export_types/saved_object.js deleted file mode 100644 index be6898d3e642c..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/saved_object.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 { flatConcatAtType, mergeAtType } from './reduce'; -import { alias, mapSpec, uniqueKeys, wrap } from './modify_reduce'; - -// mapping types -export const mappings = wrap( - alias('savedObjectMappings'), - mapSpec((spec, type, pluginSpec) => ({ - pluginId: pluginSpec.getId(), - properties: spec, - })), - flatConcatAtType -); - -const pluginId = (pluginSpec) => (pluginSpec.id ? pluginSpec.id() : pluginSpec.getId()); - -// Combines the `migrations` property of each plugin, -// ensuring that properties are unique across plugins -// and has migrations defined where the mappings are defined. -// See saved_objects/migrations for more details. -export const migrations = wrap( - alias('savedObjectMigrations'), - (next) => (acc, spec, type, pluginSpec) => { - const mappings = pluginSpec.getExportSpecs().mappings || {}; - const invalidMigrationTypes = Object.keys(spec).filter((type) => !mappings[type]); - if (invalidMigrationTypes.length) { - throw new Error( - 'Migrations and mappings must be defined together in the uiExports of a single plugin. ' + - `${pluginId(pluginSpec)} defines migrations for types ${invalidMigrationTypes.join( - ', ' - )} but does not define their mappings.` - ); - } - return next(acc, spec, type, pluginSpec); - }, - uniqueKeys(), - mergeAtType -); - -export const savedObjectSchemas = wrap(uniqueKeys(), mergeAtType); - -export const savedObjectsManagement = wrap(uniqueKeys(), mergeAtType); - -// Combines the `validations` property of each plugin, -// ensuring that properties are unique across plugins. -// See saved_objects/validation for more details. -export const validations = wrap(alias('savedObjectValidations'), uniqueKeys(), mergeAtType); diff --git a/src/legacy/ui/ui_exports/ui_export_types/task_definitions.js b/src/legacy/ui/ui_exports/ui_export_types/task_definitions.js deleted file mode 100644 index 8a0ed85d86f3e..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/task_definitions.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 { mergeAtType } from './reduce'; -import { alias, wrap, uniqueKeys } from './modify_reduce'; - -// How plugins define tasks that the task manager can run. -export const taskDefinitions = wrap(alias('taskDefinitions'), uniqueKeys(), mergeAtType); diff --git a/src/legacy/ui/ui_exports/ui_export_types/ui_nav_links.js b/src/legacy/ui/ui_exports/ui_export_types/ui_nav_links.js deleted file mode 100644 index 34aff7463a249..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/ui_nav_links.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 { flatConcatAtType } from './reduce'; -import { wrap, alias } from './modify_reduce'; - -export const links = wrap(alias('navLinkSpecs'), flatConcatAtType); -export const link = wrap(alias('navLinkSpecs'), flatConcatAtType); diff --git a/src/legacy/ui/ui_exports/ui_export_types/ui_settings.js b/src/legacy/ui/ui_exports/ui_export_types/ui_settings.js deleted file mode 100644 index 8d88490579c21..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/ui_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 { mergeAtType } from './reduce'; -import { wrap, uniqueKeys } from './modify_reduce'; - -export const uiSettingDefaults = wrap(uniqueKeys(), mergeAtType); diff --git a/src/legacy/ui/ui_exports/ui_export_types/unknown.js b/src/legacy/ui/ui_exports/ui_export_types/unknown.js deleted file mode 100644 index a12a514d2e6bf..0000000000000 --- a/src/legacy/ui/ui_exports/ui_export_types/unknown.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 { flatConcatAtType } from './reduce'; -import { wrap, alias, debug } from './modify_reduce'; - -export const unknown = wrap(debug, alias('unknown'), flatConcatAtType); From 1f8249bfd94b8a0b8f5c2757e424addbcd5a5e6b Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 16 Sep 2020 12:07:03 +0200 Subject: [PATCH 02/29] adapt some types and tests --- kibana.d.ts | 5 - .../server/legacy/legacy_internals.test.ts | 96 +------------------ src/core/server/legacy/legacy_internals.ts | 3 +- src/core/server/rendering/__mocks__/params.ts | 3 - .../rendering_service.test.ts.snap | 5 - src/legacy/types.ts | 20 ---- 6 files changed, 5 insertions(+), 127 deletions(-) delete mode 100644 src/legacy/types.ts diff --git a/kibana.d.ts b/kibana.d.ts index 517bda374af9d..1e8ddd186d372 100644 --- a/kibana.d.ts +++ b/kibana.d.ts @@ -29,7 +29,6 @@ export { Public, Server }; * All exports from TS ambient definitions (where types are added for JS source in a .d.ts file). */ import * as LegacyElasticsearch from './src/legacy/core_plugins/elasticsearch'; -import * as LegacyKibanaPluginSpec from './src/legacy/plugin_discovery/plugin_spec/plugin_spec_options'; import * as LegacyKibanaServer from './src/legacy/server/kbn_server'; /** @@ -41,10 +40,6 @@ export namespace Legacy { export type ResponseToolkit = LegacyKibanaServer.ResponseToolkit; export type Server = LegacyKibanaServer.Server; - export type InitPluginFunction = LegacyKibanaPluginSpec.InitPluginFunction; - export type UiExports = LegacyKibanaPluginSpec.UiExports; - export type PluginSpecOptions = LegacyKibanaPluginSpec.PluginSpecOptions; - export namespace Plugins { export namespace elasticsearch { export type Plugin = LegacyElasticsearch.ElasticsearchPlugin; diff --git a/src/core/server/legacy/legacy_internals.test.ts b/src/core/server/legacy/legacy_internals.test.ts index 935e36a989a0c..dc72c43470a84 100644 --- a/src/core/server/legacy/legacy_internals.test.ts +++ b/src/core/server/legacy/legacy_internals.test.ts @@ -17,36 +17,16 @@ * under the License. */ -import { Server } from 'hapi'; - -import { configMock } from '../config/mocks'; -import { httpServiceMock } from '../http/http_service.mock'; import { httpServerMock } from '../http/http_server.mocks'; -import { findLegacyPluginSpecsMock } from './legacy_service.test.mocks'; import { LegacyInternals } from './legacy_internals'; -import { ILegacyInternals, LegacyConfig, LegacyVars, LegacyUiExports } from './types'; - -function varsProvider(vars: LegacyVars, configValue?: any) { - return { - fn: jest.fn().mockReturnValue(vars), - pluginSpec: { - readConfigValue: jest.fn().mockReturnValue(configValue), - }, - }; -} +import { ILegacyInternals } from './types'; describe('LegacyInternals', () => { describe('getInjectedUiAppVars()', () => { - let uiExports: LegacyUiExports; - let config: LegacyConfig; - let server: Server; let legacyInternals: ILegacyInternals; beforeEach(async () => { - uiExports = findLegacyPluginSpecsMock().uiExports; - config = configMock.create() as any; - server = httpServiceMock.createInternalSetupContract().server; - legacyInternals = new LegacyInternals(uiExports, config, server); + legacyInternals = new LegacyInternals(); }); it('gets with no injectors', async () => { @@ -99,16 +79,10 @@ describe('LegacyInternals', () => { }); describe('getVars()', () => { - let uiExports: LegacyUiExports; - let config: LegacyConfig; - let server: Server; let legacyInternals: LegacyInternals; beforeEach(async () => { - uiExports = findLegacyPluginSpecsMock().uiExports; - config = configMock.create() as any; - server = httpServiceMock.createInternalSetupContract().server; - legacyInternals = new LegacyInternals(uiExports, config, server); + legacyInternals = new LegacyInternals(); }); it('gets: no default injectors, no injected vars replacers, no ui app injectors, no inject arg', async () => { @@ -117,42 +91,6 @@ describe('LegacyInternals', () => { expect(vars).toMatchInlineSnapshot(`Object {}`); }); - it('gets: with default injectors, no injected vars replacers, no ui app injectors, no inject arg', async () => { - uiExports.defaultInjectedVarProviders = [ - varsProvider({ alpha: 'alpha' }), - varsProvider({ gamma: 'gamma' }), - varsProvider({ alpha: 'beta' }), - ]; - - const vars = await legacyInternals.getVars('core', httpServerMock.createRawRequest()); - - expect(vars).toMatchInlineSnapshot(` - Object { - "alpha": "beta", - "gamma": "gamma", - } - `); - }); - - it('gets: no default injectors, with injected vars replacers, with ui app injectors, no inject arg', async () => { - uiExports.injectedVarsReplacers = [ - jest.fn(async (vars) => ({ ...vars, added: 'key' })), - jest.fn((vars) => vars), - jest.fn((vars) => ({ replaced: 'all' })), - jest.fn(async (vars) => ({ ...vars, added: 'last-key' })), - ]; - - const request = httpServerMock.createRawRequest(); - const vars = await legacyInternals.getVars('core', request); - - expect(vars).toMatchInlineSnapshot(` - Object { - "added": "last-key", - "replaced": "all", - } - `); - }); - it('gets: no default injectors, no injected vars replacers, with ui app injectors, no inject arg', async () => { legacyInternals.injectUiAppVars('core', async () => ({ is: 'core' })); legacyInternals.injectUiAppVars('core', () => ({ sync: 'injector' })); @@ -179,33 +117,5 @@ describe('LegacyInternals', () => { } `); }); - - it('gets: with default injectors, with injected vars replacers, with ui app injectors, with inject arg', async () => { - uiExports.defaultInjectedVarProviders = [ - varsProvider({ alpha: 'alpha' }), - varsProvider({ gamma: 'gamma' }), - varsProvider({ alpha: 'beta' }), - ]; - uiExports.injectedVarsReplacers = [jest.fn(async (vars) => ({ ...vars, gamma: 'delta' }))]; - - legacyInternals.injectUiAppVars('core', async () => ({ is: 'core' })); - legacyInternals.injectUiAppVars('core', () => ({ sync: 'injector' })); - legacyInternals.injectUiAppVars('core', async () => ({ is: 'merged-core' })); - - const vars = await legacyInternals.getVars('core', httpServerMock.createRawRequest(), { - injected: 'arg', - sync: 'arg', - }); - - expect(vars).toMatchInlineSnapshot(` - Object { - "alpha": "beta", - "gamma": "delta", - "injected": "arg", - "is": "merged-core", - "sync": "arg", - } - `); - }); }); }); diff --git a/src/core/server/legacy/legacy_internals.ts b/src/core/server/legacy/legacy_internals.ts index 9f161e19fbd9c..47d0c96fb5685 100644 --- a/src/core/server/legacy/legacy_internals.ts +++ b/src/core/server/legacy/legacy_internals.ts @@ -19,6 +19,7 @@ import { KibanaRequest, LegacyRequest } from '../http'; import { ILegacyInternals, LegacyVars, VarsInjector } from './types'; +import { mergeVars } from './merge_vars'; /** * @internal @@ -52,6 +53,6 @@ export class LegacyInternals implements ILegacyInternals { request: KibanaRequest | LegacyRequest, injected: LegacyVars = {} ) { - return Promise.resolve(injected); + return mergeVars({}, await this.getInjectedUiAppVars(id), injected); } } diff --git a/src/core/server/rendering/__mocks__/params.ts b/src/core/server/rendering/__mocks__/params.ts index 0901cec768cd2..ae3830f703a53 100644 --- a/src/core/server/rendering/__mocks__/params.ts +++ b/src/core/server/rendering/__mocks__/params.ts @@ -20,19 +20,16 @@ import { mockCoreContext } from '../../core_context.mock'; import { httpServiceMock } from '../../http/http_service.mock'; import { pluginServiceMock } from '../../plugins/plugins_service.mock'; -import { legacyServiceMock } from '../../legacy/legacy_service.mock'; import { statusServiceMock } from '../../status/status_service.mock'; const context = mockCoreContext.create(); const http = httpServiceMock.createInternalSetupContract(); const uiPlugins = pluginServiceMock.createUiPlugins(); -const legacyPlugins = legacyServiceMock.createDiscoverPlugins(); const status = statusServiceMock.createInternalSetupContract(); export const mockRenderingServiceParams = context; export const mockRenderingSetupDeps = { http, - legacyPlugins, uiPlugins, status, }; diff --git a/src/core/server/rendering/__snapshots__/rendering_service.test.ts.snap b/src/core/server/rendering/__snapshots__/rendering_service.test.ts.snap index ab828a1780425..5075e215e60f9 100644 --- a/src/core/server/rendering/__snapshots__/rendering_service.test.ts.snap +++ b/src/core/server/rendering/__snapshots__/rendering_service.test.ts.snap @@ -34,7 +34,6 @@ Object { "buildSha": Any, "bundleId": "app:core", "devMode": true, - "nav": Array [], "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { @@ -87,7 +86,6 @@ Object { "buildSha": Any, "bundleId": "app:core", "devMode": true, - "nav": Array [], "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { @@ -140,7 +138,6 @@ Object { "buildSha": Any, "bundleId": "app:core", "devMode": true, - "nav": Array [], "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { @@ -197,7 +194,6 @@ Object { "buildSha": Any, "bundleId": "app:core", "devMode": true, - "nav": Array [], "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { @@ -250,7 +246,6 @@ Object { "buildSha": Any, "bundleId": "app:core", "devMode": true, - "nav": Array [], "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { diff --git a/src/legacy/types.ts b/src/legacy/types.ts deleted file mode 100644 index 43c9ac79538b1..0000000000000 --- a/src/legacy/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -export * from './plugin_discovery/types'; From 4a8c362d81c9afec6c4e48fdae32d67b68060b63 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 16 Sep 2020 12:28:37 +0200 Subject: [PATCH 03/29] restore ensureValidConfiguration --- .../config/ensure_valid_configuration.test.ts | 70 +++++++ .../config/ensure_valid_configuration.ts | 48 +++++ .../config/get_unused_config_keys.test.ts | 174 ++++++++++++++++++ .../legacy/config/get_unused_config_keys.ts | 53 ++++++ src/core/server/legacy/config/index.ts | 20 ++ src/core/server/legacy/index.ts | 2 + src/core/server/legacy/legacy_service.mock.ts | 1 + src/core/server/legacy/legacy_service.ts | 38 ++-- src/core/server/legacy/types.ts | 9 + src/core/server/server.ts | 11 +- src/legacy/server/config/schema.js | 7 +- 11 files changed, 409 insertions(+), 24 deletions(-) create mode 100644 src/core/server/legacy/config/ensure_valid_configuration.test.ts create mode 100644 src/core/server/legacy/config/ensure_valid_configuration.ts create mode 100644 src/core/server/legacy/config/get_unused_config_keys.test.ts create mode 100644 src/core/server/legacy/config/get_unused_config_keys.ts create mode 100644 src/core/server/legacy/config/index.ts diff --git a/src/core/server/legacy/config/ensure_valid_configuration.test.ts b/src/core/server/legacy/config/ensure_valid_configuration.test.ts new file mode 100644 index 0000000000000..700fe69954655 --- /dev/null +++ b/src/core/server/legacy/config/ensure_valid_configuration.test.ts @@ -0,0 +1,70 @@ +/* + * 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 { ensureValidConfiguration } from './ensure_valid_configuration'; +import { getUnusedConfigKeys } from './get_unused_config_keys'; +import { configServiceMock } from '../../config/mocks'; + +jest.mock('./get_unused_config_keys'); + +describe('ensureValidConfiguration', () => { + let configService: ReturnType; + + beforeEach(() => { + jest.clearAllMocks(); + configService = configServiceMock.create(); + configService.getUsedPaths.mockReturnValue(Promise.resolve(['core', 'elastic'])); + + (getUnusedConfigKeys as any).mockImplementation(() => []); + }); + + it('calls getUnusedConfigKeys with correct parameters', async () => { + await ensureValidConfiguration( + configService as any, + { + settings: 'settings', + legacyConfig: 'pluginExtendedConfig', + } as any + ); + expect(getUnusedConfigKeys).toHaveBeenCalledTimes(1); + expect(getUnusedConfigKeys).toHaveBeenCalledWith({ + coreHandledConfigPaths: ['core', 'elastic'], + settings: 'settings', + legacyConfig: 'pluginExtendedConfig', + }); + }); + + it('returns normally when there is no unused keys', async () => { + await expect( + ensureValidConfiguration(configService as any, {} as any) + ).resolves.toBeUndefined(); + + expect(getUnusedConfigKeys).toHaveBeenCalledTimes(1); + }); + + it('throws when there are some unused keys', async () => { + (getUnusedConfigKeys as any).mockImplementation(() => ['some.key', 'some.other.key']); + + await expect( + ensureValidConfiguration(configService as any, {} as any) + ).rejects.toMatchInlineSnapshot( + `[Error: Unknown configuration key(s): "some.key", "some.other.key". Check for spelling errors and ensure that expected plugins are installed.]` + ); + }); +}); diff --git a/src/core/server/legacy/config/ensure_valid_configuration.ts b/src/core/server/legacy/config/ensure_valid_configuration.ts new file mode 100644 index 0000000000000..34f98b9b3a795 --- /dev/null +++ b/src/core/server/legacy/config/ensure_valid_configuration.ts @@ -0,0 +1,48 @@ +/* + * 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 { getUnusedConfigKeys } from './get_unused_config_keys'; +import { ConfigService } from '../../config'; +import { CriticalError } from '../../errors'; +import { LegacyServiceSetupConfig } from '../types'; + +export async function ensureValidConfiguration( + configService: ConfigService, + { legacyConfig, settings }: LegacyServiceSetupConfig +) { + const unusedConfigKeys = await getUnusedConfigKeys({ + coreHandledConfigPaths: await configService.getUsedPaths(), + settings, + legacyConfig, + }); + + if (unusedConfigKeys.length > 0) { + const message = `Unknown configuration key(s): ${unusedConfigKeys + .map((key) => `"${key}"`) + .join(', ')}. Check for spelling errors and ensure that expected plugins are installed.`; + throw new InvalidConfigurationError(message); + } +} + +class InvalidConfigurationError extends CriticalError { + constructor(message: string) { + super(message, 'InvalidConfig', 64); + Object.setPrototypeOf(this, InvalidConfigurationError.prototype); + } +} diff --git a/src/core/server/legacy/config/get_unused_config_keys.test.ts b/src/core/server/legacy/config/get_unused_config_keys.test.ts new file mode 100644 index 0000000000000..6ce69fca0270a --- /dev/null +++ b/src/core/server/legacy/config/get_unused_config_keys.test.ts @@ -0,0 +1,174 @@ +/* + * 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 { LegacyConfig, LegacyVars } from '../types'; +import { getUnusedConfigKeys } from './get_unused_config_keys'; + +describe('getUnusedConfigKeys', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + const getConfig = (values: LegacyVars = {}): LegacyConfig => + ({ + get: () => values as any, + } as LegacyConfig); + + describe('not using core or plugin specs', () => { + it('should return an empty list for empty parameters', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: [], + settings: {}, + legacyConfig: getConfig(), + }) + ).toEqual([]); + }); + + it('returns empty list when config and settings have the same properties', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: [], + settings: { + presentInBoth: true, + alsoInBoth: 'someValue', + }, + legacyConfig: getConfig({ + presentInBoth: true, + alsoInBoth: 'someValue', + }), + }) + ).toEqual([]); + }); + + it('returns empty list when config has entries not present in settings', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: [], + settings: { + presentInBoth: true, + }, + legacyConfig: getConfig({ + presentInBoth: true, + onlyInConfig: 'someValue', + }), + }) + ).toEqual([]); + }); + + it('returns the list of properties from settings not present in config', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: [], + settings: { + presentInBoth: true, + onlyInSetting: 'value', + }, + legacyConfig: getConfig({ + presentInBoth: true, + }), + }) + ).toEqual(['onlyInSetting']); + }); + + it('correctly handle nested properties', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: [], + settings: { + elasticsearch: { + username: 'foo', + password: 'bar', + }, + }, + legacyConfig: getConfig({ + elasticsearch: { + username: 'foo', + onlyInConfig: 'default', + }, + }), + }) + ).toEqual(['elasticsearch.password']); + }); + + it('correctly handle "env" specific case', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: [], + settings: { + env: 'development', + }, + legacyConfig: getConfig({ + env: { + name: 'development', + }, + }), + }) + ).toEqual([]); + }); + + it('correctly handle array properties', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: [], + settings: { + prop: ['a', 'b', 'c'], + }, + legacyConfig: getConfig({ + prop: ['a'], + }), + }) + ).toEqual([]); + }); + }); + + it('ignores properties managed by the new platform', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: ['core', 'foo.bar'], + settings: { + core: { + prop: 'value', + }, + foo: { + bar: true, + dolly: true, + }, + }, + legacyConfig: getConfig({}), + }) + ).toEqual(['foo.dolly']); + }); + + it('handles array values', async () => { + expect( + await getUnusedConfigKeys({ + coreHandledConfigPaths: ['core', 'array'], + settings: { + core: { + prop: 'value', + array: [1, 2, 3], + }, + array: ['some', 'values'], + }, + legacyConfig: getConfig({}), + }) + ).toEqual([]); + }); +}); diff --git a/src/core/server/legacy/config/get_unused_config_keys.ts b/src/core/server/legacy/config/get_unused_config_keys.ts new file mode 100644 index 0000000000000..5bbe169033e39 --- /dev/null +++ b/src/core/server/legacy/config/get_unused_config_keys.ts @@ -0,0 +1,53 @@ +/* + * 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 { difference } from 'lodash'; +import { getFlattenedObject } from '@kbn/std'; +import { hasConfigPathIntersection } from '../../config'; +import { LegacyConfig, LegacyVars } from '../types'; + +const getFlattenedKeys = (object: object) => Object.keys(getFlattenedObject(object)); + +export async function getUnusedConfigKeys({ + coreHandledConfigPaths, + settings, + legacyConfig, +}: { + coreHandledConfigPaths: string[]; + settings: LegacyVars; + legacyConfig: LegacyConfig; +}) { + const inputKeys = getFlattenedKeys(settings); + const appliedKeys = getFlattenedKeys(legacyConfig.get()); + + if (inputKeys.includes('env')) { + // env is a special case key, see https://github.com/elastic/kibana/blob/848bf17b/src/legacy/server/config/config.js#L74 + // where it is deleted from the settings before being injected into the schema via context and + // then renamed to `env.name` https://github.com/elastic/kibana/blob/848bf17/src/legacy/server/config/schema.js#L17 + inputKeys[inputKeys.indexOf('env')] = 'env.name'; + } + + // Filter out keys that are marked as used in the core (e.g. by new core plugins). + return difference(inputKeys, appliedKeys).filter( + (unusedConfigKey) => + !coreHandledConfigPaths.some((usedInCoreConfigKey) => + hasConfigPathIntersection(unusedConfigKey, usedInCoreConfigKey) + ) + ); +} diff --git a/src/core/server/legacy/config/index.ts b/src/core/server/legacy/config/index.ts new file mode 100644 index 0000000000000..c8781945d7cbc --- /dev/null +++ b/src/core/server/legacy/config/index.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +export { ensureValidConfiguration } from './ensure_valid_configuration'; diff --git a/src/core/server/legacy/index.ts b/src/core/server/legacy/index.ts index a811addd0c278..6b0963e3129c6 100644 --- a/src/core/server/legacy/index.ts +++ b/src/core/server/legacy/index.ts @@ -17,6 +17,8 @@ * under the License. */ +/** @internal */ +export { ensureValidConfiguration } from './config'; /** @internal */ export { LegacyInternals } from './legacy_internals'; /** @internal */ diff --git a/src/core/server/legacy/legacy_service.mock.ts b/src/core/server/legacy/legacy_service.mock.ts index 81f5799f17d42..781874f702cf8 100644 --- a/src/core/server/legacy/legacy_service.mock.ts +++ b/src/core/server/legacy/legacy_service.mock.ts @@ -24,6 +24,7 @@ type LegacyServiceMock = jest.Mocked & { legacyId const createLegacyServiceMock = (): LegacyServiceMock => ({ legacyId: Symbol(), + setupLegacyConfig: jest.fn(), setup: jest.fn(), start: jest.fn(), stop: jest.fn(), diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index effbcdb5ebe20..521d79aaddac6 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -48,7 +48,7 @@ interface LegacyKbnServer { close: () => Promise; } -function getLegacyRawConfig(config: Config, pathConfig: PathConfigType, serverUuid: string) { +function getLegacyRawConfig(config: Config, pathConfig: PathConfigType) { const rawConfig = config.toRaw(); // Elasticsearch config is solely handled by the core and legacy platform @@ -59,10 +59,6 @@ function getLegacyRawConfig(config: Config, pathConfig: PathConfigType, serverUu return { ...rawConfig, - server: { - ...rawConfig.server, - uuid: serverUuid, - }, // We rely heavily in the default value of 'path.data' in the legacy world and, // since it has been moved to NP, it won't show up in RawConfig. path: pathConfig, @@ -100,20 +96,14 @@ export class LegacyService implements CoreService { ).pipe(map(([http, csp]) => new HttpConfig(http, csp))); } - public async setup(setupDeps: LegacyServiceSetupDeps) { - this.log.debug('setting up legacy service'); - - const serverUuid = setupDeps.core.environment.instanceUuid; - + public async setupLegacyConfig() { this.update$ = combineLatest([ this.coreContext.configService.getConfig$(), this.coreContext.configService.atPath('path'), ]).pipe( tap(([config, pathConfig]) => { if (this.kbnServer !== undefined) { - this.kbnServer.applyLoggingConfiguration( - getLegacyRawConfig(config, pathConfig, serverUuid) - ); + this.kbnServer.applyLoggingConfiguration(getLegacyRawConfig(config, pathConfig)); } }), tap({ error: (err) => this.log.error(err) }), @@ -125,12 +115,30 @@ export class LegacyService implements CoreService { this.settings = await this.update$ .pipe( first(), - map(([config, pathConfig]) => getLegacyRawConfig(config, pathConfig, serverUuid)) + map(([config, pathConfig]) => getLegacyRawConfig(config, pathConfig)) ) .toPromise(); this.legacyRawConfig = LegacyConfigClass.withDefaultSchema(this.settings); + return { + settings: this.settings, + legacyConfig: this.legacyRawConfig!, + }; + } + + public async setup(setupDeps: LegacyServiceSetupDeps) { + this.log.debug('setting up legacy service'); + + if (!this.legacyRawConfig) { + throw new Error( + 'Legacy config not initialized yet. Ensure LegacyService.setupLegacyConfig() is called before LegacyService.setup()' + ); + } + + // propagate the instance uuid to the legacy config, as it was the legacy way to access it. + this.legacyRawConfig!.set('server.uuid', setupDeps.core.environment.instanceUuid); + this.setupDeps = setupDeps; this.legacyInternals = new LegacyInternals(); } @@ -138,7 +146,7 @@ export class LegacyService implements CoreService { public async start(startDeps: LegacyServiceStartDeps) { const { setupDeps } = this; - if (!setupDeps) { + if (!setupDeps || !this.legacyRawConfig) { throw new Error('Legacy service is not setup yet.'); } diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts index 3d167014d0168..48508ee2d3df9 100644 --- a/src/core/server/legacy/types.ts +++ b/src/core/server/legacy/types.ts @@ -124,6 +124,15 @@ export interface LegacyServiceStartDeps { plugins: Record; } +/** + * @internal + * @deprecated + */ +export interface LegacyServiceSetupConfig { + legacyConfig: LegacyConfig; + settings: LegacyVars; +} + /** * @internal * @deprecated diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 7cdad20c029c2..52546a44b5b1b 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -26,7 +26,7 @@ import { ElasticsearchService } from './elasticsearch'; import { HttpService } from './http'; import { HttpResourcesService } from './http_resources'; import { RenderingService } from './rendering'; -import { LegacyService } from './legacy'; +import { LegacyService, ensureValidConfiguration } from './legacy'; import { Logger, LoggerFactory, LoggingService, ILoggingSystem } from './logging'; import { UiSettingsService } from './ui_settings'; import { PluginsService, config as pluginsConfig } from './plugins'; @@ -107,15 +107,18 @@ export class Server { public async setup() { this.log.debug('setting up server'); - // Immediately terminate in case of invalid configuration - await this.configService.validate(); - const environmentSetup = await this.environment.setup(); // Discover any plugins before continuing. This allows other systems to utilize the plugin dependency graph. const { pluginTree, uiPlugins } = await this.plugins.discover({ environment: environmentSetup, }); + const legacyConfigSetup = await this.legacy.setupLegacyConfig(); + + // Immediately terminate in case of invalid configuration + // This needs to be done after plugin discovery + await this.configService.validate(); + await ensureValidConfiguration(this.configService, legacyConfigSetup); const contextServiceSetup = this.context.setup({ // We inject a fake "legacy plugin" with dependencies on every plugin so that legacy plugins: diff --git a/src/legacy/server/config/schema.js b/src/legacy/server/config/schema.js index f8736fb30f90e..6badf165bfac6 100644 --- a/src/legacy/server/config/schema.js +++ b/src/legacy/server/config/schema.js @@ -131,11 +131,7 @@ export default () => }), }).default(), - plugins: Joi.object({ - paths: Joi.array().items(Joi.string()).default([]), - scanDirs: Joi.array().items(Joi.string()).default([]), - initialize: Joi.boolean().default(true), - }).default(), + plugins: HANDLED_IN_NEW_PLATFORM, path: HANDLED_IN_NEW_PLATFORM, @@ -146,6 +142,7 @@ export default () => status: Joi.object({ allowAnonymous: Joi.boolean().default(false), }).default(), + map: Joi.object({ includeElasticMapsService: Joi.boolean().default(true), proxyElasticMapsServiceInMaps: Joi.boolean().default(false), From 28db307ffefdb018018386acc1123da4786f7c76 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 16 Sep 2020 13:00:48 +0200 Subject: [PATCH 04/29] fix legacy service tests --- src/core/server/legacy/legacy_service.test.ts | 72 +++++++++---------- 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts index 08710a82651e9..9403ab4577b21 100644 --- a/src/core/server/legacy/legacy_service.test.ts +++ b/src/core/server/legacy/legacy_service.test.ts @@ -141,9 +141,10 @@ describe('once LegacyService is set up with connection info', () => { coreId, env, logger, - configService: configService as any, + configService, }); + await legacyService.setupLegacyConfig(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -151,13 +152,14 @@ describe('once LegacyService is set up with connection info', () => { expect(MockKbnServer).toHaveBeenCalledWith( { path: { autoListen: true }, server: { autoListen: true } }, // Because of the mock, path also gets the value expect.objectContaining({ get: expect.any(Function) }), - expect.any(Object), - { disabledPluginSpecs: [], pluginSpecs: [], uiExports: {}, navLinks: [] } + expect.any(Object) + ); + expect(MockKbnServer.mock.calls[0][1].get()).toEqual( + expect.objectContaining({ + path: expect.objectContaining({ autoListen: true }), + server: expect.objectContaining({ autoListen: true }), + }) ); - expect(MockKbnServer.mock.calls[0][1].get()).toEqual({ - path: { autoListen: true }, - server: { autoListen: true }, - }); const [mockKbnServer] = MockKbnServer.mock.instances; expect(mockKbnServer.listen).toHaveBeenCalledTimes(1); @@ -173,6 +175,7 @@ describe('once LegacyService is set up with connection info', () => { logger, configService: configService as any, }); + await legacyService.setupLegacyConfig(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -180,13 +183,12 @@ describe('once LegacyService is set up with connection info', () => { expect(MockKbnServer).toHaveBeenCalledWith( { path: { autoListen: false }, server: { autoListen: true } }, expect.objectContaining({ get: expect.any(Function) }), - expect.any(Object), - { disabledPluginSpecs: [], pluginSpecs: [], uiExports: {}, navLinks: [] } + expect.any(Object) ); - expect(MockKbnServer.mock.calls[0][1].get()).toEqual({ - path: { autoListen: false }, - server: { autoListen: true }, - }); + + const legacyConfig = MockKbnServer.mock.calls[0][1].get(); + expect(legacyConfig.path.autoListen).toBe(false); + expect(legacyConfig.server.autoListen).toBe(true); const [mockKbnServer] = MockKbnServer.mock.instances; expect(mockKbnServer.ready).toHaveBeenCalledTimes(1); @@ -204,6 +206,7 @@ describe('once LegacyService is set up with connection info', () => { configService: configService as any, }); + await legacyService.setupLegacyConfig(); await legacyService.setup(setupDeps); await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingInlineSnapshot( `"something failed"` @@ -223,8 +226,11 @@ describe('once LegacyService is set up with connection info', () => { configService: configService as any, }); + await expect(legacyService.setupLegacyConfig()).rejects.toThrowErrorMatchingInlineSnapshot( + `"something failed"` + ); await expect(legacyService.setup(setupDeps)).rejects.toThrowErrorMatchingInlineSnapshot( - `"Legacy service has not discovered legacy plugins yet. Ensure LegacyService.discoverPlugins() is called before LegacyService.setup()"` + `"Legacy config not initialized yet. Ensure LegacyService.setupLegacyConfig() is called before LegacyService.setup()"` ); await expect(legacyService.start(startDeps)).rejects.toThrowErrorMatchingInlineSnapshot( `"Legacy service is not setup yet."` @@ -241,6 +247,7 @@ describe('once LegacyService is set up with connection info', () => { logger, configService: configService as any, }); + await legacyService.setupLegacyConfig(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -261,6 +268,7 @@ describe('once LegacyService is set up with connection info', () => { logger, configService: configService as any, }); + await legacyService.setupLegacyConfig(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -285,6 +293,7 @@ describe('once LegacyService is set up with connection info', () => { logger, configService: configService as any, }); + await legacyService.setupLegacyConfig(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); @@ -304,6 +313,7 @@ describe('once LegacyService is set up without connection info', () => { let legacyService: LegacyService; beforeEach(async () => { legacyService = new LegacyService({ coreId, env, logger, configService: configService as any }); + await legacyService.setupLegacyConfig(); await legacyService.setup(setupDeps); await legacyService.start(startDeps); }); @@ -313,13 +323,13 @@ describe('once LegacyService is set up without connection info', () => { expect(MockKbnServer).toHaveBeenCalledWith( { path: {}, server: { autoListen: true } }, expect.objectContaining({ get: expect.any(Function) }), - expect.any(Object), - { disabledPluginSpecs: [], pluginSpecs: [], uiExports: {}, navLinks: [] } + expect.any(Object) + ); + expect(MockKbnServer.mock.calls[0][1].get()).toEqual( + expect.objectContaining({ + server: expect.objectContaining({ autoListen: true }), + }) ); - expect(MockKbnServer.mock.calls[0][1].get()).toEqual({ - path: {}, - server: { autoListen: true }, - }); }); test('reconfigures logging configuration if new config is received.', async () => { @@ -357,6 +367,7 @@ describe('once LegacyService is set up in `devClusterMaster` mode', () => { configService: configService as any, }); + await devClusterLegacyService.setupLegacyConfig(); await devClusterLegacyService.setup(setupDeps); await devClusterLegacyService.start(startDeps); @@ -385,6 +396,7 @@ describe('once LegacyService is set up in `devClusterMaster` mode', () => { configService: configService as any, }); + await devClusterLegacyService.setupLegacyConfig(); await devClusterLegacyService.setup(setupDeps); await devClusterLegacyService.start(startDeps); @@ -425,24 +437,8 @@ test('Sets the server.uuid property on the legacy configuration', async () => { environmentSetup.instanceUuid = 'UUID_FROM_SERVICE'; - const configSetMock = jest.fn(); - + const { legacyConfig } = await legacyService.setupLegacyConfig(); await legacyService.setup(setupDeps); - expect(configSetMock).toHaveBeenCalledTimes(1); - expect(configSetMock).toHaveBeenCalledWith('server.uuid', 'UUID_FROM_SERVICE'); - - /* - expect(MockKbnServer).toHaveBeenCalledTimes(1); - expect(MockKbnServer).toHaveBeenCalledWith( - { path: {}, server: { autoListen: true } }, - expect.objectContaining({ get: expect.any(Function) }), - expect.any(Object), - { disabledPluginSpecs: [], pluginSpecs: [], uiExports: {}, navLinks: [] } - ); - expect(MockKbnServer.mock.calls[0][1].get()).toEqual({ - path: {}, - server: { autoListen: true }, - }); - */ + expect(legacyConfig.get('server.uuid')).toBe('UUID_FROM_SERVICE'); }); From 5e76aeb6d40fa922e61ccca7fb5be1d225bda8b0 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 16 Sep 2020 13:10:31 +0200 Subject: [PATCH 05/29] adapt uiRender mixin --- src/legacy/ui/ui_render/ui_render_mixin.js | 209 ++++++++++----------- 1 file changed, 101 insertions(+), 108 deletions(-) diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index e3b7c1e0c3ff9..eac9a61d535a2 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -67,115 +67,108 @@ export function uiRenderMixin(kbnServer, server, config) { }, }); - // register the bootstrap.js route after plugins are initialized so that we can - // detect if any default auth strategies were registered - kbnServer.afterPluginsInit(() => { - const authEnabled = !!server.auth.settings.default; - - server.route({ - path: '/bootstrap.js', - method: 'GET', - config: { - tags: ['api'], - auth: authEnabled ? { mode: 'try' } : false, - }, - async handler(request, h) { - const soClient = kbnServer.newPlatform.start.core.savedObjects.getScopedClient( - KibanaRequest.from(request) - ); - const uiSettings = kbnServer.newPlatform.start.core.uiSettings.asScopedToClient(soClient); - - const darkMode = - !authEnabled || request.auth.isAuthenticated - ? await uiSettings.get('theme:darkMode') - : false; - - const themeVersion = - !authEnabled || request.auth.isAuthenticated - ? await uiSettings.get('theme:version') - : 'v7'; - - const themeTag = `${themeVersion === 'v7' ? 'v7' : 'v8'}${darkMode ? 'dark' : 'light'}`; - - const buildHash = server.newPlatform.env.packageInfo.buildNum; - const basePath = config.get('server.basePath'); - - const regularBundlePath = `${basePath}/${buildHash}/bundles`; - - const styleSheetPaths = [ - `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`, - ...(darkMode - ? [ - themeVersion === 'v7' - ? `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.darkCssDistFilename}` - : `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.darkV8CssDistFilename}`, - `${basePath}/node_modules/@kbn/ui-framework/dist/kui_dark.css`, - `${basePath}/ui/legacy_dark_theme.css`, - ] - : [ - themeVersion === 'v7' - ? `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.lightCssDistFilename}` - : `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.lightV8CssDistFilename}`, - `${basePath}/node_modules/@kbn/ui-framework/dist/kui_light.css`, - `${basePath}/ui/legacy_light_theme.css`, - ]), - ]; - - const kpUiPlugins = kbnServer.newPlatform.__internals.uiPlugins; - const kpPluginPublicPaths = new Map(); - const kpPluginBundlePaths = new Set(); - - // recursively iterate over the kpUiPlugin ids and their required bundles - // to populate kpPluginPublicPaths and kpPluginBundlePaths - (function readKpPlugins(ids) { - for (const id of ids) { - if (kpPluginPublicPaths.has(id)) { - continue; - } - - kpPluginPublicPaths.set(id, `${regularBundlePath}/plugin/${id}/`); - kpPluginBundlePaths.add(`${regularBundlePath}/plugin/${id}/${id}.plugin.js`); - readKpPlugins(kpUiPlugins.internal.get(id).requiredBundles); + const authEnabled = !!server.auth.settings.default; + server.route({ + path: '/bootstrap.js', + method: 'GET', + config: { + tags: ['api'], + auth: authEnabled ? { mode: 'try' } : false, + }, + async handler(request, h) { + const soClient = kbnServer.newPlatform.start.core.savedObjects.getScopedClient( + KibanaRequest.from(request) + ); + const uiSettings = kbnServer.newPlatform.start.core.uiSettings.asScopedToClient(soClient); + + const darkMode = + !authEnabled || request.auth.isAuthenticated + ? await uiSettings.get('theme:darkMode') + : false; + + const themeVersion = + !authEnabled || request.auth.isAuthenticated ? await uiSettings.get('theme:version') : 'v7'; + + const themeTag = `${themeVersion === 'v7' ? 'v7' : 'v8'}${darkMode ? 'dark' : 'light'}`; + + const buildHash = server.newPlatform.env.packageInfo.buildNum; + const basePath = config.get('server.basePath'); + + const regularBundlePath = `${basePath}/${buildHash}/bundles`; + + const styleSheetPaths = [ + `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`, + ...(darkMode + ? [ + themeVersion === 'v7' + ? `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.darkCssDistFilename}` + : `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.darkV8CssDistFilename}`, + `${basePath}/node_modules/@kbn/ui-framework/dist/kui_dark.css`, + `${basePath}/ui/legacy_dark_theme.css`, + ] + : [ + themeVersion === 'v7' + ? `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.lightCssDistFilename}` + : `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.lightV8CssDistFilename}`, + `${basePath}/node_modules/@kbn/ui-framework/dist/kui_light.css`, + `${basePath}/ui/legacy_light_theme.css`, + ]), + ]; + + const kpUiPlugins = kbnServer.newPlatform.__internals.uiPlugins; + const kpPluginPublicPaths = new Map(); + const kpPluginBundlePaths = new Set(); + + // recursively iterate over the kpUiPlugin ids and their required bundles + // to populate kpPluginPublicPaths and kpPluginBundlePaths + (function readKpPlugins(ids) { + for (const id of ids) { + if (kpPluginPublicPaths.has(id)) { + continue; } - })(kpUiPlugins.public.keys()); - - const jsDependencyPaths = [ - ...UiSharedDeps.jsDepFilenames.map( - (filename) => `${regularBundlePath}/kbn-ui-shared-deps/${filename}` - ), - `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.jsFilename}`, - - `${regularBundlePath}/core/core.entry.js`, - ...kpPluginBundlePaths, - ]; - - // These paths should align with the bundle routes configured in - // src/optimize/bundles_route/bundles_route.ts - const publicPathMap = JSON.stringify({ - core: `${regularBundlePath}/core/`, - 'kbn-ui-shared-deps': `${regularBundlePath}/kbn-ui-shared-deps/`, - ...Object.fromEntries(kpPluginPublicPaths), - }); - - const bootstrap = new AppBootstrap({ - templateData: { - themeTag, - jsDependencyPaths, - styleSheetPaths, - publicPathMap, - }, - }); - - const body = await bootstrap.getJsFile(); - const etag = await bootstrap.getJsFileHash(); - - return h - .response(body) - .header('cache-control', 'must-revalidate') - .header('content-type', 'application/javascript') - .etag(etag); - }, - }); + + kpPluginPublicPaths.set(id, `${regularBundlePath}/plugin/${id}/`); + kpPluginBundlePaths.add(`${regularBundlePath}/plugin/${id}/${id}.plugin.js`); + readKpPlugins(kpUiPlugins.internal.get(id).requiredBundles); + } + })(kpUiPlugins.public.keys()); + + const jsDependencyPaths = [ + ...UiSharedDeps.jsDepFilenames.map( + (filename) => `${regularBundlePath}/kbn-ui-shared-deps/${filename}` + ), + `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.jsFilename}`, + + `${regularBundlePath}/core/core.entry.js`, + ...kpPluginBundlePaths, + ]; + + // These paths should align with the bundle routes configured in + // src/optimize/bundles_route/bundles_route.ts + const publicPathMap = JSON.stringify({ + core: `${regularBundlePath}/core/`, + 'kbn-ui-shared-deps': `${regularBundlePath}/kbn-ui-shared-deps/`, + ...Object.fromEntries(kpPluginPublicPaths), + }); + + const bootstrap = new AppBootstrap({ + templateData: { + themeTag, + jsDependencyPaths, + styleSheetPaths, + publicPathMap, + }, + }); + + const body = await bootstrap.getJsFile(); + const etag = await bootstrap.getJsFileHash(); + + return h + .response(body) + .header('cache-control', 'must-revalidate') + .header('content-type', 'application/javascript') + .etag(etag); + }, }); server.route({ From aa4de2bf431aa3abb82fc706e93b8e1cc353459d Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 16 Sep 2020 13:16:19 +0200 Subject: [PATCH 06/29] remove legacy types --- src/core/server/index.ts | 1 - src/core/server/legacy/types.ts | 29 ----------------------------- 2 files changed, 30 deletions(-) diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 605958be39b6d..9011f22738523 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -341,7 +341,6 @@ export { LegacyServiceSetupDeps, LegacyServiceStartDeps, LegacyConfig, - LegacyUiExports, LegacyInternals, } from './legacy'; diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts index 48508ee2d3df9..2dd6a8697b705 100644 --- a/src/core/server/legacy/types.ts +++ b/src/core/server/legacy/types.ts @@ -49,25 +49,6 @@ export interface LegacyConfig { set(config: LegacyVars): void; } -/** - * @internal - * @deprecated - */ -export interface LegacyPluginPack { - getPath(): string; -} - -/** - * @internal - * @deprecated - */ -export interface LegacyPluginSpec { - getId: () => unknown; - getExpectedKibanaVersion: () => string; - getConfigPrefix: () => string; - getPack: () => LegacyPluginPack; -} - /** * @internal * @deprecated @@ -95,16 +76,6 @@ export type VarsReplacer = ( server: Server ) => LegacyVars | Promise; -/** - * @internal - * @deprecated - */ -export interface LegacyUiExports { - defaultInjectedVarProviders?: VarsProvider[]; - injectedVarsReplacers?: VarsReplacer[]; - unknown?: [{ pluginSpec: LegacyPluginSpec; type: unknown }]; -} - /** * @public * @deprecated From f7210406833d407d67a83c4c4e941f5bdc84eb11 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 16 Sep 2020 13:19:41 +0200 Subject: [PATCH 07/29] update generated doc --- src/core/server/server.api.md | 40 ++--------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index ab26f29dce3af..904d622ab714c 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1311,7 +1311,7 @@ export class LegacyElasticsearchErrorHelpers { // // @internal @deprecated (undocumented) export class LegacyInternals implements ILegacyInternals { - constructor(uiExports: LegacyUiExports, config: LegacyConfig, server: Server); + constructor(); // (undocumented) getInjectedUiAppVars(id: string): Promise>; // (undocumented) @@ -1320,7 +1320,7 @@ export class LegacyInternals implements ILegacyInternals { // // (undocumented) injectUiAppVars(id: string, injector: VarsInjector): void; - } +} // @public @deprecated (undocumented) export interface LegacyRequest extends Request { @@ -1333,16 +1333,6 @@ export class LegacyScopedClusterClient implements ILegacyScopedClusterClient { callAsInternalUser(endpoint: string, clientParams?: Record, options?: LegacyCallAPIOptions): Promise; } -// Warning: (ae-forgotten-export) The symbol "LegacyPlugins" needs to be exported by the entry point index.d.ts -// -// @internal @deprecated (undocumented) -export interface LegacyServiceDiscoverPlugins extends LegacyPlugins { - // (undocumented) - pluginExtendedConfig: LegacyConfig; - // (undocumented) - settings: LegacyVars; -} - // @public @deprecated (undocumented) export interface LegacyServiceSetupDeps { // Warning: (ae-forgotten-export) The symbol "LegacyCoreSetup" needs to be exported by the entry point index.d.ts @@ -1367,31 +1357,6 @@ export interface LegacyServiceStartDeps { plugins: Record; } -// @internal @deprecated (undocumented) -export interface LegacyUiExports { - // Warning: (ae-forgotten-export) The symbol "VarsProvider" needs to be exported by the entry point index.d.ts - // - // (undocumented) - defaultInjectedVarProviders?: VarsProvider[]; - // Warning: (ae-forgotten-export) The symbol "VarsReplacer" needs to be exported by the entry point index.d.ts - // - // (undocumented) - injectedVarsReplacers?: VarsReplacer[]; - // Warning: (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts - // - // (undocumented) - navLinkSpecs?: LegacyNavLinkSpec[] | null; - // Warning: (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts - // - // (undocumented) - uiAppSpecs?: Array; - // (undocumented) - unknown?: [{ - pluginSpec: LegacyPluginSpec; - type: unknown; - }]; -} - // Warning: (ae-forgotten-export) The symbol "lifecycleResponseFactory" needs to be exported by the entry point index.d.ts // // @public @@ -2744,7 +2709,6 @@ 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:135:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:272:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:272:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts From e6fb28150601ce3e3ee813d4f0ba839e4ec2be6e Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Wed, 16 Sep 2020 16:27:00 +0200 Subject: [PATCH 08/29] restore legacy plugin schema --- src/legacy/server/config/schema.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/legacy/server/config/schema.js b/src/legacy/server/config/schema.js index 6badf165bfac6..a6fca8fd9bba0 100644 --- a/src/legacy/server/config/schema.js +++ b/src/legacy/server/config/schema.js @@ -131,7 +131,12 @@ export default () => }), }).default(), - plugins: HANDLED_IN_NEW_PLATFORM, + // still used by the legacy i18n mixin + plugins: Joi.object({ + paths: Joi.array().items(Joi.string()).default([]), + scanDirs: Joi.array().items(Joi.string()).default([]), + initialize: Joi.boolean().default(true), + }).default(), path: HANDLED_IN_NEW_PLATFORM, From 982494ed78812d65a90e4339b753276211941313 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 11:26:23 +0200 Subject: [PATCH 09/29] update generated doc --- src/core/server/server.api.md | 40 ++--------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 1dcf8a22e9cfd..ad70a10155821 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1310,7 +1310,7 @@ export class LegacyElasticsearchErrorHelpers { // // @internal @deprecated (undocumented) export class LegacyInternals implements ILegacyInternals { - constructor(uiExports: LegacyUiExports, config: LegacyConfig, server: Server); + constructor(); // (undocumented) getInjectedUiAppVars(id: string): Promise>; // (undocumented) @@ -1319,7 +1319,7 @@ export class LegacyInternals implements ILegacyInternals { // // (undocumented) injectUiAppVars(id: string, injector: VarsInjector): void; - } +} // @public @deprecated (undocumented) export interface LegacyRequest extends Request { @@ -1332,16 +1332,6 @@ export class LegacyScopedClusterClient implements ILegacyScopedClusterClient { callAsInternalUser(endpoint: string, clientParams?: Record, options?: LegacyCallAPIOptions): Promise; } -// Warning: (ae-forgotten-export) The symbol "LegacyPlugins" needs to be exported by the entry point index.d.ts -// -// @internal @deprecated (undocumented) -export interface LegacyServiceDiscoverPlugins extends LegacyPlugins { - // (undocumented) - pluginExtendedConfig: LegacyConfig; - // (undocumented) - settings: LegacyVars; -} - // @public @deprecated (undocumented) export interface LegacyServiceSetupDeps { // Warning: (ae-forgotten-export) The symbol "LegacyCoreSetup" needs to be exported by the entry point index.d.ts @@ -1366,31 +1356,6 @@ export interface LegacyServiceStartDeps { plugins: Record; } -// @internal @deprecated (undocumented) -export interface LegacyUiExports { - // Warning: (ae-forgotten-export) The symbol "VarsProvider" needs to be exported by the entry point index.d.ts - // - // (undocumented) - defaultInjectedVarProviders?: VarsProvider[]; - // Warning: (ae-forgotten-export) The symbol "VarsReplacer" needs to be exported by the entry point index.d.ts - // - // (undocumented) - injectedVarsReplacers?: VarsReplacer[]; - // Warning: (ae-forgotten-export) The symbol "LegacyNavLinkSpec" needs to be exported by the entry point index.d.ts - // - // (undocumented) - navLinkSpecs?: LegacyNavLinkSpec[] | null; - // Warning: (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts - // - // (undocumented) - uiAppSpecs?: Array; - // (undocumented) - unknown?: [{ - pluginSpec: LegacyPluginSpec; - type: unknown; - }]; -} - // Warning: (ae-forgotten-export) The symbol "lifecycleResponseFactory" needs to be exported by the entry point index.d.ts // // @public @@ -2752,7 +2717,6 @@ 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:135:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:274:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:274:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts // src/core/server/plugins/types.ts:277:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts From 7363722983448e4e02673ba25f914ed8c7e35d71 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 14:00:19 +0200 Subject: [PATCH 10/29] remove remaining code of x-pack/legacy --- src/cli/serve/serve.js | 16 +- x-pack/index.js | 3 +- x-pack/legacy/common/__tests__/poller.js | 240 ----------- x-pack/legacy/common/constants/index.ts | 23 - .../legacy/common/constants/license_status.ts | 10 - .../legacy/common/constants/license_types.ts | 31 -- x-pack/legacy/common/eui_draggable/index.d.ts | 17 - .../common/eui_styled_components/index.ts | 20 - x-pack/legacy/common/poller.d.ts | 14 - x-pack/legacy/common/poller.js | 79 ---- x-pack/legacy/plugins/xpack_main/index.js | 31 -- .../server/lib/__tests__/setup_xpack_main.js | 68 --- .../server/lib/__tests__/xpack_info.js | 398 ------------------ .../xpack_main/server/lib/setup_xpack_main.js | 33 -- .../xpack_main/server/lib/xpack_info.ts | 240 ----------- .../server/lib/xpack_info_license.test.js | 207 --------- .../server/lib/xpack_info_license.ts | 111 ----- .../routes/api/v1/__tests__/xpack_info.js | 85 ---- .../server/routes/api/v1/xpack_info.js | 25 -- .../plugins/xpack_main/server/xpack_main.d.ts | 14 - .../lib/__tests__/key_case_converter.js | 117 ----- .../server/lib/__tests__/kibana_state.js | 129 ------ .../server/lib/check_license/check_license.js | 75 ---- .../lib/check_license/check_license.test.js | 132 ------ .../legacy/server/lib/check_license/index.js | 7 - x-pack/legacy/server/lib/constants/index.ts | 7 - .../legacy/server/lib/constants/xpack_info.ts | 7 - .../call_with_request_factory.js | 12 - .../call_with_request_factory/index.d.ts | 18 - .../call_with_request_factory/index.js | 7 - .../__tests__/wrap_custom_error.js | 21 - .../error_wrappers/__tests__/wrap_es_error.js | 39 -- .../__tests__/wrap_unknown_error.js | 19 - .../create_router/error_wrappers/index.d.ts | 12 - .../lib/create_router/error_wrappers/index.js | 9 - .../error_wrappers/wrap_custom_error.js | 18 - .../error_wrappers/wrap_es_error.js | 59 --- .../error_wrappers/wrap_unknown_error.js | 17 - .../server/lib/create_router/index.d.ts | 38 -- .../legacy/server/lib/create_router/index.js | 61 --- .../__tests__/is_es_error_factory.js | 44 -- .../is_es_error_factory/index.js | 7 - .../is_es_error_factory.js | 18 - .../__tests__/license_pre_routing_factory.js | 70 --- .../license_pre_routing_factory/index.js | 7 - .../license_pre_routing_factory.js | 26 -- .../legacy/server/lib/key_case_converter.js | 52 --- .../legacy/server/lib/parse_kibana_state.js | 55 --- .../lib/register_license_checker/index.d.ts | 15 - .../lib/register_license_checker/index.js | 7 - .../register_license_checker.js | 34 -- .../watch_status_and_license_to_initialize.js | 83 ---- ...h_status_and_license_to_initialize.test.js | 301 ------------- x-pack/legacy/server/lib/xpack_usage.js | 16 - .../actions/server/constants/plugin.ts | 4 +- .../plugins/alerts/server/constants/plugin.ts | 4 +- .../plugins/apm/common/anomaly_detection.ts | 2 +- .../metric_control/custom_metric_form.tsx | 5 +- .../metric_control/metrics_edit_mode.tsx | 5 +- .../waffle/metric_control/mode_switcher.tsx | 5 +- .../applications/ingest_manager/index.tsx | 2 +- .../public/application/index.tsx | 2 +- .../observability/public/hooks/use_theme.tsx | 2 +- .../mock/endpoint/app_root_provider.tsx | 2 +- .../pages/policy/view/vertical_divider.ts | 2 +- x-pack/plugins/transform/common/constants.ts | 4 +- .../server/routes/api/error_utils.ts | 57 ++- .../server/routes/api/field_histograms.ts | 4 +- .../transform/server/routes/api/transforms.ts | 3 +- .../routes/api/transforms_audit_messages.ts | 3 +- .../watcher/common/constants/plugin.ts | 4 +- x-pack/plugins/watcher/server/types.ts | 3 - .../common}/eui_styled_components.tsx | 0 .../xpack_legacy/common/index.ts} | 2 +- x-pack/tasks/build.ts | 3 - x-pack/typings/hapi.d.ts | 2 - 76 files changed, 79 insertions(+), 3245 deletions(-) delete mode 100644 x-pack/legacy/common/__tests__/poller.js delete mode 100644 x-pack/legacy/common/constants/index.ts delete mode 100644 x-pack/legacy/common/constants/license_status.ts delete mode 100644 x-pack/legacy/common/constants/license_types.ts delete mode 100644 x-pack/legacy/common/eui_draggable/index.d.ts delete mode 100644 x-pack/legacy/common/eui_styled_components/index.ts delete mode 100644 x-pack/legacy/common/poller.d.ts delete mode 100644 x-pack/legacy/common/poller.js delete mode 100644 x-pack/legacy/plugins/xpack_main/index.js delete mode 100644 x-pack/legacy/plugins/xpack_main/server/lib/__tests__/setup_xpack_main.js delete mode 100644 x-pack/legacy/plugins/xpack_main/server/lib/__tests__/xpack_info.js delete mode 100644 x-pack/legacy/plugins/xpack_main/server/lib/setup_xpack_main.js delete mode 100644 x-pack/legacy/plugins/xpack_main/server/lib/xpack_info.ts delete mode 100644 x-pack/legacy/plugins/xpack_main/server/lib/xpack_info_license.test.js delete mode 100644 x-pack/legacy/plugins/xpack_main/server/lib/xpack_info_license.ts delete mode 100644 x-pack/legacy/plugins/xpack_main/server/routes/api/v1/__tests__/xpack_info.js delete mode 100644 x-pack/legacy/plugins/xpack_main/server/routes/api/v1/xpack_info.js delete mode 100644 x-pack/legacy/plugins/xpack_main/server/xpack_main.d.ts delete mode 100644 x-pack/legacy/server/lib/__tests__/key_case_converter.js delete mode 100644 x-pack/legacy/server/lib/__tests__/kibana_state.js delete mode 100644 x-pack/legacy/server/lib/check_license/check_license.js delete mode 100644 x-pack/legacy/server/lib/check_license/check_license.test.js delete mode 100644 x-pack/legacy/server/lib/check_license/index.js delete mode 100644 x-pack/legacy/server/lib/constants/index.ts delete mode 100644 x-pack/legacy/server/lib/constants/xpack_info.ts delete mode 100644 x-pack/legacy/server/lib/create_router/call_with_request_factory/call_with_request_factory.js delete mode 100644 x-pack/legacy/server/lib/create_router/call_with_request_factory/index.d.ts delete mode 100644 x-pack/legacy/server/lib/create_router/call_with_request_factory/index.js delete mode 100644 x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_custom_error.js delete mode 100644 x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_es_error.js delete mode 100644 x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_unknown_error.js delete mode 100644 x-pack/legacy/server/lib/create_router/error_wrappers/index.d.ts delete mode 100644 x-pack/legacy/server/lib/create_router/error_wrappers/index.js delete mode 100644 x-pack/legacy/server/lib/create_router/error_wrappers/wrap_custom_error.js delete mode 100644 x-pack/legacy/server/lib/create_router/error_wrappers/wrap_es_error.js delete mode 100644 x-pack/legacy/server/lib/create_router/error_wrappers/wrap_unknown_error.js delete mode 100644 x-pack/legacy/server/lib/create_router/index.d.ts delete mode 100644 x-pack/legacy/server/lib/create_router/index.js delete mode 100644 x-pack/legacy/server/lib/create_router/is_es_error_factory/__tests__/is_es_error_factory.js delete mode 100644 x-pack/legacy/server/lib/create_router/is_es_error_factory/index.js delete mode 100644 x-pack/legacy/server/lib/create_router/is_es_error_factory/is_es_error_factory.js delete mode 100644 x-pack/legacy/server/lib/create_router/license_pre_routing_factory/__tests__/license_pre_routing_factory.js delete mode 100644 x-pack/legacy/server/lib/create_router/license_pre_routing_factory/index.js delete mode 100644 x-pack/legacy/server/lib/create_router/license_pre_routing_factory/license_pre_routing_factory.js delete mode 100644 x-pack/legacy/server/lib/key_case_converter.js delete mode 100644 x-pack/legacy/server/lib/parse_kibana_state.js delete mode 100644 x-pack/legacy/server/lib/register_license_checker/index.d.ts delete mode 100644 x-pack/legacy/server/lib/register_license_checker/index.js delete mode 100644 x-pack/legacy/server/lib/register_license_checker/register_license_checker.js delete mode 100644 x-pack/legacy/server/lib/watch_status_and_license_to_initialize.js delete mode 100644 x-pack/legacy/server/lib/watch_status_and_license_to_initialize.test.js delete mode 100644 x-pack/legacy/server/lib/xpack_usage.js rename x-pack/{legacy/common/eui_styled_components => plugins/xpack_legacy/common}/eui_styled_components.tsx (100%) rename x-pack/{legacy/plugins/xpack_main/server/routes/api/v1/index.js => plugins/xpack_legacy/common/index.ts} (83%) diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index d8bd39b9dcdf4..a1715cf3dba2c 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -48,11 +48,6 @@ const CAN_CLUSTER = canRequire(CLUSTER_MANAGER_PATH); const REPL_PATH = resolve(__dirname, '../repl'); const CAN_REPL = canRequire(REPL_PATH); -// xpack is installed in both dev and the distributable, it's optional if -// install is a link to the source, not an actual install -const XPACK_DIR = resolve(__dirname, '../../../x-pack'); -const XPACK_INSTALLED = canRequire(XPACK_DIR); - const pathCollector = function () { const paths = []; return function (path) { @@ -137,16 +132,7 @@ function applyConfigOverrides(rawConfig, opts, extraCliOptions) { if (opts.logFile) set('logging.dest', opts.logFile); set('plugins.scanDirs', _.compact([].concat(get('plugins.scanDirs'), opts.pluginDir))); - set( - 'plugins.paths', - _.compact( - [].concat( - get('plugins.paths'), - opts.pluginPath, - XPACK_INSTALLED && !opts.oss ? [XPACK_DIR] : [] - ) - ) - ); + set('plugins.paths', _.compact([].concat(get('plugins.paths'), opts.pluginPath))); merge(extraCliOptions); merge(readKeystore()); diff --git a/x-pack/index.js b/x-pack/index.js index 745b4bd72dde8..12ad10a1bfec3 100644 --- a/x-pack/index.js +++ b/x-pack/index.js @@ -4,9 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { xpackMain } from './legacy/plugins/xpack_main'; import { spaces } from './legacy/plugins/spaces'; module.exports = function (kibana) { - return [xpackMain(kibana), spaces(kibana)]; + return [spaces(kibana)]; }; diff --git a/x-pack/legacy/common/__tests__/poller.js b/x-pack/legacy/common/__tests__/poller.js deleted file mode 100644 index 24558502a8d02..0000000000000 --- a/x-pack/legacy/common/__tests__/poller.js +++ /dev/null @@ -1,240 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import sinon from 'sinon'; -import { Poller } from '../poller'; - -describe('Poller', () => { - const pollFrequencyInMillis = 20; - let functionToPoll; - let successFunction; - let errorFunction; - let poller; - let clock; - - beforeEach(() => { - clock = sinon.useFakeTimers(); - }); - - afterEach(() => { - clock.restore(); - if (poller) { - poller.stop(); - } - }); - - // Allowing the Poller to poll requires intimate knowledge of the inner workings of the Poller. - // We have to ensure that the Promises internal to the `_poll` method are resolved to queue up - // the next setTimeout before incrementing the clock. The order of this differs slightly when the - // `trailing` is set, hence the different `allowPoll` and `allowDelayPoll` functions. - const queueNextPoll = async () => { - await Promise.resolve(); - await Promise.resolve(); - }; - - const allowPoll = async (interval) => { - await queueNextPoll(); - clock.tick(interval); - }; - - const allowDelayPoll = async (interval) => { - clock.tick(interval); - await queueNextPoll(); - }; - - describe('start()', () => { - beforeEach(() => { - functionToPoll = sinon.spy(() => { - return Promise.resolve(42); - }); - successFunction = sinon.spy(); - errorFunction = sinon.spy(); - poller = new Poller({ - functionToPoll, - successFunction, - errorFunction, - pollFrequencyInMillis, - }); - }); - - describe(`when trailing isn't set`, () => { - it(`polls immediately`, () => { - poller.start(); - expect(functionToPoll.callCount).to.be(1); - }); - }); - - describe(`when trailing is set to true`, () => { - beforeEach(() => { - poller = new Poller({ - functionToPoll, - successFunction, - errorFunction, - pollFrequencyInMillis, - trailing: true, - }); - }); - - it('waits for pollFrequencyInMillis before polling', async () => { - poller.start(); - expect(functionToPoll.callCount).to.be(0); - allowDelayPoll(pollFrequencyInMillis); - expect(functionToPoll.callCount).to.be(1); - }); - }); - - it('polls the functionToPoll multiple times', async () => { - poller.start(); - await allowPoll(pollFrequencyInMillis * 2); - expect(functionToPoll.callCount).to.be.greaterThan(1); - }); - - describe('when the function to poll succeeds', () => { - it('calls the successFunction multiple times', async () => { - poller.start(); - await allowPoll(pollFrequencyInMillis * 2); - expect(successFunction.callCount).to.be.greaterThan(1); - expect(errorFunction.callCount).to.be(0); - }); - }); - - describe('when the function to poll fails', () => { - beforeEach(() => { - functionToPoll = sinon.spy(() => { - return Promise.reject(42); - }); - }); - - describe('when the continuePollingOnError option has not been set', () => { - beforeEach(() => { - poller = new Poller({ - functionToPoll, - successFunction, - errorFunction, - pollFrequencyInMillis, - }); - }); - - it('calls the errorFunction exactly once and polling is stopped', async () => { - poller.start(); - await allowPoll(pollFrequencyInMillis * 4); - expect(poller.isRunning()).to.be(false); - expect(successFunction.callCount).to.be(0); - expect(errorFunction.callCount).to.be(1); - }); - }); - - describe('when the continuePollingOnError option has been set to true', () => { - beforeEach(() => { - poller = new Poller({ - functionToPoll, - successFunction, - errorFunction, - pollFrequencyInMillis, - continuePollingOnError: true, - }); - }); - - it('calls the errorFunction multiple times', async () => { - poller.start(); - await allowPoll(pollFrequencyInMillis); - await allowPoll(pollFrequencyInMillis); - expect(successFunction.callCount).to.be(0); - expect(errorFunction.callCount).to.be.greaterThan(1); - }); - - describe('when pollFrequencyErrorMultiplier has been set', () => { - beforeEach(() => { - poller = new Poller({ - functionToPoll, - successFunction, - errorFunction, - pollFrequencyInMillis, - continuePollingOnError: true, - pollFrequencyErrorMultiplier: 2, - }); - }); - - it('waits for the multiplier * the pollFrequency', async () => { - poller.start(); - await queueNextPoll(); - expect(functionToPoll.callCount).to.be(1); - await allowPoll(pollFrequencyInMillis); - expect(functionToPoll.callCount).to.be(1); - await allowPoll(pollFrequencyInMillis); - expect(functionToPoll.callCount).to.be(2); - }); - }); - }); - }); - }); - - describe('isRunning()', () => { - beforeEach(() => { - functionToPoll = sinon.spy(() => { - return Promise.resolve(42); - }); - poller = new Poller({ - functionToPoll, - }); - }); - - it('returns true immediately after invoking start()', () => { - poller.start(); - expect(poller.isRunning()).to.be(true); - }); - - it('returns false after invoking stop', () => { - poller.start(); - poller.stop(); - expect(poller.isRunning()).to.be(false); - }); - }); - - describe('stop()', () => { - describe(`when successFunction isn't set`, () => { - beforeEach(() => { - functionToPoll = sinon.spy(() => { - return Promise.resolve(42); - }); - poller = new Poller({ - functionToPoll, - pollFrequencyInMillis, - }); - }); - - it(`doesn't poll again`, async () => { - poller.start(); - expect(functionToPoll.callCount).to.be(1); - poller.stop(); - await allowPoll(pollFrequencyInMillis); - expect(functionToPoll.callCount).to.be(1); - }); - }); - - describe(`when successFunction is a Promise`, () => { - beforeEach(() => { - functionToPoll = sinon.spy(() => { - return Promise.resolve(42); - }); - poller = new Poller({ - functionToPoll, - successFunction: Promise.resolve(), - pollFrequencyInMillis, - }); - }); - - it(`doesn't poll again when successFunction is a Promise`, async () => { - poller.start(); - expect(functionToPoll.callCount).to.be(1); - poller.stop(); - await allowPoll(pollFrequencyInMillis); - expect(functionToPoll.callCount).to.be(1); - }); - }); - }); -}); diff --git a/x-pack/legacy/common/constants/index.ts b/x-pack/legacy/common/constants/index.ts deleted file mode 100644 index 4db0f994fd47e..0000000000000 --- a/x-pack/legacy/common/constants/index.ts +++ /dev/null @@ -1,23 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { - LICENSE_STATUS_UNAVAILABLE, - LICENSE_STATUS_INVALID, - LICENSE_STATUS_EXPIRED, - LICENSE_STATUS_VALID, -} from './license_status'; - -export { - LICENSE_TYPE_BASIC, - LICENSE_TYPE_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_TRIAL, - RANKED_LICENSE_TYPES, - LicenseType, -} from './license_types'; diff --git a/x-pack/legacy/common/constants/license_status.ts b/x-pack/legacy/common/constants/license_status.ts deleted file mode 100644 index 5fdfa08d73959..0000000000000 --- a/x-pack/legacy/common/constants/license_status.ts +++ /dev/null @@ -1,10 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export const LICENSE_STATUS_UNAVAILABLE = 'UNAVAILABLE'; -export const LICENSE_STATUS_INVALID = 'INVALID'; -export const LICENSE_STATUS_EXPIRED = 'EXPIRED'; -export const LICENSE_STATUS_VALID = 'VALID'; diff --git a/x-pack/legacy/common/constants/license_types.ts b/x-pack/legacy/common/constants/license_types.ts deleted file mode 100644 index 8c329df2f85f7..0000000000000 --- a/x-pack/legacy/common/constants/license_types.ts +++ /dev/null @@ -1,31 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export const LICENSE_TYPE_BASIC = 'basic'; -export const LICENSE_TYPE_STANDARD = 'standard'; -export const LICENSE_TYPE_GOLD = 'gold'; -export const LICENSE_TYPE_PLATINUM = 'platinum'; -export const LICENSE_TYPE_ENTERPRISE = 'enterprise'; -export const LICENSE_TYPE_TRIAL = 'trial'; - -export type LicenseType = - | typeof LICENSE_TYPE_BASIC - | typeof LICENSE_TYPE_STANDARD - | typeof LICENSE_TYPE_GOLD - | typeof LICENSE_TYPE_PLATINUM - | typeof LICENSE_TYPE_ENTERPRISE - | typeof LICENSE_TYPE_TRIAL; - -// These are ordered from least featureful to most featureful, so we can assume that someone holding -// a license at a particular index cannot access any features unlocked by the licenses that follow it. -export const RANKED_LICENSE_TYPES = [ - LICENSE_TYPE_BASIC, - LICENSE_TYPE_STANDARD, - LICENSE_TYPE_GOLD, - LICENSE_TYPE_PLATINUM, - LICENSE_TYPE_ENTERPRISE, - LICENSE_TYPE_TRIAL, -]; diff --git a/x-pack/legacy/common/eui_draggable/index.d.ts b/x-pack/legacy/common/eui_draggable/index.d.ts deleted file mode 100644 index 322966b3c982e..0000000000000 --- a/x-pack/legacy/common/eui_draggable/index.d.ts +++ /dev/null @@ -1,17 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { EuiDraggable, EuiDragDropContext } from '@elastic/eui'; - -type PropsOf = T extends React.ComponentType ? ComponentProps : never; -type FirstArgumentOf = Func extends (arg1: infer FirstArgument, ...rest: any[]) => any - ? FirstArgument - : never; -export type DragHandleProps = FirstArgumentOf< - Exclude['children'], React.ReactElement> ->['dragHandleProps']; -export type DropResult = FirstArgumentOf['onDragEnd']>; diff --git a/x-pack/legacy/common/eui_styled_components/index.ts b/x-pack/legacy/common/eui_styled_components/index.ts deleted file mode 100644 index 9b3ed903627b4..0000000000000 --- a/x-pack/legacy/common/eui_styled_components/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - css, - euiStyled, - EuiTheme, - EuiThemeProvider, - createGlobalStyle, - keyframes, - withTheme, -} from './eui_styled_components'; - -export { css, euiStyled, EuiTheme, EuiThemeProvider, createGlobalStyle, keyframes, withTheme }; -// In order to to mimic the styled-components module we need to ignore the following -// eslint-disable-next-line import/no-default-export -export default euiStyled; diff --git a/x-pack/legacy/common/poller.d.ts b/x-pack/legacy/common/poller.d.ts deleted file mode 100644 index df39d93a28a81..0000000000000 --- a/x-pack/legacy/common/poller.d.ts +++ /dev/null @@ -1,14 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export declare class Poller { - constructor(options: any); - - public start(): void; - public stop(): void; - public isRunning(): boolean; - public getPollFrequency(): number; -} diff --git a/x-pack/legacy/common/poller.js b/x-pack/legacy/common/poller.js deleted file mode 100644 index 09824ce9d6d23..0000000000000 --- a/x-pack/legacy/common/poller.js +++ /dev/null @@ -1,79 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import _ from 'lodash'; - -export class Poller { - constructor(options) { - this.functionToPoll = options.functionToPoll; // Must return a Promise - this.successFunction = options.successFunction || _.noop; - this.errorFunction = options.errorFunction || _.noop; - this.pollFrequencyInMillis = options.pollFrequencyInMillis; - this.trailing = options.trailing || false; - this.continuePollingOnError = options.continuePollingOnError || false; - this.pollFrequencyErrorMultiplier = options.pollFrequencyErrorMultiplier || 1; - this._timeoutId = null; - this._isRunning = false; - } - - getPollFrequency() { - return this.pollFrequencyInMillis; - } - - _poll() { - return this.functionToPoll() - .then(this.successFunction) - .then(() => { - if (!this._isRunning) { - return; - } - - this._timeoutId = setTimeout(this._poll.bind(this), this.pollFrequencyInMillis); - }) - .catch((e) => { - this.errorFunction(e); - if (!this._isRunning) { - return; - } - - if (this.continuePollingOnError) { - this._timeoutId = setTimeout( - this._poll.bind(this), - this.pollFrequencyInMillis * this.pollFrequencyErrorMultiplier - ); - } else { - this.stop(); - } - }); - } - - start() { - if (this._isRunning) { - return; - } - - this._isRunning = true; - if (this.trailing) { - this._timeoutId = setTimeout(this._poll.bind(this), this.pollFrequencyInMillis); - } else { - this._poll(); - } - } - - stop() { - if (!this._isRunning) { - return; - } - - this._isRunning = false; - clearTimeout(this._timeoutId); - this._timeoutId = null; - } - - isRunning() { - return this._isRunning; - } -} diff --git a/x-pack/legacy/plugins/xpack_main/index.js b/x-pack/legacy/plugins/xpack_main/index.js deleted file mode 100644 index a3bd66e744fda..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/index.js +++ /dev/null @@ -1,31 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { resolve } from 'path'; -import { setupXPackMain } from './server/lib/setup_xpack_main'; -import { xpackInfoRoute } from './server/routes/api/v1'; - -export const xpackMain = (kibana) => { - return new kibana.Plugin({ - id: 'xpack_main', - configPrefix: 'xpack.xpack_main', - publicDir: resolve(__dirname, 'public'), - require: [], - - config(Joi) { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - - init(server) { - setupXPackMain(server); - - // register routes - xpackInfoRoute(server); - }, - }); -}; diff --git a/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/setup_xpack_main.js b/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/setup_xpack_main.js deleted file mode 100644 index f49f44bed97a7..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/setup_xpack_main.js +++ /dev/null @@ -1,68 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { BehaviorSubject } from 'rxjs'; -import sinon from 'sinon'; -import { XPackInfo } from '../xpack_info'; -import { setupXPackMain } from '../setup_xpack_main'; - -describe('setupXPackMain()', () => { - const sandbox = sinon.createSandbox(); - - let mockServer; - let mockStatusObservable; - let mockElasticsearchPlugin; - - beforeEach(() => { - sandbox.useFakeTimers(); - - mockElasticsearchPlugin = { - getCluster: sinon.stub(), - }; - - mockStatusObservable = sinon.stub({ subscribe() {} }); - - mockServer = sinon.stub({ - plugins: { - elasticsearch: mockElasticsearchPlugin, - }, - newPlatform: { - setup: { - core: { - status: { - core$: { - pipe() { - return mockStatusObservable; - }, - }, - }, - }, - plugins: { features: {}, licensing: { license$: new BehaviorSubject() } }, - }, - }, - events: { on() {} }, - log() {}, - config() {}, - expose() {}, - ext() {}, - }); - - // Make sure plugins doesn't consume config - const configGetStub = sinon - .stub() - .throws(new Error('`config.get` is called with unexpected key.')); - mockServer.config.returns({ get: configGetStub }); - }); - - afterEach(() => sandbox.restore()); - - it('all extension hooks should be properly initialized.', () => { - setupXPackMain(mockServer); - - sinon.assert.calledWithExactly(mockServer.expose, 'info', sinon.match.instanceOf(XPackInfo)); - sinon.assert.calledWithExactly(mockStatusObservable.subscribe, sinon.match.func); - }); -}); diff --git a/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/xpack_info.js b/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/xpack_info.js deleted file mode 100644 index 81fb822882817..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/lib/__tests__/xpack_info.js +++ /dev/null @@ -1,398 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createHash } from 'crypto'; -import { BehaviorSubject } from 'rxjs'; -import expect from '@kbn/expect'; -import sinon from 'sinon'; -import { XPackInfo } from '../xpack_info'; -import { licensingMock } from '../../../../../../plugins/licensing/server/mocks'; - -function createLicense(license = {}, features = {}) { - return licensingMock.createLicense({ - license: { - uid: 'custom-uid', - type: 'gold', - mode: 'gold', - status: 'active', - expiryDateInMillis: 1286575200000, - ...license, - }, - features: { - security: { - description: 'Security for the Elastic Stack', - isAvailable: true, - isEnabled: true, - }, - watcher: { - description: 'Alerting, Notification and Automation for the Elastic Stack', - isAvailable: true, - isEnabled: false, - }, - ...features, - }, - }); -} - -function getSignature(object) { - return createHash('md5').update(JSON.stringify(object)).digest('hex'); -} - -describe('XPackInfo', () => { - let mockServer; - let mockElasticsearchPlugin; - - beforeEach(() => { - mockServer = sinon.stub({ - plugins: { elasticsearch: mockElasticsearchPlugin }, - events: { on() {} }, - newPlatform: { - setup: { - plugins: { - licensing: {}, - }, - }, - }, - }); - }); - - describe('refreshNow()', () => { - it('delegates to the new platform licensing plugin', async () => { - const refresh = sinon.spy(); - - const xPackInfo = new XPackInfo(mockServer, { - licensing: { - license$: new BehaviorSubject(createLicense()), - refresh: refresh, - }, - }); - - await xPackInfo.refreshNow(); - - sinon.assert.calledOnce(refresh); - }); - }); - - describe('license', () => { - let xPackInfo; - let license$; - beforeEach(async () => { - license$ = new BehaviorSubject(createLicense()); - xPackInfo = new XPackInfo(mockServer, { - licensing: { - license$, - refresh: () => null, - }, - }); - }); - - it('getUid() shows license uid returned from the license$.', async () => { - expect(xPackInfo.license.getUid()).to.be('custom-uid'); - - license$.next(createLicense({ uid: 'new-custom-uid' })); - - expect(xPackInfo.license.getUid()).to.be('new-custom-uid'); - - license$.next(createLicense({ uid: undefined, error: 'error-reason' })); - - expect(xPackInfo.license.getUid()).to.be(undefined); - }); - - it('isActive() is based on the status returned from the backend.', async () => { - expect(xPackInfo.license.isActive()).to.be(true); - - license$.next(createLicense({ status: 'expired' })); - expect(xPackInfo.license.isActive()).to.be(false); - - license$.next(createLicense({ status: 'some other value' })); - expect(xPackInfo.license.isActive()).to.be(false); - - license$.next(createLicense({ status: 'active' })); - expect(xPackInfo.license.isActive()).to.be(true); - - license$.next(createLicense({ status: undefined, error: 'error-reason' })); - expect(xPackInfo.license.isActive()).to.be(false); - }); - - it('getExpiryDateInMillis() is based on the value returned from the backend.', async () => { - expect(xPackInfo.license.getExpiryDateInMillis()).to.be(1286575200000); - - license$.next(createLicense({ expiryDateInMillis: 10203040 })); - expect(xPackInfo.license.getExpiryDateInMillis()).to.be(10203040); - - license$.next(createLicense({ expiryDateInMillis: undefined, error: 'error-reason' })); - expect(xPackInfo.license.getExpiryDateInMillis()).to.be(undefined); - }); - - it('getType() is based on the value returned from the backend.', async () => { - expect(xPackInfo.license.getType()).to.be('gold'); - - license$.next(createLicense({ type: 'basic' })); - expect(xPackInfo.license.getType()).to.be('basic'); - - license$.next(createLicense({ type: undefined, error: 'error-reason' })); - expect(xPackInfo.license.getType()).to.be(undefined); - }); - - it('isOneOf() correctly determines if current license is presented in the specified list.', async () => { - expect(xPackInfo.license.isOneOf('gold')).to.be(true); - expect(xPackInfo.license.isOneOf(['gold', 'basic'])).to.be(true); - expect(xPackInfo.license.isOneOf(['platinum', 'basic'])).to.be(false); - expect(xPackInfo.license.isOneOf('standard')).to.be(false); - - license$.next(createLicense({ mode: 'basic' })); - - expect(xPackInfo.license.isOneOf('basic')).to.be(true); - expect(xPackInfo.license.isOneOf(['gold', 'basic'])).to.be(true); - expect(xPackInfo.license.isOneOf(['platinum', 'gold'])).to.be(false); - expect(xPackInfo.license.isOneOf('standard')).to.be(false); - }); - }); - - describe('feature', () => { - let xPackInfo; - let license$; - beforeEach(async () => { - license$ = new BehaviorSubject( - createLicense( - {}, - { - feature: { - isAvailable: false, - isEnabled: true, - }, - } - ) - ); - xPackInfo = new XPackInfo(mockServer, { - licensing: { - license$, - refresh: () => null, - }, - }); - }); - - it('isAvailable() checks whether particular feature is available.', async () => { - const availableFeatureOne = xPackInfo.feature('security'); - const availableFeatureTwo = xPackInfo.feature('watcher'); - const unavailableFeatureOne = xPackInfo.feature('feature'); - const unavailableFeatureTwo = xPackInfo.feature('non-existing-feature'); - - expect(availableFeatureOne.isAvailable()).to.be(true); - expect(availableFeatureTwo.isAvailable()).to.be(true); - expect(unavailableFeatureOne.isAvailable()).to.be(false); - expect(unavailableFeatureTwo.isAvailable()).to.be(false); - }); - - it('isEnabled() checks whether particular feature is enabled.', async () => { - const enabledFeatureOne = xPackInfo.feature('security'); - const enabledFeatureTwo = xPackInfo.feature('feature'); - const disabledFeatureOne = xPackInfo.feature('watcher'); - const disabledFeatureTwo = xPackInfo.feature('non-existing-feature'); - - expect(enabledFeatureOne.isEnabled()).to.be(true); - expect(enabledFeatureTwo.isEnabled()).to.be(true); - expect(disabledFeatureOne.isEnabled()).to.be(false); - expect(disabledFeatureTwo.isEnabled()).to.be(false); - }); - - it('registerLicenseCheckResultsGenerator() allows to fill in XPack Info feature specific info.', async () => { - const securityFeature = xPackInfo.feature('security'); - const watcherFeature = xPackInfo.feature('watcher'); - - expect(xPackInfo.toJSON().features.security).to.be(undefined); - expect(xPackInfo.toJSON().features.watcher).to.be(undefined); - - securityFeature.registerLicenseCheckResultsGenerator((info) => { - return { - isXPackInfo: info instanceof XPackInfo, - license: info.license.getType(), - someCustomValue: 100500, - }; - }); - - expect(xPackInfo.toJSON().features.security).to.eql({ - isXPackInfo: true, - license: 'gold', - someCustomValue: 100500, - }); - expect(xPackInfo.toJSON().features.watcher).to.be(undefined); - - watcherFeature.registerLicenseCheckResultsGenerator((info) => { - return { - isXPackInfo: info instanceof XPackInfo, - license: info.license.getType(), - someAnotherCustomValue: 500100, - }; - }); - - expect(xPackInfo.toJSON().features.security).to.eql({ - isXPackInfo: true, - license: 'gold', - someCustomValue: 100500, - }); - expect(xPackInfo.toJSON().features.watcher).to.eql({ - isXPackInfo: true, - license: 'gold', - someAnotherCustomValue: 500100, - }); - - license$.next(createLicense({ type: 'platinum' })); - - expect(xPackInfo.toJSON().features.security).to.eql({ - isXPackInfo: true, - license: 'platinum', - someCustomValue: 100500, - }); - expect(xPackInfo.toJSON().features.watcher).to.eql({ - isXPackInfo: true, - license: 'platinum', - someAnotherCustomValue: 500100, - }); - }); - - it('getLicenseCheckResults() correctly returns feature specific info.', async () => { - const securityFeature = xPackInfo.feature('security'); - const watcherFeature = xPackInfo.feature('watcher'); - - expect(securityFeature.getLicenseCheckResults()).to.be(undefined); - expect(watcherFeature.getLicenseCheckResults()).to.be(undefined); - - securityFeature.registerLicenseCheckResultsGenerator((info) => { - return { - isXPackInfo: info instanceof XPackInfo, - license: info.license.getType(), - someCustomValue: 100500, - }; - }); - - expect(securityFeature.getLicenseCheckResults()).to.eql({ - isXPackInfo: true, - license: 'gold', - someCustomValue: 100500, - }); - expect(watcherFeature.getLicenseCheckResults()).to.be(undefined); - - watcherFeature.registerLicenseCheckResultsGenerator((info) => { - return { - isXPackInfo: info instanceof XPackInfo, - license: info.license.getType(), - someAnotherCustomValue: 500100, - }; - }); - - expect(securityFeature.getLicenseCheckResults()).to.eql({ - isXPackInfo: true, - license: 'gold', - someCustomValue: 100500, - }); - expect(watcherFeature.getLicenseCheckResults()).to.eql({ - isXPackInfo: true, - license: 'gold', - someAnotherCustomValue: 500100, - }); - - license$.next(createLicense({ type: 'platinum' })); - - expect(securityFeature.getLicenseCheckResults()).to.eql({ - isXPackInfo: true, - license: 'platinum', - someCustomValue: 100500, - }); - expect(watcherFeature.getLicenseCheckResults()).to.eql({ - isXPackInfo: true, - license: 'platinum', - someAnotherCustomValue: 500100, - }); - }); - }); - - it('onLicenseInfoChange() allows to subscribe to license update', async () => { - const license$ = new BehaviorSubject(createLicense()); - - const xPackInfo = new XPackInfo(mockServer, { - licensing: { - license$, - refresh: () => null, - }, - }); - - const watcherFeature = xPackInfo.feature('watcher'); - watcherFeature.registerLicenseCheckResultsGenerator((info) => ({ - type: info.license.getType(), - })); - - const statuses = []; - xPackInfo.onLicenseInfoChange(() => statuses.push(watcherFeature.getLicenseCheckResults())); - - license$.next(createLicense({ type: 'basic' })); - expect(statuses).to.eql([{ type: 'basic' }]); - - license$.next(createLicense({ type: 'trial' })); - expect(statuses).to.eql([{ type: 'basic' }, { type: 'trial' }]); - }); - - it('refreshNow() leads to onLicenseInfoChange()', async () => { - const license$ = new BehaviorSubject(createLicense()); - - const xPackInfo = new XPackInfo(mockServer, { - licensing: { - license$, - refresh: () => license$.next({ type: 'basic' }), - }, - }); - - const watcherFeature = xPackInfo.feature('watcher'); - - watcherFeature.registerLicenseCheckResultsGenerator((info) => ({ - type: info.license.getType(), - })); - - const statuses = []; - xPackInfo.onLicenseInfoChange(() => statuses.push(watcherFeature.getLicenseCheckResults())); - - await xPackInfo.refreshNow(); - expect(statuses).to.eql([{ type: 'basic' }]); - }); - - it('getSignature() returns correct signature.', async () => { - const license$ = new BehaviorSubject(createLicense()); - const xPackInfo = new XPackInfo(mockServer, { - licensing: { - license$, - refresh: () => null, - }, - }); - - expect(xPackInfo.getSignature()).to.be( - getSignature({ - license: { - type: 'gold', - isActive: true, - expiryDateInMillis: 1286575200000, - }, - features: {}, - }) - ); - - license$.next(createLicense({ type: 'platinum', expiryDateInMillis: 20304050 })); - - const expectedSignature = getSignature({ - license: { - type: 'platinum', - isActive: true, - expiryDateInMillis: 20304050, - }, - features: {}, - }); - expect(xPackInfo.getSignature()).to.be(expectedSignature); - - // Should stay the same after refresh if nothing changed. - license$.next(createLicense({ type: 'platinum', expiryDateInMillis: 20304050 })); - - expect(xPackInfo.getSignature()).to.be(expectedSignature); - }); -}); diff --git a/x-pack/legacy/plugins/xpack_main/server/lib/setup_xpack_main.js b/x-pack/legacy/plugins/xpack_main/server/lib/setup_xpack_main.js deleted file mode 100644 index fd4e3c86d0ca7..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/lib/setup_xpack_main.js +++ /dev/null @@ -1,33 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { pairwise } from 'rxjs/operators'; -import { XPackInfo } from './xpack_info'; - -/** - * Setup the X-Pack Main plugin. This is fired every time that the Elasticsearch plugin becomes Green. - * - * This will ensure that X-Pack is installed on the Elasticsearch cluster, as well as trigger the initial - * polling for _xpack/info. - * - * @param server {Object} The Kibana server object. - */ -export function setupXPackMain(server) { - const info = new XPackInfo(server, { licensing: server.newPlatform.setup.plugins.licensing }); - - server.expose('info', info); - - // trigger an xpack info refresh whenever the elasticsearch plugin status changes - server.newPlatform.setup.core.status.core$ - .pipe(pairwise()) - .subscribe(async ([coreLast, coreCurrent]) => { - if (coreLast.elasticsearch.level !== coreCurrent.elasticsearch.level) { - await info.refreshNow(); - } - }); - - return info; -} diff --git a/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info.ts b/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info.ts deleted file mode 100644 index aa66532a2897d..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info.ts +++ /dev/null @@ -1,240 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createHash } from 'crypto'; -import { Legacy } from 'kibana'; - -import { XPackInfoLicense } from './xpack_info_license'; - -import { LicensingPluginSetup, ILicense } from '../../../../../plugins/licensing/server'; - -export interface XPackInfoOptions { - clusterSource?: string; - pollFrequencyInMillis: number; -} - -type LicenseGeneratorCheck = (xpackInfo: XPackInfo) => any; - -export interface XPackFeature { - isAvailable(): boolean; - isEnabled(): boolean; - registerLicenseCheckResultsGenerator(generator: LicenseGeneratorCheck): void; - getLicenseCheckResults(): any; -} - -interface Deps { - licensing: LicensingPluginSetup; -} - -/** - * A helper that provides a convenient way to access XPack Info returned by Elasticsearch. - */ -export class XPackInfo { - /** - * XPack License object. - * @type {XPackInfoLicense} - * @private - */ - _license: XPackInfoLicense; - - /** - * Feature name <-> feature license check generator function mapping. - * @type {Map} - * @private - */ - _featureLicenseCheckResultsGenerators = new Map(); - - /** - * Set of listener functions that will be called whenever the license - * info changes - * @type {Set} - */ - _licenseInfoChangedListeners = new Set<() => void>(); - - /** - * Cache that may contain last xpack info API response or error, json representation - * of xpack info and xpack info signature. - * @type {{response: Object|undefined, error: Object|undefined, json: Object|undefined, signature: string|undefined}} - * @private - */ - private _cache: { - license?: ILicense; - error?: string; - json?: Record; - signature?: string; - }; - - /** - * XPack License instance. - * @returns {XPackInfoLicense} - */ - public get license() { - return this._license; - } - - private readonly licensingPlugin: LicensingPluginSetup; - - /** - * Constructs XPack info object. - * @param {Hapi.Server} server HapiJS server instance. - */ - constructor(server: Legacy.Server, deps: Deps) { - if (!deps.licensing) { - throw new Error('XPackInfo requires enabled Licensing plugin'); - } - this.licensingPlugin = deps.licensing; - - this._cache = {}; - - this.licensingPlugin.license$.subscribe((license: ILicense) => { - if (license.isActive) { - this._cache = { - license, - error: undefined, - }; - } else { - this._cache = { - license, - error: license.error, - }; - } - - this._licenseInfoChangedListeners.forEach((fn) => fn()); - }); - - this._license = new XPackInfoLicense(() => this._cache.license); - } - - /** - * Checks whether XPack info is available. - * @returns {boolean} - */ - isAvailable() { - return Boolean(this._cache.license?.isAvailable); - } - - /** - * Checks whether ES was available - * @returns {boolean} - */ - isXpackUnavailable() { - return ( - this._cache.error && - this._cache.error === 'X-Pack plugin is not installed on the Elasticsearch cluster.' - ); - } - - /** - * If present, describes the reason why XPack info is not available. - * @returns {Error|string} - */ - unavailableReason() { - return this._cache.license?.getUnavailableReason(); - } - - onLicenseInfoChange(handler: () => void) { - this._licenseInfoChangedListeners.add(handler); - } - - /** - * Queries server to get the updated XPack info. - * @returns {Promise.} - */ - async refreshNow() { - await this.licensingPlugin.refresh(); - return this; - } - - /** - * Returns a wrapper around XPack info that gives an access to the properties of - * the specific feature. - * @param {string} name Name of the feature to get a wrapper for. - * @returns {Object} - */ - feature(name: string): XPackFeature { - return { - /** - * Checks whether feature is available (permitted by the current license). - * @returns {boolean} - */ - isAvailable: () => { - return Boolean(this._cache.license?.getFeature(name).isAvailable); - }, - - /** - * Checks whether feature is enabled (not disabled by the configuration specifically). - * @returns {boolean} - */ - isEnabled: () => { - return Boolean(this._cache.license?.getFeature(name).isEnabled); - }, - - /** - * Registers a `generator` function that will be called with XPackInfo instance as - * argument whenever XPack info changes. Whatever `generator` returns will be stored - * in XPackInfo JSON representation and can be accessed with `getLicenseCheckResults`. - * @param {Function} generator Function to call whenever XPackInfo changes. - */ - registerLicenseCheckResultsGenerator: (generator: LicenseGeneratorCheck) => { - this._featureLicenseCheckResultsGenerators.set(name, generator); - - // Since JSON representation and signature are cached we should invalidate them to - // include results from newly registered generator when they are requested. - this._cache.json = undefined; - this._cache.signature = undefined; - }, - - /** - * Returns license check results that were previously produced by the `generator` function. - * @returns {Object} - */ - getLicenseCheckResults: () => this.toJSON().features[name], - }; - } - - /** - * Extracts string md5 hash from the stringified version of license JSON representation. - * @returns {string} - */ - getSignature() { - if (this._cache.signature) { - return this._cache.signature; - } - - this._cache.signature = createHash('md5').update(JSON.stringify(this.toJSON())).digest('hex'); - - return this._cache.signature; - } - - /** - * Returns JSON representation of the license object that is suitable for serialization. - * @returns {Object} - */ - toJSON() { - if (this._cache.json) { - return this._cache.json; - } - - this._cache.json = { - license: { - type: this.license.getType(), - isActive: this.license.isActive(), - expiryDateInMillis: this.license.getExpiryDateInMillis(), - }, - features: {}, - }; - - // Set response elements specific to each feature. To do this, - // call the license check results generator for each feature, passing them - // the xpack info object - for (const [feature, licenseChecker] of this._featureLicenseCheckResultsGenerators) { - // return value expected to be a dictionary object. - this._cache.json.features[feature] = licenseChecker(this); - } - - return this._cache.json; - } -} diff --git a/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info_license.test.js b/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info_license.test.js deleted file mode 100644 index ccb5742216ca7..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info_license.test.js +++ /dev/null @@ -1,207 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { licensingMock } from '../../../../../plugins/licensing/server/mocks'; -import { XPackInfoLicense } from './xpack_info_license'; - -function getXPackInfoLicense(getRawLicense) { - return new XPackInfoLicense(getRawLicense); -} - -describe('XPackInfoLicense', () => { - const xpackInfoLicenseUndefined = getXPackInfoLicense(() => {}); - let xpackInfoLicense; - let getRawLicense; - - beforeEach(() => { - getRawLicense = jest.fn(); - xpackInfoLicense = getXPackInfoLicense(getRawLicense); - }); - - test('getUid returns uid field', () => { - const uid = 'abc123'; - - getRawLicense.mockReturnValue(licensingMock.createLicense({ license: { uid } })); - - expect(xpackInfoLicense.getUid()).toBe(uid); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - expect(xpackInfoLicenseUndefined.getUid()).toBe(undefined); - }); - - test('isActive returns true if status is active', () => { - getRawLicense.mockReturnValue(licensingMock.createLicense({ license: { status: 'active' } })); - - expect(xpackInfoLicense.isActive()).toBe(true); - expect(getRawLicense).toHaveBeenCalledTimes(1); - }); - - test('isActive returns false if status is not active', () => { - getRawLicense.mockReturnValue(licensingMock.createLicense({ license: { status: 'aCtIvE' } })); // needs to match exactly - - expect(xpackInfoLicense.isActive()).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - expect(xpackInfoLicenseUndefined.isActive()).toBe(false); - }); - - test('getExpiryDateInMillis returns expiry_date_in_millis', () => { - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { expiryDateInMillis: 123 } }) - ); - - expect(xpackInfoLicense.getExpiryDateInMillis()).toBe(123); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - expect(xpackInfoLicenseUndefined.getExpiryDateInMillis()).toBe(undefined); - }); - - test('isOneOf returns true of the mode includes one of the types', () => { - getRawLicense.mockReturnValue(licensingMock.createLicense({ license: { mode: 'platinum' } })); - - expect(xpackInfoLicense.isOneOf('platinum')).toBe(true); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - expect(xpackInfoLicense.isOneOf(['platinum'])).toBe(true); - expect(getRawLicense).toHaveBeenCalledTimes(2); - expect(xpackInfoLicense.isOneOf(['gold', 'platinum'])).toBe(true); - expect(getRawLicense).toHaveBeenCalledTimes(3); - expect(xpackInfoLicense.isOneOf(['platinum', 'gold'])).toBe(true); - expect(getRawLicense).toHaveBeenCalledTimes(4); - expect(xpackInfoLicense.isOneOf(['basic', 'gold'])).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(5); - expect(xpackInfoLicense.isOneOf(['basic'])).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(6); - - expect(xpackInfoLicenseUndefined.isOneOf(['platinum', 'gold'])).toBe(false); - }); - - test('getType returns the type', () => { - getRawLicense.mockReturnValue(licensingMock.createLicense({ license: { type: 'basic' } })); - - expect(xpackInfoLicense.getType()).toBe('basic'); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - getRawLicense.mockReturnValue(licensingMock.createLicense({ license: { type: 'gold' } })); - - expect(xpackInfoLicense.getType()).toBe('gold'); - expect(getRawLicense).toHaveBeenCalledTimes(2); - - expect(xpackInfoLicenseUndefined.getType()).toBe(undefined); - }); - - test('getMode returns the mode', () => { - getRawLicense.mockReturnValue(licensingMock.createLicense({ license: { mode: 'basic' } })); - - expect(xpackInfoLicense.getMode()).toBe('basic'); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - getRawLicense.mockReturnValue(licensingMock.createLicense({ license: { mode: 'gold' } })); - - expect(xpackInfoLicense.getMode()).toBe('gold'); - expect(getRawLicense).toHaveBeenCalledTimes(2); - - expect(xpackInfoLicenseUndefined.getMode()).toBe(undefined); - }); - - test('isActiveLicense returns the true if active and typeChecker matches', () => { - const expectAbc123 = (type) => type === 'abc123'; - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'active', mode: 'abc123' } }) - ); - - expect(xpackInfoLicense.isActiveLicense(expectAbc123)).toBe(true); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'NOTactive', mode: 'abc123' } }) - ); - - expect(xpackInfoLicense.isActiveLicense(expectAbc123)).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(2); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'NOTactive', mode: 'NOTabc123' } }) - ); - - expect(xpackInfoLicense.isActiveLicense(expectAbc123)).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(3); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'active', mode: 'NOTabc123' } }) - ); - - expect(xpackInfoLicense.isActiveLicense(expectAbc123)).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(4); - - expect(xpackInfoLicenseUndefined.isActive(expectAbc123)).toBe(false); - }); - - test('isBasic returns the true if active and basic', () => { - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'active', mode: 'basic' } }) - ); - - expect(xpackInfoLicense.isBasic()).toBe(true); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'NOTactive', mode: 'gold' } }) - ); - - expect(xpackInfoLicense.isBasic()).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(2); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'NOTactive', mode: 'trial' } }) - ); - - expect(xpackInfoLicense.isBasic()).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(3); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'active', mode: 'platinum' } }) - ); - - expect(xpackInfoLicense.isBasic()).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(4); - - expect(xpackInfoLicenseUndefined.isBasic()).toBe(false); - }); - - test('isNotBasic returns the true if active and not basic', () => { - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'active', mode: 'platinum' } }) - ); - - expect(xpackInfoLicense.isNotBasic()).toBe(true); - expect(getRawLicense).toHaveBeenCalledTimes(1); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'NOTactive', mode: 'gold' } }) - ); - - expect(xpackInfoLicense.isNotBasic()).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(2); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'NOTactive', mode: 'trial' } }) - ); - - expect(xpackInfoLicense.isNotBasic()).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(3); - - getRawLicense.mockReturnValue( - licensingMock.createLicense({ license: { status: 'active', mode: 'basic' } }) - ); - - expect(xpackInfoLicense.isNotBasic()).toBe(false); - expect(getRawLicense).toHaveBeenCalledTimes(4); - - expect(xpackInfoLicenseUndefined.isNotBasic()).toBe(false); - }); -}); diff --git a/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info_license.ts b/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info_license.ts deleted file mode 100644 index dd53f63909475..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/lib/xpack_info_license.ts +++ /dev/null @@ -1,111 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { ILicense } from '../../../../../plugins/licensing/server'; - -/** - * "View" for XPack Info license information. - */ -export class XPackInfoLicense { - /** - * Function that retrieves license information from the XPack info object. - * @type {Function} - * @private - */ - _getRawLicense: () => ILicense | undefined; - - constructor(getRawLicense: () => ILicense | undefined) { - this._getRawLicense = getRawLicense; - } - - /** - * Returns unique identifier of the license. - * @returns {string|undefined} - */ - getUid() { - return this._getRawLicense()?.uid; - } - - /** - * Indicates whether license is still active. - * @returns {boolean} - */ - isActive() { - return Boolean(this._getRawLicense()?.isActive); - } - - /** - * Returns license expiration date in ms. - * - * Note: A basic license created after 6.3 will have no expiration, thus returning undefined. - * - * @returns {number|undefined} - */ - getExpiryDateInMillis() { - return this._getRawLicense()?.expiryDateInMillis; - } - - /** - * Checks if the license is represented in a specified license list. - * @param {String} candidateLicenses List of the licenses to check against. - * @returns {boolean} - */ - isOneOf(candidateLicenses: string | string[]) { - const candidates = Array.isArray(candidateLicenses) ? candidateLicenses : [candidateLicenses]; - const mode = this._getRawLicense()?.mode; - return Boolean(mode && candidates.includes(mode)); - } - - /** - * Returns type of the license (basic, gold etc.). - * @returns {string|undefined} - */ - getType() { - return this._getRawLicense()?.type; - } - - /** - * Returns mode of the license (basic, gold etc.). This is the "effective" type of the license. - * @returns {string|undefined} - */ - getMode() { - return this._getRawLicense()?.mode; - } - - /** - * Determine if the current license is active and the supplied {@code type}. - * - * @param {Function} typeChecker The license type checker. - * @returns {boolean} - */ - isActiveLicense(typeChecker: (mode: string) => boolean) { - const license = this._getRawLicense(); - - return Boolean(license?.isActive && typeChecker(license.mode as any)); - } - - /** - * Determine if the license is an active, basic license. - * - * Note: This also verifies that the license is active. Therefore it is not safe to assume that !isBasic() === isNotBasic(). - * - * @returns {boolean} - */ - isBasic() { - return this.isActiveLicense((mode) => mode === 'basic'); - } - - /** - * Determine if the license is an active, non-basic license (e.g., standard, gold, platinum, or trial). - * - * Note: This also verifies that the license is active. Therefore it is not safe to assume that !isBasic() === isNotBasic(). - * - * @returns {boolean} - */ - isNotBasic() { - return this.isActiveLicense((mode) => mode !== 'basic'); - } -} diff --git a/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/__tests__/xpack_info.js b/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/__tests__/xpack_info.js deleted file mode 100644 index 540d9f63ea6c8..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/__tests__/xpack_info.js +++ /dev/null @@ -1,85 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import sinon from 'sinon'; - -import { xpackInfoRoute } from '../xpack_info'; - -describe('XPackInfo routes', () => { - let serverStub; - beforeEach(() => { - serverStub = { - route: sinon.stub(), - plugins: { - xpack_main: { - info: sinon.stub({ isAvailable() {}, toJSON() {} }), - }, - }, - }; - - xpackInfoRoute(serverStub); - }); - - it('correctly initialize XPack Info route.', () => { - sinon.assert.calledWithExactly(serverStub.route, { - method: 'GET', - path: '/api/xpack/v1/info', - handler: sinon.match.func, - }); - }); - - it('replies with `Not Found` Boom error if `xpackInfo` is not available.', () => { - serverStub.plugins.xpack_main.info.isAvailable.returns(false); - - const onRouteHandler = serverStub.route.firstCall.args[0].handler; - const response = onRouteHandler(); - - expect(response.isBoom).to.be(true); - expect(response.message).to.be('Not Found'); - expect(response.output.statusCode).to.be(404); - }); - - it('replies with pre-processed `xpackInfo` if it is available.', () => { - serverStub.plugins.xpack_main.info.isAvailable.returns(true); - serverStub.plugins.xpack_main.info.toJSON.returns({ - license: { - type: 'gold', - isActive: true, - expiryDateInMillis: 1509368280381, - }, - features: { - security: { - showLogin: true, - allowLogin: true, - showLinks: false, - allowRoleDocumentLevelSecurity: false, - allowRoleFieldLevelSecurity: false, - }, - }, - }); - - const onRouteHandler = serverStub.route.firstCall.args[0].handler; - const response = onRouteHandler(); - - expect(response).to.eql({ - license: { - type: 'gold', - is_active: true, - expiry_date_in_millis: 1509368280381, - }, - features: { - security: { - show_login: true, - allow_login: true, - show_links: false, - allow_role_document_level_security: false, - allow_role_field_level_security: false, - }, - }, - }); - }); -}); diff --git a/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/xpack_info.js b/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/xpack_info.js deleted file mode 100644 index 3cc57ae9fcab4..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/xpack_info.js +++ /dev/null @@ -1,25 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; -import { convertKeysToSnakeCaseDeep } from '../../../../../../server/lib/key_case_converter'; - -/* - * A route to provide the basic XPack info for the production cluster - */ -export function xpackInfoRoute(server) { - server.route({ - method: 'GET', - path: '/api/xpack/v1/info', - handler() { - const xPackInfo = server.plugins.xpack_main.info; - - return xPackInfo.isAvailable() - ? convertKeysToSnakeCaseDeep(xPackInfo.toJSON()) - : Boom.notFound(); - }, - }); -} diff --git a/x-pack/legacy/plugins/xpack_main/server/xpack_main.d.ts b/x-pack/legacy/plugins/xpack_main/server/xpack_main.d.ts deleted file mode 100644 index c2ec5662ad12e..0000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/xpack_main.d.ts +++ /dev/null @@ -1,14 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import KbnServer from 'src/legacy/server/kbn_server'; -import { KibanaFeature } from '../../../../plugins/features/server'; -import { XPackInfo, XPackInfoOptions } from './lib/xpack_info'; -export { XPackFeature } from './lib/xpack_info'; - -export interface XPackMainPlugin { - info: XPackInfo; -} diff --git a/x-pack/legacy/server/lib/__tests__/key_case_converter.js b/x-pack/legacy/server/lib/__tests__/key_case_converter.js deleted file mode 100644 index 7ed9fa668ae66..0000000000000 --- a/x-pack/legacy/server/lib/__tests__/key_case_converter.js +++ /dev/null @@ -1,117 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { convertKeysToSnakeCaseDeep, convertKeysToCamelCaseDeep } from '../key_case_converter'; - -describe('key_case_converter', () => { - let testObject; - - beforeEach(() => { - testObject = { - topLevelKey1: { - innerLevelKey1: 17, - inner_level_key2: [19, 31], - }, - top_level_key2: { - innerLevelKey1: 'foo_fooFoo', - inner_level_key2: [{ foo_bar: 29 }, { barBar: 37 }], - }, - }; - }); - - describe('convertKeysToSnakeCaseDeep', () => { - it('should recursively convert camelCase keys to snake_case keys', () => { - const expectedResultObject = { - top_level_key_1: { - inner_level_key_1: 17, - inner_level_key_2: [19, 31], - }, - top_level_key_2: { - inner_level_key_1: 'foo_fooFoo', - inner_level_key_2: [{ foo_bar: 29 }, { bar_bar: 37 }], - }, - }; - expect(convertKeysToSnakeCaseDeep(testObject)).to.eql(expectedResultObject); - }); - - it('should not modify original object', () => { - convertKeysToSnakeCaseDeep(testObject); - expect(Object.keys(testObject)).to.contain('topLevelKey1'); - expect(Object.keys(testObject.topLevelKey1)).to.contain('innerLevelKey1'); - }); - - it('should preserve inner arrays', () => { - const result = convertKeysToSnakeCaseDeep(testObject); - expect(testObject.topLevelKey1.inner_level_key2).to.be.an(Array); - expect(result.top_level_key_1.inner_level_key_2).to.be.an(Array); - }); - - it('should preserve top-level arrays', () => { - testObject = [{ foo_bar: 17 }, [19, { barBaz: 'qux' }]]; - const expectedResultObject = [{ foo_bar: 17 }, [19, { bar_baz: 'qux' }]]; - const result = convertKeysToSnakeCaseDeep(testObject); - expect(testObject).to.be.an(Array); - expect(testObject[1]).to.be.an(Array); - expect(result).to.be.an(Array); - expect(result[1]).to.be.an(Array); - expect(result).to.eql(expectedResultObject); - }); - - it('should throw an error if something other an object or array is passed in', () => { - const expectedErrorMessageRegexp = /Specified object should be an Object or Array/; - expect(convertKeysToSnakeCaseDeep) - .withArgs('neither an object nor an array') - .to.throwException(expectedErrorMessageRegexp); - }); - }); - - describe('convertKeysToCamelCaseDeep', () => { - it('should recursively convert snake_case keys to camelCase keys', () => { - const expectedResultObject = { - topLevelKey1: { - innerLevelKey1: 17, - innerLevelKey2: [19, 31], - }, - topLevelKey2: { - innerLevelKey1: 'foo_fooFoo', - innerLevelKey2: [{ fooBar: 29 }, { barBar: 37 }], - }, - }; - expect(convertKeysToCamelCaseDeep(testObject)).to.eql(expectedResultObject); - }); - - it('should not modify original object', () => { - convertKeysToCamelCaseDeep(testObject); - expect(Object.keys(testObject)).to.contain('top_level_key2'); - expect(Object.keys(testObject.topLevelKey1)).to.contain('inner_level_key2'); - }); - - it('should preserve inner arrays', () => { - const result = convertKeysToCamelCaseDeep(testObject); - expect(testObject.topLevelKey1.inner_level_key2).to.be.an(Array); - expect(result.topLevelKey1.innerLevelKey2).to.be.an(Array); - }); - - it('should preserve top-level arrays', () => { - testObject = [{ foo_bar: 17 }, [19, { barBaz: 'qux' }]]; - const expectedResultObject = [{ fooBar: 17 }, [19, { barBaz: 'qux' }]]; - const result = convertKeysToCamelCaseDeep(testObject); - expect(testObject).to.be.an(Array); - expect(testObject[1]).to.be.an(Array); - expect(result).to.be.an(Array); - expect(result[1]).to.be.an(Array); - expect(result).to.eql(expectedResultObject); - }); - - it('should throw an error if something other an object or array is passed in', () => { - const expectedErrorMessageRegexp = /Specified object should be an Object or Array/; - expect(convertKeysToCamelCaseDeep) - .withArgs('neither an object nor an array') - .to.throwException(expectedErrorMessageRegexp); - }); - }); -}); diff --git a/x-pack/legacy/server/lib/__tests__/kibana_state.js b/x-pack/legacy/server/lib/__tests__/kibana_state.js deleted file mode 100644 index d1b4142b10446..0000000000000 --- a/x-pack/legacy/server/lib/__tests__/kibana_state.js +++ /dev/null @@ -1,129 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import rison from 'rison-node'; -import { parseKibanaState } from '../parse_kibana_state'; - -const stateIndices = { - global: '_g', - app: '_a', -}; -const globalTime = - '(refreshInterval:(display:Off,pause:!f,value:0),time:(from:now-15m,mode:quick,to:now))'; - -describe('Kibana state', function () { - describe('type checking', function () { - it('should throw if not given an object', function () { - const fn = () => parseKibanaState('i am not an object', 'global'); - const fn2 = () => parseKibanaState(['arrays are not valid either'], 'global'); - expect(fn).to.throwException(/must be an object/i); - expect(fn2).to.throwException(/must be an object/i); - }); - - it('should throw with invalid type', function () { - const fn = () => parseKibanaState({}, 'this is an invalid state type'); - expect(fn).to.throwException(/unknown state type/i); - }); - }); - - describe('value of exists', function () { - it('should be false if state does not exist', function () { - const state = parseKibanaState({}, 'global'); - expect(state.exists).to.equal(false); - }); - - it('should be true if state exists', function () { - const query = {}; - query[stateIndices.global] = rison.encode({ hello: 'world' }); - const state = parseKibanaState(query, 'global'); - expect(state.exists).to.equal(true); - }); - }); - - describe('instance methods', function () { - let query; - - beforeEach(function () { - query = {}; - query[stateIndices.global] = globalTime; - }); - - describe('get', function () { - it('should return the value', function () { - const state = parseKibanaState(query, 'global'); - const { refreshInterval } = rison.decode(globalTime); - expect(state.get('refreshInterval')).to.eql(refreshInterval); - }); - - it('should use the default value for missing props', function () { - const defaultValue = 'default value'; - const state = parseKibanaState(query, 'global'); - expect(state.get('no such value', defaultValue)).to.equal(defaultValue); - }); - }); - - describe('set', function () { - it('should update the value of the state', function () { - const state = parseKibanaState(query, 'global'); - expect(state.get('refreshInterval.pause')).to.equal(false); - - state.set(['refreshInterval', 'pause'], true); - expect(state.get('refreshInterval.pause')).to.equal(true); - }); - - it('should create new properties', function () { - const prop = 'newProp'; - const value = 12345; - const state = parseKibanaState(query, 'global'); - expect(state.get(prop)).to.be(undefined); - - state.set(prop, value); - expect(state.get(prop)).to.not.be(undefined); - expect(state.get(prop)).to.equal(value); - }); - }); - - describe('removing properties', function () { - it('should remove a single value', function () { - const state = parseKibanaState(query, 'global'); - expect(state.get('refreshInterval')).to.be.an('object'); - - state.removeProps('refreshInterval'); - expect(state.get('refreshInterval')).to.be(undefined); - }); - - it('should remove multiple values', function () { - const state = parseKibanaState(query, 'global'); - expect(state.get('refreshInterval')).to.be.an('object'); - expect(state.get('time')).to.be.an('object'); - - state.removeProps(['refreshInterval', 'time']); - expect(state.get('refreshInterval')).to.be(undefined); - expect(state.get('time')).to.be(undefined); - }); - }); - - describe('toString', function () { - it('should rison encode the state', function () { - const state = parseKibanaState(query, 'global'); - expect(state.toString()).to.equal(globalTime); - }); - }); - - describe('toQuery', function () { - it('should return an object', function () { - const state = parseKibanaState(query, 'global'); - expect(state.toQuery()).to.be.an('object'); - }); - - it('should contain the kibana state property', function () { - const state = parseKibanaState(query, 'global'); - expect(state.toQuery()).to.have.property(stateIndices.global, globalTime); - }); - }); - }); -}); diff --git a/x-pack/legacy/server/lib/check_license/check_license.js b/x-pack/legacy/server/lib/check_license/check_license.js deleted file mode 100644 index 7695755622310..0000000000000 --- a/x-pack/legacy/server/lib/check_license/check_license.js +++ /dev/null @@ -1,75 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; -import { - LICENSE_STATUS_UNAVAILABLE, - LICENSE_STATUS_INVALID, - LICENSE_STATUS_EXPIRED, - LICENSE_STATUS_VALID, - RANKED_LICENSE_TYPES, -} from '../../../common/constants'; - -export function checkLicense(pluginName, minimumLicenseRequired, xpackLicenseInfo) { - if (!minimumLicenseRequired) { - throw new Error( - `Error checking license for plugin "${pluginName}". The minimum license required has not been provided.` - ); - } - - if (!RANKED_LICENSE_TYPES.includes(minimumLicenseRequired)) { - throw new Error(`Invalid license type supplied to checkLicense: ${minimumLicenseRequired}`); - } - - // If, for some reason, we cannot get the license information - // from Elasticsearch, assume worst case and disable - if (!xpackLicenseInfo || !xpackLicenseInfo.isAvailable()) { - return { - status: LICENSE_STATUS_UNAVAILABLE, - message: i18n.translate('xpack.server.checkLicense.errorUnavailableMessage', { - defaultMessage: - 'You cannot use {pluginName} because license information is not available at this time.', - values: { pluginName }, - }), - }; - } - - const { license } = xpackLicenseInfo; - const isLicenseModeValid = license.isOneOf( - [...RANKED_LICENSE_TYPES].splice(RANKED_LICENSE_TYPES.indexOf(minimumLicenseRequired)) - ); - const isLicenseActive = license.isActive(); - const licenseType = license.getType(); - - // License is not valid - if (!isLicenseModeValid) { - return { - status: LICENSE_STATUS_INVALID, - message: i18n.translate('xpack.server.checkLicense.errorUnsupportedMessage', { - defaultMessage: - 'Your {licenseType} license does not support {pluginName}. Please upgrade your license.', - values: { licenseType, pluginName }, - }), - }; - } - - // License is valid but not active - if (!isLicenseActive) { - return { - status: LICENSE_STATUS_EXPIRED, - message: i18n.translate('xpack.server.checkLicense.errorExpiredMessage', { - defaultMessage: - 'You cannot use {pluginName} because your {licenseType} license has expired.', - values: { licenseType, pluginName }, - }), - }; - } - - // License is valid and active - return { - status: LICENSE_STATUS_VALID, - }; -} diff --git a/x-pack/legacy/server/lib/check_license/check_license.test.js b/x-pack/legacy/server/lib/check_license/check_license.test.js deleted file mode 100644 index 65b599ed4a5f6..0000000000000 --- a/x-pack/legacy/server/lib/check_license/check_license.test.js +++ /dev/null @@ -1,132 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { set } from '@elastic/safer-lodash-set'; -import { checkLicense } from './check_license'; -import { - LICENSE_STATUS_UNAVAILABLE, - LICENSE_STATUS_EXPIRED, - LICENSE_STATUS_VALID, - LICENSE_TYPE_BASIC, -} from '../../../common/constants'; - -describe('check_license', function () { - const pluginName = 'Foo'; - const minimumLicenseRequired = LICENSE_TYPE_BASIC; - let mockLicenseInfo; - beforeEach(() => (mockLicenseInfo = {})); - - describe('license information is undefined', () => { - beforeEach(() => (mockLicenseInfo = undefined)); - - it('should set status to unavailable', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).status).toBe( - LICENSE_STATUS_UNAVAILABLE - ); - }); - - it('should set a message', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).message).not.toBe( - undefined - ); - }); - }); - - describe('license information is not available', () => { - beforeEach(() => (mockLicenseInfo.isAvailable = () => false)); - - it('should set status to unavailable', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).status).toBe( - LICENSE_STATUS_UNAVAILABLE - ); - }); - - it('should set a message', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).message).not.toBe( - undefined - ); - }); - }); - - describe('license information is available', () => { - beforeEach(() => { - mockLicenseInfo.isAvailable = () => true; - set(mockLicenseInfo, 'license.getType', () => LICENSE_TYPE_BASIC); - }); - - describe('& license is trial, standard, gold, platinum', () => { - beforeEach(() => set(mockLicenseInfo, 'license.isOneOf', () => true)); - - describe('& license is active', () => { - beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => true)); - - it('should set status to valid', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).status).toBe( - LICENSE_STATUS_VALID - ); - }); - - it('should not set a message', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).message).toBe( - undefined - ); - }); - }); - - describe('& license is expired', () => { - beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => false)); - - it('should set status to inactive', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).status).toBe( - LICENSE_STATUS_EXPIRED - ); - }); - - it('should set a message', () => { - expect( - checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).message - ).not.toBe(undefined); - }); - }); - }); - - describe('& license is basic', () => { - beforeEach(() => set(mockLicenseInfo, 'license.isOneOf', () => true)); - - describe('& license is active', () => { - beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => true)); - - it('should set status to valid', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).status).toBe( - LICENSE_STATUS_VALID - ); - }); - - it('should not set a message', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).message).toBe( - undefined - ); - }); - }); - - describe('& license is expired', () => { - beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => false)); - - it('should set status to inactive', () => { - expect(checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).status).toBe( - LICENSE_STATUS_EXPIRED - ); - }); - - it('should set a message', () => { - expect( - checkLicense(pluginName, minimumLicenseRequired, mockLicenseInfo).message - ).not.toBe(undefined); - }); - }); - }); - }); -}); diff --git a/x-pack/legacy/server/lib/check_license/index.js b/x-pack/legacy/server/lib/check_license/index.js deleted file mode 100644 index f2c070fd44b6e..0000000000000 --- a/x-pack/legacy/server/lib/check_license/index.js +++ /dev/null @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { checkLicense } from './check_license'; diff --git a/x-pack/legacy/server/lib/constants/index.ts b/x-pack/legacy/server/lib/constants/index.ts deleted file mode 100644 index 2378aca824042..0000000000000 --- a/x-pack/legacy/server/lib/constants/index.ts +++ /dev/null @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { XPACK_INFO_API_DEFAULT_POLL_FREQUENCY_IN_MILLIS } from './xpack_info'; diff --git a/x-pack/legacy/server/lib/constants/xpack_info.ts b/x-pack/legacy/server/lib/constants/xpack_info.ts deleted file mode 100644 index c58bb275245b6..0000000000000 --- a/x-pack/legacy/server/lib/constants/xpack_info.ts +++ /dev/null @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export const XPACK_INFO_API_DEFAULT_POLL_FREQUENCY_IN_MILLIS = 30001; // 30 seconds diff --git a/x-pack/legacy/server/lib/create_router/call_with_request_factory/call_with_request_factory.js b/x-pack/legacy/server/lib/create_router/call_with_request_factory/call_with_request_factory.js deleted file mode 100644 index df1ce95b31655..0000000000000 --- a/x-pack/legacy/server/lib/create_router/call_with_request_factory/call_with_request_factory.js +++ /dev/null @@ -1,12 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export const callWithRequestFactory = (server, pluginId, config) => { - const { callWithRequest } = config - ? server.plugins.elasticsearch.createCluster(pluginId, config) - : server.plugins.elasticsearch.getCluster('data'); - return callWithRequest; -}; diff --git a/x-pack/legacy/server/lib/create_router/call_with_request_factory/index.d.ts b/x-pack/legacy/server/lib/create_router/call_with_request_factory/index.d.ts deleted file mode 100644 index 3537d1bf42079..0000000000000 --- a/x-pack/legacy/server/lib/create_router/call_with_request_factory/index.d.ts +++ /dev/null @@ -1,18 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Legacy } from 'kibana'; -import { LegacyAPICaller } from '../../../../../../src/core/server'; - -export type CallWithRequest = (...args: any[]) => LegacyAPICaller; - -export declare function callWithRequestFactory( - server: Legacy.Server, - pluginId: string, - config?: { - plugins: any[]; - } -): CallWithRequest; diff --git a/x-pack/legacy/server/lib/create_router/call_with_request_factory/index.js b/x-pack/legacy/server/lib/create_router/call_with_request_factory/index.js deleted file mode 100644 index 787814d87dff9..0000000000000 --- a/x-pack/legacy/server/lib/create_router/call_with_request_factory/index.js +++ /dev/null @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { callWithRequestFactory } from './call_with_request_factory'; diff --git a/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_custom_error.js b/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_custom_error.js deleted file mode 100644 index f9c102be7a1ff..0000000000000 --- a/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_custom_error.js +++ /dev/null @@ -1,21 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { wrapCustomError } from '../wrap_custom_error'; - -describe('wrap_custom_error', () => { - describe('#wrapCustomError', () => { - it('should return a Boom object', () => { - const originalError = new Error('I am an error'); - const statusCode = 404; - const wrappedError = wrapCustomError(originalError, statusCode); - - expect(wrappedError.isBoom).to.be(true); - expect(wrappedError.output.statusCode).to.equal(statusCode); - }); - }); -}); diff --git a/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_es_error.js b/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_es_error.js deleted file mode 100644 index 8241dc4329137..0000000000000 --- a/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_es_error.js +++ /dev/null @@ -1,39 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { wrapEsError } from '../wrap_es_error'; - -describe('wrap_es_error', () => { - describe('#wrapEsError', () => { - let originalError; - beforeEach(() => { - originalError = new Error('I am an error'); - originalError.statusCode = 404; - originalError.response = '{}'; - }); - - it('should return a Boom object', () => { - const wrappedError = wrapEsError(originalError); - - expect(wrappedError.isBoom).to.be(true); - }); - - it('should return the correct Boom object', () => { - const wrappedError = wrapEsError(originalError); - - expect(wrappedError.output.statusCode).to.be(originalError.statusCode); - expect(wrappedError.output.payload.message).to.be(originalError.message); - }); - - it('should return the correct Boom object with custom message', () => { - const wrappedError = wrapEsError(originalError, { 404: 'No encontrado!' }); - - expect(wrappedError.output.statusCode).to.be(originalError.statusCode); - expect(wrappedError.output.payload.message).to.be('No encontrado!'); - }); - }); -}); diff --git a/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_unknown_error.js b/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_unknown_error.js deleted file mode 100644 index 85e0b2b3033ad..0000000000000 --- a/x-pack/legacy/server/lib/create_router/error_wrappers/__tests__/wrap_unknown_error.js +++ /dev/null @@ -1,19 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { wrapUnknownError } from '../wrap_unknown_error'; - -describe('wrap_unknown_error', () => { - describe('#wrapUnknownError', () => { - it('should return a Boom object', () => { - const originalError = new Error('I am an error'); - const wrappedError = wrapUnknownError(originalError); - - expect(wrappedError.isBoom).to.be(true); - }); - }); -}); diff --git a/x-pack/legacy/server/lib/create_router/error_wrappers/index.d.ts b/x-pack/legacy/server/lib/create_router/error_wrappers/index.d.ts deleted file mode 100644 index 1aaefb4e3727c..0000000000000 --- a/x-pack/legacy/server/lib/create_router/error_wrappers/index.d.ts +++ /dev/null @@ -1,12 +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; - * you may not use this file except in compliance with the Elastic License. - */ -import Boom from 'boom'; - -export declare function wrapCustomError(error: Error, statusCode: number): Boom; - -export declare function wrapEsError(error: Error, statusCodeToMessageMap?: object): Boom; - -export declare function wrapUnknownError(error: Error): Boom; diff --git a/x-pack/legacy/server/lib/create_router/error_wrappers/index.js b/x-pack/legacy/server/lib/create_router/error_wrappers/index.js deleted file mode 100644 index f275f15637091..0000000000000 --- a/x-pack/legacy/server/lib/create_router/error_wrappers/index.js +++ /dev/null @@ -1,9 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { wrapCustomError } from './wrap_custom_error'; -export { wrapEsError } from './wrap_es_error'; -export { wrapUnknownError } from './wrap_unknown_error'; diff --git a/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_custom_error.js b/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_custom_error.js deleted file mode 100644 index 3295113d38ee5..0000000000000 --- a/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_custom_error.js +++ /dev/null @@ -1,18 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -/** - * Wraps a custom error into a Boom error response and returns it - * - * @param err Object error - * @param statusCode Error status code - * @return Object Boom error response - */ -export function wrapCustomError(err, statusCode) { - return Boom.boomify(err, { statusCode }); -} diff --git a/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_es_error.js b/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_es_error.js deleted file mode 100644 index 72be6321af8a2..0000000000000 --- a/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_es_error.js +++ /dev/null @@ -1,59 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -function extractCausedByChain(causedBy = {}, accumulator = []) { - const { reason, caused_by } = causedBy; // eslint-disable-line camelcase - - if (reason) { - accumulator.push(reason); - } - - // eslint-disable-next-line camelcase - if (caused_by) { - return extractCausedByChain(caused_by, accumulator); - } - - return accumulator; -} - -/** - * Wraps an error thrown by the ES JS client into a Boom error response and returns it - * - * @param err Object Error thrown by ES JS client - * @param statusCodeToMessageMap Object Optional map of HTTP status codes => error messages - * @return Object Boom error response - */ -export function wrapEsError(err, statusCodeToMessageMap = {}) { - const { statusCode, response } = err; - - const { - error: { - root_cause = [], // eslint-disable-line camelcase - caused_by, // eslint-disable-line camelcase - } = {}, - } = JSON.parse(response); - - // If no custom message if specified for the error's status code, just - // wrap the error as a Boom error response, include the additional information from ES, and return it - if (!statusCodeToMessageMap[statusCode]) { - const boomError = Boom.boomify(err, { statusCode }); - - // The caused_by chain has the most information so use that if it's available. If not then - // settle for the root_cause. - const causedByChain = extractCausedByChain(caused_by); - const defaultCause = root_cause.length ? extractCausedByChain(root_cause[0]) : undefined; - - boomError.output.payload.cause = causedByChain.length ? causedByChain : defaultCause; - return boomError; - } - - // Otherwise, use the custom message to create a Boom error response and - // return it - const message = statusCodeToMessageMap[statusCode]; - return new Boom(message, { statusCode }); -} diff --git a/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_unknown_error.js b/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_unknown_error.js deleted file mode 100644 index ffd915c513362..0000000000000 --- a/x-pack/legacy/server/lib/create_router/error_wrappers/wrap_unknown_error.js +++ /dev/null @@ -1,17 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -/** - * Wraps an unknown error into a Boom error response and returns it - * - * @param err Object Unknown error - * @return Object Boom error response - */ -export function wrapUnknownError(err) { - return Boom.boomify(err); -} diff --git a/x-pack/legacy/server/lib/create_router/index.d.ts b/x-pack/legacy/server/lib/create_router/index.d.ts deleted file mode 100644 index 76e5f4b599708..0000000000000 --- a/x-pack/legacy/server/lib/create_router/index.d.ts +++ /dev/null @@ -1,38 +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; - * you may not use this file except in compliance with the Elastic License. - */ -import { Request, ResponseToolkit } from 'hapi'; -import { Legacy } from 'kibana'; -import { CallWithRequest } from './call_with_request_factory'; - -export * from './error_wrappers'; - -export type RouterRouteHandler = ( - req: Request, - callWithRequest: ReturnType, - responseToolkit: ResponseToolkit -) => Promise; - -export type RouterRoute = (path: string, handler: RouterRouteHandler) => Router; - -export interface Router { - get: RouterRoute; - post: RouterRoute; - put: RouterRoute; - delete: RouterRoute; - patch: RouterRoute; - isEsError: any; -} - -export declare function createRouter( - server: Legacy.Server, - pluginId: string, - apiBasePath: string, - config?: { - plugins: any[]; - } -): Router; - -export declare function isEsErrorFactory(server: Legacy.Server): any; diff --git a/x-pack/legacy/server/lib/create_router/index.js b/x-pack/legacy/server/lib/create_router/index.js deleted file mode 100644 index e4d66bdb5a48b..0000000000000 --- a/x-pack/legacy/server/lib/create_router/index.js +++ /dev/null @@ -1,61 +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; - * you may not use this file except in compliance with the Elastic License. - */ -import Boom from 'boom'; -import { callWithRequestFactory } from './call_with_request_factory'; -import { isEsErrorFactory as createIsEsError } from './is_es_error_factory'; -import { wrapEsError, wrapUnknownError } from './error_wrappers'; -import { licensePreRoutingFactory } from './license_pre_routing_factory'; - -export { wrapEsError, wrapUnknownError, wrapCustomError } from './error_wrappers'; - -// Sometimes consumers will need to check if errors are ES errors, too. -export const isEsErrorFactory = (server) => { - return createIsEsError(server); -}; - -export const createRouter = (server, pluginId, apiBasePath = '', config) => { - const isEsError = isEsErrorFactory(server); - - // NOTE: The license-checking logic depends on the xpack_main plugin, so if your plugin - // consumes this helper, make sure it declares 'xpack_main' as a dependency. - const licensePreRouting = licensePreRoutingFactory(server, pluginId); - - const callWithRequestInstance = callWithRequestFactory(server, pluginId, config); - - const requestHandler = (handler) => async (request, h) => { - try { - const callWithRequest = (...args) => { - return callWithRequestInstance(request, ...args); - }; - return await handler(request, callWithRequest, h); - } catch (err) { - if (err instanceof Boom) { - throw err; - } - - if (isEsError(err)) { - throw wrapEsError(err); - } - - throw wrapUnknownError(err); - } - }; - - // Decorate base router with HTTP methods. - return ['get', 'post', 'put', 'delete', 'patch'].reduce((router, methodName) => { - router[methodName] = (subPath, handler) => { - const method = methodName.toUpperCase(); - const path = apiBasePath + subPath; - server.route({ - path, - method, - handler: requestHandler(handler), - config: { pre: [licensePreRouting] }, - }); - }; - return router; - }, {}); -}; diff --git a/x-pack/legacy/server/lib/create_router/is_es_error_factory/__tests__/is_es_error_factory.js b/x-pack/legacy/server/lib/create_router/is_es_error_factory/__tests__/is_es_error_factory.js deleted file mode 100644 index ef6fbaf9c53d0..0000000000000 --- a/x-pack/legacy/server/lib/create_router/is_es_error_factory/__tests__/is_es_error_factory.js +++ /dev/null @@ -1,44 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { isEsErrorFactory } from '../is_es_error_factory'; -import { set } from '@elastic/safer-lodash-set'; - -class MockAbstractEsError {} - -describe('is_es_error_factory', () => { - let mockServer; - let isEsError; - - beforeEach(() => { - const mockEsErrors = { - _Abstract: MockAbstractEsError, - }; - mockServer = {}; - set(mockServer, 'plugins.elasticsearch.getCluster', () => ({ errors: mockEsErrors })); - - isEsError = isEsErrorFactory(mockServer); - }); - - describe('#isEsErrorFactory', () => { - it('should return a function', () => { - expect(isEsError).to.be.a(Function); - }); - - describe('returned function', () => { - it('should return true if passed-in err is a known esError', () => { - const knownEsError = new MockAbstractEsError(); - expect(isEsError(knownEsError)).to.be(true); - }); - - it('should return false if passed-in err is not a known esError', () => { - const unknownEsError = {}; - expect(isEsError(unknownEsError)).to.be(false); - }); - }); - }); -}); diff --git a/x-pack/legacy/server/lib/create_router/is_es_error_factory/index.js b/x-pack/legacy/server/lib/create_router/is_es_error_factory/index.js deleted file mode 100644 index 441648a8701e0..0000000000000 --- a/x-pack/legacy/server/lib/create_router/is_es_error_factory/index.js +++ /dev/null @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { isEsErrorFactory } from './is_es_error_factory'; diff --git a/x-pack/legacy/server/lib/create_router/is_es_error_factory/is_es_error_factory.js b/x-pack/legacy/server/lib/create_router/is_es_error_factory/is_es_error_factory.js deleted file mode 100644 index 80daac5bd496d..0000000000000 --- a/x-pack/legacy/server/lib/create_router/is_es_error_factory/is_es_error_factory.js +++ /dev/null @@ -1,18 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { memoize } from 'lodash'; - -const esErrorsFactory = memoize((server) => { - return server.plugins.elasticsearch.getCluster('admin').errors; -}); - -export function isEsErrorFactory(server) { - const esErrors = esErrorsFactory(server); - return function isEsError(err) { - return err instanceof esErrors._Abstract; - }; -} diff --git a/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/__tests__/license_pre_routing_factory.js b/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/__tests__/license_pre_routing_factory.js deleted file mode 100644 index dde18a0ccd7dd..0000000000000 --- a/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/__tests__/license_pre_routing_factory.js +++ /dev/null @@ -1,70 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { licensePreRoutingFactory } from '../license_pre_routing_factory'; -import { LICENSE_STATUS_INVALID, LICENSE_STATUS_VALID } from '../../../../../common/constants'; - -describe('license_pre_routing_factory', () => { - describe('#reportingFeaturePreRoutingFactory', () => { - let mockServer; - let mockLicenseCheckResults; - - beforeEach(() => { - mockServer = { - plugins: { - xpack_main: { - info: { - feature: () => ({ - getLicenseCheckResults: () => mockLicenseCheckResults, - }), - }, - }, - }, - }; - }); - - it('instantiates a new instance per plugin', () => { - const firstInstance = licensePreRoutingFactory(mockServer, 'foo'); - const secondInstance = licensePreRoutingFactory(mockServer, 'bar'); - - expect(firstInstance).to.not.be(secondInstance); - }); - - describe('status is invalid', () => { - beforeEach(() => { - mockLicenseCheckResults = { - status: LICENSE_STATUS_INVALID, - }; - }); - - it('replies with 403', () => { - const licensePreRouting = licensePreRoutingFactory(mockServer); - const stubRequest = {}; - expect(() => licensePreRouting(stubRequest)).to.throwException((response) => { - expect(response).to.be.an(Error); - expect(response.isBoom).to.be(true); - expect(response.output.statusCode).to.be(403); - }); - }); - }); - - describe('status is valid', () => { - beforeEach(() => { - mockLicenseCheckResults = { - status: LICENSE_STATUS_VALID, - }; - }); - - it('replies with nothing', () => { - const licensePreRouting = licensePreRoutingFactory(mockServer); - const stubRequest = {}; - const response = licensePreRouting(stubRequest); - expect(response).to.be(null); - }); - }); - }); -}); diff --git a/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/index.js b/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/index.js deleted file mode 100644 index 0743e443955f4..0000000000000 --- a/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/index.js +++ /dev/null @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { licensePreRoutingFactory } from './license_pre_routing_factory'; diff --git a/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/license_pre_routing_factory.js b/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/license_pre_routing_factory.js deleted file mode 100644 index 81640ebb35ea9..0000000000000 --- a/x-pack/legacy/server/lib/create_router/license_pre_routing_factory/license_pre_routing_factory.js +++ /dev/null @@ -1,26 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { wrapCustomError } from '../error_wrappers'; -import { LICENSE_STATUS_VALID } from '../../../../common/constants'; - -export const licensePreRoutingFactory = (server, pluginId) => { - return () => { - const xpackMainPlugin = server.plugins.xpack_main; - const licenseCheckResults = xpackMainPlugin.info.feature(pluginId).getLicenseCheckResults(); - - // Apps which don't have any license restrictions will return undefined license check results. - if (licenseCheckResults) { - if (licenseCheckResults.status !== LICENSE_STATUS_VALID) { - const error = new Error(licenseCheckResults.message); - const statusCode = 403; - throw wrapCustomError(error, statusCode); - } - } - - return null; - }; -}; diff --git a/x-pack/legacy/server/lib/key_case_converter.js b/x-pack/legacy/server/lib/key_case_converter.js deleted file mode 100644 index a2a5452b3a1d9..0000000000000 --- a/x-pack/legacy/server/lib/key_case_converter.js +++ /dev/null @@ -1,52 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import _ from 'lodash'; - -// Note: This function uses _.clone. This will clone objects created by constructors other than Object -// to plain Object objects. Uncloneable values such as functions, DOM nodes, Maps, Sets, and WeakMaps -// will be cloned to the empty object. -function convertKeysToSpecifiedCaseDeep(object, caseConversionFunction) { - // Base case - if (!(_.isPlainObject(object) || _.isArray(object))) { - return object; - } - - // Clone (so we don't modify the original object that was passed in) - let newObject; - if (Array.isArray(object)) { - newObject = object.slice(0); - } else { - newObject = _.clone(object); - - // Convert top-level keys - newObject = _.mapKeys(newObject, (value, key) => caseConversionFunction(key)); - } - - // Recursively convert nested object keys - _.forEach( - newObject, - (value, key) => (newObject[key] = convertKeysToSpecifiedCaseDeep(value, caseConversionFunction)) - ); - - return newObject; -} - -function validateObject(object) { - if (!(_.isPlainObject(object) || _.isArray(object))) { - throw new Error('Specified object should be an Object or Array'); - } -} - -export function convertKeysToSnakeCaseDeep(object) { - validateObject(object); - return convertKeysToSpecifiedCaseDeep(object, _.snakeCase); -} - -export function convertKeysToCamelCaseDeep(object) { - validateObject(object); - return convertKeysToSpecifiedCaseDeep(object, _.camelCase); -} diff --git a/x-pack/legacy/server/lib/parse_kibana_state.js b/x-pack/legacy/server/lib/parse_kibana_state.js deleted file mode 100644 index a6c9bfbb511c1..0000000000000 --- a/x-pack/legacy/server/lib/parse_kibana_state.js +++ /dev/null @@ -1,55 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { set } from '@elastic/safer-lodash-set'; -import { isPlainObject, omit, get } from 'lodash'; -import rison from 'rison-node'; - -const stateTypeKeys = { - global: '_g', - app: '_a', -}; - -class KibanaState { - constructor(query, type = 'global') { - const propId = stateTypeKeys[type]; - if (!isPlainObject(query)) throw new TypeError('Query parameter must be an object'); - if (!propId) throw new TypeError(`Unknown state type: '${type}'`); - - const queryValue = query[propId]; - - this.exists = Boolean(queryValue); - this.state = queryValue ? rison.decode(queryValue) : {}; - this.type = type; - } - - removeProps(props) { - this.state = omit(this.state, props); - } - - get(prop, defVal) { - return get(this.state, prop, defVal); - } - - set(prop, val) { - return set(this.state, prop, val); - } - - toString() { - return rison.encode(this.state); - } - - toQuery() { - const index = stateTypeKeys[this.type]; - const output = {}; - output[index] = this.toString(); - return output; - } -} - -export function parseKibanaState(query, type) { - return new KibanaState(query, type); -} diff --git a/x-pack/legacy/server/lib/register_license_checker/index.d.ts b/x-pack/legacy/server/lib/register_license_checker/index.d.ts deleted file mode 100644 index 555008921df42..0000000000000 --- a/x-pack/legacy/server/lib/register_license_checker/index.d.ts +++ /dev/null @@ -1,15 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Legacy } from 'kibana'; -import { LicenseType } from '../../../common/constants'; - -export declare function registerLicenseChecker( - server: Legacy.Server, - pluginId: string, - pluginName: string, - minimumLicenseRequired: LicenseType -): void; diff --git a/x-pack/legacy/server/lib/register_license_checker/index.js b/x-pack/legacy/server/lib/register_license_checker/index.js deleted file mode 100644 index 7b0f97c38d129..0000000000000 --- a/x-pack/legacy/server/lib/register_license_checker/index.js +++ /dev/null @@ -1,7 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { registerLicenseChecker } from './register_license_checker'; diff --git a/x-pack/legacy/server/lib/register_license_checker/register_license_checker.js b/x-pack/legacy/server/lib/register_license_checker/register_license_checker.js deleted file mode 100644 index 57cbe30c25cb2..0000000000000 --- a/x-pack/legacy/server/lib/register_license_checker/register_license_checker.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { pairwise } from 'rxjs/operators'; - -import { ServiceStatusLevels } from '../../../../../src/core/server'; -import { checkLicense } from '../check_license'; - -export function registerLicenseChecker(server, pluginId, pluginName, minimumLicenseRequired) { - const xpackMainPlugin = server.plugins.xpack_main; - const subscription = server.newPlatform.setup.core.status.core$ - .pipe(pairwise()) - .subscribe(([coreLast, coreCurrent]) => { - if ( - !subscription.closed && - coreLast.elasticsearch.level !== ServiceStatusLevels.available && - coreCurrent.elasticsearch.level === ServiceStatusLevels.available - ) { - // Unsubscribe as soon as ES becomes available so this function only runs once - subscription.unsubscribe(); - - // Register a function that is called whenever the xpack info changes, - // to re-compute the license check results for this plugin - xpackMainPlugin.info - .feature(pluginId) - .registerLicenseCheckResultsGenerator((xpackLicenseInfo) => { - return checkLicense(pluginName, minimumLicenseRequired, xpackLicenseInfo); - }); - } - }); -} diff --git a/x-pack/legacy/server/lib/watch_status_and_license_to_initialize.js b/x-pack/legacy/server/lib/watch_status_and_license_to_initialize.js deleted file mode 100644 index 109dbbb20e35d..0000000000000 --- a/x-pack/legacy/server/lib/watch_status_and_license_to_initialize.js +++ /dev/null @@ -1,83 +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; - * you may not use this file except in compliance with the Elastic License. - */ -import * as Rx from 'rxjs'; -import { catchError, mergeMap, map, switchMap, tap } from 'rxjs/operators'; - -export const RETRY_SCALE_DURATION = 100; -export const RETRY_DURATION_MAX = 10000; - -const calculateDuration = (i) => { - const duration = i * RETRY_SCALE_DURATION; - if (duration > RETRY_DURATION_MAX) { - return RETRY_DURATION_MAX; - } - - return duration; -}; - -// we can't use a retryWhen here, because we want to propagate the red status and then retry -const propagateRedStatusAndScaleRetry = () => { - let i = 0; - return (err, caught) => - Rx.concat( - Rx.of({ - state: 'red', - message: err.message, - }), - Rx.timer(calculateDuration(++i)).pipe(mergeMap(() => caught)) - ); -}; - -export function watchStatusAndLicenseToInitialize(xpackMainPlugin, downstreamPlugin, initialize) { - const xpackInfo = xpackMainPlugin.info; - const xpackInfoFeature = xpackInfo.feature(downstreamPlugin.id); - - const upstreamStatus = xpackMainPlugin.status; - const currentStatus$ = Rx.of({ - state: upstreamStatus.state, - message: upstreamStatus.message, - }); - const newStatus$ = Rx.fromEvent( - upstreamStatus, - 'change', - null, - (previousState, previousMsg, state, message) => { - return { - state, - message, - }; - } - ); - const status$ = Rx.merge(currentStatus$, newStatus$); - - const currentLicense$ = Rx.of(xpackInfoFeature.getLicenseCheckResults()); - const newLicense$ = Rx.fromEventPattern(xpackInfo.onLicenseInfoChange.bind(xpackInfo)).pipe( - map(() => xpackInfoFeature.getLicenseCheckResults()) - ); - const license$ = Rx.merge(currentLicense$, newLicense$); - - Rx.combineLatest(status$, license$) - .pipe( - map(([status, license]) => ({ status, license })), - switchMap(({ status, license }) => { - if (status.state !== 'green') { - return Rx.of({ state: status.state, message: status.message }); - } - - return Rx.defer(() => initialize(license)).pipe( - map(() => ({ - state: 'green', - message: 'Ready', - })), - catchError(propagateRedStatusAndScaleRetry()) - ); - }), - tap(({ state, message }) => { - downstreamPlugin.status[state](message); - }) - ) - .subscribe(); -} diff --git a/x-pack/legacy/server/lib/watch_status_and_license_to_initialize.test.js b/x-pack/legacy/server/lib/watch_status_and_license_to_initialize.test.js deleted file mode 100644 index 33282b7591db7..0000000000000 --- a/x-pack/legacy/server/lib/watch_status_and_license_to_initialize.test.js +++ /dev/null @@ -1,301 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { EventEmitter } from 'events'; -import { - watchStatusAndLicenseToInitialize, - RETRY_SCALE_DURATION, - RETRY_DURATION_MAX, -} from './watch_status_and_license_to_initialize'; - -const createMockXpackMainPluginAndFeature = (featureId) => { - const licenseChangeCallbacks = []; - - const mockFeature = { - getLicenseCheckResults: jest.fn(), - mock: { - triggerLicenseChange: () => { - for (const callback of licenseChangeCallbacks) { - callback(); - } - }, - setLicenseCheckResults: (value) => { - mockFeature.getLicenseCheckResults.mockReturnValue(value); - }, - }, - }; - - const mockXpackMainPlugin = { - info: { - onLicenseInfoChange: (callback) => { - licenseChangeCallbacks.push(callback); - }, - feature: (id) => { - if (id === featureId) { - return mockFeature; - } - throw new Error('Unexpected feature'); - }, - }, - status: new EventEmitter(), - mock: { - setStatus: (state, message) => { - mockXpackMainPlugin.status.state = state; - mockXpackMainPlugin.status.message = message; - mockXpackMainPlugin.status.emit('change', null, null, state, message); - }, - }, - }; - - return { mockXpackMainPlugin, mockFeature }; -}; - -const createMockDownstreamPlugin = (id) => { - const defaultImplementation = () => { - throw new Error('Not implemented'); - }; - return { - id, - status: { - disabled: jest.fn().mockImplementation(defaultImplementation), - yellow: jest.fn().mockImplementation(defaultImplementation), - green: jest.fn().mockImplementation(defaultImplementation), - red: jest.fn().mockImplementation(defaultImplementation), - }, - }; -}; - -const advanceRetry = async (initializeCount) => { - await Promise.resolve(); - let duration = initializeCount * RETRY_SCALE_DURATION; - if (duration > RETRY_DURATION_MAX) { - duration = RETRY_DURATION_MAX; - } - jest.advanceTimersByTime(duration); -}; - -['red', 'yellow', 'disabled'].forEach((state) => { - test(`mirrors ${state} immediately`, () => { - const pluginId = 'foo-plugin'; - const message = `${state} is now the state`; - const { mockXpackMainPlugin } = createMockXpackMainPluginAndFeature(pluginId); - mockXpackMainPlugin.mock.setStatus(state, message); - const downstreamPlugin = createMockDownstreamPlugin(pluginId); - const initializeMock = jest.fn(); - downstreamPlugin.status[state].mockImplementation(() => {}); - - watchStatusAndLicenseToInitialize(mockXpackMainPlugin, downstreamPlugin, initializeMock); - - expect(initializeMock).not.toHaveBeenCalled(); - expect(downstreamPlugin.status[state]).toHaveBeenCalledTimes(1); - expect(downstreamPlugin.status[state]).toHaveBeenCalledWith(message); - }); -}); - -test(`calls initialize and doesn't immediately set downstream status when the initial status is green`, () => { - const pluginId = 'foo-plugin'; - const { mockXpackMainPlugin, mockFeature } = createMockXpackMainPluginAndFeature(pluginId); - mockXpackMainPlugin.mock.setStatus('green', 'green is now the state'); - const licenseCheckResults = Symbol(); - mockFeature.mock.setLicenseCheckResults(licenseCheckResults); - const downstreamPlugin = createMockDownstreamPlugin(pluginId); - const initializeMock = jest.fn().mockImplementation(() => new Promise(() => {})); - - watchStatusAndLicenseToInitialize(mockXpackMainPlugin, downstreamPlugin, initializeMock); - - expect(initializeMock).toHaveBeenCalledTimes(1); - expect(initializeMock).toHaveBeenCalledWith(licenseCheckResults); - expect(downstreamPlugin.status.green).toHaveBeenCalledTimes(0); -}); - -test(`sets downstream plugin's status to green when initialize resolves`, (done) => { - const pluginId = 'foo-plugin'; - const { mockXpackMainPlugin, mockFeature } = createMockXpackMainPluginAndFeature(pluginId); - mockXpackMainPlugin.mock.setStatus('green', 'green is now the state'); - const licenseCheckResults = Symbol(); - mockFeature.mock.setLicenseCheckResults(licenseCheckResults); - const downstreamPlugin = createMockDownstreamPlugin(pluginId); - const initializeMock = jest.fn().mockImplementation(() => Promise.resolve()); - - watchStatusAndLicenseToInitialize(mockXpackMainPlugin, downstreamPlugin, initializeMock); - - expect(initializeMock).toHaveBeenCalledTimes(1); - expect(initializeMock).toHaveBeenCalledWith(licenseCheckResults); - downstreamPlugin.status.green.mockImplementation((actualMessage) => { - expect(actualMessage).toBe('Ready'); - done(); - }); -}); - -test(`sets downstream plugin's status to red when initialize initially rejects, and continually polls initialize`, (done) => { - jest.useFakeTimers(); - - const pluginId = 'foo-plugin'; - const errorMessage = 'the error message'; - const { mockXpackMainPlugin, mockFeature } = createMockXpackMainPluginAndFeature(pluginId); - mockXpackMainPlugin.mock.setStatus('green'); - const licenseCheckResults = Symbol(); - mockFeature.mock.setLicenseCheckResults(licenseCheckResults); - const downstreamPlugin = createMockDownstreamPlugin(pluginId); - - let isRed = false; - let initializeCount = 0; - const initializeMock = jest.fn().mockImplementation(() => { - ++initializeCount; - - // on the second retry, ensure we already set the status to red - if (initializeCount === 2) { - expect(isRed).toBe(true); - } - - // this should theoretically continue indefinitely, but we only have so long to run the tests - if (initializeCount === 100) { - done(); - } - - // everytime this is called, we have to wait for a new promise to be resolved - // allowing the Promise the we return below to run, and then advance the timers - setImmediate(() => { - advanceRetry(initializeCount); - }); - return Promise.reject(new Error(errorMessage)); - }); - - watchStatusAndLicenseToInitialize(mockXpackMainPlugin, downstreamPlugin, initializeMock); - - expect(initializeMock).toHaveBeenCalledTimes(1); - expect(initializeMock).toHaveBeenCalledWith(licenseCheckResults); - downstreamPlugin.status.red.mockImplementation((message) => { - isRed = true; - expect(message).toBe(errorMessage); - }); -}); - -test(`sets downstream plugin's status to green when initialize resolves after rejecting 10 times`, (done) => { - jest.useFakeTimers(); - - const pluginId = 'foo-plugin'; - const errorMessage = 'the error message'; - const { mockXpackMainPlugin, mockFeature } = createMockXpackMainPluginAndFeature(pluginId); - mockXpackMainPlugin.mock.setStatus('green'); - const licenseCheckResults = Symbol(); - mockFeature.mock.setLicenseCheckResults(licenseCheckResults); - const downstreamPlugin = createMockDownstreamPlugin(pluginId); - - let initializeCount = 0; - const initializeMock = jest.fn().mockImplementation(() => { - ++initializeCount; - - // everytime this is called, we have to wait for a new promise to be resolved - // allowing the Promise the we return below to run, and then advance the timers - setImmediate(() => { - advanceRetry(initializeCount); - }); - - if (initializeCount >= 10) { - return Promise.resolve(); - } - - return Promise.reject(new Error(errorMessage)); - }); - - watchStatusAndLicenseToInitialize(mockXpackMainPlugin, downstreamPlugin, initializeMock); - - expect(initializeMock).toHaveBeenCalledTimes(1); - expect(initializeMock).toHaveBeenCalledWith(licenseCheckResults); - downstreamPlugin.status.red.mockImplementation((message) => { - expect(initializeCount).toBeLessThan(10); - expect(message).toBe(errorMessage); - }); - downstreamPlugin.status.green.mockImplementation((message) => { - expect(initializeCount).toBe(10); - expect(message).toBe('Ready'); - done(); - }); -}); - -test(`calls initialize twice when it gets a new license and the status is green`, (done) => { - const pluginId = 'foo-plugin'; - const { mockXpackMainPlugin, mockFeature } = createMockXpackMainPluginAndFeature(pluginId); - mockXpackMainPlugin.mock.setStatus('green'); - const firstLicenseCheckResults = Symbol(); - const secondLicenseCheckResults = Symbol(); - mockFeature.mock.setLicenseCheckResults(firstLicenseCheckResults); - const downstreamPlugin = createMockDownstreamPlugin(pluginId); - const initializeMock = jest.fn().mockImplementation(() => Promise.resolve()); - - let count = 0; - downstreamPlugin.status.green.mockImplementation((message) => { - expect(message).toBe('Ready'); - ++count; - if (count === 1) { - mockFeature.mock.setLicenseCheckResults(secondLicenseCheckResults); - mockFeature.mock.triggerLicenseChange(); - } - if (count === 2) { - expect(initializeMock).toHaveBeenCalledWith(firstLicenseCheckResults); - expect(initializeMock).toHaveBeenCalledWith(secondLicenseCheckResults); - expect(initializeMock).toHaveBeenCalledTimes(2); - done(); - } - }); - - watchStatusAndLicenseToInitialize(mockXpackMainPlugin, downstreamPlugin, initializeMock); -}); - -test(`doesn't call initialize twice when it gets a new license when the status isn't green`, (done) => { - const pluginId = 'foo-plugin'; - const redMessage = 'the red message'; - const { mockXpackMainPlugin, mockFeature } = createMockXpackMainPluginAndFeature(pluginId); - mockXpackMainPlugin.mock.setStatus('green'); - const firstLicenseCheckResults = Symbol(); - const secondLicenseCheckResults = Symbol(); - mockFeature.mock.setLicenseCheckResults(firstLicenseCheckResults); - const downstreamPlugin = createMockDownstreamPlugin(pluginId); - const initializeMock = jest.fn().mockImplementation(() => Promise.resolve()); - - downstreamPlugin.status.green.mockImplementation((message) => { - expect(message).toBe('Ready'); - mockXpackMainPlugin.mock.setStatus('red', redMessage); - mockFeature.mock.setLicenseCheckResults(secondLicenseCheckResults); - mockFeature.mock.triggerLicenseChange(); - }); - - downstreamPlugin.status.red.mockImplementation((message) => { - expect(message).toBe(redMessage); - expect(initializeMock).toHaveBeenCalledTimes(1); - expect(initializeMock).toHaveBeenCalledWith(firstLicenseCheckResults); - done(); - }); - - watchStatusAndLicenseToInitialize(mockXpackMainPlugin, downstreamPlugin, initializeMock); -}); - -test(`calls initialize twice when the status changes to green twice`, (done) => { - const pluginId = 'foo-plugin'; - const { mockXpackMainPlugin, mockFeature } = createMockXpackMainPluginAndFeature(pluginId); - mockXpackMainPlugin.mock.setStatus('green'); - const licenseCheckResults = Symbol(); - mockFeature.mock.setLicenseCheckResults(licenseCheckResults); - const downstreamPlugin = createMockDownstreamPlugin(pluginId); - const initializeMock = jest.fn().mockImplementation(() => Promise.resolve()); - - let count = 0; - downstreamPlugin.status.green.mockImplementation((message) => { - expect(message).toBe('Ready'); - ++count; - if (count === 1) { - mockXpackMainPlugin.mock.setStatus('green'); - } - if (count === 2) { - expect(initializeMock).toHaveBeenCalledWith(licenseCheckResults); - expect(initializeMock).toHaveBeenCalledTimes(2); - done(); - } - }); - - watchStatusAndLicenseToInitialize(mockXpackMainPlugin, downstreamPlugin, initializeMock); -}); diff --git a/x-pack/legacy/server/lib/xpack_usage.js b/x-pack/legacy/server/lib/xpack_usage.js deleted file mode 100644 index 50b50ba18c37f..0000000000000 --- a/x-pack/legacy/server/lib/xpack_usage.js +++ /dev/null @@ -1,16 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export function xpackUsage(client) { - /* - * Get an object over the Usage API that as available/enabled data and some - * select metadata for each of the X-Pack UI plugins - */ - return client.transport.request({ - method: 'GET', - path: '/_xpack/usage', - }); -} diff --git a/x-pack/plugins/actions/server/constants/plugin.ts b/x-pack/plugins/actions/server/constants/plugin.ts index 7d20eb6990247..b82464bd92a18 100644 --- a/x-pack/plugins/actions/server/constants/plugin.ts +++ b/x-pack/plugins/actions/server/constants/plugin.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LICENSE_TYPE_BASIC, LicenseType } from '../../../../legacy/common/constants'; +import { LicenseType } from '../../../licensing/server'; export const PLUGIN = { ID: 'actions', - MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC as LicenseType, // TODO: supposed to be changed up on requirements + MINIMUM_LICENSE_REQUIRED: 'basic' as LicenseType, // TODO: supposed to be changed up on requirements // eslint-disable-next-line @typescript-eslint/no-explicit-any getI18nName: (i18n: any): string => i18n.translate('xpack.actions.appName', { diff --git a/x-pack/plugins/alerts/server/constants/plugin.ts b/x-pack/plugins/alerts/server/constants/plugin.ts index c180b68680841..4e1e0c59e0b48 100644 --- a/x-pack/plugins/alerts/server/constants/plugin.ts +++ b/x-pack/plugins/alerts/server/constants/plugin.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LICENSE_TYPE_BASIC, LicenseType } from '../../../../legacy/common/constants'; +import { LicenseType } from '../../../licensing/server'; export const PLUGIN = { ID: 'alerts', - MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC as LicenseType, // TODO: supposed to be changed up on requirements + MINIMUM_LICENSE_REQUIRED: 'basic' as LicenseType, // TODO: supposed to be changed up on requirements // all plugins seem to use getI18nName with any // eslint-disable-next-line @typescript-eslint/no-explicit-any getI18nName: (i18n: any): string => diff --git a/x-pack/plugins/apm/common/anomaly_detection.ts b/x-pack/plugins/apm/common/anomaly_detection.ts index 5d80ee6381267..64dff22095937 100644 --- a/x-pack/plugins/apm/common/anomaly_detection.ts +++ b/x-pack/plugins/apm/common/anomaly_detection.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { EuiTheme } from '../../../legacy/common/eui_styled_components'; +import type { EuiTheme } from '../../xpack_legacy/common'; export interface ServiceAnomalyStats { transactionType?: string; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx index a785cb31c3cf4..262d94d8f3674 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx @@ -27,10 +27,7 @@ import { SNAPSHOT_CUSTOM_AGGREGATIONS, SnapshotCustomAggregationRT, } from '../../../../../../../common/http_api/snapshot_api'; -import { - EuiTheme, - withTheme, -} from '../../../../../../../../../legacy/common/eui_styled_components'; +import { EuiTheme, withTheme } from '../../../../../../../../xpack_legacy/common'; interface SelectedOption { label: string; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx index e75885ccbc917..831a0cde49cfb 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/metrics_edit_mode.tsx @@ -8,10 +8,7 @@ import { EuiFlexItem, EuiFlexGroup, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { getCustomMetricLabel } from '../../../../../../../common/formatters/get_custom_metric_label'; import { SnapshotCustomMetricInput } from '../../../../../../../common/http_api/snapshot_api'; -import { - EuiTheme, - withTheme, -} from '../../../../../../../../../legacy/common/eui_styled_components'; +import { EuiTheme, withTheme } from '../../../../../../../../xpack_legacy/common'; interface Props { theme: EuiTheme | undefined; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/mode_switcher.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/mode_switcher.tsx index d1abcade5d660..956241545e8be 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/mode_switcher.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/mode_switcher.tsx @@ -9,10 +9,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { CustomMetricMode } from './types'; import { SnapshotCustomMetricInput } from '../../../../../../../common/http_api/snapshot_api'; -import { - EuiTheme, - withTheme, -} from '../../../../../../../../../legacy/common/eui_styled_components'; +import { EuiTheme, withTheme } from '../../../../../../../../xpack_legacy/common'; interface Props { theme: EuiTheme | undefined; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/index.tsx index 5520a50463db4..69fb2ff6f9506 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/index.tsx @@ -12,7 +12,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import styled from 'styled-components'; import { EuiErrorBoundary, EuiPanel, EuiEmptyPrompt, EuiCode } from '@elastic/eui'; import { CoreStart, AppMountParameters } from 'src/core/public'; -import { EuiThemeProvider } from '../../../../../legacy/common/eui_styled_components'; +import { EuiThemeProvider } from '../../../../xpack_legacy/common'; import { IngestManagerSetupDeps, IngestManagerConfigType, diff --git a/x-pack/plugins/observability/public/application/index.tsx b/x-pack/plugins/observability/public/application/index.tsx index fa691a7f41ddb..6cb7e8d9cf8fd 100644 --- a/x-pack/plugins/observability/public/application/index.tsx +++ b/x-pack/plugins/observability/public/application/index.tsx @@ -9,7 +9,7 @@ import ReactDOM from 'react-dom'; import { Route, Router, Switch } from 'react-router-dom'; import { AppMountParameters, CoreStart } from '../../../../../src/core/public'; import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public'; -import { EuiThemeProvider } from '../../../../legacy/common/eui_styled_components'; +import { EuiThemeProvider } from '../../../xpack_legacy/common'; import { PluginContext } from '../context/plugin_context'; import { usePluginContext } from '../hooks/use_plugin_context'; import { useRouteParams } from '../hooks/use_route_params'; diff --git a/x-pack/plugins/observability/public/hooks/use_theme.tsx b/x-pack/plugins/observability/public/hooks/use_theme.tsx index d0449a4432d93..51a1ad5029538 100644 --- a/x-pack/plugins/observability/public/hooks/use_theme.tsx +++ b/x-pack/plugins/observability/public/hooks/use_theme.tsx @@ -5,7 +5,7 @@ */ import { useContext } from 'react'; import { ThemeContext } from 'styled-components'; -import { EuiTheme } from '../../../../legacy/common/eui_styled_components'; +import { EuiTheme } from '../../../xpack_legacy/common'; export function useTheme() { const theme: EuiTheme = useContext(ThemeContext); diff --git a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_root_provider.tsx b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_root_provider.tsx index 73c0f00573911..3b7262e8a8d7e 100644 --- a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_root_provider.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_root_provider.tsx @@ -11,7 +11,7 @@ import { Router } from 'react-router-dom'; import { History } from 'history'; import { useObservable } from 'react-use'; import { Store } from 'redux'; -import { EuiThemeProvider } from '../../../../../../legacy/common/eui_styled_components'; +import { EuiThemeProvider } from '../../../../../xpack_legacy/common'; import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; import { RouteCapture } from '../../components/endpoint/route_capture'; import { StartPlugins } from '../../../types'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/vertical_divider.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/vertical_divider.ts index 6a3aecb4a6503..b6f5c9b7421b5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/vertical_divider.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/vertical_divider.ts @@ -5,7 +5,7 @@ */ import styled from 'styled-components'; -import { EuiTheme } from '../../../../../../../legacy/common/eui_styled_components'; +import { EuiTheme } from '../../../../../../xpack_legacy/common'; type SpacingOptions = keyof EuiTheme['eui']['spacerSizes']; diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts index 5efb6f31c1e3f..f2dbc085ab46f 100644 --- a/x-pack/plugins/transform/common/constants.ts +++ b/x-pack/plugins/transform/common/constants.ts @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; -import { LICENSE_TYPE_BASIC, LicenseType } from '../../../legacy/common/constants'; +import { LicenseType } from '../../licensing/common/types'; export const DEFAULT_REFRESH_INTERVAL_MS = 30000; export const MINIMUM_REFRESH_INTERVAL_MS = 1000; @@ -14,7 +14,7 @@ export const PROGRESS_REFRESH_INTERVAL_MS = 2000; export const PLUGIN = { ID: 'transform', - MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC as LicenseType, + MINIMUM_LICENSE_REQUIRED: 'basic' as LicenseType, getI18nName: (): string => { return i18n.translate('xpack.transform.appName', { defaultMessage: 'Transforms', diff --git a/x-pack/plugins/transform/server/routes/api/error_utils.ts b/x-pack/plugins/transform/server/routes/api/error_utils.ts index 269cd28c4bda6..74f3c7ac58da2 100644 --- a/x-pack/plugins/transform/server/routes/api/error_utils.ts +++ b/x-pack/plugins/transform/server/routes/api/error_utils.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { boomify, isBoom } from 'boom'; +import Boom, { boomify, isBoom } from 'boom'; import { i18n } from '@kbn/i18n'; @@ -83,3 +83,58 @@ export function wrapError(error: any): CustomHttpResponseOptions statusCode: boom.output.statusCode, }; } + +function extractCausedByChain( + causedBy: Record = {}, + accumulator: string[] = [] +): string[] { + const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/naming-convention + + if (reason) { + accumulator.push(reason); + } + + if (caused_by) { + return extractCausedByChain(caused_by, accumulator); + } + + return accumulator; +} + +/** + * Wraps an error thrown by the ES JS client into a Boom error response and returns it + * + * @param err Object Error thrown by ES JS client + * @param statusCodeToMessageMap Object Optional map of HTTP status codes => error messages + * @return Object Boom error response + */ +export function wrapEsError(err: any, statusCodeToMessageMap: Record = {}) { + const { statusCode, response } = err; + + const { + error: { + root_cause = [], // eslint-disable-line @typescript-eslint/naming-convention + caused_by = {}, // eslint-disable-line @typescript-eslint/naming-convention + } = {}, + } = JSON.parse(response); + + // If no custom message if specified for the error's status code, just + // wrap the error as a Boom error response, include the additional information from ES, and return it + if (!statusCodeToMessageMap[statusCode]) { + const boomError = Boom.boomify(err, { statusCode }); + + // The caused_by chain has the most information so use that if it's available. If not then + // settle for the root_cause. + const causedByChain = extractCausedByChain(caused_by); + const defaultCause = root_cause.length ? extractCausedByChain(root_cause[0]) : undefined; + + // @ts-expect-error cause is not defined on payload type + boomError.output.payload.cause = causedByChain.length ? causedByChain : defaultCause; + return boomError; + } + + // Otherwise, use the custom message to create a Boom error response and + // return it + const message = statusCodeToMessageMap[statusCode]; + return new Boom(message, { statusCode }); +} diff --git a/x-pack/plugins/transform/server/routes/api/field_histograms.ts b/x-pack/plugins/transform/server/routes/api/field_histograms.ts index 88352ec4af129..636af095e0053 100644 --- a/x-pack/plugins/transform/server/routes/api/field_histograms.ts +++ b/x-pack/plugins/transform/server/routes/api/field_histograms.ts @@ -9,8 +9,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { wrapEsError } from '../../../../../legacy/server/lib/create_router/error_wrappers'; - import { indexPatternTitleSchema, IndexPatternTitleSchema, @@ -24,7 +22,7 @@ import { RouteDependencies } from '../../types'; import { addBasePath } from '../index'; -import { wrapError } from './error_utils'; +import { wrapError, wrapEsError } from './error_utils'; export function registerFieldHistogramsRoutes({ router, license }: RouteDependencies) { router.post( diff --git a/x-pack/plugins/transform/server/routes/api/transforms.ts b/x-pack/plugins/transform/server/routes/api/transforms.ts index 3d2018eb5801f..31b2c2285a764 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms.ts @@ -12,7 +12,6 @@ import { SavedObjectsClientContract, LegacyAPICaller, } from 'kibana/server'; -import { wrapEsError } from '../../../../../legacy/server/lib/create_router/error_wrappers'; import { TRANSFORM_STATE } from '../../../common/constants'; import { TransformId } from '../../../common/types/transform'; @@ -54,7 +53,7 @@ import { RouteDependencies } from '../../types'; import { addBasePath } from '../index'; -import { isRequestTimeout, fillResultsWithTimeouts, wrapError } from './error_utils'; +import { isRequestTimeout, fillResultsWithTimeouts, wrapError, wrapEsError } from './error_utils'; import { registerTransformsAuditMessagesRoutes } from './transforms_audit_messages'; import { IIndexPattern } from '../../../../../../src/plugins/data/common/index_patterns'; diff --git a/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts b/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts index f01b2bdb73fd5..20cb6ffb4978b 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_audit_messages.ts @@ -6,13 +6,12 @@ import { transformIdParamSchema, TransformIdParamSchema } from '../../../common/api_schemas/common'; import { AuditMessage, TransformMessage } from '../../../common/types/messages'; -import { wrapEsError } from '../../../../../legacy/server/lib/create_router/error_wrappers'; import { RouteDependencies } from '../../types'; import { addBasePath } from '../index'; -import { wrapError } from './error_utils'; +import { wrapError, wrapEsError } from './error_utils'; const ML_DF_NOTIFICATION_INDEX_PATTERN = '.transform-notifications-read'; const SIZE = 500; diff --git a/x-pack/plugins/watcher/common/constants/plugin.ts b/x-pack/plugins/watcher/common/constants/plugin.ts index f89ef95e9261f..fa95b86c0673b 100644 --- a/x-pack/plugins/watcher/common/constants/plugin.ts +++ b/x-pack/plugins/watcher/common/constants/plugin.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LICENSE_TYPE_GOLD, LicenseType } from '../../../../legacy/common/constants'; +import { LicenseType } from '../../../licensing/common/types'; export const PLUGIN = { ID: 'watcher', - MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_GOLD as LicenseType, + MINIMUM_LICENSE_REQUIRED: 'gold' as LicenseType, getI18nName: (i18n: any): string => { return i18n.translate('xpack.watcher.appName', { defaultMessage: 'Watcher', diff --git a/x-pack/plugins/watcher/server/types.ts b/x-pack/plugins/watcher/server/types.ts index 167dcb3ab64c3..5ef3aef7de1c6 100644 --- a/x-pack/plugins/watcher/server/types.ts +++ b/x-pack/plugins/watcher/server/types.ts @@ -8,8 +8,6 @@ import { IRouter } from 'kibana/server'; import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; import { LicensingPluginSetup } from '../../licensing/server'; -import { XPackMainPlugin } from '../../../legacy/plugins/xpack_main/server/xpack_main'; - export interface Dependencies { licensing: LicensingPluginSetup; features: FeaturesPluginSetup; @@ -18,7 +16,6 @@ export interface Dependencies { export interface ServerShim { route: any; plugins: { - xpack_main: XPackMainPlugin; watcher: any; }; } diff --git a/x-pack/legacy/common/eui_styled_components/eui_styled_components.tsx b/x-pack/plugins/xpack_legacy/common/eui_styled_components.tsx similarity index 100% rename from x-pack/legacy/common/eui_styled_components/eui_styled_components.tsx rename to x-pack/plugins/xpack_legacy/common/eui_styled_components.tsx diff --git a/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/index.js b/x-pack/plugins/xpack_legacy/common/index.ts similarity index 83% rename from x-pack/legacy/plugins/xpack_main/server/routes/api/v1/index.js rename to x-pack/plugins/xpack_legacy/common/index.ts index 80baf7bf1a64d..8c0dace27faf4 100644 --- a/x-pack/legacy/plugins/xpack_main/server/routes/api/v1/index.js +++ b/x-pack/plugins/xpack_legacy/common/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { xpackInfoRoute } from './xpack_info'; +export * from './eui_styled_components'; diff --git a/x-pack/tasks/build.ts b/x-pack/tasks/build.ts index 41bf9587cad1e..a3b08a16f4b08 100644 --- a/x-pack/tasks/build.ts +++ b/x-pack/tasks/build.ts @@ -61,9 +61,6 @@ async function copySourceAndBabelify() { 'plugins/**/*', 'plugins/reporting/.phantom/*', 'plugins/reporting/.chromium/*', - 'legacy/common/**/*', - 'legacy/plugins/**/*', - 'legacy/server/**/*', 'typings/**/*', ], { diff --git a/x-pack/typings/hapi.d.ts b/x-pack/typings/hapi.d.ts index 253b639a52ff2..dd9e0239aeee7 100644 --- a/x-pack/typings/hapi.d.ts +++ b/x-pack/typings/hapi.d.ts @@ -6,7 +6,6 @@ import 'hapi'; -import { XPackMainPlugin } from '../legacy/plugins/xpack_main/server/xpack_main'; import { ActionsPlugin, ActionsClient } from '../plugins/actions/server'; import { AlertingPlugin, AlertsClient } from '../plugins/alerts/server'; import { TaskManager } from '../plugins/task_manager/server'; @@ -17,7 +16,6 @@ declare module 'hapi' { getAlertsClient?: () => AlertsClient; } interface PluginProperties { - xpack_main: XPackMainPlugin; actions?: ActionsPlugin; alerts?: AlertingPlugin; task_manager?: TaskManager; From 1498f79ce61615ffdfe1b574856b29a28eaf0dc9 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 14:13:26 +0200 Subject: [PATCH 11/29] adapt imports due to merge --- x-pack/plugins/apm/common/service_health_status.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/common/service_health_status.ts b/x-pack/plugins/apm/common/service_health_status.ts index 468f06ab97af8..1d4bcfb3b0e07 100644 --- a/x-pack/plugins/apm/common/service_health_status.ts +++ b/x-pack/plugins/apm/common/service_health_status.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { ANOMALY_SEVERITY } from '../../ml/common'; -import { EuiTheme } from '../../../legacy/common/eui_styled_components'; +import { EuiTheme } from '../../xpack_legacy/common'; export enum ServiceHealthStatus { healthy = 'healthy', From 719280afca4fc3f93b2a7ea43ff7262d193b5200 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 14:23:01 +0200 Subject: [PATCH 12/29] cleanup CODEOWNERS --- .github/CODEOWNERS | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7daa42af7024d..de291b5c34c9a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -71,7 +71,7 @@ /x-pack/plugins/apm/server/projections/rum_overview.ts @elastic/uptime # Beats -/x-pack/legacy/plugins/beats_management/ @elastic/beats +/x-pack/plugins/beats_management/ @elastic/beats # Canvas /x-pack/plugins/canvas/ @elastic/kibana-canvas @@ -85,16 +85,13 @@ /x-pack/plugins/global_search_bar/ @elastic/kibana-core-ui # Observability UIs -/x-pack/legacy/plugins/infra/ @elastic/logs-metrics-ui /x-pack/plugins/infra/ @elastic/logs-metrics-ui /x-pack/plugins/ingest_manager/ @elastic/ingest-management -/x-pack/legacy/plugins/ingest_manager/ @elastic/ingest-management /x-pack/plugins/observability/ @elastic/observability-ui /x-pack/plugins/monitoring/ @elastic/stack-monitoring-ui /x-pack/plugins/uptime @elastic/uptime # Machine Learning -/x-pack/legacy/plugins/ml/ @elastic/ml-ui /x-pack/plugins/ml/ @elastic/ml-ui /x-pack/test/functional/apps/machine_learning/ @elastic/ml-ui /x-pack/test/functional/services/machine_learning/ @elastic/ml-ui @@ -106,7 +103,6 @@ /x-pack/test/functional/services/transform.ts @elastic/ml-ui # Maps -/x-pack/legacy/plugins/maps/ @elastic/kibana-gis /x-pack/plugins/maps/ @elastic/kibana-gis /x-pack/test/api_integration/apis/maps/ @elastic/kibana-gis /x-pack/test/functional/apps/maps/ @elastic/kibana-gis @@ -234,13 +230,8 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib /src/plugins/dev_tools/ @elastic/es-ui /src/plugins/console/ @elastic/es-ui /src/plugins/es_ui_shared/ @elastic/es-ui -/x-pack/legacy/plugins/cross_cluster_replication/ @elastic/es-ui +/x-pack/plugins/cross_cluster_replication/ @elastic/es-ui /x-pack/plugins/index_lifecycle_management/ @elastic/es-ui -/x-pack/legacy/plugins/index_management/ @elastic/es-ui -/x-pack/legacy/plugins/license_management/ @elastic/es-ui -/x-pack/legacy/plugins/rollup/ @elastic/es-ui -/x-pack/legacy/plugins/snapshot_restore/ @elastic/es-ui -/x-pack/legacy/plugins/upgrade_assistant/ @elastic/es-ui /x-pack/plugins/console_extensions/ @elastic/es-ui /x-pack/plugins/es_ui_shared/ @elastic/es-ui /x-pack/plugins/grokdebugger/ @elastic/es-ui From 5e5b44869fdfb519f573a6e66eddf9007fd4ca8b Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 14:26:37 +0200 Subject: [PATCH 13/29] cleanup gitignore & i18nrc --- x-pack/.gitignore | 4 ---- x-pack/.i18nrc.json | 12 ++++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/x-pack/.gitignore b/x-pack/.gitignore index d73b6f64f036a..99e33dbb88e92 100644 --- a/x-pack/.gitignore +++ b/x-pack/.gitignore @@ -6,13 +6,9 @@ /test/functional/apps/reporting/reports/session /test/reporting/configs/failure_debug/ /plugins/reporting/.chromium/ -/legacy/plugins/reporting/.chromium/ -/legacy/plugins/reporting/.phantom/ /plugins/reporting/chromium/ /plugins/reporting/.phantom/ /.aws-config.json /.env /.kibana-plugin-helpers.dev.* -!/legacy/plugins/infra/**/target .cache -!/legacy/plugins/security_solution/**/target diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index bdd0fbea35fa8..c6796124993a0 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -9,8 +9,8 @@ "xpack.alerts": "plugins/alerts", "xpack.eventLog": "plugins/event_log", "xpack.alertingBuiltins": "plugins/alerting_builtins", - "xpack.apm": ["legacy/plugins/apm", "plugins/apm"], - "xpack.beatsManagement": ["legacy/plugins/beats_management", "plugins/beats_management"], + "xpack.apm": "plugins/apm", + "xpack.beatsManagement": "plugins/beats_management", "xpack.canvas": "plugins/canvas", "xpack.cloud": "plugins/cloud", "xpack.dashboard": "plugins/dashboard_enhanced", @@ -35,15 +35,15 @@ "xpack.lens": "plugins/lens", "xpack.licenseMgmt": "plugins/license_management", "xpack.licensing": "plugins/licensing", - "xpack.logstash": ["plugins/logstash", "legacy/plugins/logstash"], + "xpack.logstash": ["plugins/logstash"], "xpack.main": "legacy/plugins/xpack_main", - "xpack.maps": ["plugins/maps", "legacy/plugins/maps"], - "xpack.ml": ["plugins/ml", "legacy/plugins/ml"], + "xpack.maps": ["plugins/maps"], + "xpack.ml": ["plugins/ml"], "xpack.monitoring": ["plugins/monitoring"], "xpack.remoteClusters": "plugins/remote_clusters", "xpack.painlessLab": "plugins/painless_lab", "xpack.reporting": ["plugins/reporting"], - "xpack.rollupJobs": ["legacy/plugins/rollup", "plugins/rollup"], + "xpack.rollupJobs": ["plugins/rollup"], "xpack.searchProfiler": "plugins/searchprofiler", "xpack.security": "plugins/security", "xpack.server": "legacy/server", From 1a10e3b15a6d364de25985f7239ee66cee51828e Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 14:27:40 +0200 Subject: [PATCH 14/29] cleanup tsconfig.json --- x-pack/tsconfig.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x-pack/tsconfig.json b/x-pack/tsconfig.json index 0f5a7526d98bc..6fd601e06fee2 100644 --- a/x-pack/tsconfig.json +++ b/x-pack/tsconfig.json @@ -3,9 +3,6 @@ "include": [ "mocks.ts", "typings/**/*", - "legacy/common/**/*", - "legacy/server/**/*", - "legacy/plugins/**/*", "plugins/**/*", "test_utils/**/*", "tasks/**/*" @@ -21,7 +18,6 @@ "paths": { "kibana/public": ["src/core/public"], "kibana/server": ["src/core/server"], - "plugins/xpack_main/*": ["x-pack/legacy/plugins/xpack_main/public/*"], "plugins/spaces/*": ["x-pack/legacy/plugins/spaces/public/*"], "test_utils/*": ["x-pack/test_utils/*"], "fixtures/*": ["src/fixtures/*"] From c5d76126635584f9eee132f987a843de9001c96a Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 16:02:13 +0200 Subject: [PATCH 15/29] remove unused i18n keys --- x-pack/plugins/translations/translations/ja-JP.json | 3 --- x-pack/plugins/translations/translations/zh-CN.json | 3 --- 2 files changed, 6 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 76a3b58a8f3e3..22e380b1361e5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -16696,9 +16696,6 @@ "xpack.securitySolution.zeek.sfDescription": "通常のSYN/FIN完了", "xpack.securitySolution.zeek.shDescription": "接続元がFINに続きSYNを送信しました。レスポンダーからSYN-ACKはありません", "xpack.securitySolution.zeek.shrDescription": "レスポンダーがFINに続きSYNを送信しました。接続元からSYN-ACKはありません", - "xpack.server.checkLicense.errorExpiredMessage": "{licenseType} ライセンスが期限切れのため {pluginName} を使用できません", - "xpack.server.checkLicense.errorUnavailableMessage": "現在ライセンス情報が利用できないため {pluginName} を使用できません。", - "xpack.server.checkLicense.errorUnsupportedMessage": "ご使用の {licenseType} ライセンスは {pluginName} をサポートしていません。ライセンスをアップグレードしてください。", "xpack.snapshotRestore.addPolicy.breadcrumbTitle": "ポリシーを追加", "xpack.snapshotRestore.addPolicy.loadingIndicesDescription": "利用可能なインデックスを読み込み中…", "xpack.snapshotRestore.addPolicy.LoadingIndicesErrorMessage": "利用可能なインデックスを読み込み中にエラーが発生", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 89c7a03e099d3..c28b24006578a 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -16706,9 +16706,6 @@ "xpack.securitySolution.zeek.sfDescription": "正常 SYN/FIN 完成", "xpack.securitySolution.zeek.shDescription": "发起方已发送 SYN,后跟 FIN,响应方未发送 SYN ACK", "xpack.securitySolution.zeek.shrDescription": "响应方已发送 SYN ACK,后跟 FIN,发起方未发送 SYN", - "xpack.server.checkLicense.errorExpiredMessage": "您不能使用 {pluginName},因为您的{licenseType}许可证已过期", - "xpack.server.checkLicense.errorUnavailableMessage": "您不能使用 {pluginName},因为许可证信息当前不可用。", - "xpack.server.checkLicense.errorUnsupportedMessage": "您的{licenseType}许可证不支持 {pluginName}。请升级您的许可证。", "xpack.snapshotRestore.addPolicy.breadcrumbTitle": "添加策略", "xpack.snapshotRestore.addPolicy.loadingIndicesDescription": "正在加载可用索引……", "xpack.snapshotRestore.addPolicy.LoadingIndicesErrorMessage": "加载可用索引时出错", From 462388a8b0823dad225f1872a0ef36ed5f67ad35 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 16:03:38 +0200 Subject: [PATCH 16/29] add back `"legacy/plugins/**/*",` to tsconfig until legacy space plugin is deleted --- x-pack/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/tsconfig.json b/x-pack/tsconfig.json index 6fd601e06fee2..44e3d8ab3b465 100644 --- a/x-pack/tsconfig.json +++ b/x-pack/tsconfig.json @@ -4,6 +4,7 @@ "mocks.ts", "typings/**/*", "plugins/**/*", + "legacy/plugins/**/*", "test_utils/**/*", "tasks/**/*" ], From a20cc660165c9b66cf7f2a8eca5bc5ce073a1aef Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 16:04:54 +0200 Subject: [PATCH 17/29] fix create_jest_config --- x-pack/dev-tools/jest/create_jest_config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js index e6f160ce8c654..d1631118c4557 100644 --- a/x-pack/dev-tools/jest/create_jest_config.js +++ b/x-pack/dev-tools/jest/create_jest_config.js @@ -8,7 +8,7 @@ export function createJestConfig({ kibanaDirectory, rootDir, xPackKibanaDirector const fileMockPath = `${kibanaDirectory}/src/dev/jest/mocks/file_mock.js`; return { rootDir, - roots: ['/plugins', '/legacy/plugins', '/legacy/server'], + roots: ['/plugins'], moduleFileExtensions: ['js', 'mjs', 'json', 'ts', 'tsx', 'node'], moduleNameMapper: { '@elastic/eui$': `${kibanaDirectory}/node_modules/@elastic/eui/test-env`, From 8443d968ed6d2f0fb17ac10b4ddf07ae4612fd1b Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 16:24:28 +0200 Subject: [PATCH 18/29] remove references from eslintrc --- .eslintrc.js | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 3161a25b70870..e696fc824c159 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,9 +17,6 @@ * under the License. */ -const { readdirSync } = require('fs'); -const { resolve } = require('path'); - const APACHE_2_0_LICENSE_HEADER = ` /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -345,10 +342,6 @@ module.exports = { '!src/legacy/core_plugins/**/server/**/*', '!src/legacy/core_plugins/**/index.{js,mjs,ts,tsx}', - 'x-pack/legacy/plugins/**/*', - '!x-pack/legacy/plugins/**/server/**/*', - '!x-pack/legacy/plugins/**/index.{js,mjs,ts,tsx}', - 'examples/**/*', '!examples/**/server/**/*', ], @@ -392,8 +385,6 @@ module.exports = { 'src/legacy/core_plugins/vis_type_*/public/**/*', '!src/legacy/core_plugins/vis_type_*/public/legacy*', 'src/legacy/core_plugins/**/server/np_ready/**/*', - 'x-pack/legacy/plugins/**/public/np_ready/**/*', - 'x-pack/legacy/plugins/**/server/np_ready/**/*', ], allowSameFolder: true, errorMessage: @@ -450,15 +441,7 @@ module.exports = { forceNode: false, rootPackageName: 'kibana', kibanaPath: '.', - pluginMap: readdirSync(resolve(__dirname, 'x-pack/legacy/plugins')).reduce( - (acc, name) => { - if (!name.startsWith('_')) { - acc[name] = `x-pack/legacy/plugins/${name}`; - } - return acc; - }, - {} - ), + pluginMap: {}, }, }, }, @@ -764,16 +747,6 @@ module.exports = { }, }, - /** - * GIS overrides - */ - { - files: ['x-pack/legacy/plugins/maps/**/*.js'], - rules: { - 'react/prefer-stateless-function': [0, { ignorePureComponents: false }], - }, - }, - /** * ML overrides */ From eced56213c9b12d67d9cd3dbe5f3c5baf71c115f Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 16:26:14 +0200 Subject: [PATCH 19/29] more eslint cleanup --- .eslintrc.js | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index e696fc824c159..39867f84cd1ef 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -338,10 +338,6 @@ module.exports = { '(src|x-pack)/plugins/**/*', '!(src|x-pack)/plugins/**/server/**/*', - 'src/legacy/core_plugins/**/*', - '!src/legacy/core_plugins/**/server/**/*', - '!src/legacy/core_plugins/**/index.{js,mjs,ts,tsx}', - 'examples/**/*', '!examples/**/server/**/*', ], @@ -363,12 +359,7 @@ module.exports = { }, { target: ['src/core/**/*'], - from: [ - 'plugins/**/*', - 'src/plugins/**/*', - 'src/legacy/core_plugins/**/*', - 'src/legacy/ui/**/*', - ], + from: ['plugins/**/*', 'src/plugins/**/*', 'src/legacy/ui/**/*'], errorMessage: 'The core cannot depend on any plugins.', }, { @@ -381,10 +372,6 @@ module.exports = { target: [ 'test/plugin_functional/plugins/**/public/np_ready/**/*', 'test/plugin_functional/plugins/**/server/np_ready/**/*', - 'src/legacy/core_plugins/**/public/np_ready/**/*', - 'src/legacy/core_plugins/vis_type_*/public/**/*', - '!src/legacy/core_plugins/vis_type_*/public/legacy*', - 'src/legacy/core_plugins/**/server/np_ready/**/*', ], allowSameFolder: true, errorMessage: @@ -1211,10 +1198,7 @@ module.exports = { * TSVB overrides */ { - files: [ - 'src/plugins/vis_type_timeseries/**/*.{js,mjs,ts,tsx}', - 'src/legacy/core_plugins/vis_type_timeseries/**/*.{js,mjs,ts,tsx}', - ], + files: ['src/plugins/vis_type_timeseries/**/*.{js,mjs,ts,tsx}'], rules: { 'import/no-default-export': 'error', }, From 60e69636123adf97de146dd18b31e14d6535ec78 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 16:42:20 +0200 Subject: [PATCH 20/29] remove `x-pack/index.js` --- x-pack/index.js | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 x-pack/index.js diff --git a/x-pack/index.js b/x-pack/index.js deleted file mode 100644 index bed8d328cd994..0000000000000 --- a/x-pack/index.js +++ /dev/null @@ -1,9 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -module.exports = function () { - return []; -}; From 14569f0c3058d707014f3370cd0d3dedda962709 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 17:59:18 +0200 Subject: [PATCH 21/29] fix xpack gulp scripts --- x-pack/tasks/helpers/flags.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/x-pack/tasks/helpers/flags.ts b/x-pack/tasks/helpers/flags.ts index 33ee126c2a2ee..8820a4d60aa40 100644 --- a/x-pack/tasks/helpers/flags.ts +++ b/x-pack/tasks/helpers/flags.ts @@ -4,14 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resolve } from 'path'; - import log from 'fancy-log'; import getopts from 'getopts'; -import { toArray } from 'rxjs/operators'; - -// @ts-ignore complicated module doesn't have types yet -import { findPluginSpecs } from '../../../src/legacy/plugin_discovery'; /* Usage: @@ -53,18 +47,3 @@ export const FLAGS = { .map((id) => id.trim()) : undefined, }; - -export async function getEnabledPlugins() { - if (FLAGS.plugins) { - return FLAGS.plugins; - } - - const { spec$ } = findPluginSpecs({ - plugins: { - paths: [resolve(__dirname, '..', '..')], - }, - }); - - const enabledPlugins: Array<{ getId: () => string }> = await spec$.pipe(toArray()).toPromise(); - return enabledPlugins.map((spec) => spec.getId()); -} From beed1f9376b0fe79d8187351769c0a94b84013b1 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 18 Sep 2020 21:44:19 +0200 Subject: [PATCH 22/29] fix bug with default + named imports from boom --- x-pack/plugins/transform/server/routes/api/error_utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/transform/server/routes/api/error_utils.ts b/x-pack/plugins/transform/server/routes/api/error_utils.ts index 74f3c7ac58da2..ef5927651df88 100644 --- a/x-pack/plugins/transform/server/routes/api/error_utils.ts +++ b/x-pack/plugins/transform/server/routes/api/error_utils.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom, { boomify, isBoom } from 'boom'; +import Boom from 'boom'; import { i18n } from '@kbn/i18n'; @@ -76,7 +76,7 @@ export function fillResultsWithTimeouts({ results, id, items, action }: Params) } export function wrapError(error: any): CustomHttpResponseOptions { - const boom = isBoom(error) ? error : boomify(error, { statusCode: error.status }); + const boom = Boom.isBoom(error) ? error : Boom.boomify(error, { statusCode: error.status }); return { body: boom, headers: boom.output.headers, From 6ba86824fd8f869ffa6f77746236ed11a82cb970 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 22 Sep 2020 07:50:54 +0200 Subject: [PATCH 23/29] remove rules from eslintrc --- .eslintrc.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 39867f84cd1ef..e9e47bc8099b4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -421,16 +421,7 @@ module.exports = { settings: { // instructs import/no-extraneous-dependencies to treat certain modules // as core modules, even if they aren't listed in package.json - 'import/core-modules': ['plugins', 'legacy/ui'], - - 'import/resolver': { - '@kbn/eslint-import-resolver-kibana': { - forceNode: false, - rootPackageName: 'kibana', - kibanaPath: '.', - pluginMap: {}, - }, - }, + 'import/core-modules': ['plugins'], }, }, From 7e4a35bc0987c4ee87fdad87bbb851d88f31a343 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 22 Sep 2020 08:18:03 +0200 Subject: [PATCH 24/29] remove LegacyInternals --- src/core/server/index.ts | 7 +- src/core/server/legacy/index.ts | 2 - .../server/legacy/legacy_internals.test.ts | 121 ------------------ src/core/server/legacy/legacy_internals.ts | 58 --------- src/core/server/legacy/legacy_service.ts | 12 +- src/core/server/legacy/types.ts | 55 -------- .../rendering/__mocks__/rendering_service.ts | 2 - .../rendering/rendering_service.test.ts | 7 - .../server/rendering/rendering_service.tsx | 15 +-- src/core/server/server.ts | 4 - src/legacy/server/kbn_server.d.ts | 3 +- .../fixtures/plugin_async_foo/index.js | 40 ------ .../fixtures/plugin_async_foo/package.json | 4 - .../ui/__tests__/fixtures/plugin_bar/index.js | 36 ------ .../fixtures/plugin_bar/package.json | 4 - .../ui/__tests__/fixtures/plugin_foo/index.js | 36 ------ .../fixtures/plugin_foo/package.json | 4 - .../ui/__tests__/fixtures/test_app/index.js | 39 ------ .../__tests__/fixtures/test_app/package.json | 4 - src/legacy/ui/ui_render/ui_render_mixin.js | 6 +- 20 files changed, 8 insertions(+), 451 deletions(-) delete mode 100644 src/core/server/legacy/legacy_internals.test.ts delete mode 100644 src/core/server/legacy/legacy_internals.ts delete mode 100644 src/legacy/ui/__tests__/fixtures/plugin_async_foo/index.js delete mode 100644 src/legacy/ui/__tests__/fixtures/plugin_async_foo/package.json delete mode 100644 src/legacy/ui/__tests__/fixtures/plugin_bar/index.js delete mode 100644 src/legacy/ui/__tests__/fixtures/plugin_bar/package.json delete mode 100644 src/legacy/ui/__tests__/fixtures/plugin_foo/index.js delete mode 100644 src/legacy/ui/__tests__/fixtures/plugin_foo/package.json delete mode 100644 src/legacy/ui/__tests__/fixtures/test_app/index.js delete mode 100644 src/legacy/ui/__tests__/fixtures/test_app/package.json diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 6db328eb4b428..70ef93963c69f 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -339,12 +339,7 @@ export { SavedObjectsMigrationVersion, } from './types'; -export { - LegacyServiceSetupDeps, - LegacyServiceStartDeps, - LegacyConfig, - LegacyInternals, -} from './legacy'; +export { LegacyServiceSetupDeps, LegacyServiceStartDeps, LegacyConfig } from './legacy'; export { CoreStatus, diff --git a/src/core/server/legacy/index.ts b/src/core/server/legacy/index.ts index 6b0963e3129c6..1a0bc8955be0f 100644 --- a/src/core/server/legacy/index.ts +++ b/src/core/server/legacy/index.ts @@ -20,8 +20,6 @@ /** @internal */ export { ensureValidConfiguration } from './config'; /** @internal */ -export { LegacyInternals } from './legacy_internals'; -/** @internal */ export { LegacyService, ILegacyService } from './legacy_service'; /** @internal */ export * from './types'; diff --git a/src/core/server/legacy/legacy_internals.test.ts b/src/core/server/legacy/legacy_internals.test.ts deleted file mode 100644 index dc72c43470a84..0000000000000 --- a/src/core/server/legacy/legacy_internals.test.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 { httpServerMock } from '../http/http_server.mocks'; -import { LegacyInternals } from './legacy_internals'; -import { ILegacyInternals } from './types'; - -describe('LegacyInternals', () => { - describe('getInjectedUiAppVars()', () => { - let legacyInternals: ILegacyInternals; - - beforeEach(async () => { - legacyInternals = new LegacyInternals(); - }); - - it('gets with no injectors', async () => { - await expect(legacyInternals.getInjectedUiAppVars('core')).resolves.toMatchInlineSnapshot( - `Object {}` - ); - }); - - it('gets with no matching injectors', async () => { - const injector = jest.fn().mockResolvedValue({ not: 'core' }); - legacyInternals.injectUiAppVars('not-core', injector); - - await expect(legacyInternals.getInjectedUiAppVars('core')).resolves.toMatchInlineSnapshot( - `Object {}` - ); - expect(injector).not.toHaveBeenCalled(); - }); - - it('gets with single matching injector', async () => { - const injector = jest.fn().mockResolvedValue({ is: 'core' }); - legacyInternals.injectUiAppVars('core', injector); - - await expect(legacyInternals.getInjectedUiAppVars('core')).resolves.toMatchInlineSnapshot(` - Object { - "is": "core", - } - `); - expect(injector).toHaveBeenCalled(); - }); - - it('gets with multiple matching injectors', async () => { - const injectors = [ - jest.fn().mockResolvedValue({ is: 'core' }), - jest.fn().mockReturnValue({ sync: 'injector' }), - jest.fn().mockResolvedValue({ is: 'merged-core' }), - ]; - - injectors.forEach((injector) => legacyInternals.injectUiAppVars('core', injector)); - - await expect(legacyInternals.getInjectedUiAppVars('core')).resolves.toMatchInlineSnapshot(` - Object { - "is": "merged-core", - "sync": "injector", - } - `); - expect(injectors[0]).toHaveBeenCalled(); - expect(injectors[1]).toHaveBeenCalled(); - expect(injectors[2]).toHaveBeenCalled(); - }); - }); - - describe('getVars()', () => { - let legacyInternals: LegacyInternals; - - beforeEach(async () => { - legacyInternals = new LegacyInternals(); - }); - - it('gets: no default injectors, no injected vars replacers, no ui app injectors, no inject arg', async () => { - const vars = await legacyInternals.getVars('core', httpServerMock.createRawRequest()); - - expect(vars).toMatchInlineSnapshot(`Object {}`); - }); - - it('gets: no default injectors, no injected vars replacers, with ui app injectors, no inject arg', async () => { - legacyInternals.injectUiAppVars('core', async () => ({ is: 'core' })); - legacyInternals.injectUiAppVars('core', () => ({ sync: 'injector' })); - legacyInternals.injectUiAppVars('core', async () => ({ is: 'merged-core' })); - - const vars = await legacyInternals.getVars('core', httpServerMock.createRawRequest()); - - expect(vars).toMatchInlineSnapshot(` - Object { - "is": "merged-core", - "sync": "injector", - } - `); - }); - - it('gets: no default injectors, no injected vars replacers, no ui app injectors, with inject arg', async () => { - const vars = await legacyInternals.getVars('core', httpServerMock.createRawRequest(), { - injected: 'arg', - }); - - expect(vars).toMatchInlineSnapshot(` - Object { - "injected": "arg", - } - `); - }); - }); -}); diff --git a/src/core/server/legacy/legacy_internals.ts b/src/core/server/legacy/legacy_internals.ts deleted file mode 100644 index 47d0c96fb5685..0000000000000 --- a/src/core/server/legacy/legacy_internals.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 { KibanaRequest, LegacyRequest } from '../http'; -import { ILegacyInternals, LegacyVars, VarsInjector } from './types'; -import { mergeVars } from './merge_vars'; - -/** - * @internal - * @deprecated - */ -export class LegacyInternals implements ILegacyInternals { - private readonly injectors = new Map>(); - - constructor() {} - - public injectUiAppVars(id: string, injector: VarsInjector) { - if (!this.injectors.has(id)) { - this.injectors.set(id, new Set()); - } - - this.injectors.get(id)!.add(injector); - } - - public getInjectedUiAppVars(id: string) { - return [...(this.injectors.get(id) || [])].reduce( - async (promise, injector) => ({ - ...(await promise), - ...(await injector()), - }), - Promise.resolve({}) - ); - } - - public async getVars( - id: string, - request: KibanaRequest | LegacyRequest, - injected: LegacyVars = {} - ) { - return mergeVars({}, await this.getInjectedUiAppVars(id), injected); - } -} diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index f1d988025384a..af5ee26207dfd 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -31,14 +31,7 @@ import { CspConfigType, config as cspConfig } from '../csp'; import { DevConfig, DevConfigType, config as devConfig } from '../dev'; import { BasePathProxyServer, HttpConfig, HttpConfigType, config as httpConfig } from '../http'; import { Logger } from '../logging'; -import { - ILegacyInternals, - LegacyServiceSetupDeps, - LegacyServiceStartDeps, - LegacyConfig, - LegacyVars, -} from './types'; -import { LegacyInternals } from './legacy_internals'; +import { LegacyServiceSetupDeps, LegacyServiceStartDeps, LegacyConfig, LegacyVars } from './types'; import { CoreSetup, CoreStart } from '..'; interface LegacyKbnServer { @@ -81,7 +74,6 @@ export class LegacyService implements CoreService { private update$?: ConnectableObservable<[Config, PathConfigType]>; private legacyRawConfig?: LegacyConfig; private settings?: LegacyVars; - public legacyInternals?: ILegacyInternals; constructor(private readonly coreContext: CoreContext) { const { logger, configService } = coreContext; @@ -140,7 +132,6 @@ export class LegacyService implements CoreService { this.legacyRawConfig!.set('server.uuid', setupDeps.core.environment.instanceUuid); this.setupDeps = setupDeps; - this.legacyInternals = new LegacyInternals(); } public async start(startDeps: LegacyServiceStartDeps) { @@ -315,7 +306,6 @@ export class LegacyService implements CoreService { uiPlugins: setupDeps.uiPlugins, elasticsearch: setupDeps.core.elasticsearch, rendering: setupDeps.core.rendering, - legacy: this.legacyInternals, }, logger: this.coreContext.logger, }); diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts index 2dd6a8697b705..12bfddfff1961 100644 --- a/src/core/server/legacy/types.ts +++ b/src/core/server/legacy/types.ts @@ -17,9 +17,6 @@ * under the License. */ -import { Server } from 'hapi'; - -import { KibanaRequest, LegacyRequest } from '../http'; import { InternalCoreSetup, InternalCoreStart } from '../internal_types'; import { PluginsServiceSetup, PluginsServiceStart, UiPlugins } from '../plugins'; import { InternalRenderingServiceSetup } from '../rendering'; @@ -49,33 +46,6 @@ export interface LegacyConfig { set(config: LegacyVars): void; } -/** - * @internal - * @deprecated - */ -export interface VarsProvider { - fn: (server: Server, configValue: any) => LegacyVars; - pluginSpec: { - readConfigValue(config: any, key: string | string[]): any; - }; -} - -/** - * @internal - * @deprecated - */ -export type VarsInjector = () => LegacyVars; - -/** - * @internal - * @deprecated - */ -export type VarsReplacer = ( - vars: LegacyVars, - request: LegacyRequest, - server: Server -) => LegacyVars | Promise; - /** * @public * @deprecated @@ -103,28 +73,3 @@ export interface LegacyServiceSetupConfig { legacyConfig: LegacyConfig; settings: LegacyVars; } - -/** - * @internal - * @deprecated - */ -export interface ILegacyInternals { - /** - * Inject UI app vars for a particular plugin - */ - injectUiAppVars(id: string, injector: VarsInjector): void; - - /** - * Get all the merged injected UI app vars for a particular plugin - */ - getInjectedUiAppVars(id: string): Promise; - - /** - * Get the metadata vars for a particular plugin - */ - getVars( - id: string, - request: KibanaRequest | LegacyRequest, - injected?: LegacyVars - ): Promise; -} diff --git a/src/core/server/rendering/__mocks__/rendering_service.ts b/src/core/server/rendering/__mocks__/rendering_service.ts index 179a09b8619b0..01d084f9ae53c 100644 --- a/src/core/server/rendering/__mocks__/rendering_service.ts +++ b/src/core/server/rendering/__mocks__/rendering_service.ts @@ -27,11 +27,9 @@ export const setupMock: jest.Mocked = { render: jest.fn(), }; export const mockSetup = jest.fn().mockResolvedValue(setupMock); -export const mockStart = jest.fn(); export const mockStop = jest.fn(); export const mockRenderingService: jest.Mocked = { setup: mockSetup, - start: mockStart, stop: mockStop, }; export const RenderingService = jest.fn( diff --git a/src/core/server/rendering/rendering_service.test.ts b/src/core/server/rendering/rendering_service.test.ts index 254bafed5b194..3cd698f54655d 100644 --- a/src/core/server/rendering/rendering_service.test.ts +++ b/src/core/server/rendering/rendering_service.test.ts @@ -72,13 +72,6 @@ describe('RenderingService', () => { registered: { name: 'title' }, }); render = (await service.setup(mockRenderingSetupDeps)).render; - await service.start({ - legacy: { - legacyInternals: { - getVars: () => ({}), - }, - }, - } as any); }); it('renders "core" page', async () => { diff --git a/src/core/server/rendering/rendering_service.tsx b/src/core/server/rendering/rendering_service.tsx index 7997afd83d350..d805e6e529785 100644 --- a/src/core/server/rendering/rendering_service.tsx +++ b/src/core/server/rendering/rendering_service.tsx @@ -20,14 +20,11 @@ import React from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { take } from 'rxjs/operators'; - import { i18n } from '@kbn/i18n'; import { UiPlugins } from '../plugins'; -import { CoreService } from '../../types'; import { CoreContext } from '../core_context'; import { Template } from './views'; -import { LegacyService } from '../legacy'; import { IRenderOptions, RenderingSetupDeps, @@ -36,8 +33,7 @@ import { } from './types'; /** @internal */ -export class RenderingService implements CoreService { - private legacyInternals?: LegacyService['legacyInternals']; +export class RenderingService { constructor(private readonly coreContext: CoreContext) {} public async setup({ @@ -51,9 +47,6 @@ export class RenderingService implements CoreService 'core' }, includeUserSettings = true, vars }: IRenderOptions = {} ) => { - if (!this.legacyInternals) { - throw new Error('Cannot render before "start"'); - } const env = { mode: this.coreContext.env.mode, packageInfo: this.coreContext.env.packageInfo, @@ -86,7 +79,7 @@ export class RenderingService implements CoreService ({ id, @@ -114,10 +107,6 @@ export class RenderingService implements CoreService - new kibana.Plugin({ - config(Joi) { - return Joi.object() - .keys({ - enabled: Joi.boolean().default(true), - delay: Joi.number().required(), - shared: Joi.string(), - }) - .default(); - }, - - uiExports: { - async injectDefaultVars(server, options) { - await Bluebird.delay(options.delay); - return { shared: options.shared }; - }, - }, - }); diff --git a/src/legacy/ui/__tests__/fixtures/plugin_async_foo/package.json b/src/legacy/ui/__tests__/fixtures/plugin_async_foo/package.json deleted file mode 100644 index fc1c8d8088f1b..0000000000000 --- a/src/legacy/ui/__tests__/fixtures/plugin_async_foo/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "plugin_async_foo", - "version": "kibana" -} diff --git a/src/legacy/ui/__tests__/fixtures/plugin_bar/index.js b/src/legacy/ui/__tests__/fixtures/plugin_bar/index.js deleted file mode 100644 index 975a1dc7c92e7..0000000000000 --- a/src/legacy/ui/__tests__/fixtures/plugin_bar/index.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ - -export default (kibana) => - new kibana.Plugin({ - config(Joi) { - return Joi.object() - .keys({ - enabled: Joi.boolean().default(true), - shared: Joi.string(), - }) - .default(); - }, - - uiExports: { - injectDefaultVars(server, options) { - return { shared: options.shared }; - }, - }, - }); diff --git a/src/legacy/ui/__tests__/fixtures/plugin_bar/package.json b/src/legacy/ui/__tests__/fixtures/plugin_bar/package.json deleted file mode 100644 index f79b807990dca..0000000000000 --- a/src/legacy/ui/__tests__/fixtures/plugin_bar/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "plugin_bar", - "version": "kibana" -} diff --git a/src/legacy/ui/__tests__/fixtures/plugin_foo/index.js b/src/legacy/ui/__tests__/fixtures/plugin_foo/index.js deleted file mode 100644 index 975a1dc7c92e7..0000000000000 --- a/src/legacy/ui/__tests__/fixtures/plugin_foo/index.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ - -export default (kibana) => - new kibana.Plugin({ - config(Joi) { - return Joi.object() - .keys({ - enabled: Joi.boolean().default(true), - shared: Joi.string(), - }) - .default(); - }, - - uiExports: { - injectDefaultVars(server, options) { - return { shared: options.shared }; - }, - }, - }); diff --git a/src/legacy/ui/__tests__/fixtures/plugin_foo/package.json b/src/legacy/ui/__tests__/fixtures/plugin_foo/package.json deleted file mode 100644 index c1b7ddd35c9a2..0000000000000 --- a/src/legacy/ui/__tests__/fixtures/plugin_foo/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "plugin_foo", - "version": "kibana" -} diff --git a/src/legacy/ui/__tests__/fixtures/test_app/index.js b/src/legacy/ui/__tests__/fixtures/test_app/index.js deleted file mode 100644 index 3eddefd618ce0..0000000000000 --- a/src/legacy/ui/__tests__/fixtures/test_app/index.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -export default (kibana) => - new kibana.Plugin({ - uiExports: { - app: { - name: 'test_app', - main: 'plugins/test_app/index.js', - }, - - injectDefaultVars() { - return { - from_defaults: true, - }; - }, - }, - init(server) { - server.injectUiAppVars('test_app', () => ({ - from_test_app: true, - })); - }, - }); diff --git a/src/legacy/ui/__tests__/fixtures/test_app/package.json b/src/legacy/ui/__tests__/fixtures/test_app/package.json deleted file mode 100644 index 3aeb029e4f4cc..0000000000000 --- a/src/legacy/ui/__tests__/fixtures/test_app/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "test_app", - "version": "kibana" -} diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index eac9a61d535a2..acf6fdef2698c 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -187,14 +187,14 @@ export function uiRenderMixin(kbnServer, server, config) { const app = { getId: () => 'core' }; const { http } = kbnServer.newPlatform.setup.core; const { savedObjects } = kbnServer.newPlatform.start.core; - const { rendering, legacy } = kbnServer.newPlatform.__internals; + const { rendering } = kbnServer.newPlatform.__internals; const req = KibanaRequest.from(h.request); const uiSettings = kbnServer.newPlatform.start.core.uiSettings.asScopedToClient( savedObjects.getScopedClient(req) ); - const vars = await legacy.getVars(app.getId(), h.request, { + const vars = { apmConfig: getApmConfig(h.request.path), - }); + }; const content = await rendering.render(h.request, uiSettings, { app, includeUserSettings: true, From 91d2a6b5ab59bccb3b146162cfa872403e09b085 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 22 Sep 2020 08:35:58 +0200 Subject: [PATCH 25/29] review comments --- .eslintrc.js | 13 ++-- src/core/server/legacy/legacy_service.ts | 4 -- src/dev/jest/config.js | 1 - src/legacy/server/config/schema.js | 66 +-------------------- src/legacy/server/kbn_server.d.ts | 4 -- x-pack/dev-tools/jest/create_jest_config.js | 4 -- 6 files changed, 6 insertions(+), 86 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index e9e47bc8099b4..d7fabeee74248 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -285,7 +285,7 @@ module.exports = { }, { target: [ - '(src|x-pack)/legacy/**/*', + 'src/legacy/**/*', '(src|x-pack)/plugins/**/(public|server)/**/*', 'examples/**/*', ], @@ -316,14 +316,11 @@ module.exports = { }, { target: [ - '(src|x-pack)/legacy/**/*', + 'src/legacy/**/*', '(src|x-pack)/plugins/**/(public|server)/**/*', 'examples/**/*', '!(src|x-pack)/**/*.test.*', '!(x-pack/)?test/**/*', - // next folder contains legacy browser tests which can't be migrated to jest - // which import np files - '!src/legacy/core_plugins/kibana/public/__tests__/**/*', ], from: [ '(src|x-pack)/plugins/**/(public|server)/**/*', @@ -763,7 +760,7 @@ module.exports = { }, { // typescript only for front and back end - files: ['x-pack/{,legacy/}plugins/security_solution/**/*.{ts,tsx}'], + files: ['x-pack/plugins/security_solution/**/*.{ts,tsx}'], rules: { // This will be turned on after bug fixes are complete // '@typescript-eslint/explicit-member-accessibility': 'warn', @@ -809,7 +806,7 @@ module.exports = { // }, { // typescript and javascript for front and back end - files: ['x-pack/{,legacy/}plugins/security_solution/**/*.{js,mjs,ts,tsx}'], + files: ['x-pack/plugins/security_solution/**/*.{js,mjs,ts,tsx}'], plugins: ['eslint-plugin-node', 'react'], env: { mocha: true, @@ -1040,7 +1037,7 @@ module.exports = { { // typescript only for front and back end files: [ - 'x-pack/{,legacy/}plugins/{alerts,alerting_builtins,actions,task_manager,event_log}/**/*.{ts,tsx}', + 'x-pack/plugins/{alerts,alerting_builtins,actions,task_manager,event_log}/**/*.{ts,tsx}', ], rules: { '@typescript-eslint/no-explicit-any': 'error', diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index af5ee26207dfd..086e20c98c1a3 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -299,12 +299,8 @@ export class LegacyService implements CoreService { plugins: startDeps.plugins, }, __internals: { - http: { - registerStaticDir: setupDeps.core.http.registerStaticDir, - }, hapiServer: setupDeps.core.http.server, uiPlugins: setupDeps.uiPlugins, - elasticsearch: setupDeps.core.elasticsearch, rendering: setupDeps.core.rendering, }, logger: this.coreContext.logger, diff --git a/src/dev/jest/config.js b/src/dev/jest/config.js index 5d31db63773fa..3c556a4f1ba3c 100644 --- a/src/dev/jest/config.js +++ b/src/dev/jest/config.js @@ -55,7 +55,6 @@ export default { '@elastic/eui$': '/node_modules/@elastic/eui/test-env', '@elastic/eui/lib/(.*)?': '/node_modules/@elastic/eui/test-env/$1', '^src/plugins/(.*)': '/src/plugins/$1', - '^uiExports/(.*)': '/src/dev/jest/mocks/file_mock.js', '^test_utils/(.*)': '/src/test_utils/public/$1', '^fixtures/(.*)': '/src/fixtures/$1', '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': diff --git a/src/legacy/server/config/schema.js b/src/legacy/server/config/schema.js index a6fca8fd9bba0..a94766ef06926 100644 --- a/src/legacy/server/config/schema.js +++ b/src/legacy/server/config/schema.js @@ -148,71 +148,7 @@ export default () => allowAnonymous: Joi.boolean().default(false), }).default(), - map: Joi.object({ - includeElasticMapsService: Joi.boolean().default(true), - proxyElasticMapsServiceInMaps: Joi.boolean().default(false), - tilemap: Joi.object({ - url: Joi.string(), - options: Joi.object({ - attribution: Joi.string(), - minZoom: Joi.number().min(0, 'Must be 0 or higher').default(0), - maxZoom: Joi.number().default(10), - tileSize: Joi.number(), - subdomains: Joi.array().items(Joi.string()).single(), - errorTileUrl: Joi.string().uri(), - tms: Joi.boolean(), - reuseTiles: Joi.boolean(), - bounds: Joi.array().items(Joi.array().items(Joi.number()).min(2).required()).min(2), - default: Joi.boolean(), - }).default({ - default: true, - }), - }).default(), - regionmap: Joi.object({ - includeElasticMapsService: Joi.boolean().default(true), - layers: Joi.array() - .items( - Joi.object({ - url: Joi.string(), - format: Joi.object({ - type: Joi.string().default('geojson'), - }).default({ - type: 'geojson', - }), - meta: Joi.object({ - feature_collection_path: Joi.string().default('data'), - }).default({ - feature_collection_path: 'data', - }), - attribution: Joi.string(), - name: Joi.string(), - fields: Joi.array().items( - Joi.object({ - name: Joi.string(), - description: Joi.string(), - }) - ), - }) - ) - .default([]), - }).default(), - manifestServiceUrl: Joi.string().default('').allow(''), - emsFileApiUrl: Joi.string().default('https://vector.maps.elastic.co'), - emsTileApiUrl: Joi.string().default('https://tiles.maps.elastic.co'), - emsLandingPageUrl: Joi.string().default('https://maps.elastic.co/v7.9'), - emsFontLibraryUrl: Joi.string().default( - 'https://tiles.maps.elastic.co/fonts/{fontstack}/{range}.pbf' - ), - emsTileLayerId: Joi.object({ - bright: Joi.string().default('road_map'), - desaturated: Joi.string().default('road_map_desaturated'), - dark: Joi.string().default('dark_map'), - }).default({ - bright: 'road_map', - desaturated: 'road_map_desaturated', - dark: 'dark_map', - }), - }).default(), + map: HANDLED_IN_NEW_PLATFORM, i18n: Joi.object({ locale: Joi.string().default('en'), diff --git a/src/legacy/server/kbn_server.d.ts b/src/legacy/server/kbn_server.d.ts index 462ffe571e117..1718a9a8f55da 100644 --- a/src/legacy/server/kbn_server.d.ts +++ b/src/legacy/server/kbn_server.d.ts @@ -57,7 +57,6 @@ export interface PluginsSetup { export interface KibanaCore { __internals: { - elasticsearch: LegacyServiceSetupDeps['core']['elasticsearch']; hapiServer: LegacyServiceSetupDeps['core']['http']['server']; rendering: LegacyServiceSetupDeps['core']['rendering']; uiPlugins: UiPlugins; @@ -93,8 +92,6 @@ export default class KbnServer { public readonly newPlatform: NewPlatform; public server: Server; public inject: Server['inject']; - public pluginSpecs: any[]; - public uiBundles: any; constructor(settings: Record, config: KibanaConfig, core: KibanaCore); @@ -102,7 +99,6 @@ export default class KbnServer { public mixin(...fns: KbnMixinFunc[]): Promise; public listen(): Promise; public close(): Promise; - public afterPluginsInit(callback: () => void): void; public applyLoggingConfiguration(settings: any): void; public config: KibanaConfig; } diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js index d1631118c4557..eec7b0246d026 100644 --- a/x-pack/dev-tools/jest/create_jest_config.js +++ b/x-pack/dev-tools/jest/create_jest_config.js @@ -14,11 +14,9 @@ export function createJestConfig({ kibanaDirectory, rootDir, xPackKibanaDirector '@elastic/eui$': `${kibanaDirectory}/node_modules/@elastic/eui/test-env`, '@elastic/eui/lib/(.*)?': `${kibanaDirectory}/node_modules/@elastic/eui/test-env/$1`, '^fixtures/(.*)': `${kibanaDirectory}/src/fixtures/$1`, - 'uiExports/(.*)': fileMockPath, '^src/core/(.*)': `${kibanaDirectory}/src/core/$1`, '^src/legacy/(.*)': `${kibanaDirectory}/src/legacy/$1`, '^src/plugins/(.*)': `${kibanaDirectory}/src/plugins/$1`, - '^legacy/plugins/xpack_main/(.*);': `${xPackKibanaDirectory}/legacy/plugins/xpack_main/public/$1`, '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': fileMockPath, '\\.module.(css|scss)$': `${kibanaDirectory}/src/dev/jest/mocks/css_module_mock.js`, '\\.(css|less|scss)$': `${kibanaDirectory}/src/dev/jest/mocks/style_mock.js`, @@ -30,8 +28,6 @@ export function createJestConfig({ kibanaDirectory, rootDir, xPackKibanaDirector '^(!!)?file-loader!': fileMockPath, }, collectCoverageFrom: [ - 'legacy/plugins/**/*.{js,mjs,jsx,ts,tsx}', - 'legacy/server/**/*.{js,mjs,jsx,ts,tsx}', 'plugins/**/*.{js,mjs,jsx,ts,tsx}', '!**/{__test__,__snapshots__,__examples__,integration_tests,tests}/**', '!**/*.test.{js,mjs,ts,tsx}', From a570f53c65583396941cb73a76d38e2dd4fa7772 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 22 Sep 2020 08:39:32 +0200 Subject: [PATCH 26/29] update generated doc --- .../public/kibana-plugin-plugins-data-public.md | 6 +++--- src/core/server/server.api.md | 15 --------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index f51549c81fb62..71f66a1b46d85 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -57,7 +57,6 @@ | [EsQueryConfig](./kibana-plugin-plugins-data-public.esqueryconfig.md) | | | [FieldFormatConfig](./kibana-plugin-plugins-data-public.fieldformatconfig.md) | | | [FieldMappingSpec](./kibana-plugin-plugins-data-public.fieldmappingspec.md) | | -| [Filter](./kibana-plugin-plugins-data-public.filter.md) | | | [IDataPluginServices](./kibana-plugin-plugins-data-public.idatapluginservices.md) | | | [IEsSearchRequest](./kibana-plugin-plugins-data-public.iessearchrequest.md) | | | [IEsSearchResponse](./kibana-plugin-plugins-data-public.iessearchresponse.md) | | @@ -75,7 +74,6 @@ | [ISearchStartSearchSource](./kibana-plugin-plugins-data-public.isearchstartsearchsource.md) | high level search service | | [KueryNode](./kibana-plugin-plugins-data-public.kuerynode.md) | | | [OptionedValueProp](./kibana-plugin-plugins-data-public.optionedvalueprop.md) | | -| [Query](./kibana-plugin-plugins-data-public.query.md) | | | [QueryState](./kibana-plugin-plugins-data-public.querystate.md) | All query state service state | | [QueryStateChange](./kibana-plugin-plugins-data-public.querystatechange.md) | | | [QuerySuggestionBasic](./kibana-plugin-plugins-data-public.querysuggestionbasic.md) | \* | @@ -90,7 +88,6 @@ | [SearchSourceFields](./kibana-plugin-plugins-data-public.searchsourcefields.md) | search source fields | | [TabbedAggColumn](./kibana-plugin-plugins-data-public.tabbedaggcolumn.md) | \* | | [TabbedTable](./kibana-plugin-plugins-data-public.tabbedtable.md) | \* | -| [TimeRange](./kibana-plugin-plugins-data-public.timerange.md) | | ## Variables @@ -145,6 +142,7 @@ | [FieldFormatsContentType](./kibana-plugin-plugins-data-public.fieldformatscontenttype.md) | \* | | [FieldFormatsGetConfigFn](./kibana-plugin-plugins-data-public.fieldformatsgetconfigfn.md) | | | [FieldFormatsStart](./kibana-plugin-plugins-data-public.fieldformatsstart.md) | | +| [Filter](./kibana-plugin-plugins-data-public.filter.md) | | | [IAggConfig](./kibana-plugin-plugins-data-public.iaggconfig.md) | AggConfig This class represents an aggregation, which is displayed in the left-hand nav of the Visualize app. | | [IAggType](./kibana-plugin-plugins-data-public.iaggtype.md) | | | [IFieldFormat](./kibana-plugin-plugins-data-public.ifieldformat.md) | | @@ -162,6 +160,7 @@ | [ParsedInterval](./kibana-plugin-plugins-data-public.parsedinterval.md) | | | [PhraseFilter](./kibana-plugin-plugins-data-public.phrasefilter.md) | | | [PhrasesFilter](./kibana-plugin-plugins-data-public.phrasesfilter.md) | | +| [Query](./kibana-plugin-plugins-data-public.query.md) | | | [QueryStart](./kibana-plugin-plugins-data-public.querystart.md) | | | [QuerySuggestion](./kibana-plugin-plugins-data-public.querysuggestion.md) | \* | | [QuerySuggestionGetFn](./kibana-plugin-plugins-data-public.querysuggestiongetfn.md) | | @@ -173,4 +172,5 @@ | [TabbedAggRow](./kibana-plugin-plugins-data-public.tabbedaggrow.md) | \* | | [TimefilterContract](./kibana-plugin-plugins-data-public.timefiltercontract.md) | | | [TimeHistoryContract](./kibana-plugin-plugins-data-public.timehistorycontract.md) | | +| [TimeRange](./kibana-plugin-plugins-data-public.timerange.md) | | diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index b284c38c9cfeb..2154f978e6be7 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1286,21 +1286,6 @@ export class LegacyElasticsearchErrorHelpers { static isNotAuthorizedError(error: any): error is LegacyElasticsearchError; } -// Warning: (ae-forgotten-export) The symbol "ILegacyInternals" needs to be exported by the entry point index.d.ts -// -// @internal @deprecated (undocumented) -export class LegacyInternals implements ILegacyInternals { - constructor(); - // (undocumented) - getInjectedUiAppVars(id: string): Promise>; - // (undocumented) - getVars(id: string, request: KibanaRequest | LegacyRequest, injected?: LegacyVars): Promise>; - // Warning: (ae-forgotten-export) The symbol "VarsInjector" needs to be exported by the entry point index.d.ts - // - // (undocumented) - injectUiAppVars(id: string, injector: VarsInjector): void; -} - // @public @deprecated (undocumented) export interface LegacyRequest extends Request { } From ccf62c799e1a3ff51296151470ea024ba82a9ced Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 22 Sep 2020 09:24:56 +0200 Subject: [PATCH 27/29] cleanup legacy metadatas --- .../injected_metadata_service.ts | 25 ----------- .../rendering_service.test.ts.snap | 45 ------------------- .../rendering/rendering_service.test.ts | 6 --- .../server/rendering/rendering_service.tsx | 12 +---- src/core/server/rendering/types.ts | 17 ------- src/legacy/ui/ui_render/ui_render_mixin.js | 2 - 6 files changed, 1 insertion(+), 106 deletions(-) diff --git a/src/core/public/injected_metadata/injected_metadata_service.ts b/src/core/public/injected_metadata/injected_metadata_service.ts index 5b51bc823d166..bd8c9e91f15a2 100644 --- a/src/core/public/injected_metadata/injected_metadata_service.ts +++ b/src/core/public/injected_metadata/injected_metadata_service.ts @@ -58,19 +58,6 @@ export interface InjectedMetadataParams { uiPlugins: InjectedPluginMetadata[]; anonymousStatusPage: boolean; legacyMetadata: { - app: { - id: string; - title: string; - }; - bundleId: string; - version: string; - branch: string; - buildNum: number; - buildSha: string; - basePath: string; - serverName: string; - devMode: boolean; - category?: AppCategory; uiSettings: { defaults: Record; user?: Record; @@ -167,18 +154,6 @@ export interface InjectedMetadataSetup { getPlugins: () => InjectedPluginMetadata[]; getAnonymousStatusPage: () => boolean; getLegacyMetadata: () => { - app: { - id: string; - title: string; - }; - bundleId: string; - version: string; - branch: string; - buildNum: number; - buildSha: string; - basePath: string; - serverName: string; - devMode: boolean; uiSettings: { defaults: Record; user?: Record | undefined; diff --git a/src/core/server/rendering/__snapshots__/rendering_service.test.ts.snap b/src/core/server/rendering/__snapshots__/rendering_service.test.ts.snap index 5075e215e60f9..07ca59a48c6b0 100644 --- a/src/core/server/rendering/__snapshots__/rendering_service.test.ts.snap +++ b/src/core/server/rendering/__snapshots__/rendering_service.test.ts.snap @@ -27,14 +27,6 @@ Object { "translationsUrl": "/mock-server-basepath/translations/en.json", }, "legacyMetadata": Object { - "app": Object {}, - "basePath": "/mock-server-basepath", - "branch": Any, - "buildNum": Any, - "buildSha": Any, - "bundleId": "app:core", - "devMode": true, - "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { "registered": Object { @@ -43,7 +35,6 @@ Object { }, "user": Object {}, }, - "version": Any, }, "serverBasePath": "/mock-server-basepath", "uiPlugins": Array [], @@ -79,14 +70,6 @@ Object { "translationsUrl": "/mock-server-basepath/translations/en.json", }, "legacyMetadata": Object { - "app": Object {}, - "basePath": "/mock-server-basepath", - "branch": Any, - "buildNum": Any, - "buildSha": Any, - "bundleId": "app:core", - "devMode": true, - "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { "registered": Object { @@ -95,7 +78,6 @@ Object { }, "user": Object {}, }, - "version": Any, }, "serverBasePath": "/mock-server-basepath", "uiPlugins": Array [], @@ -131,14 +113,6 @@ Object { "translationsUrl": "/mock-server-basepath/translations/en.json", }, "legacyMetadata": Object { - "app": Object {}, - "basePath": "/mock-server-basepath", - "branch": Any, - "buildNum": Any, - "buildSha": Any, - "bundleId": "app:core", - "devMode": true, - "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { "registered": Object { @@ -151,7 +125,6 @@ Object { }, }, }, - "version": Any, }, "serverBasePath": "/mock-server-basepath", "uiPlugins": Array [], @@ -187,14 +160,6 @@ Object { "translationsUrl": "/translations/en.json", }, "legacyMetadata": Object { - "app": Object {}, - "basePath": "", - "branch": Any, - "buildNum": Any, - "buildSha": Any, - "bundleId": "app:core", - "devMode": true, - "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { "registered": Object { @@ -203,7 +168,6 @@ Object { }, "user": Object {}, }, - "version": Any, }, "serverBasePath": "/mock-server-basepath", "uiPlugins": Array [], @@ -239,14 +203,6 @@ Object { "translationsUrl": "/mock-server-basepath/translations/en.json", }, "legacyMetadata": Object { - "app": Object {}, - "basePath": "/mock-server-basepath", - "branch": Any, - "buildNum": Any, - "buildSha": Any, - "bundleId": "app:core", - "devMode": true, - "serverName": "http-server-test", "uiSettings": Object { "defaults": Object { "registered": Object { @@ -255,7 +211,6 @@ Object { }, "user": Object {}, }, - "version": Any, }, "serverBasePath": "/mock-server-basepath", "uiPlugins": Array [], diff --git a/src/core/server/rendering/rendering_service.test.ts b/src/core/server/rendering/rendering_service.test.ts index 3cd698f54655d..08978cd1df64d 100644 --- a/src/core/server/rendering/rendering_service.test.ts +++ b/src/core/server/rendering/rendering_service.test.ts @@ -43,12 +43,6 @@ const INJECTED_METADATA = { version: expect.any(String), }, }, - legacyMetadata: { - branch: expect.any(String), - buildNum: expect.any(Number), - buildSha: expect.any(String), - version: expect.any(String), - }, }; const { createKibanaRequest, createRawRequest } = httpServerMock; diff --git a/src/core/server/rendering/rendering_service.tsx b/src/core/server/rendering/rendering_service.tsx index d805e6e529785..738787f940905 100644 --- a/src/core/server/rendering/rendering_service.tsx +++ b/src/core/server/rendering/rendering_service.tsx @@ -45,7 +45,7 @@ export class RenderingService { render: async ( request, uiSettings, - { app = { getId: () => 'core' }, includeUserSettings = true, vars }: IRenderOptions = {} + { includeUserSettings = true, vars }: IRenderOptions = {} ) => { const env = { mode: this.coreContext.env.mode, @@ -57,7 +57,6 @@ export class RenderingService { defaults: uiSettings.getRegistered(), user: includeUserSettings ? await uiSettings.getUserProvided() : {}, }; - const appId = app.getId(); const metadata: RenderingMetadata = { strictCsp: http.csp.strict, uiPublicUrl: `${basePath}/ui`, @@ -88,15 +87,6 @@ export class RenderingService { })) ), legacyMetadata: { - app, - bundleId: `app:${appId}`, - version: env.packageInfo.version, - branch: env.packageInfo.branch, - buildNum: env.packageInfo.buildNum, - buildSha: env.packageInfo.buildSha, - serverName: http.server.name, - devMode: env.mode.dev, - basePath, uiSettings: settings, }, }, diff --git a/src/core/server/rendering/types.ts b/src/core/server/rendering/types.ts index 3e30b318f785c..75bbac1a243e9 100644 --- a/src/core/server/rendering/types.ts +++ b/src/core/server/rendering/types.ts @@ -56,15 +56,6 @@ export interface RenderingMetadata { config?: Record; }>; legacyMetadata: { - app: { getId(): string }; - bundleId: string; - version: string; - branch: string; - buildNum: number; - buildSha: string; - serverName: string; - devMode: boolean; - basePath: string; uiSettings: { defaults: Record; user: Record>; @@ -88,14 +79,6 @@ export interface IRenderOptions { */ includeUserSettings?: boolean; - /** - * Render the bootstrapped HTML content for an optional legacy application. - * Defaults to `core`. - * @deprecated for legacy use only, remove with ui_render_mixin - * @internal - */ - app?: { getId(): string }; - /** * Inject custom vars into the page metadata. * @deprecated for legacy use only, remove with ui_render_mixin diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index acf6fdef2698c..2983dbbc28667 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -184,7 +184,6 @@ export function uiRenderMixin(kbnServer, server, config) { }); async function renderApp(h) { - const app = { getId: () => 'core' }; const { http } = kbnServer.newPlatform.setup.core; const { savedObjects } = kbnServer.newPlatform.start.core; const { rendering } = kbnServer.newPlatform.__internals; @@ -196,7 +195,6 @@ export function uiRenderMixin(kbnServer, server, config) { apmConfig: getApmConfig(h.request.path), }; const content = await rendering.render(h.request, uiSettings, { - app, includeUserSettings: true, vars, }); From 18bb41ced7a2c8fc4fbb49f318acade5fdeb9693 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 22 Sep 2020 09:30:14 +0200 Subject: [PATCH 28/29] revert changes to eslintrc --- .eslintrc.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index d7fabeee74248..3778bd374da61 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -419,6 +419,15 @@ module.exports = { // instructs import/no-extraneous-dependencies to treat certain modules // as core modules, even if they aren't listed in package.json 'import/core-modules': ['plugins'], + + 'import/resolver': { + '@kbn/eslint-import-resolver-kibana': { + forceNode: false, + rootPackageName: 'kibana', + kibanaPath: '.', + pluginMap: {}, + }, + }, }, }, From ca6412ca4c39336ec3fdf08f22b6da9f37e92ff3 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Tue, 22 Sep 2020 09:30:38 +0200 Subject: [PATCH 29/29] update generated doc --- src/core/server/server.api.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 2154f978e6be7..a76a6a17c3c54 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -864,10 +864,6 @@ export interface IndexSettingsDeprecationInfo { // @public (undocumented) export interface IRenderOptions { - // @internal @deprecated - app?: { - getId(): string; - }; includeUserSettings?: boolean; // @internal @deprecated vars?: Record;