Expose current branch and version to config deprecation providers (#113600)

* Expose deprecation context to config deprecations

* fix import

* add correct doc annotations

* fix another test file

* update generated doc

* fix yet another test file

* fix more types

* add proper mock

* fix import
This commit is contained in:
Pierre Gayvallet 2021-10-06 10:58:34 +02:00 committed by GitHub
parent 2c8686770e
commit 58bab9105c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 311 additions and 99 deletions

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [DomainDeprecationDetails](./kibana-plugin-core-public.domaindeprecationdetails.md) &gt; [domainId](./kibana-plugin-core-public.domaindeprecationdetails.domainid.md)
## DomainDeprecationDetails.domainId property
<b>Signature:</b>
```typescript
domainId: string;
```

View file

@ -1,18 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [DomainDeprecationDetails](./kibana-plugin-core-public.domaindeprecationdetails.md)
## DomainDeprecationDetails interface
<b>Signature:</b>
```typescript
export interface DomainDeprecationDetails extends DeprecationsDetails
```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [domainId](./kibana-plugin-core-public.domaindeprecationdetails.domainid.md) | <code>string</code> | |

View file

@ -60,7 +60,6 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [CoreStart](./kibana-plugin-core-public.corestart.md) | Core services exposed to the <code>Plugin</code> start lifecycle |
| [DeprecationsServiceStart](./kibana-plugin-core-public.deprecationsservicestart.md) | DeprecationsService provides methods to fetch domain deprecation details from the Kibana server. |
| [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | |
| [DomainDeprecationDetails](./kibana-plugin-core-public.domaindeprecationdetails.md) | |
| [ErrorToastOptions](./kibana-plugin-core-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) error APIs. |
| [FatalErrorInfo](./kibana-plugin-core-public.fatalerrorinfo.md) | Represents the <code>message</code> and <code>stack</code> of a fatal Error |
| [FatalErrorsSetup](./kibana-plugin-core-public.fatalerrorssetup.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. |

View file

@ -4,6 +4,8 @@
## DeprecationsDetails.correctiveActions property
corrective action needed to fix this deprecation.
<b>Signature:</b>
```typescript

View file

@ -4,6 +4,8 @@
## DeprecationsDetails.documentationUrl property
(optional) link to the documentation for more details on the deprecation.
<b>Signature:</b>
```typescript

View file

@ -4,6 +4,7 @@
## DeprecationsDetails interface
<b>Signature:</b>
```typescript
@ -14,11 +15,11 @@ export interface DeprecationsDetails
| Property | Type | Description |
| --- | --- | --- |
| [correctiveActions](./kibana-plugin-core-server.deprecationsdetails.correctiveactions.md) | <code>{</code><br/><code> api?: {</code><br/><code> path: string;</code><br/><code> method: 'POST' &#124; 'PUT';</code><br/><code> body?: {</code><br/><code> [key: string]: any;</code><br/><code> };</code><br/><code> };</code><br/><code> manualSteps: string[];</code><br/><code> }</code> | |
| [correctiveActions](./kibana-plugin-core-server.deprecationsdetails.correctiveactions.md) | <code>{</code><br/><code> api?: {</code><br/><code> path: string;</code><br/><code> method: 'POST' &#124; 'PUT';</code><br/><code> body?: {</code><br/><code> [key: string]: any;</code><br/><code> };</code><br/><code> };</code><br/><code> manualSteps: string[];</code><br/><code> }</code> | corrective action needed to fix this deprecation. |
| [deprecationType](./kibana-plugin-core-server.deprecationsdetails.deprecationtype.md) | <code>'config' &#124; 'feature'</code> | (optional) Used to identify between different deprecation types. Example use case: in Upgrade Assistant, we may want to allow the user to sort by deprecation type or show each type in a separate tab.<!-- -->Feel free to add new types if necessary. Predefined types are necessary to reduce having similar definitions with different keywords across kibana deprecations. |
| [documentationUrl](./kibana-plugin-core-server.deprecationsdetails.documentationurl.md) | <code>string</code> | |
| [documentationUrl](./kibana-plugin-core-server.deprecationsdetails.documentationurl.md) | <code>string</code> | (optional) link to the documentation for more details on the deprecation. |
| [level](./kibana-plugin-core-server.deprecationsdetails.level.md) | <code>'warning' &#124; 'critical' &#124; 'fetch_error'</code> | levels: - warning: will not break deployment upon upgrade - critical: needs to be addressed before upgrade. - fetch\_error: Deprecations service failed to grab the deprecation details for the domain. |
| [message](./kibana-plugin-core-server.deprecationsdetails.message.md) | <code>string</code> | The description message to be displayed for the deprecation. Check the README for writing deprecations in <code>src/core/server/deprecations/README.mdx</code> |
| [requireRestart](./kibana-plugin-core-server.deprecationsdetails.requirerestart.md) | <code>boolean</code> | |
| [requireRestart](./kibana-plugin-core-server.deprecationsdetails.requirerestart.md) | <code>boolean</code> | (optional) specify the fix for this deprecation requires a full kibana restart. |
| [title](./kibana-plugin-core-server.deprecationsdetails.title.md) | <code>string</code> | The title of the deprecation. Check the README for writing deprecations in <code>src/core/server/deprecations/README.mdx</code> |

View file

@ -4,6 +4,8 @@
## DeprecationsDetails.requireRestart property
(optional) specify the fix for this deprecation requires a full kibana restart.
<b>Signature:</b>
```typescript

View file

@ -27,7 +27,6 @@ async function getDeprecations({ esClient, savedObjectsClient }: GetDeprecations
const deprecations: DeprecationsDetails[] = [];
const count = await getFooCount(savedObjectsClient);
if (count > 0) {
// Example of a manual correctiveAction
deprecations.push({
title: i18n.translate('xpack.foo.deprecations.title', {
defaultMessage: `Foo's are deprecated`

View file

@ -4,6 +4,7 @@
## GetDeprecationsContext interface
<b>Signature:</b>
```typescript

View file

@ -4,6 +4,7 @@
## RegisterDeprecationsConfig interface
<b>Signature:</b>
```typescript

View file

@ -15,6 +15,7 @@ import { rawConfigServiceMock } from './raw/raw_config_service.mock';
import { schema } from '@kbn/config-schema';
import { MockedLogger, loggerMock } from '@kbn/logging/mocks';
import type { ConfigDeprecationContext } from './deprecation';
import { ConfigService, Env, RawPackageInfo } from '.';
import { getEnvOptions } from './__mocks__/env';
@ -475,6 +476,43 @@ test('logs deprecation warning during validation', async () => {
`);
});
test('calls `applyDeprecations` with the correct parameters', async () => {
const cfg = { foo: { bar: 1 } };
const rawConfig = getRawConfigProvider(cfg);
const configService = new ConfigService(rawConfig, defaultEnv, logger);
const context: ConfigDeprecationContext = {
branch: defaultEnv.packageInfo.branch,
version: defaultEnv.packageInfo.version,
};
const deprecationA = jest.fn();
const deprecationB = jest.fn();
configService.addDeprecationProvider('foo', () => [deprecationA]);
configService.addDeprecationProvider('bar', () => [deprecationB]);
await configService.validate();
expect(mockApplyDeprecations).toHaveBeenCalledTimes(1);
expect(mockApplyDeprecations).toHaveBeenCalledWith(
cfg,
[
{
deprecation: deprecationA,
path: 'foo',
context,
},
{
deprecation: deprecationB,
path: 'bar',
context,
},
],
expect.any(Function)
);
});
test('does not log warnings for silent deprecations during validation', async () => {
const rawConfig = getRawConfigProvider({});
const configService = new ConfigService(rawConfig, defaultEnv, logger);

View file

@ -19,6 +19,7 @@ import { RawConfigurationProvider } from './raw/raw_config_service';
import {
applyDeprecations,
ConfigDeprecationWithContext,
ConfigDeprecationContext,
ConfigDeprecationProvider,
configDeprecationFactory,
DeprecatedConfigDetails,
@ -103,6 +104,7 @@ export class ConfigService {
...provider(configDeprecationFactory).map((deprecation) => ({
deprecation,
path: flatPath,
context: createDeprecationContext(this.env),
})),
]);
}
@ -298,3 +300,10 @@ const pathToString = (path: ConfigPath) => (Array.isArray(path) ? path.join('.')
*/
const isPathHandled = (path: string, handledPaths: string[]) =>
handledPaths.some((handledPath) => hasConfigPathIntersection(path, handledPath));
const createDeprecationContext = (env: Env): ConfigDeprecationContext => {
return {
branch: env.packageInfo.branch,
version: env.packageInfo.version,
};
};

View file

@ -7,18 +7,24 @@
*/
import { applyDeprecations } from './apply_deprecations';
import { ConfigDeprecation, ConfigDeprecationWithContext } from './types';
import { ConfigDeprecation, ConfigDeprecationContext, ConfigDeprecationWithContext } from './types';
import { configDeprecationFactory as deprecations } from './deprecation_factory';
const wrapHandler = (
handler: ConfigDeprecation,
path: string = ''
): ConfigDeprecationWithContext => ({
deprecation: handler,
path,
});
describe('applyDeprecations', () => {
const context: ConfigDeprecationContext = {
version: '7.16.2',
branch: '7.16',
};
const wrapHandler = (
handler: ConfigDeprecation,
path: string = ''
): ConfigDeprecationWithContext => ({
deprecation: handler,
path,
context,
});
it('calls all deprecations handlers once', () => {
const handlerA = jest.fn();
const handlerB = jest.fn();
@ -32,6 +38,26 @@ describe('applyDeprecations', () => {
expect(handlerC).toHaveBeenCalledTimes(1);
});
it('calls deprecations handlers with the correct parameters', () => {
const config = { foo: 'bar' };
const addDeprecation = jest.fn();
const createAddDeprecation = jest.fn().mockReturnValue(addDeprecation);
const handlerA = jest.fn();
const handlerB = jest.fn();
applyDeprecations(
config,
[wrapHandler(handlerA, 'pathA'), wrapHandler(handlerB, 'pathB')],
createAddDeprecation
);
expect(handlerA).toHaveBeenCalledTimes(1);
expect(handlerA).toHaveBeenCalledWith(config, 'pathA', addDeprecation, context);
expect(handlerB).toHaveBeenCalledTimes(1);
expect(handlerB).toHaveBeenCalledWith(config, 'pathB', addDeprecation, context);
});
it('passes path to addDeprecation factory', () => {
const addDeprecation = jest.fn();
const createAddDeprecation = jest.fn().mockReturnValue(addDeprecation);
@ -51,7 +77,7 @@ describe('applyDeprecations', () => {
expect(createAddDeprecation).toHaveBeenNthCalledWith(2, 'pathB');
});
it('calls handlers with correct arguments', () => {
it('calls handlers with correct config argument', () => {
const addDeprecation = jest.fn();
const createAddDeprecation = jest.fn().mockReturnValue(addDeprecation);
const initialConfig = { foo: 'bar', deprecated: 'deprecated' };

View file

@ -15,6 +15,7 @@ import type {
} from './types';
const noopAddDeprecationFactory: () => AddConfigDeprecation = () => () => undefined;
/**
* Applies deprecations on given configuration and passes addDeprecation hook.
* This hook is used for logging any deprecation warning using provided logger.
@ -32,8 +33,8 @@ export const applyDeprecations = (
set: [],
unset: [],
};
deprecations.forEach(({ deprecation, path }) => {
const commands = deprecation(result, path, createAddDeprecation(path));
deprecations.forEach(({ deprecation, path, context }) => {
const commands = deprecation(result, path, createAddDeprecation(path), context);
if (commands) {
if (commands.set) {
changedPaths.set.push(...commands.set.map((c) => c.path));

View file

@ -7,11 +7,13 @@
*/
import { DeprecatedConfigDetails } from './types';
import { configDeprecationsMock } from './deprecations.mock';
import { configDeprecationFactory } from './deprecation_factory';
describe('DeprecationFactory', () => {
const { deprecate, deprecateFromRoot, rename, renameFromRoot, unused, unusedFromRoot } =
configDeprecationFactory;
const context = configDeprecationsMock.createContext();
const addDeprecation = jest.fn<void, [DeprecatedConfigDetails]>();
@ -30,7 +32,12 @@ describe('DeprecationFactory', () => {
property: 'value',
},
};
const commands = deprecate('deprecated', '8.0.0')(rawConfig, 'myplugin', addDeprecation);
const commands = deprecate('deprecated', '8.0.0')(
rawConfig,
'myplugin',
addDeprecation,
context
);
expect(commands).toBeUndefined();
expect(addDeprecation.mock.calls).toMatchInlineSnapshot(`
Array [
@ -64,7 +71,8 @@ describe('DeprecationFactory', () => {
const commands = deprecate('section.deprecated', '8.0.0')(
rawConfig,
'myplugin',
addDeprecation
addDeprecation,
context
);
expect(commands).toBeUndefined();
expect(addDeprecation.mock.calls).toMatchInlineSnapshot(`
@ -93,7 +101,12 @@ describe('DeprecationFactory', () => {
property: 'value',
},
};
const commands = deprecate('deprecated', '8.0.0')(rawConfig, 'myplugin', addDeprecation);
const commands = deprecate('deprecated', '8.0.0')(
rawConfig,
'myplugin',
addDeprecation,
context
);
expect(commands).toBeUndefined();
expect(addDeprecation).toBeCalledTimes(0);
});
@ -113,7 +126,8 @@ describe('DeprecationFactory', () => {
const commands = deprecateFromRoot('myplugin.deprecated', '8.0.0')(
rawConfig,
'does-not-matter',
addDeprecation
addDeprecation,
context
);
expect(commands).toBeUndefined();
expect(addDeprecation.mock.calls).toMatchInlineSnapshot(`
@ -145,7 +159,8 @@ describe('DeprecationFactory', () => {
const commands = deprecateFromRoot('myplugin.deprecated', '8.0.0')(
rawConfig,
'does-not-matter',
addDeprecation
addDeprecation,
context
);
expect(commands).toBeUndefined();
expect(addDeprecation).toBeCalledTimes(0);
@ -163,7 +178,12 @@ describe('DeprecationFactory', () => {
property: 'value',
},
};
const commands = rename('deprecated', 'renamed')(rawConfig, 'myplugin', addDeprecation);
const commands = rename('deprecated', 'renamed')(
rawConfig,
'myplugin',
addDeprecation,
context
);
expect(commands).toEqual({
set: [
{
@ -199,7 +219,7 @@ describe('DeprecationFactory', () => {
property: 'value',
},
};
const commands = rename('deprecated', 'new')(rawConfig, 'myplugin', addDeprecation);
const commands = rename('deprecated', 'new')(rawConfig, 'myplugin', addDeprecation, context);
expect(commands).toBeUndefined();
expect(addDeprecation).toHaveBeenCalledTimes(0);
});
@ -218,7 +238,8 @@ describe('DeprecationFactory', () => {
const commands = rename('oldsection.deprecated', 'newsection.renamed')(
rawConfig,
'myplugin',
addDeprecation
addDeprecation,
context
);
expect(commands).toEqual({
set: [
@ -252,7 +273,12 @@ describe('DeprecationFactory', () => {
renamed: 'renamed',
},
};
const commands = rename('deprecated', 'renamed')(rawConfig, 'myplugin', addDeprecation);
const commands = rename('deprecated', 'renamed')(
rawConfig,
'myplugin',
addDeprecation,
context
);
expect(commands).toEqual({
unset: [{ path: 'myplugin.deprecated' }],
});
@ -289,7 +315,8 @@ describe('DeprecationFactory', () => {
const commands = renameFromRoot('myplugin.deprecated', 'myplugin.renamed')(
rawConfig,
'does-not-matter',
addDeprecation
addDeprecation,
context
);
expect(commands).toEqual({
set: [
@ -330,7 +357,8 @@ describe('DeprecationFactory', () => {
const commands = renameFromRoot('oldplugin.deprecated', 'newplugin.renamed')(
rawConfig,
'does-not-matter',
addDeprecation
addDeprecation,
context
);
expect(commands).toEqual({
set: [
@ -371,7 +399,8 @@ describe('DeprecationFactory', () => {
const commands = renameFromRoot('myplugin.deprecated', 'myplugin.new')(
rawConfig,
'does-not-matter',
addDeprecation
addDeprecation,
context
);
expect(commands).toBeUndefined();
expect(addDeprecation).toBeCalledTimes(0);
@ -387,7 +416,8 @@ describe('DeprecationFactory', () => {
const commands = renameFromRoot('myplugin.deprecated', 'myplugin.renamed')(
rawConfig,
'does-not-matter',
addDeprecation
addDeprecation,
context
);
expect(commands).toEqual({
unset: [{ path: 'myplugin.deprecated' }],
@ -423,7 +453,7 @@ describe('DeprecationFactory', () => {
property: 'value',
},
};
const commands = unused('deprecated')(rawConfig, 'myplugin', addDeprecation);
const commands = unused('deprecated')(rawConfig, 'myplugin', addDeprecation, context);
expect(commands).toEqual({
unset: [{ path: 'myplugin.deprecated' }],
});
@ -456,7 +486,7 @@ describe('DeprecationFactory', () => {
property: 'value',
},
};
const commands = unused('section.deprecated')(rawConfig, 'myplugin', addDeprecation);
const commands = unused('section.deprecated')(rawConfig, 'myplugin', addDeprecation, context);
expect(commands).toEqual({
unset: [{ path: 'myplugin.section.deprecated' }],
});
@ -486,7 +516,7 @@ describe('DeprecationFactory', () => {
property: 'value',
},
};
const commands = unused('deprecated')(rawConfig, 'myplugin', addDeprecation);
const commands = unused('deprecated')(rawConfig, 'myplugin', addDeprecation, context);
expect(commands).toBeUndefined();
expect(addDeprecation).toBeCalledTimes(0);
});
@ -506,7 +536,8 @@ describe('DeprecationFactory', () => {
const commands = unusedFromRoot('myplugin.deprecated')(
rawConfig,
'does-not-matter',
addDeprecation
addDeprecation,
context
);
expect(commands).toEqual({
unset: [{ path: 'myplugin.deprecated' }],
@ -540,7 +571,8 @@ describe('DeprecationFactory', () => {
const commands = unusedFromRoot('myplugin.deprecated')(
rawConfig,
'does-not-matter',
addDeprecation
addDeprecation,
context
);
expect(commands).toBeUndefined();
expect(addDeprecation).toBeCalledTimes(0);

View file

@ -0,0 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import type { ConfigDeprecationContext } from './types';
const createMockedContext = (): ConfigDeprecationContext => {
return {
branch: 'master',
version: '8.0.0',
};
};
export const configDeprecationsMock = {
createContext: createMockedContext,
};

View file

@ -9,6 +9,7 @@
export type {
ConfigDeprecation,
ConfigDeprecationCommand,
ConfigDeprecationContext,
ConfigDeprecationWithContext,
ConfigDeprecationFactory,
AddConfigDeprecation,

View file

@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
import type { RecursiveReadonly } from '@kbn/utility-types';
/**
* Config deprecation hook used when invoking a {@link ConfigDeprecation}
*
@ -19,9 +20,9 @@ export type AddConfigDeprecation = (details: DeprecatedConfigDetails) => void;
* @public
*/
export interface DeprecatedConfigDetails {
/* The title to be displayed for the deprecation. */
/** The title to be displayed for the deprecation. */
title?: string;
/* The message to be displayed for the deprecation. */
/** The message to be displayed for the deprecation. */
message: string;
/**
* levels:
@ -29,11 +30,11 @@ export interface DeprecatedConfigDetails {
* - critical: needs to be addressed before upgrade.
*/
level?: 'warning' | 'critical';
/* (optional) set false to prevent the config service from logging the deprecation message. */
/** (optional) set false to prevent the config service from logging the deprecation message. */
silent?: boolean;
/* (optional) link to the documentation for more details on the deprecation. */
/** (optional) link to the documentation for more details on the deprecation. */
documentationUrl?: string;
/* corrective action needed to fix this deprecation. */
/** corrective action needed to fix this deprecation. */
correctiveActions: {
/**
* Specify a list of manual steps our users need to follow
@ -55,14 +56,27 @@ export interface DeprecatedConfigDetails {
* ```typescript
* const provider: ConfigDeprecation = (config, path) => ({ unset: [{ key: 'path.to.key' }] })
* ```
* @internal
* @public
*/
export type ConfigDeprecation = (
config: RecursiveReadonly<Record<string, any>>,
fromPath: string,
addDeprecation: AddConfigDeprecation
addDeprecation: AddConfigDeprecation,
context: ConfigDeprecationContext
) => void | ConfigDeprecationCommand;
/**
* Deprecation context provided to {@link ConfigDeprecation | config deprecations}
*
* @public
*/
export interface ConfigDeprecationContext {
/** The current Kibana version, e.g `7.16.1`, `8.0.0` */
version: string;
/** The current Kibana branch, e.g `7.x`, `7.16`, `master` */
branch: string;
}
/**
* List of config paths changed during deprecation.
*
@ -137,6 +151,7 @@ export interface ConfigDeprecationFactory {
removeBy: string,
details?: Partial<DeprecatedConfigDetails>
): ConfigDeprecation;
/**
* Deprecate a configuration property from the root configuration.
* Will log a deprecation warning if the deprecatedKey was found.
@ -157,6 +172,7 @@ export interface ConfigDeprecationFactory {
removeBy: string,
details?: Partial<DeprecatedConfigDetails>
): ConfigDeprecation;
/**
* Rename a configuration property from inside a plugin's configuration path.
* Will log a deprecation warning if the oldKey was found and deprecation applied.
@ -174,6 +190,7 @@ export interface ConfigDeprecationFactory {
newKey: string,
details?: Partial<DeprecatedConfigDetails>
): ConfigDeprecation;
/**
* Rename a configuration property from the root configuration.
* Will log a deprecation warning if the oldKey was found and deprecation applied.
@ -194,6 +211,7 @@ export interface ConfigDeprecationFactory {
newKey: string,
details?: Partial<DeprecatedConfigDetails>
): 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.
@ -207,6 +225,7 @@ export interface ConfigDeprecationFactory {
* ```
*/
unused(unusedKey: string, details?: Partial<DeprecatedConfigDetails>): ConfigDeprecation;
/**
* Remove a configuration property from the root configuration.
* Will log a deprecation warning if the unused key was found and deprecation applied.
@ -229,4 +248,5 @@ export interface ConfigDeprecationFactory {
export interface ConfigDeprecationWithContext {
deprecation: ConfigDeprecation;
path: string;
context: ConfigDeprecationContext;
}

View file

@ -13,6 +13,7 @@ export type {
ConfigDeprecationWithContext,
ConfigDeprecation,
ConfigDeprecationCommand,
ConfigDeprecationContext,
ChangedDeprecatedPaths,
} from './deprecation';

View file

@ -14,4 +14,5 @@
export { configMock } from './config.mock';
export { configServiceMock } from './config_service.mock';
export { rawConfigServiceMock } from './raw/raw_config_service.mock';
export { configDeprecationsMock } from './deprecation/deprecations.mock';
export { getEnvOptions } from './__mocks__/env';

View file

@ -459,9 +459,13 @@ export const DEFAULT_APP_CATEGORIES: Record<string, AppCategory>;
// @public
export interface DeprecationsServiceStart {
// Warning: (ae-incompatible-release-tags) The symbol "getAllDeprecations" is marked as @public, but its signature references "DomainDeprecationDetails" which is marked as @internal
getAllDeprecations: () => Promise<DomainDeprecationDetails[]>;
// Warning: (ae-incompatible-release-tags) The symbol "getDeprecations" is marked as @public, but its signature references "DomainDeprecationDetails" which is marked as @internal
getDeprecations: (domainId: string) => Promise<DomainDeprecationDetails[]>;
// Warning: (ae-incompatible-release-tags) The symbol "isDeprecationResolvable" is marked as @public, but its signature references "DomainDeprecationDetails" which is marked as @internal
isDeprecationResolvable: (details: DomainDeprecationDetails) => boolean;
// Warning: (ae-incompatible-release-tags) The symbol "resolveDeprecation" is marked as @public, but its signature references "DomainDeprecationDetails" which is marked as @internal
resolveDeprecation: (details: DomainDeprecationDetails) => Promise<ResolveDeprecationResponse>;
}
@ -715,9 +719,8 @@ export interface DocLinksStart {
}
// Warning: (ae-forgotten-export) The symbol "DeprecationsDetails" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "DomainDeprecationDetails" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @internal (undocumented)
export interface DomainDeprecationDetails extends DeprecationsDetails {
// (undocumented)
domainId: string;

View file

@ -25,6 +25,7 @@ export type {
ConfigPath,
CliArgs,
ConfigDeprecation,
ConfigDeprecationContext,
AddConfigDeprecation,
ConfigDeprecationProvider,
ConfigDeprecationFactory,

View file

@ -11,6 +11,7 @@ import type {
rawConfigServiceMock as rawConfigServiceMockTyped,
configServiceMock as configServiceMockTyped,
configMock as configMockTyped,
configDeprecationsMock as configDeprecationsMockTyped,
} from '@kbn/config/target_types/mocks';
import {
@ -18,6 +19,7 @@ import {
rawConfigServiceMock as rawConfigServiceMockNonTyped,
configServiceMock as configServiceMockNonTyped,
configMock as configMockNonTyped,
configDeprecationsMock as configDeprecationsMockNonTyped,
// @ts-expect-error
} from '@kbn/config/target_node/mocks';
@ -25,5 +27,12 @@ const getEnvOptions: typeof getEnvOptionsTyped = getEnvOptionsNonTyped;
const rawConfigServiceMock: typeof rawConfigServiceMockTyped = rawConfigServiceMockNonTyped;
const configServiceMock: typeof configServiceMockTyped = configServiceMockNonTyped;
const configMock: typeof configMockTyped = configMockNonTyped;
const configDeprecationsMock: typeof configDeprecationsMockTyped = configDeprecationsMockNonTyped;
export { getEnvOptions, rawConfigServiceMock, configServiceMock, configMock };
export {
getEnvOptions,
rawConfigServiceMock,
configServiceMock,
configMock,
configDeprecationsMock,
};

View file

@ -6,13 +6,17 @@
* Side Public License, v 1.
*/
import { set } from '@elastic/safer-lodash-set';
import type { ConfigDeprecationProvider } from '@kbn/config';
import type { ConfigDeprecationProvider, ConfigDeprecationContext } from '@kbn/config';
import { configDeprecationFactory, applyDeprecations } from '@kbn/config';
import { configDeprecationsMock } from './mocks';
const defaultContext = configDeprecationsMock.createContext();
function collectDeprecations(
provider: ConfigDeprecationProvider,
settings: Record<string, any>,
path: string
path: string,
context: ConfigDeprecationContext = defaultContext
) {
const deprecations = provider(configDeprecationFactory);
const deprecationMessages: string[] = [];
@ -22,6 +26,7 @@ function collectDeprecations(
deprecations.map((deprecation) => ({
deprecation,
path,
context,
})),
() =>
({ message, level }) => {

View file

@ -11,10 +11,16 @@ import type { IScopedClusterClient } from '../elasticsearch';
type MaybePromise<T> = T | Promise<T>;
/**
* @internal
*/
export interface DomainDeprecationDetails extends DeprecationsDetails {
domainId: string;
}
/**
* @public
*/
export interface DeprecationsDetails {
/**
* The title of the deprecation.
@ -43,11 +49,11 @@ export interface DeprecationsDetails {
* across kibana deprecations.
*/
deprecationType?: 'config' | 'feature';
/* (optional) link to the documentation for more details on the deprecation. */
/** (optional) link to the documentation for more details on the deprecation. */
documentationUrl?: string;
/* (optional) specify the fix for this deprecation requires a full kibana restart. */
/** (optional) specify the fix for this deprecation requires a full kibana restart. */
requireRestart?: boolean;
/* corrective action needed to fix this deprecation. */
/** corrective action needed to fix this deprecation. */
correctiveActions: {
/**
* (optional) The api to be called to automatically fix the deprecation
@ -55,11 +61,11 @@ export interface DeprecationsDetails {
* handle their deprecations.
*/
api?: {
/* Kibana route path. Passing a query string is allowed */
/** Kibana route path. Passing a query string is allowed */
path: string;
/* Kibana route method: 'POST' or 'PUT'. */
/** Kibana route method: 'POST' or 'PUT'. */
method: 'POST' | 'PUT';
/* Additional details to be passed to the route. */
/** Additional details to be passed to the route. */
body?: {
[key: string]: any;
};
@ -74,15 +80,24 @@ export interface DeprecationsDetails {
};
}
/**
* @public
*/
export interface RegisterDeprecationsConfig {
getDeprecations: (context: GetDeprecationsContext) => MaybePromise<DeprecationsDetails[]>;
}
/**
* @public
*/
export interface GetDeprecationsContext {
esClient: IScopedClusterClient;
savedObjectsClient: SavedObjectsClientContract;
}
/**
* @public
*/
export interface DeprecationsGetResponse {
deprecations: DomainDeprecationDetails[];
}

View file

@ -96,6 +96,7 @@ export type {
ConfigPath,
ConfigService,
ConfigDeprecation,
ConfigDeprecationContext,
ConfigDeprecationProvider,
ConfigDeprecationFactory,
AddConfigDeprecation,

View file

@ -39,7 +39,7 @@ import { deprecationsServiceMock } from './deprecations/deprecations_service.moc
import { executionContextServiceMock } from './execution_context/execution_context_service.mock';
import { prebootServiceMock } from './preboot/preboot_service.mock';
export { configServiceMock } from './config/mocks';
export { configServiceMock, configDeprecationsMock } from './config/mocks';
export { httpServerMock } from './http/http_server.mocks';
export { httpResourcesMock } from './http_resources/http_resources_service.mock';
export { sessionStorageMock } from './http/cookie_session_storage.mocks';

View file

@ -11,6 +11,7 @@ import { ByteSizeValue } from '@kbn/config-schema';
import { CliArgs } from '@kbn/config';
import { ClientOptions } from '@elastic/elasticsearch';
import { ConfigDeprecation } from '@kbn/config';
import { ConfigDeprecationContext } from '@kbn/config';
import { ConfigDeprecationFactory } from '@kbn/config';
import { ConfigDeprecationProvider } from '@kbn/config';
import { ConfigPath } from '@kbn/config';
@ -246,6 +247,8 @@ export const config: {
export { ConfigDeprecation }
export { ConfigDeprecationContext }
export { ConfigDeprecationFactory }
export { ConfigDeprecationProvider }
@ -800,11 +803,8 @@ export interface DeprecationsClient {
getAllDeprecations: () => Promise<DomainDeprecationDetails[]>;
}
// Warning: (ae-missing-release-tag) "DeprecationsDetails" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export interface DeprecationsDetails {
// (undocumented)
correctiveActions: {
api?: {
path: string;
@ -816,11 +816,9 @@ export interface DeprecationsDetails {
manualSteps: string[];
};
deprecationType?: 'config' | 'feature';
// (undocumented)
documentationUrl?: string;
level: 'warning' | 'critical' | 'fetch_error';
message: string;
// (undocumented)
requireRestart?: boolean;
title: string;
}
@ -983,8 +981,6 @@ export type GetAuthState = <T = unknown>(request: KibanaRequest) => {
state: T;
};
// Warning: (ae-missing-release-tag) "GetDeprecationsContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export interface GetDeprecationsContext {
// (undocumented)
@ -1699,8 +1695,6 @@ export type RedirectResponseOptions = HttpResponseOptions & {
};
};
// Warning: (ae-missing-release-tag) "RegisterDeprecationsConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export interface RegisterDeprecationsConfig {
// Warning: (ae-forgotten-export) The symbol "MaybePromise" needs to be exported by the entry point index.d.ts

View file

@ -9,9 +9,12 @@
import { cloneDeep } from 'lodash';
import { applyDeprecations, configDeprecationFactory } from '@kbn/config';
import { configDeprecationsMock } from '../../../core/server/mocks';
import { autocompleteConfigDeprecationProvider } from './config_deprecations';
const deprecationContext = configDeprecationsMock.createContext();
const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
const deprecations = autocompleteConfigDeprecationProvider(configDeprecationFactory);
const deprecationMessages: string[] = [];
@ -20,6 +23,7 @@ const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
deprecations.map((deprecation) => ({
deprecation,
path: '',
context: deprecationContext,
})),
() =>
({ message }) =>

View file

@ -6,12 +6,16 @@
* Side Public License, v 1.
*/
import { configDeprecationsMock } from '../../../../core/server/mocks';
import { deprecateEndpointConfigs } from './deprecations';
import type { TelemetryConfigType } from './config';
import { TELEMETRY_ENDPOINT } from '../../common/constants';
describe('deprecateEndpointConfigs', () => {
const fromPath = 'telemetry';
const mockAddDeprecation = jest.fn();
const deprecationContext = configDeprecationsMock.createContext();
beforeEach(() => {
jest.clearAllMocks();
});
@ -28,7 +32,12 @@ describe('deprecateEndpointConfigs', () => {
it('returns void if telemetry.* config is not set', () => {
const rawConfig = createMockRawConfig();
const result = deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation);
const result = deprecateEndpointConfigs(
rawConfig,
fromPath,
mockAddDeprecation,
deprecationContext
);
expect(result).toBe(undefined);
});
@ -36,7 +45,12 @@ describe('deprecateEndpointConfigs', () => {
const rawConfig = createMockRawConfig({
url: TELEMETRY_ENDPOINT.MAIN_CHANNEL.STAGING,
});
const result = deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation);
const result = deprecateEndpointConfigs(
rawConfig,
fromPath,
mockAddDeprecation,
deprecationContext
);
expect(result).toMatchInlineSnapshot(`
Object {
"set": Array [
@ -58,7 +72,12 @@ describe('deprecateEndpointConfigs', () => {
const rawConfig = createMockRawConfig({
url: 'random-endpoint',
});
const result = deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation);
const result = deprecateEndpointConfigs(
rawConfig,
fromPath,
mockAddDeprecation,
deprecationContext
);
expect(result).toMatchInlineSnapshot(`
Object {
"set": Array [
@ -80,7 +99,12 @@ describe('deprecateEndpointConfigs', () => {
const rawConfig = createMockRawConfig({
optInStatusUrl: TELEMETRY_ENDPOINT.MAIN_CHANNEL.STAGING,
});
const result = deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation);
const result = deprecateEndpointConfigs(
rawConfig,
fromPath,
mockAddDeprecation,
deprecationContext
);
expect(result).toMatchInlineSnapshot(`
Object {
"set": Array [
@ -102,7 +126,12 @@ describe('deprecateEndpointConfigs', () => {
const rawConfig = createMockRawConfig({
optInStatusUrl: 'random-endpoint',
});
const result = deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation);
const result = deprecateEndpointConfigs(
rawConfig,
fromPath,
mockAddDeprecation,
deprecationContext
);
expect(result).toMatchInlineSnapshot(`
Object {
"set": Array [
@ -124,7 +153,7 @@ describe('deprecateEndpointConfigs', () => {
const rawConfig = createMockRawConfig({
url: TELEMETRY_ENDPOINT.MAIN_CHANNEL.PROD,
});
deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation);
deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation, deprecationContext);
expect(mockAddDeprecation).toBeCalledTimes(1);
expect(mockAddDeprecation.mock.calls[0]).toMatchInlineSnapshot(`
Array [
@ -146,7 +175,7 @@ describe('deprecateEndpointConfigs', () => {
const rawConfig = createMockRawConfig({
optInStatusUrl: 'random-endpoint',
});
deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation);
deprecateEndpointConfigs(rawConfig, fromPath, mockAddDeprecation, deprecationContext);
expect(mockAddDeprecation).toBeCalledTimes(1);
expect(mockAddDeprecation.mock.calls[0]).toMatchInlineSnapshot(`
Array [

View file

@ -6,9 +6,12 @@
*/
import { applyDeprecations, configDeprecationFactory } from '@kbn/config';
import { configDeprecationsMock } from '../../../../src/core/server/mocks';
import { config } from '.';
const deprecationContext = configDeprecationsMock.createContext();
const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
if (!config.deprecations) {
throw new Error('Config is not valid no deprecations');
@ -20,6 +23,7 @@ const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
deprecations.map((deprecation) => ({
deprecation,
path: '',
context: deprecationContext,
})),
() =>
({ message }) =>

View file

@ -7,9 +7,12 @@
import { config } from './index';
import { applyDeprecations, configDeprecationFactory } from '@kbn/config';
import { configDeprecationsMock } from '../../../../../src/core/server/mocks';
const CONFIG_PATH = 'xpack.reporting';
const deprecationContext = configDeprecationsMock.createContext();
const applyReportingDeprecations = (settings: Record<string, any> = {}) => {
const deprecations = config.deprecations!(configDeprecationFactory);
const deprecationMessages: string[] = [];
@ -20,6 +23,7 @@ const applyReportingDeprecations = (settings: Record<string, any> = {}) => {
deprecations.map((deprecation) => ({
deprecation,
path: CONFIG_PATH,
context: deprecationContext,
})),
() =>
({ message }) =>

View file

@ -9,8 +9,11 @@ import { cloneDeep } from 'lodash';
import { applyDeprecations, configDeprecationFactory } from '@kbn/config';
import { configDeprecationsMock } from '../../../../src/core/server/mocks';
import { securityConfigDeprecationProvider } from './config_deprecations';
const deprecationContext = configDeprecationsMock.createContext();
const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
const deprecations = securityConfigDeprecationProvider(configDeprecationFactory);
const deprecationMessages: string[] = [];
@ -19,6 +22,7 @@ const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
deprecations.map((deprecation) => ({
deprecation,
path: 'xpack.security',
context: deprecationContext,
})),
() =>
({ message }) =>

View file

@ -8,8 +8,11 @@
import { applyDeprecations, configDeprecationFactory } from '@kbn/config';
import { deepFreeze } from '@kbn/std';
import { configDeprecationsMock } from '../../../../src/core/server/mocks';
import { spacesConfigDeprecationProvider } from './config';
const deprecationContext = configDeprecationsMock.createContext();
const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
const deprecations = spacesConfigDeprecationProvider(configDeprecationFactory);
const deprecationMessages: string[] = [];
@ -18,6 +21,7 @@ const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
deprecations.map((deprecation) => ({
deprecation,
path: '',
context: deprecationContext,
})),
() =>
({ message }) =>

View file

@ -6,8 +6,11 @@
*/
import { config } from './index';
import { applyDeprecations, configDeprecationFactory } from '@kbn/config';
import { configDeprecationsMock } from '../../../../src/core/server/mocks';
const CONFIG_PATH = 'xpack.stack_alerts';
const deprecationContext = configDeprecationsMock.createContext();
const applyStackAlertDeprecations = (settings: Record<string, unknown> = {}) => {
const deprecations = config.deprecations!(configDeprecationFactory);
const deprecationMessages: string[] = [];
@ -19,6 +22,7 @@ const applyStackAlertDeprecations = (settings: Record<string, unknown> = {}) =>
deprecations.map((deprecation) => ({
deprecation,
path: CONFIG_PATH,
context: deprecationContext,
})),
() =>
({ message }) =>

View file

@ -7,9 +7,12 @@
import { config } from './index';
import { applyDeprecations, configDeprecationFactory } from '@kbn/config';
import { configDeprecationsMock } from '../../../../src/core/server/mocks';
const CONFIG_PATH = 'xpack.task_manager';
const deprecationContext = configDeprecationsMock.createContext();
const applyTaskManagerDeprecations = (settings: Record<string, unknown> = {}) => {
const deprecations = config.deprecations!(configDeprecationFactory);
const deprecationMessages: string[] = [];
@ -21,6 +24,7 @@ const applyTaskManagerDeprecations = (settings: Record<string, unknown> = {}) =>
deprecations.map((deprecation) => ({
deprecation,
path: CONFIG_PATH,
context: deprecationContext,
})),
() =>
({ message }) =>