mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Co-authored-by: Alejandro Fernández Haro <alejandro.haro@elastic.co>
This commit is contained in:
parent
6af011eb8b
commit
35ffb8b88c
3 changed files with 110 additions and 45 deletions
|
@ -340,7 +340,7 @@ test('throws if reading "enabled" when it is not present in the schema', async (
|
|||
})
|
||||
);
|
||||
|
||||
expect(
|
||||
await expect(
|
||||
async () => await configService.isEnabledAtPath('foo')
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"[config validation of [foo].enabled]: definition for this key is missing"`
|
||||
|
@ -357,7 +357,7 @@ test('throws if reading "enabled" when no schema exists', async () => {
|
|||
const rawConfigProvider = rawConfigServiceMock.create({ rawConfig: initialConfig });
|
||||
const configService = new ConfigService(rawConfigProvider, defaultEnv, logger);
|
||||
|
||||
expect(
|
||||
await expect(
|
||||
async () => await configService.isEnabledAtPath('foo')
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(`"No validation schema has been defined for [foo]"`);
|
||||
});
|
||||
|
@ -372,7 +372,7 @@ test('throws if reading any config value when no schema exists', async () => {
|
|||
const rawConfigProvider = rawConfigServiceMock.create({ rawConfig: initialConfig });
|
||||
const configService = new ConfigService(rawConfigProvider, defaultEnv, logger);
|
||||
|
||||
expect(
|
||||
await expect(
|
||||
async () => await configService.isEnabledAtPath('foo')
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(`"No validation schema has been defined for [foo]"`);
|
||||
});
|
||||
|
|
|
@ -25,7 +25,7 @@ import { PluginsService } from './plugins_service';
|
|||
import { PluginsSystem } from './plugins_system';
|
||||
import { config } from './plugins_config';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { DiscoveredPlugin, PluginType } from './types';
|
||||
import { DiscoveredPlugin, PluginConfigDescriptor, PluginType } from './types';
|
||||
|
||||
const MockPluginsSystem: jest.Mock<PluginsSystem<PluginType>> = PluginsSystem as any;
|
||||
|
||||
|
@ -1065,6 +1065,65 @@ describe('PluginsService', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('"root" deprecations from one plugin should be applied before accessing other plugins config', async () => {
|
||||
const pluginA = createPlugin('plugin-1-deprecations', {
|
||||
type: PluginType.standard,
|
||||
path: 'plugin-1-deprecations',
|
||||
version: 'version-1',
|
||||
});
|
||||
|
||||
const pluginB = createPlugin('plugin-2-deprecations', {
|
||||
type: PluginType.standard,
|
||||
path: 'plugin-2-deprecations',
|
||||
version: 'version-2',
|
||||
});
|
||||
|
||||
jest.doMock(
|
||||
join(pluginA.path, 'server'),
|
||||
() => ({
|
||||
config: {
|
||||
schema: schema.object({
|
||||
enabled: schema.maybe(schema.boolean({ defaultValue: true })),
|
||||
}),
|
||||
},
|
||||
}),
|
||||
{ virtual: true }
|
||||
);
|
||||
|
||||
jest.doMock(
|
||||
join(pluginB.path, 'server'),
|
||||
(): { config: PluginConfigDescriptor } => ({
|
||||
config: {
|
||||
schema: schema.object({
|
||||
enabled: schema.maybe(schema.boolean({ defaultValue: true })),
|
||||
renamed: schema.string(), // Mandatory string to make sure that the field is actually renamed by deprecations
|
||||
}),
|
||||
deprecations: ({ renameFromRoot }) => [
|
||||
renameFromRoot('plugin-1-deprecations.toBeRenamed', 'plugin-2-deprecations.renamed'),
|
||||
],
|
||||
},
|
||||
}),
|
||||
{ virtual: true }
|
||||
);
|
||||
|
||||
mockDiscover.mockReturnValue({
|
||||
error$: from([]),
|
||||
plugin$: from([pluginA, pluginB]),
|
||||
});
|
||||
|
||||
config$.next({
|
||||
'plugin-1-deprecations': {
|
||||
toBeRenamed: 'renamed',
|
||||
},
|
||||
});
|
||||
|
||||
await expect(
|
||||
pluginsService.discover({
|
||||
environment: environmentPreboot,
|
||||
})
|
||||
).resolves.not.toThrow(); // If the rename is not applied, it'll fail
|
||||
});
|
||||
|
||||
describe('plugin initialization', () => {
|
||||
beforeEach(() => {
|
||||
const prebootPlugins = [
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import Path from 'path';
|
||||
import { Observable } from 'rxjs';
|
||||
import { concatMap, filter, first, map, tap, toArray } from 'rxjs/operators';
|
||||
import { filter, first, map, tap, toArray } from 'rxjs/operators';
|
||||
import { getFlattenedObject, pick } from '@kbn/std';
|
||||
|
||||
import { CoreService } from '../../types';
|
||||
|
@ -271,50 +271,56 @@ export class PluginsService implements CoreService<PluginsServiceSetup, PluginsS
|
|||
PluginName,
|
||||
{ plugin: PluginWrapper; isEnabled: boolean }
|
||||
>();
|
||||
await plugin$
|
||||
.pipe(
|
||||
concatMap(async (plugin) => {
|
||||
const configDescriptor = plugin.getConfigDescriptor();
|
||||
if (configDescriptor) {
|
||||
this.pluginConfigDescriptors.set(plugin.name, configDescriptor);
|
||||
if (configDescriptor.deprecations) {
|
||||
this.coreContext.configService.addDeprecationProvider(
|
||||
plugin.configPath,
|
||||
configDescriptor.deprecations
|
||||
);
|
||||
}
|
||||
if (configDescriptor.exposeToUsage) {
|
||||
this.pluginConfigUsageDescriptors.set(
|
||||
Array.isArray(plugin.configPath) ? plugin.configPath.join('.') : plugin.configPath,
|
||||
getFlattenedObject(configDescriptor.exposeToUsage)
|
||||
);
|
||||
}
|
||||
this.coreContext.configService.setSchema(plugin.configPath, configDescriptor.schema);
|
||||
}
|
||||
const isEnabled = await this.coreContext.configService.isEnabledAtPath(plugin.configPath);
|
||||
const plugins = await plugin$.pipe(toArray()).toPromise();
|
||||
|
||||
if (pluginEnableStatuses.has(plugin.name)) {
|
||||
throw new Error(`Plugin with id "${plugin.name}" is already registered!`);
|
||||
}
|
||||
// Register config descriptors and deprecations
|
||||
for (const plugin of plugins) {
|
||||
const configDescriptor = plugin.getConfigDescriptor();
|
||||
if (configDescriptor) {
|
||||
this.pluginConfigDescriptors.set(plugin.name, configDescriptor);
|
||||
if (configDescriptor.deprecations) {
|
||||
this.coreContext.configService.addDeprecationProvider(
|
||||
plugin.configPath,
|
||||
configDescriptor.deprecations
|
||||
);
|
||||
}
|
||||
if (configDescriptor.exposeToUsage) {
|
||||
this.pluginConfigUsageDescriptors.set(
|
||||
Array.isArray(plugin.configPath) ? plugin.configPath.join('.') : plugin.configPath,
|
||||
getFlattenedObject(configDescriptor.exposeToUsage)
|
||||
);
|
||||
}
|
||||
this.coreContext.configService.setSchema(plugin.configPath, configDescriptor.schema);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.includesUiPlugin) {
|
||||
const uiPluginInternalInfo =
|
||||
plugin.manifest.type === PluginType.preboot
|
||||
? this.prebootUiPluginInternalInfo
|
||||
: this.standardUiPluginInternalInfo;
|
||||
uiPluginInternalInfo.set(plugin.name, {
|
||||
requiredBundles: plugin.requiredBundles,
|
||||
version: plugin.manifest.version,
|
||||
publicTargetDir: Path.resolve(plugin.path, 'target/public'),
|
||||
publicAssetsDir: Path.resolve(plugin.path, 'public/assets'),
|
||||
});
|
||||
}
|
||||
// Validate config and handle enabled statuses.
|
||||
// NOTE: We can't do both in the same previous loop because some plugins' deprecations may affect others.
|
||||
// Hence, we need all the deprecations to be registered before accessing any config parameter.
|
||||
for (const plugin of plugins) {
|
||||
const isEnabled = await this.coreContext.configService.isEnabledAtPath(plugin.configPath);
|
||||
|
||||
pluginEnableStatuses.set(plugin.name, { plugin, isEnabled });
|
||||
})
|
||||
)
|
||||
.toPromise();
|
||||
if (pluginEnableStatuses.has(plugin.name)) {
|
||||
throw new Error(`Plugin with id "${plugin.name}" is already registered!`);
|
||||
}
|
||||
|
||||
if (plugin.includesUiPlugin) {
|
||||
const uiPluginInternalInfo =
|
||||
plugin.manifest.type === PluginType.preboot
|
||||
? this.prebootUiPluginInternalInfo
|
||||
: this.standardUiPluginInternalInfo;
|
||||
uiPluginInternalInfo.set(plugin.name, {
|
||||
requiredBundles: plugin.requiredBundles,
|
||||
version: plugin.manifest.version,
|
||||
publicTargetDir: Path.resolve(plugin.path, 'target/public'),
|
||||
publicAssetsDir: Path.resolve(plugin.path, 'public/assets'),
|
||||
});
|
||||
}
|
||||
|
||||
pluginEnableStatuses.set(plugin.name, { plugin, isEnabled });
|
||||
}
|
||||
|
||||
// Add the plugins to the Plugin System if enabled and its dependencies are met
|
||||
for (const [pluginName, { plugin, isEnabled }] of pluginEnableStatuses) {
|
||||
this.validatePluginDependencies(plugin, pluginEnableStatuses);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue