Kibana property config migrations (#55937)

* Move defaultAppId config param into kibanaLegacy
* Move disableWelcomeScreen config param into Home plugin
* Update api and docs with silent option for renameFromRoot
This commit is contained in:
Nick Partridge 2020-02-03 22:17:27 -06:00 committed by GitHub
parent 0f117c9c32
commit 186a82669f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 257 additions and 57 deletions

View file

@ -30,7 +30,7 @@ const provider: ConfigDeprecationProvider = ({ rename, unused }) => [
| Method | Description |
| --- | --- |
| [rename(oldKey, newKey)](./kibana-plugin-server.configdeprecationfactory.rename.md) | Rename a configuration property from inside a plugin's configuration path. Will log a deprecation warning if the oldKey was found and deprecation applied. |
| [renameFromRoot(oldKey, newKey)](./kibana-plugin-server.configdeprecationfactory.renamefromroot.md) | Rename a configuration property from the root configuration. Will log a deprecation warning if the oldKey was found and deprecation applied.<!-- -->This should be only used when renaming properties from different configuration's path. To rename properties from inside a plugin's configuration, use 'rename' instead. |
| [renameFromRoot(oldKey, newKey, silent)](./kibana-plugin-server.configdeprecationfactory.renamefromroot.md) | Rename a configuration property from the root configuration. Will log a deprecation warning if the oldKey was found and deprecation applied.<!-- -->This should be only used when renaming properties from different configuration's path. To rename properties from inside a plugin's configuration, use 'rename' instead. |
| [unused(unusedKey)](./kibana-plugin-server.configdeprecationfactory.unused.md) | Remove a configuration property from inside a plugin's configuration path. Will log a deprecation warning if the unused key was found and deprecation applied. |
| [unusedFromRoot(unusedKey)](./kibana-plugin-server.configdeprecationfactory.unusedfromroot.md) | Remove a configuration property from the root configuration. Will log a deprecation warning if the unused key was found and deprecation applied.<!-- -->This should be only used when removing properties from outside of a plugin's configuration. To remove properties from inside a plugin's configuration, use 'unused' instead. |

View file

@ -11,7 +11,7 @@ This should be only used when renaming properties from different configuration's
<b>Signature:</b>
```typescript
renameFromRoot(oldKey: string, newKey: string): ConfigDeprecation;
renameFromRoot(oldKey: string, newKey: string, silent?: boolean): ConfigDeprecation;
```
## Parameters
@ -20,6 +20,7 @@ renameFromRoot(oldKey: string, newKey: string): ConfigDeprecation;
| --- | --- | --- |
| oldKey | <code>string</code> | |
| newKey | <code>string</code> | |
| silent | <code>boolean</code> | |
<b>Returns:</b>

View file

@ -26,7 +26,8 @@ const _rename = (
rootPath: string,
log: ConfigDeprecationLogger,
oldKey: string,
newKey: string
newKey: string,
silent?: boolean
) => {
const fullOldPath = getPath(rootPath, oldKey);
const oldValue = get(config, fullOldPath);
@ -40,11 +41,16 @@ const _rename = (
const newValue = get(config, fullNewPath);
if (newValue === undefined) {
set(config, fullNewPath, oldValue);
log(`"${fullOldPath}" is deprecated and has been replaced by "${fullNewPath}"`);
if (!silent) {
log(`"${fullOldPath}" is deprecated and has been replaced by "${fullNewPath}"`);
}
} else {
log(
`"${fullOldPath}" is deprecated and has been replaced by "${fullNewPath}". However both key are present, ignoring "${fullOldPath}"`
);
if (!silent) {
log(
`"${fullOldPath}" is deprecated and has been replaced by "${fullNewPath}". However both key are present, ignoring "${fullOldPath}"`
);
}
}
return config;
};
@ -67,11 +73,11 @@ const _unused = (
const rename = (oldKey: string, newKey: string): ConfigDeprecation => (config, rootPath, log) =>
_rename(config, rootPath, log, oldKey, newKey);
const renameFromRoot = (oldKey: string, newKey: string): ConfigDeprecation => (
const renameFromRoot = (oldKey: string, newKey: string, silent?: boolean): ConfigDeprecation => (
config,
rootPath,
log
) => _rename(config, '', log, oldKey, newKey);
) => _rename(config, '', log, oldKey, newKey, silent);
const unused = (unusedKey: string): ConfigDeprecation => (config, rootPath, log) =>
_unused(config, rootPath, log, unusedKey);

View file

@ -102,7 +102,7 @@ export interface ConfigDeprecationFactory {
* ]
* ```
*/
renameFromRoot(oldKey: string, newKey: string): ConfigDeprecation;
renameFromRoot(oldKey: string, newKey: string, silent?: boolean): ConfigDeprecation;
/**
* Remove a configuration property from inside a plugin's configuration path.
* Will log a deprecation warning if the unused key was found and deprecation applied.

View file

@ -25,9 +25,7 @@ export const config = {
path: 'kibana',
schema: schema.object({
enabled: schema.boolean({ defaultValue: true }),
defaultAppId: schema.string({ defaultValue: 'home' }),
index: schema.string({ defaultValue: '.kibana' }),
disableWelcomeScreen: schema.boolean({ defaultValue: false }),
autocompleteTerminateAfter: schema.duration({ defaultValue: 100000 }),
autocompleteTimeout: schema.duration({ defaultValue: 1000 }),
}),

View file

@ -43,7 +43,7 @@ import { uuidServiceMock } from './uuid/uuid_service.mock';
export function pluginInitializerContextConfigMock<T>(config: T) {
const globalConfig: SharedGlobalConfig = {
kibana: { defaultAppId: 'home-mocks', index: '.kibana-tests' },
kibana: { index: '.kibana-tests' },
elasticsearch: {
shardTimeout: duration('30s'),
requestTimeout: duration('30s'),

View file

@ -75,7 +75,7 @@ describe('Plugin Context', () => {
.pipe(first())
.toPromise();
expect(configObject).toStrictEqual({
kibana: { defaultAppId: 'home', index: '.kibana' },
kibana: { index: '.kibana' },
elasticsearch: {
shardTimeout: duration(30, 's'),
requestTimeout: duration(30, 's'),

View file

@ -214,7 +214,7 @@ export interface Plugin<
export const SharedGlobalConfigKeys = {
// We can add more if really needed
kibana: ['defaultAppId', 'index'] as const,
kibana: ['index'] as const,
elasticsearch: ['shardTimeout', 'requestTimeout', 'pingTimeout', 'startupTimeout'] as const,
path: ['data'] as const,
};

View file

@ -509,7 +509,7 @@ export type ConfigDeprecation = (config: Record<string, any>, fromPath: string,
// @public
export interface ConfigDeprecationFactory {
rename(oldKey: string, newKey: string): ConfigDeprecation;
renameFromRoot(oldKey: string, newKey: string): ConfigDeprecation;
renameFromRoot(oldKey: string, newKey: string, silent?: boolean): ConfigDeprecation;
unused(unusedKey: string): ConfigDeprecation;
unusedFromRoot(unusedKey: string): ConfigDeprecation;
}

View file

@ -42,9 +42,7 @@ export default function(kibana) {
config: function(Joi) {
return Joi.object({
enabled: Joi.boolean().default(true),
defaultAppId: Joi.string().default('home'),
index: Joi.string().default('.kibana'),
disableWelcomeScreen: Joi.boolean().default(false),
autocompleteTerminateAfter: Joi.number()
.integer()
.min(1)

View file

@ -28,8 +28,6 @@ export function injectVars(server) {
);
return {
kbnDefaultAppId: serverConfig.get('kibana.defaultAppId'),
disableWelcomeScreen: serverConfig.get('kibana.disableWelcomeScreen'),
importAndExportableTypes,
autocompleteTerminateAfter: serverConfig.get('kibana.autocompleteTerminateAfter'),
autocompleteTimeout: serverConfig.get('kibana.autocompleteTimeout'),

View file

@ -46,6 +46,7 @@ import { IEmbeddableStart } from '../../../../../../plugins/embeddable/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../../plugins/navigation/public';
import { DataPublicPluginStart as NpDataStart } from '../../../../../../plugins/data/public';
import { SharePluginStart } from '../../../../../../plugins/share/public';
import { KibanaLegacyStart } from '../../../../../../plugins/kibana_legacy/public';
export interface RenderDeps {
core: LegacyCoreStart;
@ -62,6 +63,7 @@ export interface RenderDeps {
embeddables: IEmbeddableStart;
localStorage: Storage;
share: SharePluginStart;
config: KibanaLegacyStart['config'];
}
let angularModuleInstance: IModule | null = null;

View file

@ -88,7 +88,6 @@ export interface DashboardAppScope extends ng.IScope {
export function initDashboardAppDirective(app: any, deps: RenderDeps) {
app.directive('dashboardApp', function($injector: IInjector) {
const confirmModal = $injector.get<ConfirmModalFn>('confirmModal');
const config = deps.uiSettings;
return {
restrict: 'E',
@ -106,7 +105,6 @@ export function initDashboardAppDirective(app: any, deps: RenderDeps) {
$route,
$scope,
$routeParams,
config,
confirmModal,
indexPatterns: deps.npDataStart.indexPatterns,
kbnUrlStateStorage,

View file

@ -90,7 +90,6 @@ export interface DashboardAppControllerDependencies extends RenderDeps {
$routeParams: any;
indexPatterns: IndexPatternsContract;
dashboardConfig: any;
config: any;
confirmModal: ConfirmModalFn;
history: History;
kbnUrlStateStorage: IKbnUrlStateStorage;
@ -109,7 +108,6 @@ export class DashboardAppController {
dashboardConfig,
localStorage,
indexPatterns,
config,
confirmModal,
savedQueryService,
embeddables,
@ -376,7 +374,7 @@ export class DashboardAppController {
dashboardStateManager.getQuery() || {
query: '',
language:
localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage'),
localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'),
},
queryFilter.getFilters()
);
@ -493,7 +491,7 @@ export class DashboardAppController {
{
query: '',
language:
localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage'),
localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'),
},
queryFilter.getGlobalFilters()
);

View file

@ -246,10 +246,10 @@ export function initDashboardApp(app, deps) {
},
})
.when(`dashboard/:tail*?`, {
redirectTo: `/${deps.core.injectedMetadata.getInjectedVar('kbnDefaultAppId')}`,
redirectTo: `/${deps.config.defaultAppId}`,
})
.when(`dashboards/:tail*?`, {
redirectTo: `/${deps.core.injectedMetadata.getInjectedVar('kbnDefaultAppId')}`,
redirectTo: `/${deps.config.defaultAppId}`,
});
});
}

View file

@ -107,6 +107,7 @@ export class DashboardPlugin implements Plugin {
chrome: contextCore.chrome,
addBasePath: contextCore.http.basePath.prepend,
uiSettings: contextCore.uiSettings,
config: kibana_legacy.config,
savedQueryService: npDataStart.query.savedQueries,
embeddables,
dashboardCapabilities: contextCore.application.capabilities.dashboard,

View file

@ -29,7 +29,12 @@ import {
UiSettingsState,
} from 'kibana/public';
import { UiStatsMetricType } from '@kbn/analytics';
import { Environment, FeatureCatalogueEntry } from '../../../../../plugins/home/public';
import {
Environment,
FeatureCatalogueEntry,
HomePublicPluginSetup,
} from '../../../../../plugins/home/public';
import { KibanaLegacySetup } from '../../../../../plugins/kibana_legacy/public';
export interface HomeKibanaServices {
indexPatternService: any;
@ -51,6 +56,8 @@ export interface HomeKibanaServices {
chrome: ChromeStart;
telemetryOptInProvider: any;
uiSettings: IUiSettingsClient;
config: KibanaLegacySetup['config'];
homeConfig: HomePublicPluginSetup['config'];
http: HttpStart;
savedObjectsClient: SavedObjectsClientContract;
toastNotifications: NotificationsSetup['toasts'];

View file

@ -48,7 +48,7 @@ export class Home extends Component {
super(props);
const isWelcomeEnabled = !(
getServices().getInjected('disableWelcomeScreen') ||
getServices().homeConfig.disableWelcomeScreen ||
props.localStorage.getItem(KEY_ENABLE_WELCOME) === 'false'
);
const currentOptInStatus = this.props.getOptInStatus();

View file

@ -30,6 +30,7 @@ jest.mock('../../kibana_services', () => ({
getServices: () => ({
getBasePath: () => 'path',
getInjected: () => '',
homeConfig: { disableWelcomeScreen: false },
}),
}));

View file

@ -30,7 +30,7 @@ import { replaceTemplateStrings } from './tutorial/replace_template_strings';
import { getServices } from '../../kibana_services';
export function HomeApp({ directories }) {
const {
getInjected,
config,
savedObjectsClient,
getBasePath,
addBasePath,
@ -41,7 +41,7 @@ export function HomeApp({ directories }) {
const mlEnabled = environment.ml;
const apmUiEnabled = environment.apmUi;
const defaultAppId = getInjected('kbnDefaultAppId', 'discover');
const defaultAppId = config.defaultAppId || 'discover';
const renderTutorialDirectory = props => {
return (

View file

@ -27,6 +27,7 @@ import {
Environment,
FeatureCatalogueEntry,
HomePublicPluginStart,
HomePublicPluginSetup,
} from '../../../../../plugins/home/public';
export interface LegacyAngularInjectedDependencies {
@ -59,6 +60,7 @@ export interface HomePluginSetupDependencies {
};
usageCollection: UsageCollectionSetup;
kibana_legacy: KibanaLegacySetup;
home: HomePublicPluginSetup;
}
export class HomePlugin implements Plugin {
@ -69,6 +71,7 @@ export class HomePlugin implements Plugin {
setup(
core: CoreSetup,
{
home,
kibana_legacy,
usageCollection,
__LEGACY: { getAngularDependencies, ...legacyServices },
@ -95,6 +98,8 @@ export class HomePlugin implements Plugin {
getBasePath: core.http.basePath.get,
indexPatternService: this.dataStart!.indexPatterns,
environment: this.environment!,
config: kibana_legacy.config,
homeConfig: home.config,
...angularDependencies,
});
const { renderApp } = await import('./np_ready/application');

View file

@ -20,7 +20,6 @@
// autoloading
// preloading (for faster webpack builds)
import chrome from 'ui/chrome';
import routes from 'ui/routes';
import { uiModules } from 'ui/modules';
import { npSetup } from 'ui/new_platform';
@ -64,8 +63,9 @@ localApplicationService.attachToAngular(routes);
routes.enable();
const { config } = npSetup.plugins.kibana_legacy;
routes.otherwise({
redirectTo: `/${chrome.getInjected('kbnDefaultAppId', 'discover')}`,
redirectTo: `/${config.defaultAppId || 'discover'}`,
});
uiModules.get('kibana').run(showAppRedirectNotification);

View file

@ -34,6 +34,7 @@ import { VisualizationsStart } from '../../../visualizations/public';
import { SavedVisualizations } from './np_ready/types';
import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public';
import { Chrome } from './legacy_imports';
import { KibanaLegacyStart } from '../../../../../plugins/kibana_legacy/public';
export interface VisualizeKibanaServices {
addBasePath: (url: string) => string;
@ -52,6 +53,7 @@ export interface VisualizeKibanaServices {
savedVisualizations: SavedVisualizations;
share: SharePluginStart;
uiSettings: IUiSettingsClient;
config: KibanaLegacyStart['config'];
visualizeCapabilities: any;
visualizations: VisualizationsStart;
usageCollection?: UsageCollectionSetup;

View file

@ -173,7 +173,7 @@ export function initVisualizeApp(app, deps) {
},
})
.when(`visualize/:tail*?`, {
redirectTo: `/${deps.core.injectedMetadata.getInjectedVar('kbnDefaultAppId')}`,
redirectTo: `/${deps.config.defaultAppId}`,
});
});
}

View file

@ -108,6 +108,7 @@ export class VisualizePlugin implements Plugin {
share,
toastNotifications: contextCore.notifications.toasts,
uiSettings: contextCore.uiSettings,
config: kibana_legacy.config,
visualizeCapabilities: contextCore.application.capabilities.visualize,
visualizations,
usageCollection,

View file

@ -27,6 +27,7 @@ import { inspectorPluginMock } from '../../../../../plugins/inspector/public/moc
import { uiActionsPluginMock } from '../../../../../plugins/ui_actions/public/mocks';
import { managementPluginMock } from '../../../../../plugins/management/public/mocks';
import { usageCollectionPluginMock } from '../../../../../plugins/usage_collection/public/mocks';
import { kibanaLegacyPluginMock } from '../../../../../plugins/kibana_legacy/public/mocks';
import { chartPluginMock } from '../../../../../plugins/charts/public/mocks';
/* eslint-enable @kbn/eslint/no-restricted-paths */
@ -40,6 +41,7 @@ export const pluginsMock = {
expressions: expressionsPluginMock.createSetupContract(),
uiActions: uiActionsPluginMock.createSetupContract(),
usageCollection: usageCollectionPluginMock.createSetupContract(),
kibana_legacy: kibanaLegacyPluginMock.createSetupContract(),
}),
createStart: () => ({
data: dataPluginMock.createStartContract(),
@ -50,6 +52,7 @@ export const pluginsMock = {
expressions: expressionsPluginMock.createStartContract(),
uiActions: uiActionsPluginMock.createStartContract(),
management: managementPluginMock.createStartContract(),
kibana_legacy: kibanaLegacyPluginMock.createStartContract(),
}),
};

View file

@ -119,6 +119,9 @@ export const npSetup = {
kibana_legacy: {
registerLegacyApp: () => {},
forwardApp: () => {},
config: {
defaultAppId: 'home',
},
},
inspector: {
registerView: () => undefined,
@ -140,6 +143,9 @@ export const npSetup = {
environment: {
update: sinon.fake(),
},
config: {
disableWelcomeScreen: false,
},
},
charts: {
theme: {
@ -196,6 +202,9 @@ export const npStart = {
kibana_legacy: {
getApps: () => [],
getForwards: () => [],
config: {
defaultAppId: 'home',
},
},
data: {
autocomplete: {
@ -297,6 +306,9 @@ export const npStart = {
environment: {
get: sinon.fake(),
},
config: {
disableWelcomeScreen: false,
},
},
navigation: {
ui: {

View file

@ -0,0 +1,26 @@
/*
* 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 { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
disableWelcomeScreen: schema.boolean({ defaultValue: false }),
});
export type ConfigSchema = TypeOf<typeof configSchema>;

View file

@ -17,6 +17,8 @@
* under the License.
*/
import { PluginInitializerContext } from 'kibana/public';
export {
FeatureCatalogueSetup,
FeatureCatalogueStart,
@ -26,4 +28,5 @@ export {
export { FeatureCatalogueEntry, FeatureCatalogueCategory, Environment } from './services';
import { HomePublicPlugin } from './plugin';
export const plugin = () => new HomePublicPlugin();
export const plugin = (initializerContext: PluginInitializerContext) =>
new HomePublicPlugin(initializerContext);

View file

@ -19,6 +19,9 @@
import { registryMock, environmentMock } from './plugin.test.mocks';
import { HomePublicPlugin } from './plugin';
import { coreMock } from '../../../core/public/mocks';
const mockInitializerContext = coreMock.createPluginInitializerContext();
describe('HomePublicPlugin', () => {
beforeEach(() => {
@ -30,13 +33,13 @@ describe('HomePublicPlugin', () => {
describe('setup', () => {
test('wires up and returns registry', async () => {
const setup = await new HomePublicPlugin().setup();
const setup = await new HomePublicPlugin(mockInitializerContext).setup();
expect(setup).toHaveProperty('featureCatalogue');
expect(setup.featureCatalogue).toHaveProperty('register');
});
test('wires up and returns environment service', async () => {
const setup = await new HomePublicPlugin().setup();
const setup = await new HomePublicPlugin(mockInitializerContext).setup();
expect(setup).toHaveProperty('environment');
expect(setup.environment).toHaveProperty('update');
});
@ -44,7 +47,7 @@ describe('HomePublicPlugin', () => {
describe('start', () => {
test('wires up and returns registry', async () => {
const service = new HomePublicPlugin();
const service = new HomePublicPlugin(mockInitializerContext);
await service.setup();
const core = { application: { capabilities: { catalogue: {} } } } as any;
const start = await service.start(core);
@ -55,7 +58,7 @@ describe('HomePublicPlugin', () => {
});
test('wires up and returns environment service', async () => {
const service = new HomePublicPlugin();
const service = new HomePublicPlugin(mockInitializerContext);
await service.setup();
const start = await service.start({
application: { capabilities: { catalogue: {} } },

View file

@ -17,7 +17,8 @@
* under the License.
*/
import { CoreStart, Plugin } from 'src/core/public';
import { CoreStart, Plugin, PluginInitializerContext } from 'kibana/public';
import {
EnvironmentService,
EnvironmentServiceSetup,
@ -26,19 +27,23 @@ import {
FeatureCatalogueRegistrySetup,
FeatureCatalogueRegistryStart,
} from './services';
import { ConfigSchema } from '../config';
export class HomePublicPlugin implements Plugin<HomePublicPluginSetup, HomePublicPluginStart> {
private readonly featuresCatalogueRegistry = new FeatureCatalogueRegistry();
private readonly environmentService = new EnvironmentService();
public async setup() {
constructor(private readonly initializerContext: PluginInitializerContext<ConfigSchema>) {}
public setup(): HomePublicPluginSetup {
return {
featureCatalogue: { ...this.featuresCatalogueRegistry.setup() },
environment: { ...this.environmentService.setup() },
config: this.initializerContext.config.get(),
};
}
public async start(core: CoreStart) {
public start(core: CoreStart): HomePublicPluginStart {
return {
featureCatalogue: {
...this.featuresCatalogueRegistry.start({
@ -71,6 +76,7 @@ export interface HomePublicPluginSetup {
* @deprecated
*/
environment: EnvironmentSetup;
config: ConfigSchema;
}
/** @public */

View file

@ -20,8 +20,19 @@
export { HomeServerPluginSetup, HomeServerPluginStart } from './plugin';
export { TutorialProvider } from './services';
export { SampleDatasetProvider, SampleDataRegistrySetup } from './services';
import { PluginInitializerContext } from 'src/core/server';
import { PluginInitializerContext, PluginConfigDescriptor } from 'kibana/server';
import { HomeServerPlugin } from './plugin';
import { configSchema, ConfigSchema } from '../config';
export const config: PluginConfigDescriptor<ConfigSchema> = {
exposeToBrowser: {
disableWelcomeScreen: true,
},
schema: configSchema,
deprecations: ({ renameFromRoot }) => [
renameFromRoot('kibana.disableWelcomeScreen', 'home.disableWelcomeScreen'),
],
};
export const plugin = (initContext: PluginInitializerContext) => new HomeServerPlugin(initContext);

View file

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/server';
import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server';
import {
TutorialsRegistry,
TutorialsRegistrySetup,

View file

@ -0,0 +1,26 @@
/*
* 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 { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
defaultAppId: schema.string({ defaultValue: 'home' }),
});
export type ConfigSchema = TypeOf<typeof configSchema>;

View file

@ -1,6 +1,6 @@
{
"id": "kibana_legacy",
"version": "kibana",
"server": false,
"server": true,
"ui": true
}

View file

@ -20,8 +20,7 @@
import { PluginInitializerContext } from 'kibana/public';
import { KibanaLegacyPlugin } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
return new KibanaLegacyPlugin();
}
export const plugin = (initializerContext: PluginInitializerContext) =>
new KibanaLegacyPlugin(initializerContext);
export * from './plugin';

View file

@ -0,0 +1,44 @@
/*
* 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 { KibanaLegacyPlugin } from './plugin';
export type Setup = jest.Mocked<ReturnType<KibanaLegacyPlugin['setup']>>;
export type Start = jest.Mocked<ReturnType<KibanaLegacyPlugin['start']>>;
const createSetupContract = (): Setup => ({
forwardApp: jest.fn(),
registerLegacyApp: jest.fn(),
config: {
defaultAppId: 'home',
},
});
const createStartContract = (): Start => ({
getApps: jest.fn(),
getForwards: jest.fn(),
config: {
defaultAppId: 'home',
},
});
export const kibanaLegacyPluginMock = {
createSetupContract,
createStartContract,
};

View file

@ -17,7 +17,9 @@
* under the License.
*/
import { App } from 'kibana/public';
import { App, PluginInitializerContext } from 'kibana/public';
import { ConfigSchema } from '../config';
interface ForwardDefinition {
legacyAppId: string;
@ -29,6 +31,8 @@ export class KibanaLegacyPlugin {
private apps: App[] = [];
private forwards: ForwardDefinition[] = [];
constructor(private readonly initializerContext: PluginInitializerContext<ConfigSchema>) {}
public setup() {
return {
/**
@ -77,6 +81,8 @@ export class KibanaLegacyPlugin {
) => {
this.forwards.push({ legacyAppId, newAppId, ...options });
},
config: this.initializerContext.config.get(),
};
}
@ -92,6 +98,7 @@ export class KibanaLegacyPlugin {
* Just exported for wiring up with legacy platform, should not be used.
*/
getForwards: () => this.forwards,
config: this.initializerContext.config.get(),
};
}
}

View file

@ -0,0 +1,41 @@
/*
* 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 { CoreSetup, CoreStart, PluginConfigDescriptor } from 'kibana/server';
import { configSchema, ConfigSchema } from '../config';
export const config: PluginConfigDescriptor<ConfigSchema> = {
exposeToBrowser: {
defaultAppId: true,
},
schema: configSchema,
deprecations: ({ renameFromRoot }) => [
// TODO: Remove deprecation once defaultAppId is deleted
renameFromRoot('kibana.defaultAppId', 'kibana_legacy.defaultAppId', true),
],
};
class Plugin {
public setup(core: CoreSetup) {}
public start(core: CoreStart) {}
}
export const plugin = () => new Plugin();

View file

@ -19,12 +19,13 @@
import { ManagementService } from './management_service';
import { coreMock } from '../../../core/public/mocks';
import { npSetup } from '../../../legacy/ui/public/new_platform/__mocks__';
const mockKibanaLegacy = { registerLegacyApp: () => {}, forwardApp: () => {} };
jest.mock('ui/new_platform');
test('Provides default sections', () => {
const service = new ManagementService().setup(
mockKibanaLegacy,
npSetup.plugins.kibana_legacy,
() => {},
coreMock.createSetup().getStartServices
);
@ -36,7 +37,7 @@ test('Provides default sections', () => {
test('Register section, enable and disable', () => {
const service = new ManagementService().setup(
mockKibanaLegacy,
npSetup.plugins.kibana_legacy,
() => {},
coreMock.createSetup().getStartServices
);

View file

@ -54,7 +54,7 @@ export default function() {
`--elasticsearch.hosts=${formatUrl(servers.elasticsearch)}`,
`--elasticsearch.username=${kibanaServerTestUser.username}`,
`--elasticsearch.password=${kibanaServerTestUser.password}`,
`--kibana.disableWelcomeScreen=true`,
`--home.disableWelcomeScreen=true`,
'--telemetry.banner=false',
`--server.maxPayloadBytes=1679958`,
// newsfeed mock service

View file

@ -55,10 +55,12 @@ chrome.setRootController('kibana', function() {
uiModules.get('kibana').run(showAppRedirectNotification);
// If there is a configured kbnDefaultAppId, and it is a dashboard ID, we'll
// show that dashboard, otherwise, we'll show the default dasbhoard landing page.
/**
* If there is a configured `kibana.defaultAppId`, and it is a dashboard ID, we'll
* show that dashboard, otherwise, we'll show the default dasbhoard landing page.
*/
function defaultUrl() {
const defaultAppId = chrome.getInjected('kbnDefaultAppId', '');
const defaultAppId = npStart.plugins.kibana_legacy.config.defaultAppId || '';
const isDashboardId = defaultAppId.startsWith(dashboardAppIdPrefix());
return isDashboardId ? `/${defaultAppId}` : DashboardConstants.LANDING_PAGE_PATH;
}