mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
Adds node.roles
configuration & exposes via PluginInitializerContext
(#135272)
This commit is contained in:
parent
3b6fc59e55
commit
cf6ae210ef
58 changed files with 1514 additions and 160 deletions
|
@ -96,6 +96,9 @@ enabled:
|
||||||
- test/interactive_setup_functional/manual_configuration.config.ts
|
- test/interactive_setup_functional/manual_configuration.config.ts
|
||||||
- test/interpreter_functional/config.ts
|
- test/interpreter_functional/config.ts
|
||||||
- test/new_visualize_flow/config.ts
|
- test/new_visualize_flow/config.ts
|
||||||
|
- test/node_roles_functional/all.config.ts
|
||||||
|
- test/node_roles_functional/background_tasks.config.ts
|
||||||
|
- test/node_roles_functional/ui.config.ts
|
||||||
- test/plugin_functional/config.ts
|
- test/plugin_functional/config.ts
|
||||||
- test/server_integration/http/platform/config.status.ts
|
- test/server_integration/http/platform/config.status.ts
|
||||||
- test/server_integration/http/platform/config.ts
|
- test/server_integration/http/platform/config.ts
|
||||||
|
|
|
@ -311,6 +311,11 @@ Controls whether to enable the newsfeed
|
||||||
system for the {kib} UI notification center. Set to `false` to disable the
|
system for the {kib} UI notification center. Set to `false` to disable the
|
||||||
newsfeed system. *Default: `true`*
|
newsfeed system. *Default: `true`*
|
||||||
|
|
||||||
|
`node.roles`::
|
||||||
|
Indicates which roles to configure the {kib} process with, which will effectively
|
||||||
|
run {kib} in different modes. Valid options are `background_tasks` and `ui`,
|
||||||
|
or `*` to select all roles. *Default: `*`*
|
||||||
|
|
||||||
[[path-data]] `path.data`::
|
[[path-data]] `path.data`::
|
||||||
The path where {kib} stores persistent data
|
The path where {kib} stores persistent data
|
||||||
not saved in {es}. *Default: `data`*
|
not saved in {es}. *Default: `data`*
|
||||||
|
|
|
@ -181,6 +181,9 @@
|
||||||
"@kbn/core-logging-server": "link:bazel-bin/packages/core/logging/core-logging-server",
|
"@kbn/core-logging-server": "link:bazel-bin/packages/core/logging/core-logging-server",
|
||||||
"@kbn/core-logging-server-internal": "link:bazel-bin/packages/core/logging/core-logging-server-internal",
|
"@kbn/core-logging-server-internal": "link:bazel-bin/packages/core/logging/core-logging-server-internal",
|
||||||
"@kbn/core-logging-server-mocks": "link:bazel-bin/packages/core/logging/core-logging-server-mocks",
|
"@kbn/core-logging-server-mocks": "link:bazel-bin/packages/core/logging/core-logging-server-mocks",
|
||||||
|
"@kbn/core-node-server": "link:bazel-bin/packages/core/node/core-node-server",
|
||||||
|
"@kbn/core-node-server-internal": "link:bazel-bin/packages/core/node/core-node-server-internal",
|
||||||
|
"@kbn/core-node-server-mocks": "link:bazel-bin/packages/core/node/core-node-server-mocks",
|
||||||
"@kbn/core-theme-browser": "link:bazel-bin/packages/core/theme/core-theme-browser",
|
"@kbn/core-theme-browser": "link:bazel-bin/packages/core/theme/core-theme-browser",
|
||||||
"@kbn/core-theme-browser-internal": "link:bazel-bin/packages/core/theme/core-theme-browser-internal",
|
"@kbn/core-theme-browser-internal": "link:bazel-bin/packages/core/theme/core-theme-browser-internal",
|
||||||
"@kbn/core-theme-browser-mocks": "link:bazel-bin/packages/core/theme/core-theme-browser-mocks",
|
"@kbn/core-theme-browser-mocks": "link:bazel-bin/packages/core/theme/core-theme-browser-mocks",
|
||||||
|
@ -715,6 +718,9 @@
|
||||||
"@types/kbn__core-logging-server": "link:bazel-bin/packages/core/logging/core-logging-server/npm_module_types",
|
"@types/kbn__core-logging-server": "link:bazel-bin/packages/core/logging/core-logging-server/npm_module_types",
|
||||||
"@types/kbn__core-logging-server-internal": "link:bazel-bin/packages/core/logging/core-logging-server-internal/npm_module_types",
|
"@types/kbn__core-logging-server-internal": "link:bazel-bin/packages/core/logging/core-logging-server-internal/npm_module_types",
|
||||||
"@types/kbn__core-logging-server-mocks": "link:bazel-bin/packages/core/logging/core-logging-server-mocks/npm_module_types",
|
"@types/kbn__core-logging-server-mocks": "link:bazel-bin/packages/core/logging/core-logging-server-mocks/npm_module_types",
|
||||||
|
"@types/kbn__core-node-server": "link:bazel-bin/packages/core/node/core-node-server/npm_module_types",
|
||||||
|
"@types/kbn__core-node-server-internal": "link:bazel-bin/packages/core/node/core-node-server-internal/npm_module_types",
|
||||||
|
"@types/kbn__core-node-server-mocks": "link:bazel-bin/packages/core/node/core-node-server-mocks/npm_module_types",
|
||||||
"@types/kbn__core-public-internal-base": "link:bazel-bin/packages/core/public/internal-base/npm_module_types",
|
"@types/kbn__core-public-internal-base": "link:bazel-bin/packages/core/public/internal-base/npm_module_types",
|
||||||
"@types/kbn__core-server-internal-base": "link:bazel-bin/packages/core/server/internal-base/npm_module_types",
|
"@types/kbn__core-server-internal-base": "link:bazel-bin/packages/core/server/internal-base/npm_module_types",
|
||||||
"@types/kbn__core-theme-browser": "link:bazel-bin/packages/core/theme/core-theme-browser/npm_module_types",
|
"@types/kbn__core-theme-browser": "link:bazel-bin/packages/core/theme/core-theme-browser/npm_module_types",
|
||||||
|
|
|
@ -50,6 +50,9 @@ filegroup(
|
||||||
"//packages/core/logging/core-logging-server-internal:build",
|
"//packages/core/logging/core-logging-server-internal:build",
|
||||||
"//packages/core/logging/core-logging-server-mocks:build",
|
"//packages/core/logging/core-logging-server-mocks:build",
|
||||||
"//packages/core/logging/core-logging-server:build",
|
"//packages/core/logging/core-logging-server:build",
|
||||||
|
"//packages/core/node/core-node-server-internal:build",
|
||||||
|
"//packages/core/node/core-node-server-mocks:build",
|
||||||
|
"//packages/core/node/core-node-server:build",
|
||||||
"//packages/core/theme/core-theme-browser-internal:build",
|
"//packages/core/theme/core-theme-browser-internal:build",
|
||||||
"//packages/core/theme/core-theme-browser-mocks:build",
|
"//packages/core/theme/core-theme-browser-mocks:build",
|
||||||
"//packages/core/theme/core-theme-browser:build",
|
"//packages/core/theme/core-theme-browser:build",
|
||||||
|
@ -217,6 +220,9 @@ filegroup(
|
||||||
"//packages/core/logging/core-logging-server-internal:build_types",
|
"//packages/core/logging/core-logging-server-internal:build_types",
|
||||||
"//packages/core/logging/core-logging-server-mocks:build_types",
|
"//packages/core/logging/core-logging-server-mocks:build_types",
|
||||||
"//packages/core/logging/core-logging-server:build_types",
|
"//packages/core/logging/core-logging-server:build_types",
|
||||||
|
"//packages/core/node/core-node-server-internal:build_types",
|
||||||
|
"//packages/core/node/core-node-server-mocks:build_types",
|
||||||
|
"//packages/core/node/core-node-server:build_types",
|
||||||
"//packages/core/theme/core-theme-browser-internal:build_types",
|
"//packages/core/theme/core-theme-browser-internal:build_types",
|
||||||
"//packages/core/theme/core-theme-browser-mocks:build_types",
|
"//packages/core/theme/core-theme-browser-mocks:build_types",
|
||||||
"//packages/core/theme/core-theme-browser:build_types",
|
"//packages/core/theme/core-theme-browser:build_types",
|
||||||
|
|
104
packages/core/node/core-node-server-internal/BUILD.bazel
Normal file
104
packages/core/node/core-node-server-internal/BUILD.bazel
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||||
|
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||||
|
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||||
|
|
||||||
|
PKG_DIRNAME = "core-node-server-internal"
|
||||||
|
PKG_REQUIRE_NAME = "@kbn/core-node-server-internal"
|
||||||
|
|
||||||
|
SOURCE_FILES = glob(
|
||||||
|
[
|
||||||
|
"src/**/*.ts",
|
||||||
|
],
|
||||||
|
exclude = [
|
||||||
|
"**/*.test.*",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
SRCS = SOURCE_FILES
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "srcs",
|
||||||
|
srcs = SRCS,
|
||||||
|
)
|
||||||
|
|
||||||
|
NPM_MODULE_EXTRA_FILES = [
|
||||||
|
"package.json",
|
||||||
|
]
|
||||||
|
|
||||||
|
RUNTIME_DEPS = [
|
||||||
|
"@npm//lodash",
|
||||||
|
"@npm//rxjs",
|
||||||
|
"//packages/kbn-config-schema",
|
||||||
|
]
|
||||||
|
|
||||||
|
TYPES_DEPS = [
|
||||||
|
"@npm//@types/node",
|
||||||
|
"@npm//@types/jest",
|
||||||
|
"@npm//@types/lodash",
|
||||||
|
"//packages/kbn-config:npm_module_types",
|
||||||
|
"//packages/kbn-config-schema:npm_module_types",
|
||||||
|
"//packages/kbn-logging:npm_module_types",
|
||||||
|
"//packages/core/base/core-base-server-internal:npm_module_types",
|
||||||
|
"//packages/core/node/core-node-server:npm_module_types",
|
||||||
|
]
|
||||||
|
|
||||||
|
jsts_transpiler(
|
||||||
|
name = "target_node",
|
||||||
|
srcs = SRCS,
|
||||||
|
build_pkg_name = package_name(),
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_config(
|
||||||
|
name = "tsconfig",
|
||||||
|
src = "tsconfig.json",
|
||||||
|
deps = [
|
||||||
|
"//:tsconfig.base.json",
|
||||||
|
"//:tsconfig.bazel.json",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_project(
|
||||||
|
name = "tsc_types",
|
||||||
|
args = ['--pretty'],
|
||||||
|
srcs = SRCS,
|
||||||
|
deps = TYPES_DEPS,
|
||||||
|
declaration = True,
|
||||||
|
emit_declaration_only = True,
|
||||||
|
out_dir = "target_types",
|
||||||
|
root_dir = "src",
|
||||||
|
tsconfig = ":tsconfig",
|
||||||
|
)
|
||||||
|
|
||||||
|
js_library(
|
||||||
|
name = PKG_DIRNAME,
|
||||||
|
srcs = NPM_MODULE_EXTRA_FILES,
|
||||||
|
deps = RUNTIME_DEPS + [":target_node"],
|
||||||
|
package_name = PKG_REQUIRE_NAME,
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_npm(
|
||||||
|
name = "npm_module",
|
||||||
|
deps = [":" + PKG_DIRNAME],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "build",
|
||||||
|
srcs = [":npm_module"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_npm_types(
|
||||||
|
name = "npm_module_types",
|
||||||
|
srcs = SRCS,
|
||||||
|
deps = [":tsc_types"],
|
||||||
|
package_name = PKG_REQUIRE_NAME,
|
||||||
|
tsconfig = ":tsconfig",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "build_types",
|
||||||
|
srcs = [":npm_module_types"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
3
packages/core/node/core-node-server-internal/README.md
Normal file
3
packages/core/node/core-node-server-internal/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# @kbn/core-node-server-internal
|
||||||
|
|
||||||
|
Contains internal code for Core's server-side `node` service.
|
13
packages/core/node/core-node-server-internal/jest.config.js
Normal file
13
packages/core/node/core-node-server-internal/jest.config.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
preset: '@kbn/test/jest_node',
|
||||||
|
rootDir: '../../../..',
|
||||||
|
roots: ['<rootDir>/packages/core/node/core-node-server-internal'],
|
||||||
|
};
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"name": "@kbn/core-node-server-internal",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "./target_node/index.js",
|
||||||
|
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||||
|
}
|
12
packages/core/node/core-node-server-internal/src/index.ts
Normal file
12
packages/core/node/core-node-server-internal/src/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { nodeConfig } from './node_config';
|
||||||
|
|
||||||
|
export { NodeService } from './node_service';
|
||||||
|
export type { InternalNodeServicePreboot } from './node_service';
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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 { schema } from '@kbn/config-schema';
|
||||||
|
import type { ServiceConfigDescriptor } from '@kbn/core-base-server-internal';
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export const NODE_CONFIG_PATH = 'node' as const;
|
||||||
|
/** @internal */
|
||||||
|
export const NODE_WILDCARD_CHAR = '*';
|
||||||
|
/** @internal */
|
||||||
|
export const NODE_ACCEPTED_ROLES = ['background_tasks', 'ui'];
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export interface NodeConfigType {
|
||||||
|
roles: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const configSchema = schema.object({
|
||||||
|
roles: schema.oneOf(
|
||||||
|
[
|
||||||
|
schema.arrayOf(schema.oneOf([schema.literal('background_tasks'), schema.literal('ui')])),
|
||||||
|
schema.arrayOf(schema.literal(NODE_WILDCARD_CHAR), { minSize: 1, maxSize: 1 }),
|
||||||
|
],
|
||||||
|
{
|
||||||
|
defaultValue: [NODE_WILDCARD_CHAR],
|
||||||
|
}
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const nodeConfig: ServiceConfigDescriptor<NodeConfigType> = {
|
||||||
|
path: NODE_CONFIG_PATH,
|
||||||
|
schema: configSchema,
|
||||||
|
};
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* 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 { BehaviorSubject } from 'rxjs';
|
||||||
|
|
||||||
|
import type { CoreContext } from '@kbn/core-base-server-internal';
|
||||||
|
|
||||||
|
import { NodeService } from './node_service';
|
||||||
|
|
||||||
|
import { configServiceMock } from '@kbn/config-mocks';
|
||||||
|
import { mockCoreContext } from '@kbn/core-base-server-mocks';
|
||||||
|
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
||||||
|
|
||||||
|
const getMockedConfigService = (nodeConfig: unknown) => {
|
||||||
|
const configService = configServiceMock.create();
|
||||||
|
configService.atPath.mockImplementation((path) => {
|
||||||
|
if (path === 'node') {
|
||||||
|
return new BehaviorSubject(nodeConfig);
|
||||||
|
}
|
||||||
|
return new BehaviorSubject({});
|
||||||
|
});
|
||||||
|
return configService;
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('NodeService', () => {
|
||||||
|
let logger: ReturnType<typeof loggingSystemMock.create>;
|
||||||
|
let configService: ReturnType<typeof configServiceMock.create>;
|
||||||
|
let coreContext: CoreContext;
|
||||||
|
let service: NodeService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
logger = loggingSystemMock.create();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#preboot()', () => {
|
||||||
|
it('returns default roles values when wildcard is provided', async () => {
|
||||||
|
configService = getMockedConfigService({ roles: ['*'] });
|
||||||
|
coreContext = mockCoreContext.create({ logger, configService });
|
||||||
|
|
||||||
|
service = new NodeService(coreContext);
|
||||||
|
const { roles } = await service.preboot();
|
||||||
|
|
||||||
|
expect(roles.backgroundTasks).toBe(true);
|
||||||
|
expect(roles.ui).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns correct roles when node is configured to `background_tasks`', async () => {
|
||||||
|
configService = getMockedConfigService({ roles: ['background_tasks'] });
|
||||||
|
coreContext = mockCoreContext.create({ logger, configService });
|
||||||
|
|
||||||
|
service = new NodeService(coreContext);
|
||||||
|
const { roles } = await service.preboot();
|
||||||
|
|
||||||
|
expect(roles.backgroundTasks).toBe(true);
|
||||||
|
expect(roles.ui).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns correct roles when node is configured to `ui`', async () => {
|
||||||
|
configService = getMockedConfigService({ roles: ['ui'] });
|
||||||
|
coreContext = mockCoreContext.create({ logger, configService });
|
||||||
|
|
||||||
|
service = new NodeService(coreContext);
|
||||||
|
const { roles } = await service.preboot();
|
||||||
|
|
||||||
|
expect(roles.backgroundTasks).toBe(false);
|
||||||
|
expect(roles.ui).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns correct roles when node is configured to both `background_tasks` and `ui`', async () => {
|
||||||
|
configService = getMockedConfigService({ roles: ['background_tasks', 'ui'] });
|
||||||
|
coreContext = mockCoreContext.create({ logger, configService });
|
||||||
|
|
||||||
|
service = new NodeService(coreContext);
|
||||||
|
const { roles } = await service.preboot();
|
||||||
|
|
||||||
|
expect(roles.backgroundTasks).toBe(true);
|
||||||
|
expect(roles.ui).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('logs the node roles', async () => {
|
||||||
|
const mockLogger = loggingSystemMock.createLogger();
|
||||||
|
logger.get.mockImplementation(() => mockLogger);
|
||||||
|
|
||||||
|
configService = getMockedConfigService({ roles: ['*'] });
|
||||||
|
coreContext = mockCoreContext.create({ logger, configService });
|
||||||
|
|
||||||
|
service = new NodeService(coreContext);
|
||||||
|
await service.preboot();
|
||||||
|
|
||||||
|
expect(logger.get).toHaveBeenCalledTimes(1);
|
||||||
|
expect(logger.get).toHaveBeenCalledWith('node');
|
||||||
|
expect(mockLogger.info).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockLogger.info.mock.calls[0][0]).toMatchInlineSnapshot(
|
||||||
|
`"Kibana process configured with roles: [background_tasks, ui]"`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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 { firstValueFrom } from 'rxjs';
|
||||||
|
import { camelCase } from 'lodash';
|
||||||
|
import type { IConfigService } from '@kbn/config';
|
||||||
|
import type { CoreContext } from '@kbn/core-base-server-internal';
|
||||||
|
import type { NodeRoles } from '@kbn/core-node-server';
|
||||||
|
import type { Logger } from '@kbn/logging';
|
||||||
|
import {
|
||||||
|
NodeConfigType,
|
||||||
|
NODE_WILDCARD_CHAR,
|
||||||
|
NODE_ACCEPTED_ROLES,
|
||||||
|
NODE_CONFIG_PATH,
|
||||||
|
} from './node_config';
|
||||||
|
|
||||||
|
const DEFAULT_ROLES = NODE_ACCEPTED_ROLES;
|
||||||
|
const containsWildcard = (roles: string[]) => roles.includes(NODE_WILDCARD_CHAR);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export interface InternalNodeServicePreboot {
|
||||||
|
/**
|
||||||
|
* Retrieve the Kibana instance uuid.
|
||||||
|
*/
|
||||||
|
roles: NodeRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export class NodeService {
|
||||||
|
private readonly configService: IConfigService;
|
||||||
|
private readonly log: Logger;
|
||||||
|
|
||||||
|
constructor(core: CoreContext) {
|
||||||
|
this.configService = core.configService;
|
||||||
|
this.log = core.logger.get('node');
|
||||||
|
}
|
||||||
|
|
||||||
|
public async preboot(): Promise<InternalNodeServicePreboot> {
|
||||||
|
const nodeRoles = await this.getNodeRoles();
|
||||||
|
this.log.info(`Kibana process configured with roles: [${nodeRoles.join(', ')}]`, {
|
||||||
|
service: {
|
||||||
|
// @ts-expect-error Field not available in ECS until 8.4
|
||||||
|
node: { roles: nodeRoles },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
roles: NODE_ACCEPTED_ROLES.reduce((acc, curr) => {
|
||||||
|
return { ...acc, [camelCase(curr)]: nodeRoles.includes(curr) };
|
||||||
|
}, {} as NodeRoles),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public stop() {
|
||||||
|
// nothing to do here yet
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getNodeRoles(): Promise<string[]> {
|
||||||
|
const { roles } = await firstValueFrom(
|
||||||
|
this.configService.atPath<NodeConfigType>(NODE_CONFIG_PATH)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (containsWildcard(roles)) {
|
||||||
|
return DEFAULT_ROLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
}
|
17
packages/core/node/core-node-server-internal/tsconfig.json
Normal file
17
packages/core/node/core-node-server-internal/tsconfig.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"extends": "../../../../tsconfig.bazel.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"declaration": true,
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"outDir": "target_types",
|
||||||
|
"rootDir": "src",
|
||||||
|
"stripInternal": false,
|
||||||
|
"types": [
|
||||||
|
"jest",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
]
|
||||||
|
}
|
97
packages/core/node/core-node-server-mocks/BUILD.bazel
Normal file
97
packages/core/node/core-node-server-mocks/BUILD.bazel
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||||
|
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||||
|
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||||
|
|
||||||
|
PKG_DIRNAME = "core-node-server-mocks"
|
||||||
|
PKG_REQUIRE_NAME = "@kbn/core-node-server-mocks"
|
||||||
|
|
||||||
|
SOURCE_FILES = glob(
|
||||||
|
[
|
||||||
|
"src/**/*.ts",
|
||||||
|
],
|
||||||
|
exclude = [
|
||||||
|
"**/*.test.*",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
SRCS = SOURCE_FILES
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "srcs",
|
||||||
|
srcs = SRCS,
|
||||||
|
)
|
||||||
|
|
||||||
|
NPM_MODULE_EXTRA_FILES = [
|
||||||
|
"package.json",
|
||||||
|
]
|
||||||
|
|
||||||
|
RUNTIME_DEPS = [
|
||||||
|
'//packages/core/node/core-node-server-internal'
|
||||||
|
]
|
||||||
|
|
||||||
|
TYPES_DEPS = [
|
||||||
|
"@npm//@types/node",
|
||||||
|
"@npm//@types/jest",
|
||||||
|
'//packages/core/node/core-node-server-internal:npm_module_types'
|
||||||
|
]
|
||||||
|
|
||||||
|
jsts_transpiler(
|
||||||
|
name = "target_node",
|
||||||
|
srcs = SRCS,
|
||||||
|
build_pkg_name = package_name(),
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_config(
|
||||||
|
name = "tsconfig",
|
||||||
|
src = "tsconfig.json",
|
||||||
|
deps = [
|
||||||
|
"//:tsconfig.base.json",
|
||||||
|
"//:tsconfig.bazel.json",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_project(
|
||||||
|
name = "tsc_types",
|
||||||
|
args = ['--pretty'],
|
||||||
|
srcs = SRCS,
|
||||||
|
deps = TYPES_DEPS,
|
||||||
|
declaration = True,
|
||||||
|
emit_declaration_only = True,
|
||||||
|
out_dir = "target_types",
|
||||||
|
root_dir = "src",
|
||||||
|
tsconfig = ":tsconfig",
|
||||||
|
)
|
||||||
|
|
||||||
|
js_library(
|
||||||
|
name = PKG_DIRNAME,
|
||||||
|
srcs = NPM_MODULE_EXTRA_FILES,
|
||||||
|
deps = RUNTIME_DEPS + [":target_node"],
|
||||||
|
package_name = PKG_REQUIRE_NAME,
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_npm(
|
||||||
|
name = "npm_module",
|
||||||
|
deps = [":" + PKG_DIRNAME],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "build",
|
||||||
|
srcs = [":npm_module"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_npm_types(
|
||||||
|
name = "npm_module_types",
|
||||||
|
srcs = SRCS,
|
||||||
|
deps = [":tsc_types"],
|
||||||
|
package_name = PKG_REQUIRE_NAME,
|
||||||
|
tsconfig = ":tsconfig",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "build_types",
|
||||||
|
srcs = [":npm_module_types"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
3
packages/core/node/core-node-server-mocks/README.md
Normal file
3
packages/core/node/core-node-server-mocks/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# @kbn/core-node-server-mocks
|
||||||
|
|
||||||
|
Contains mocks for Core's server-side `node` service.
|
13
packages/core/node/core-node-server-mocks/jest.config.js
Normal file
13
packages/core/node/core-node-server-mocks/jest.config.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
preset: '@kbn/test/jest_node',
|
||||||
|
rootDir: '../../../..',
|
||||||
|
roots: ['<rootDir>/packages/core/node/core-node-server-mocks'],
|
||||||
|
};
|
7
packages/core/node/core-node-server-mocks/package.json
Normal file
7
packages/core/node/core-node-server-mocks/package.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"name": "@kbn/core-node-server-mocks",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "./target_node/index.js",
|
||||||
|
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||||
|
}
|
9
packages/core/node/core-node-server-mocks/src/index.ts
Normal file
9
packages/core/node/core-node-server-mocks/src/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { nodeServiceMock } from './node_service.mock';
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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 { PublicMethodsOf } from '@kbn/utility-types';
|
||||||
|
import type { NodeService, InternalNodeServicePreboot } from '@kbn/core-node-server-internal';
|
||||||
|
|
||||||
|
const createInternalPrebootContractMock = () => {
|
||||||
|
const prebootContract: jest.Mocked<InternalNodeServicePreboot> = {
|
||||||
|
roles: {
|
||||||
|
backgroundTasks: true,
|
||||||
|
ui: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return prebootContract;
|
||||||
|
};
|
||||||
|
|
||||||
|
type NodeServiceContract = PublicMethodsOf<NodeService>;
|
||||||
|
const createMock = () => {
|
||||||
|
const mocked: jest.Mocked<NodeServiceContract> = {
|
||||||
|
preboot: jest.fn(),
|
||||||
|
stop: jest.fn(),
|
||||||
|
};
|
||||||
|
mocked.preboot.mockResolvedValue(createInternalPrebootContractMock());
|
||||||
|
return mocked;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const nodeServiceMock = {
|
||||||
|
create: createMock,
|
||||||
|
createInternalPrebootContract: createInternalPrebootContractMock,
|
||||||
|
};
|
17
packages/core/node/core-node-server-mocks/tsconfig.json
Normal file
17
packages/core/node/core-node-server-mocks/tsconfig.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"extends": "../../../../tsconfig.bazel.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"declaration": true,
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"outDir": "target_types",
|
||||||
|
"rootDir": "src",
|
||||||
|
"stripInternal": false,
|
||||||
|
"types": [
|
||||||
|
"jest",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
]
|
||||||
|
}
|
95
packages/core/node/core-node-server/BUILD.bazel
Normal file
95
packages/core/node/core-node-server/BUILD.bazel
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||||
|
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||||
|
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||||
|
|
||||||
|
PKG_DIRNAME = "core-node-server"
|
||||||
|
PKG_REQUIRE_NAME = "@kbn/core-node-server"
|
||||||
|
|
||||||
|
SOURCE_FILES = glob(
|
||||||
|
[
|
||||||
|
"src/**/*.ts",
|
||||||
|
],
|
||||||
|
exclude = [
|
||||||
|
"**/*.test.*",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
SRCS = SOURCE_FILES
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "srcs",
|
||||||
|
srcs = SRCS,
|
||||||
|
)
|
||||||
|
|
||||||
|
NPM_MODULE_EXTRA_FILES = [
|
||||||
|
"package.json",
|
||||||
|
]
|
||||||
|
|
||||||
|
RUNTIME_DEPS = [
|
||||||
|
]
|
||||||
|
|
||||||
|
TYPES_DEPS = [
|
||||||
|
"@npm//@types/node",
|
||||||
|
"@npm//@types/jest",
|
||||||
|
]
|
||||||
|
|
||||||
|
jsts_transpiler(
|
||||||
|
name = "target_node",
|
||||||
|
srcs = SRCS,
|
||||||
|
build_pkg_name = package_name(),
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_config(
|
||||||
|
name = "tsconfig",
|
||||||
|
src = "tsconfig.json",
|
||||||
|
deps = [
|
||||||
|
"//:tsconfig.base.json",
|
||||||
|
"//:tsconfig.bazel.json",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
ts_project(
|
||||||
|
name = "tsc_types",
|
||||||
|
args = ['--pretty'],
|
||||||
|
srcs = SRCS,
|
||||||
|
deps = TYPES_DEPS,
|
||||||
|
declaration = True,
|
||||||
|
emit_declaration_only = True,
|
||||||
|
out_dir = "target_types",
|
||||||
|
root_dir = "src",
|
||||||
|
tsconfig = ":tsconfig",
|
||||||
|
)
|
||||||
|
|
||||||
|
js_library(
|
||||||
|
name = PKG_DIRNAME,
|
||||||
|
srcs = NPM_MODULE_EXTRA_FILES,
|
||||||
|
deps = RUNTIME_DEPS + [":target_node"],
|
||||||
|
package_name = PKG_REQUIRE_NAME,
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_npm(
|
||||||
|
name = "npm_module",
|
||||||
|
deps = [":" + PKG_DIRNAME],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "build",
|
||||||
|
srcs = [":npm_module"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_npm_types(
|
||||||
|
name = "npm_module_types",
|
||||||
|
srcs = SRCS,
|
||||||
|
deps = [":tsc_types"],
|
||||||
|
package_name = PKG_REQUIRE_NAME,
|
||||||
|
tsconfig = ":tsconfig",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "build_types",
|
||||||
|
srcs = [":npm_module_types"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
3
packages/core/node/core-node-server/README.md
Normal file
3
packages/core/node/core-node-server/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# @kbn/core-node-server
|
||||||
|
|
||||||
|
Contains public types for Core's server-side `node` service.
|
13
packages/core/node/core-node-server/jest.config.js
Normal file
13
packages/core/node/core-node-server/jest.config.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
preset: '@kbn/test/jest_node',
|
||||||
|
rootDir: '../../../..',
|
||||||
|
roots: ['<rootDir>/packages/core/node/core-node-server'],
|
||||||
|
};
|
7
packages/core/node/core-node-server/package.json
Normal file
7
packages/core/node/core-node-server/package.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"name": "@kbn/core-node-server",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "./target_node/index.js",
|
||||||
|
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||||
|
}
|
9
packages/core/node/core-node-server/src/index.ts
Normal file
9
packages/core/node/core-node-server/src/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type { NodeInfo, NodeRoles } from './types';
|
40
packages/core/node/core-node-server/src/types.ts
Normal file
40
packages/core/node/core-node-server/src/types.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains information about how this Kibana process has been configured.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface NodeInfo {
|
||||||
|
/** A list of roles this node has been configured with. */
|
||||||
|
roles: NodeRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Kibana process can be run in dedicated "modes" via `node.roles`.
|
||||||
|
* This configuration is then exposed to plugins via `NodeRoles`,
|
||||||
|
* which is available on the `PluginInitializerContext`.
|
||||||
|
*
|
||||||
|
* The node roles can be used by plugins to adjust their behavior based
|
||||||
|
* on the way the Kibana process has been configured.
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface NodeRoles {
|
||||||
|
/**
|
||||||
|
* The backgroundTasks role includes operations which don't involve
|
||||||
|
* responding to incoming http traffic from the UI.
|
||||||
|
*/
|
||||||
|
backgroundTasks: boolean;
|
||||||
|
/**
|
||||||
|
* The ui role covers any operations that need to occur in order
|
||||||
|
* to handle http traffic from the browser.
|
||||||
|
*/
|
||||||
|
ui: boolean;
|
||||||
|
}
|
17
packages/core/node/core-node-server/tsconfig.json
Normal file
17
packages/core/node/core-node-server/tsconfig.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"extends": "../../../../tsconfig.bazel.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"declaration": true,
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"outDir": "target_types",
|
||||||
|
"rootDir": "src",
|
||||||
|
"stripInternal": false,
|
||||||
|
"types": [
|
||||||
|
"jest",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
]
|
||||||
|
}
|
|
@ -262,6 +262,8 @@ export type {
|
||||||
LogLevel,
|
LogLevel,
|
||||||
} from '@kbn/logging';
|
} from '@kbn/logging';
|
||||||
|
|
||||||
|
export type { NodeInfo, NodeRoles } from '@kbn/core-node-server';
|
||||||
|
|
||||||
export { PluginType } from '@kbn/core-base-common';
|
export { PluginType } from '@kbn/core-base-common';
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import type { MockedKeys } from '@kbn/utility-types-jest';
|
||||||
import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks';
|
import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks';
|
||||||
import { loggingSystemMock, loggingServiceMock } from '@kbn/core-logging-server-mocks';
|
import { loggingSystemMock, loggingServiceMock } from '@kbn/core-logging-server-mocks';
|
||||||
import { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
|
import { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
|
||||||
|
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
|
||||||
import type {
|
import type {
|
||||||
PluginInitializerContext,
|
PluginInitializerContext,
|
||||||
CoreSetup,
|
CoreSetup,
|
||||||
|
@ -124,6 +125,7 @@ function pluginInitializerContextMock<T>(config: T = {} as T) {
|
||||||
configs: ['/some/path/to/config/kibana.yml'],
|
configs: ['/some/path/to/config/kibana.yml'],
|
||||||
},
|
},
|
||||||
config: pluginInitializerContextConfigMock<T>(config),
|
config: pluginInitializerContextConfigMock<T>(config),
|
||||||
|
node: nodeServiceMock.createInternalPrebootContract(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return mock;
|
return mock;
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { map, toArray } from 'rxjs/operators';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import { ConfigService, Env } from '@kbn/config';
|
import { ConfigService, Env } from '@kbn/config';
|
||||||
import type { CoreContext } from '@kbn/core-base-server-internal';
|
import type { CoreContext } from '@kbn/core-base-server-internal';
|
||||||
|
import type { NodeInfo } from '@kbn/core-node-server';
|
||||||
import { PluginsConfig, PluginsConfigType, config } from '../plugins_config';
|
import { PluginsConfig, PluginsConfigType, config } from '../plugins_config';
|
||||||
import type { InstanceInfo } from '../plugin_context';
|
import type { InstanceInfo } from '../plugin_context';
|
||||||
import { discover } from './plugins_discovery';
|
import { discover } from './plugins_discovery';
|
||||||
|
@ -128,6 +129,7 @@ const manifestPath = (...pluginPath: string[]) =>
|
||||||
describe('plugins discovery system', () => {
|
describe('plugins discovery system', () => {
|
||||||
let logger: ReturnType<typeof loggingSystemMock.create>;
|
let logger: ReturnType<typeof loggingSystemMock.create>;
|
||||||
let instanceInfo: InstanceInfo;
|
let instanceInfo: InstanceInfo;
|
||||||
|
let nodeInfo: NodeInfo;
|
||||||
let env: Env;
|
let env: Env;
|
||||||
let configService: ConfigService;
|
let configService: ConfigService;
|
||||||
let pluginConfig: PluginsConfigType;
|
let pluginConfig: PluginsConfigType;
|
||||||
|
@ -142,6 +144,13 @@ describe('plugins discovery system', () => {
|
||||||
uuid: 'instance-uuid',
|
uuid: 'instance-uuid',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nodeInfo = {
|
||||||
|
roles: {
|
||||||
|
backgroundTasks: true,
|
||||||
|
ui: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
env = Env.createDefault(
|
env = Env.createDefault(
|
||||||
REPO_ROOT,
|
REPO_ROOT,
|
||||||
getEnvOptions({
|
getEnvOptions({
|
||||||
|
@ -180,7 +189,12 @@ describe('plugins discovery system', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('discovers plugins in the search locations', async () => {
|
it('discovers plugins in the search locations', async () => {
|
||||||
const { plugin$ } = discover(new PluginsConfig(pluginConfig, env), coreContext, instanceInfo);
|
const { plugin$ } = discover({
|
||||||
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
|
coreContext,
|
||||||
|
instanceInfo,
|
||||||
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
mockFs(
|
mockFs(
|
||||||
{
|
{
|
||||||
|
@ -202,11 +216,12 @@ describe('plugins discovery system', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('return errors when the manifest is invalid or incompatible', async () => {
|
it('return errors when the manifest is invalid or incompatible', async () => {
|
||||||
const { plugin$, error$ } = discover(
|
const { plugin$, error$ } = discover({
|
||||||
new PluginsConfig(pluginConfig, env),
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
coreContext,
|
coreContext,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
mockFs(
|
mockFs(
|
||||||
{
|
{
|
||||||
|
@ -268,11 +283,12 @@ describe('plugins discovery system', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('return errors when the plugin search path is not accessible', async () => {
|
it('return errors when the plugin search path is not accessible', async () => {
|
||||||
const { plugin$, error$ } = discover(
|
const { plugin$, error$ } = discover({
|
||||||
new PluginsConfig(pluginConfig, env),
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
coreContext,
|
coreContext,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
mockFs(
|
mockFs(
|
||||||
{
|
{
|
||||||
|
@ -307,11 +323,12 @@ describe('plugins discovery system', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('return an error when the manifest file is not accessible', async () => {
|
it('return an error when the manifest file is not accessible', async () => {
|
||||||
const { plugin$, error$ } = discover(
|
const { plugin$, error$ } = discover({
|
||||||
new PluginsConfig(pluginConfig, env),
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
coreContext,
|
coreContext,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
mockFs(
|
mockFs(
|
||||||
{
|
{
|
||||||
|
@ -342,11 +359,12 @@ describe('plugins discovery system', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('discovers plugins in nested directories', async () => {
|
it('discovers plugins in nested directories', async () => {
|
||||||
const { plugin$, error$ } = discover(
|
const { plugin$, error$ } = discover({
|
||||||
new PluginsConfig(pluginConfig, env),
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
coreContext,
|
coreContext,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
mockFs(
|
mockFs(
|
||||||
{
|
{
|
||||||
|
@ -386,7 +404,12 @@ describe('plugins discovery system', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not discover plugins nested inside another plugin', async () => {
|
it('does not discover plugins nested inside another plugin', async () => {
|
||||||
const { plugin$ } = discover(new PluginsConfig(pluginConfig, env), coreContext, instanceInfo);
|
const { plugin$ } = discover({
|
||||||
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
|
coreContext,
|
||||||
|
instanceInfo,
|
||||||
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
mockFs(
|
mockFs(
|
||||||
{
|
{
|
||||||
|
@ -405,7 +428,12 @@ describe('plugins discovery system', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('stops scanning when reaching `maxDepth`', async () => {
|
it('stops scanning when reaching `maxDepth`', async () => {
|
||||||
const { plugin$ } = discover(new PluginsConfig(pluginConfig, env), coreContext, instanceInfo);
|
const { plugin$ } = discover({
|
||||||
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
|
coreContext,
|
||||||
|
instanceInfo,
|
||||||
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
mockFs(
|
mockFs(
|
||||||
{
|
{
|
||||||
|
@ -430,7 +458,12 @@ describe('plugins discovery system', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works with symlinks', async () => {
|
it('works with symlinks', async () => {
|
||||||
const { plugin$ } = discover(new PluginsConfig(pluginConfig, env), coreContext, instanceInfo);
|
const { plugin$ } = discover({
|
||||||
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
|
coreContext,
|
||||||
|
instanceInfo,
|
||||||
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
const pluginFolder = resolve(KIBANA_ROOT, '..', 'ext-plugins');
|
const pluginFolder = resolve(KIBANA_ROOT, '..', 'ext-plugins');
|
||||||
|
|
||||||
|
@ -465,16 +498,17 @@ describe('plugins discovery system', () => {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
discover(
|
discover({
|
||||||
new PluginsConfig({ ...pluginConfig, paths: [extraPluginTestPath] }, env),
|
config: new PluginsConfig({ ...pluginConfig, paths: [extraPluginTestPath] }, env),
|
||||||
{
|
coreContext: {
|
||||||
coreId: Symbol(),
|
coreId: Symbol(),
|
||||||
configService,
|
configService,
|
||||||
env,
|
env,
|
||||||
logger,
|
logger,
|
||||||
},
|
},
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
expect(loggingSystemMock.collect(logger).warn).toEqual([
|
expect(loggingSystemMock.collect(logger).warn).toEqual([
|
||||||
[
|
[
|
||||||
|
@ -493,16 +527,17 @@ describe('plugins discovery system', () => {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
discover(
|
discover({
|
||||||
new PluginsConfig({ ...pluginConfig, paths: [extraPluginTestPath] }, env),
|
config: new PluginsConfig({ ...pluginConfig, paths: [extraPluginTestPath] }, env),
|
||||||
{
|
coreContext: {
|
||||||
coreId: Symbol(),
|
coreId: Symbol(),
|
||||||
configService,
|
configService,
|
||||||
env,
|
env,
|
||||||
logger,
|
logger,
|
||||||
},
|
},
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
expect(loggingSystemMock.collect(logger).warn).toEqual([]);
|
expect(loggingSystemMock.collect(logger).warn).toEqual([]);
|
||||||
});
|
});
|
||||||
|
@ -530,7 +565,12 @@ describe('plugins discovery system', () => {
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
let { plugin$ } = discover(new PluginsConfig(pluginConfig, env), coreContext, instanceInfo);
|
let { plugin$ } = discover({
|
||||||
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
|
coreContext,
|
||||||
|
instanceInfo,
|
||||||
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
expect(scanPluginSearchPathsMock).toHaveBeenCalledTimes(1);
|
expect(scanPluginSearchPathsMock).toHaveBeenCalledTimes(1);
|
||||||
let plugins = await firstValueFrom(plugin$.pipe(toArray()));
|
let plugins = await firstValueFrom(plugin$.pipe(toArray()));
|
||||||
|
@ -549,7 +589,12 @@ describe('plugins discovery system', () => {
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
plugin$ = discover(new PluginsConfig(pluginConfig, env), coreContext, instanceInfo).plugin$;
|
plugin$ = discover({
|
||||||
|
config: new PluginsConfig(pluginConfig, env),
|
||||||
|
coreContext,
|
||||||
|
instanceInfo,
|
||||||
|
nodeInfo,
|
||||||
|
}).plugin$;
|
||||||
|
|
||||||
expect(scanPluginSearchPathsMock).toHaveBeenCalledTimes(2);
|
expect(scanPluginSearchPathsMock).toHaveBeenCalledTimes(2);
|
||||||
plugins = await firstValueFrom(plugin$.pipe(toArray()));
|
plugins = await firstValueFrom(plugin$.pipe(toArray()));
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { from, merge } from 'rxjs';
|
||||||
import { catchError, filter, map, mergeMap, concatMap, shareReplay, toArray } from 'rxjs/operators';
|
import { catchError, filter, map, mergeMap, concatMap, shareReplay, toArray } from 'rxjs/operators';
|
||||||
import { Logger } from '@kbn/logging';
|
import { Logger } from '@kbn/logging';
|
||||||
import type { CoreContext } from '@kbn/core-base-server-internal';
|
import type { CoreContext } from '@kbn/core-base-server-internal';
|
||||||
|
import type { NodeInfo } from '@kbn/core-node-server';
|
||||||
import { PluginWrapper } from '../plugin';
|
import { PluginWrapper } from '../plugin';
|
||||||
import { createPluginInitializerContext, InstanceInfo } from '../plugin_context';
|
import { createPluginInitializerContext, InstanceInfo } from '../plugin_context';
|
||||||
import { PluginsConfig } from '../plugins_config';
|
import { PluginsConfig } from '../plugins_config';
|
||||||
|
@ -27,11 +28,17 @@ import { scanPluginSearchPaths } from './scan_plugin_search_paths';
|
||||||
* @param coreContext Kibana core values.
|
* @param coreContext Kibana core values.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export function discover(
|
export function discover({
|
||||||
config: PluginsConfig,
|
config,
|
||||||
coreContext: CoreContext,
|
coreContext,
|
||||||
instanceInfo: InstanceInfo
|
instanceInfo,
|
||||||
) {
|
nodeInfo,
|
||||||
|
}: {
|
||||||
|
config: PluginsConfig;
|
||||||
|
coreContext: CoreContext;
|
||||||
|
instanceInfo: InstanceInfo;
|
||||||
|
nodeInfo: NodeInfo;
|
||||||
|
}) {
|
||||||
const log = coreContext.logger.get('plugins-discovery');
|
const log = coreContext.logger.get('plugins-discovery');
|
||||||
log.debug('Discovering plugins...');
|
log.debug('Discovering plugins...');
|
||||||
|
|
||||||
|
@ -55,7 +62,7 @@ export function discover(
|
||||||
}),
|
}),
|
||||||
concatMap((pluginPathOrError) => {
|
concatMap((pluginPathOrError) => {
|
||||||
return typeof pluginPathOrError === 'string'
|
return typeof pluginPathOrError === 'string'
|
||||||
? createPlugin$(pluginPathOrError, log, coreContext, instanceInfo)
|
? createPlugin$(pluginPathOrError, log, coreContext, instanceInfo, nodeInfo)
|
||||||
: [pluginPathOrError];
|
: [pluginPathOrError];
|
||||||
}),
|
}),
|
||||||
shareReplay()
|
shareReplay()
|
||||||
|
@ -78,12 +85,15 @@ export function discover(
|
||||||
* @param path Path to the plugin directory where manifest should be loaded from.
|
* @param path Path to the plugin directory where manifest should be loaded from.
|
||||||
* @param log Plugin discovery logger instance.
|
* @param log Plugin discovery logger instance.
|
||||||
* @param coreContext Kibana core context.
|
* @param coreContext Kibana core context.
|
||||||
|
* @param instanceInfo Info about the instance running Kibana, including uuid.
|
||||||
|
* @param nodeRoles Roles this process has been configured with.
|
||||||
*/
|
*/
|
||||||
function createPlugin$(
|
function createPlugin$(
|
||||||
path: string,
|
path: string,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
coreContext: CoreContext,
|
coreContext: CoreContext,
|
||||||
instanceInfo: InstanceInfo
|
instanceInfo: InstanceInfo,
|
||||||
|
nodeInfo: NodeInfo
|
||||||
) {
|
) {
|
||||||
return from(parseManifest(path, coreContext.env.packageInfo)).pipe(
|
return from(parseManifest(path, coreContext.env.packageInfo)).pipe(
|
||||||
map((manifest) => {
|
map((manifest) => {
|
||||||
|
@ -93,12 +103,13 @@ function createPlugin$(
|
||||||
path,
|
path,
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
catchError((err) => [err])
|
catchError((err) => [err])
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { join } from 'path';
|
||||||
import { ConfigPath, ConfigService, Env } from '@kbn/config';
|
import { ConfigPath, ConfigService, Env } from '@kbn/config';
|
||||||
import { getEnvOptions, rawConfigServiceMock } from '@kbn/config-mocks';
|
import { getEnvOptions, rawConfigServiceMock } from '@kbn/config-mocks';
|
||||||
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
||||||
|
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
|
||||||
import { PluginsService } from '../plugins_service';
|
import { PluginsService } from '../plugins_service';
|
||||||
import { BehaviorSubject, from } from 'rxjs';
|
import { BehaviorSubject, from } from 'rxjs';
|
||||||
import { config } from '../plugins_config';
|
import { config } from '../plugins_config';
|
||||||
|
@ -26,6 +27,7 @@ import { PluginWrapper } from '../plugin';
|
||||||
describe('PluginsService', () => {
|
describe('PluginsService', () => {
|
||||||
const logger = loggingSystemMock.create();
|
const logger = loggingSystemMock.create();
|
||||||
const environmentPreboot = environmentServiceMock.createPrebootContract();
|
const environmentPreboot = environmentServiceMock.createPrebootContract();
|
||||||
|
const nodePreboot = nodeServiceMock.createInternalPrebootContract();
|
||||||
let pluginsService: PluginsService;
|
let pluginsService: PluginsService;
|
||||||
|
|
||||||
const createPlugin = (
|
const createPlugin = (
|
||||||
|
@ -156,7 +158,7 @@ describe('PluginsService', () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
|
|
||||||
const prebootDeps = coreMock.createInternalPreboot();
|
const prebootDeps = coreMock.createInternalPreboot();
|
||||||
await pluginsService.preboot(prebootDeps);
|
await pluginsService.preboot(prebootDeps);
|
||||||
|
|
|
@ -15,6 +15,8 @@ import { Env } from '@kbn/config';
|
||||||
import { configServiceMock, getEnvOptions } from '@kbn/config-mocks';
|
import { configServiceMock, getEnvOptions } from '@kbn/config-mocks';
|
||||||
import type { CoreContext } from '@kbn/core-base-server-internal';
|
import type { CoreContext } from '@kbn/core-base-server-internal';
|
||||||
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
||||||
|
import type { NodeInfo } from '@kbn/core-node-server';
|
||||||
|
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
|
||||||
import { coreMock } from '../mocks';
|
import { coreMock } from '../mocks';
|
||||||
|
|
||||||
import { PluginWrapper } from './plugin';
|
import { PluginWrapper } from './plugin';
|
||||||
|
@ -68,6 +70,7 @@ let coreId: symbol;
|
||||||
let env: Env;
|
let env: Env;
|
||||||
let coreContext: CoreContext;
|
let coreContext: CoreContext;
|
||||||
let instanceInfo: InstanceInfo;
|
let instanceInfo: InstanceInfo;
|
||||||
|
let nodeInfo: NodeInfo;
|
||||||
|
|
||||||
const setupDeps = coreMock.createInternalSetup();
|
const setupDeps = coreMock.createInternalSetup();
|
||||||
|
|
||||||
|
@ -77,6 +80,7 @@ beforeEach(() => {
|
||||||
instanceInfo = {
|
instanceInfo = {
|
||||||
uuid: 'instance-uuid',
|
uuid: 'instance-uuid',
|
||||||
};
|
};
|
||||||
|
nodeInfo = nodeServiceMock.createInternalPrebootContract();
|
||||||
|
|
||||||
coreContext = { coreId, env, logger, configService: configService as any };
|
coreContext = { coreId, env, logger, configService: configService as any };
|
||||||
});
|
});
|
||||||
|
@ -92,12 +96,13 @@ test('`constructor` correctly initializes plugin instance', () => {
|
||||||
path: 'some-plugin-path',
|
path: 'some-plugin-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(plugin.name).toBe('some-plugin-id');
|
expect(plugin.name).toBe('some-plugin-id');
|
||||||
|
@ -116,12 +121,13 @@ describe('`constructor` correctly sets non-external source', () => {
|
||||||
path,
|
path,
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,12 +159,13 @@ test('`setup` fails if `plugin` initializer is not exported', () => {
|
||||||
path: 'plugin-without-initializer-path',
|
path: 'plugin-without-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(() =>
|
expect(() =>
|
||||||
|
@ -175,12 +182,13 @@ test('`setup` fails if plugin initializer is not a function', () => {
|
||||||
path: 'plugin-with-wrong-initializer-path',
|
path: 'plugin-with-wrong-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(() =>
|
expect(() =>
|
||||||
|
@ -197,12 +205,13 @@ test('`setup` fails if initializer does not return object', () => {
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
mockPluginInitializer.mockReturnValue(null);
|
mockPluginInitializer.mockReturnValue(null);
|
||||||
|
@ -221,12 +230,13 @@ test('`setup` fails if object returned from initializer does not define `setup`
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockPluginInstance = { run: jest.fn() };
|
const mockPluginInstance = { run: jest.fn() };
|
||||||
|
@ -242,12 +252,13 @@ test('`setup` fails if object returned from initializer does not define `setup`
|
||||||
test('`setup` initializes plugin and calls appropriate lifecycle hook', async () => {
|
test('`setup` initializes plugin and calls appropriate lifecycle hook', async () => {
|
||||||
const manifest = createPluginManifest();
|
const manifest = createPluginManifest();
|
||||||
const opaqueId = Symbol();
|
const opaqueId = Symbol();
|
||||||
const initializerContext = createPluginInitializerContext(
|
const initializerContext = createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
const plugin = new PluginWrapper({
|
const plugin = new PluginWrapper({
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
|
@ -276,12 +287,13 @@ test('`start` fails if setup is not called first', () => {
|
||||||
path: 'some-plugin-path',
|
path: 'some-plugin-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(() => plugin.start({} as any, {} as any)).toThrowErrorMatchingInlineSnapshot(
|
expect(() => plugin.start({} as any, {} as any)).toThrowErrorMatchingInlineSnapshot(
|
||||||
|
@ -296,12 +308,13 @@ test('`start` fails invoked for the `preboot` plugin', async () => {
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockPluginInstance = { setup: jest.fn() };
|
const mockPluginInstance = { setup: jest.fn() };
|
||||||
|
@ -321,12 +334,13 @@ test('`start` calls plugin.start with context and dependencies', async () => {
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
const context = { any: 'thing' } as any;
|
const context = { any: 'thing' } as any;
|
||||||
const deps = { otherDep: 'value' };
|
const deps = { otherDep: 'value' };
|
||||||
|
@ -355,12 +369,13 @@ test("`start` resolves `startDependencies` Promise after plugin's start", async
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
const startContext = { any: 'thing' } as any;
|
const startContext = { any: 'thing' } as any;
|
||||||
const pluginDeps = { someDep: 'value' };
|
const pluginDeps = { someDep: 'value' };
|
||||||
|
@ -399,12 +414,13 @@ test('`stop` fails if plugin is not set up', async () => {
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockPluginInstance = { setup: jest.fn(), stop: jest.fn() };
|
const mockPluginInstance = { setup: jest.fn(), stop: jest.fn() };
|
||||||
|
@ -423,12 +439,13 @@ test('`stop` does nothing if plugin does not define `stop` function', async () =
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
mockPluginInitializer.mockReturnValue({ setup: jest.fn() });
|
mockPluginInitializer.mockReturnValue({ setup: jest.fn() });
|
||||||
|
@ -444,12 +461,13 @@ test('`stop` calls `stop` defined by the plugin instance', async () => {
|
||||||
path: 'plugin-with-initializer-path',
|
path: 'plugin-with-initializer-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockPluginInstance = { setup: jest.fn(), stop: jest.fn() };
|
const mockPluginInstance = { setup: jest.fn(), stop: jest.fn() };
|
||||||
|
@ -479,12 +497,13 @@ describe('#getConfigSchema()', () => {
|
||||||
path: 'plugin-with-schema',
|
path: 'plugin-with-schema',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(plugin.getConfigDescriptor()).toBe(configDescriptor);
|
expect(plugin.getConfigDescriptor()).toBe(configDescriptor);
|
||||||
|
@ -498,12 +517,13 @@ describe('#getConfigSchema()', () => {
|
||||||
path: 'plugin-with-no-definition',
|
path: 'plugin-with-no-definition',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
expect(plugin.getConfigDescriptor()).toBe(null);
|
expect(plugin.getConfigDescriptor()).toBe(null);
|
||||||
});
|
});
|
||||||
|
@ -515,12 +535,13 @@ describe('#getConfigSchema()', () => {
|
||||||
path: 'plugin-with-no-definition',
|
path: 'plugin-with-no-definition',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
expect(plugin.getConfigDescriptor()).toBe(null);
|
expect(plugin.getConfigDescriptor()).toBe(null);
|
||||||
});
|
});
|
||||||
|
@ -543,12 +564,13 @@ describe('#getConfigSchema()', () => {
|
||||||
path: 'plugin-invalid-schema',
|
path: 'plugin-invalid-schema',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(
|
initializerContext: createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
),
|
nodeInfo,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
expect(() => plugin.getConfigDescriptor()).toThrowErrorMatchingInlineSnapshot(
|
expect(() => plugin.getConfigDescriptor()).toThrowErrorMatchingInlineSnapshot(
|
||||||
`"Configuration schema expected to be an instance of Type"`
|
`"Configuration schema expected to be an instance of Type"`
|
||||||
|
|
|
@ -13,6 +13,8 @@ import { fromRoot } from '@kbn/utils';
|
||||||
import { rawConfigServiceMock, getEnvOptions, configServiceMock } from '@kbn/config-mocks';
|
import { rawConfigServiceMock, getEnvOptions, configServiceMock } from '@kbn/config-mocks';
|
||||||
import type { CoreContext } from '@kbn/core-base-server-internal';
|
import type { CoreContext } from '@kbn/core-base-server-internal';
|
||||||
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
||||||
|
import type { NodeInfo } from '@kbn/core-node-server';
|
||||||
|
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
|
||||||
import {
|
import {
|
||||||
createPluginInitializerContext,
|
createPluginInitializerContext,
|
||||||
createPluginPrebootSetupContext,
|
createPluginPrebootSetupContext,
|
||||||
|
@ -54,6 +56,7 @@ describe('createPluginInitializerContext', () => {
|
||||||
let coreContext: CoreContext;
|
let coreContext: CoreContext;
|
||||||
let server: Server;
|
let server: Server;
|
||||||
let instanceInfo: InstanceInfo;
|
let instanceInfo: InstanceInfo;
|
||||||
|
let nodeInfo: NodeInfo;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
logger = loggingSystemMock.create();
|
logger = loggingSystemMock.create();
|
||||||
|
@ -62,6 +65,7 @@ describe('createPluginInitializerContext', () => {
|
||||||
instanceInfo = {
|
instanceInfo = {
|
||||||
uuid: 'instance-uuid',
|
uuid: 'instance-uuid',
|
||||||
};
|
};
|
||||||
|
nodeInfo = nodeServiceMock.createInternalPrebootContract();
|
||||||
env = Env.createDefault(REPO_ROOT, getEnvOptions());
|
env = Env.createDefault(REPO_ROOT, getEnvOptions());
|
||||||
const config$ = rawConfigServiceMock.create({ rawConfig: {} });
|
const config$ = rawConfigServiceMock.create({ rawConfig: {} });
|
||||||
server = new Server(config$, env, logger);
|
server = new Server(config$, env, logger);
|
||||||
|
@ -96,12 +100,13 @@ describe('createPluginInitializerContext', () => {
|
||||||
configPath: 'plugin',
|
configPath: 'plugin',
|
||||||
});
|
});
|
||||||
|
|
||||||
const pluginInitializerContext = createPluginInitializerContext(
|
const pluginInitializerContext = createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
expect(pluginInitializerContext.config.get()).toEqual({
|
expect(pluginInitializerContext.config.get()).toEqual({
|
||||||
foo: 'bar',
|
foo: 'bar',
|
||||||
|
@ -111,12 +116,13 @@ describe('createPluginInitializerContext', () => {
|
||||||
|
|
||||||
it('config.globalConfig$ should be an observable for the global config', async () => {
|
it('config.globalConfig$ should be an observable for the global config', async () => {
|
||||||
const manifest = createPluginManifest();
|
const manifest = createPluginManifest();
|
||||||
const pluginInitializerContext = createPluginInitializerContext(
|
const pluginInitializerContext = createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
|
|
||||||
expect(pluginInitializerContext.config.legacy.globalConfig$).toBeDefined();
|
expect(pluginInitializerContext.config.legacy.globalConfig$).toBeDefined();
|
||||||
|
|
||||||
|
@ -141,12 +147,13 @@ describe('createPluginInitializerContext', () => {
|
||||||
instanceInfo = {
|
instanceInfo = {
|
||||||
uuid: 'kibana-uuid',
|
uuid: 'kibana-uuid',
|
||||||
};
|
};
|
||||||
const pluginInitializerContext = createPluginInitializerContext(
|
const pluginInitializerContext = createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
manifest,
|
manifest,
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
expect(pluginInitializerContext.env.instanceUuid).toBe('kibana-uuid');
|
expect(pluginInitializerContext.env.instanceUuid).toBe('kibana-uuid');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -160,23 +167,39 @@ describe('createPluginInitializerContext', () => {
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
const pluginInitializerContext = createPluginInitializerContext(
|
const pluginInitializerContext = createPluginInitializerContext({
|
||||||
coreContext,
|
coreContext,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
createPluginManifest(),
|
manifest: createPluginManifest(),
|
||||||
instanceInfo
|
instanceInfo,
|
||||||
);
|
nodeInfo,
|
||||||
|
});
|
||||||
expect(pluginInitializerContext.env.configs).toEqual([
|
expect(pluginInitializerContext.env.configs).toEqual([
|
||||||
'/home/kibana/config/kibana.yml',
|
'/home/kibana/config/kibana.yml',
|
||||||
'/home/kibana/config/kibana.dev.yml',
|
'/home/kibana/config/kibana.dev.yml',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('context.node', () => {
|
||||||
|
it('should expose the correct node roles', () => {
|
||||||
|
const pluginInitializerContext = createPluginInitializerContext({
|
||||||
|
coreContext,
|
||||||
|
opaqueId,
|
||||||
|
manifest: createPluginManifest(),
|
||||||
|
instanceInfo,
|
||||||
|
nodeInfo: { roles: { backgroundTasks: false, ui: true } },
|
||||||
|
});
|
||||||
|
expect(pluginInitializerContext.node.roles.backgroundTasks).toBe(false);
|
||||||
|
expect(pluginInitializerContext.node.roles.ui).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('createPluginPrebootSetupContext', () => {
|
describe('createPluginPrebootSetupContext', () => {
|
||||||
let coreContext: CoreContext;
|
let coreContext: CoreContext;
|
||||||
let opaqueId: symbol;
|
let opaqueId: symbol;
|
||||||
|
let nodeInfo: NodeInfo;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
opaqueId = Symbol();
|
opaqueId = Symbol();
|
||||||
|
@ -186,6 +209,7 @@ describe('createPluginPrebootSetupContext', () => {
|
||||||
logger: loggingSystemMock.create(),
|
logger: loggingSystemMock.create(),
|
||||||
configService: configServiceMock.create(),
|
configService: configServiceMock.create(),
|
||||||
};
|
};
|
||||||
|
nodeInfo = nodeServiceMock.createInternalPrebootContract();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('`holdSetupUntilResolved` captures plugin.name', () => {
|
it('`holdSetupUntilResolved` captures plugin.name', () => {
|
||||||
|
@ -194,8 +218,14 @@ describe('createPluginPrebootSetupContext', () => {
|
||||||
path: 'some-path',
|
path: 'some-path',
|
||||||
manifest,
|
manifest,
|
||||||
opaqueId,
|
opaqueId,
|
||||||
initializerContext: createPluginInitializerContext(coreContext, opaqueId, manifest, {
|
initializerContext: createPluginInitializerContext({
|
||||||
uuid: 'instance-uuid',
|
coreContext,
|
||||||
|
opaqueId,
|
||||||
|
manifest,
|
||||||
|
instanceInfo: {
|
||||||
|
uuid: 'instance-uuid',
|
||||||
|
},
|
||||||
|
nodeInfo,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
import { shareReplay } from 'rxjs/operators';
|
import { shareReplay } from 'rxjs/operators';
|
||||||
import type { CoreContext } from '@kbn/core-base-server-internal';
|
import type { CoreContext } from '@kbn/core-base-server-internal';
|
||||||
import type { PluginOpaqueId } from '@kbn/core-base-common';
|
import type { PluginOpaqueId } from '@kbn/core-base-common';
|
||||||
|
import type { NodeInfo } from '@kbn/core-node-server';
|
||||||
import type { RequestHandlerContext } from '..';
|
import type { RequestHandlerContext } from '..';
|
||||||
import { PluginWrapper } from './plugin';
|
import { PluginWrapper } from './plugin';
|
||||||
import {
|
import {
|
||||||
|
@ -21,6 +22,7 @@ import { IRouter, RequestHandlerContextProvider } from '../http';
|
||||||
import { getGlobalConfig, getGlobalConfig$ } from './legacy_config';
|
import { getGlobalConfig, getGlobalConfig$ } from './legacy_config';
|
||||||
import { CorePreboot, CoreSetup, CoreStart } from '..';
|
import { CorePreboot, CoreSetup, CoreStart } from '..';
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
export interface InstanceInfo {
|
export interface InstanceInfo {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
}
|
}
|
||||||
|
@ -35,15 +37,26 @@ export interface InstanceInfo {
|
||||||
* We should aim to be restrictive and specific in the APIs that we expose.
|
* We should aim to be restrictive and specific in the APIs that we expose.
|
||||||
*
|
*
|
||||||
* @param coreContext Kibana core context
|
* @param coreContext Kibana core context
|
||||||
* @param pluginManifest The manifest of the plugin we're building these values for.
|
* @param opaqueId The opaque id created for this particular plugin.
|
||||||
|
* @param manifest The manifest of the plugin we're building these values for.
|
||||||
|
* @param instanceInfo Info about the instance Kibana is running on.
|
||||||
|
* @param nodeInfo Info about how the Kibana process has been configured.
|
||||||
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export function createPluginInitializerContext(
|
export function createPluginInitializerContext({
|
||||||
coreContext: CoreContext,
|
coreContext,
|
||||||
opaqueId: PluginOpaqueId,
|
opaqueId,
|
||||||
pluginManifest: PluginManifest,
|
manifest,
|
||||||
instanceInfo: InstanceInfo
|
instanceInfo,
|
||||||
): PluginInitializerContext {
|
nodeInfo,
|
||||||
|
}: {
|
||||||
|
coreContext: CoreContext;
|
||||||
|
opaqueId: PluginOpaqueId;
|
||||||
|
manifest: PluginManifest;
|
||||||
|
instanceInfo: InstanceInfo;
|
||||||
|
nodeInfo: NodeInfo;
|
||||||
|
}): PluginInitializerContext {
|
||||||
return {
|
return {
|
||||||
opaqueId,
|
opaqueId,
|
||||||
|
|
||||||
|
@ -57,12 +70,23 @@ export function createPluginInitializerContext(
|
||||||
configs: coreContext.env.configs,
|
configs: coreContext.env.configs,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access the configuration for this particular Kibana node.
|
||||||
|
* Can be used to determine which `roles` the current process was started with.
|
||||||
|
*/
|
||||||
|
node: {
|
||||||
|
roles: {
|
||||||
|
backgroundTasks: nodeInfo.roles.backgroundTasks,
|
||||||
|
ui: nodeInfo.roles.ui,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin-scoped logger
|
* Plugin-scoped logger
|
||||||
*/
|
*/
|
||||||
logger: {
|
logger: {
|
||||||
get(...contextParts) {
|
get(...contextParts) {
|
||||||
return coreContext.logger.get('plugins', pluginManifest.id, ...contextParts);
|
return coreContext.logger.get('plugins', manifest.id, ...contextParts);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -80,10 +104,10 @@ export function createPluginInitializerContext(
|
||||||
* manifest.
|
* manifest.
|
||||||
*/
|
*/
|
||||||
create<T>() {
|
create<T>() {
|
||||||
return coreContext.configService.atPath<T>(pluginManifest.configPath).pipe(shareReplay(1));
|
return coreContext.configService.atPath<T>(manifest.configPath).pipe(shareReplay(1));
|
||||||
},
|
},
|
||||||
get<T>() {
|
get<T>() {
|
||||||
return coreContext.configService.atPathSync<T>(pluginManifest.configPath);
|
return coreContext.configService.atPathSync<T>(manifest.configPath);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { ConfigPath, ConfigService, Env } from '@kbn/config';
|
||||||
|
|
||||||
import { rawConfigServiceMock, getEnvOptions } from '@kbn/config-mocks';
|
import { rawConfigServiceMock, getEnvOptions } from '@kbn/config-mocks';
|
||||||
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
||||||
|
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
|
||||||
import { coreMock } from '../mocks';
|
import { coreMock } from '../mocks';
|
||||||
import { environmentServiceMock } from '../environment/environment_service.mock';
|
import { environmentServiceMock } from '../environment/environment_service.mock';
|
||||||
import { PluginDiscoveryError } from './discovery';
|
import { PluginDiscoveryError } from './discovery';
|
||||||
|
@ -37,6 +38,7 @@ let env: Env;
|
||||||
let prebootMockPluginSystem: jest.Mocked<PluginsSystem<PluginType.preboot>>;
|
let prebootMockPluginSystem: jest.Mocked<PluginsSystem<PluginType.preboot>>;
|
||||||
let standardMockPluginSystem: jest.Mocked<PluginsSystem<PluginType.standard>>;
|
let standardMockPluginSystem: jest.Mocked<PluginsSystem<PluginType.standard>>;
|
||||||
let environmentPreboot: ReturnType<typeof environmentServiceMock.createPrebootContract>;
|
let environmentPreboot: ReturnType<typeof environmentServiceMock.createPrebootContract>;
|
||||||
|
let nodePreboot: ReturnType<typeof nodeServiceMock.createInternalPrebootContract>;
|
||||||
|
|
||||||
const prebootDeps = coreMock.createInternalPreboot();
|
const prebootDeps = coreMock.createInternalPreboot();
|
||||||
const setupDeps = coreMock.createInternalSetup();
|
const setupDeps = coreMock.createInternalSetup();
|
||||||
|
@ -140,6 +142,7 @@ async function testSetup() {
|
||||||
standardMockPluginSystem.getPlugins.mockReturnValue([]);
|
standardMockPluginSystem.getPlugins.mockReturnValue([]);
|
||||||
|
|
||||||
environmentPreboot = environmentServiceMock.createPrebootContract();
|
environmentPreboot = environmentServiceMock.createPrebootContract();
|
||||||
|
nodePreboot = nodeServiceMock.createInternalPrebootContract();
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -158,8 +161,8 @@ describe('PluginsService', () => {
|
||||||
plugin$: from([]),
|
plugin$: from([]),
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(pluginsService.discover({ environment: environmentPreboot })).rejects
|
await expect(pluginsService.discover({ environment: environmentPreboot, node: nodePreboot }))
|
||||||
.toMatchInlineSnapshot(`
|
.rejects.toMatchInlineSnapshot(`
|
||||||
[Error: Failed to initialize plugins:
|
[Error: Failed to initialize plugins:
|
||||||
Invalid JSON (invalid-manifest, path-1)]
|
Invalid JSON (invalid-manifest, path-1)]
|
||||||
`);
|
`);
|
||||||
|
@ -180,8 +183,8 @@ describe('PluginsService', () => {
|
||||||
plugin$: from([]),
|
plugin$: from([]),
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(pluginsService.discover({ environment: environmentPreboot })).rejects
|
await expect(pluginsService.discover({ environment: environmentPreboot, node: nodePreboot }))
|
||||||
.toMatchInlineSnapshot(`
|
.rejects.toMatchInlineSnapshot(`
|
||||||
[Error: Failed to initialize plugins:
|
[Error: Failed to initialize plugins:
|
||||||
Incompatible version (incompatible-version, path-3)]
|
Incompatible version (incompatible-version, path-3)]
|
||||||
`);
|
`);
|
||||||
|
@ -216,7 +219,7 @@ describe('PluginsService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
pluginsService.discover({ environment: environmentPreboot })
|
pluginsService.discover({ environment: environmentPreboot, node: nodePreboot })
|
||||||
).rejects.toMatchInlineSnapshot(
|
).rejects.toMatchInlineSnapshot(
|
||||||
`[Error: Plugin with id "conflicting-id" is already registered!]`
|
`[Error: Plugin with id "conflicting-id" is already registered!]`
|
||||||
);
|
);
|
||||||
|
@ -250,7 +253,7 @@ describe('PluginsService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
pluginsService.discover({ environment: environmentPreboot })
|
pluginsService.discover({ environment: environmentPreboot, node: nodePreboot })
|
||||||
).rejects.toMatchInlineSnapshot(
|
).rejects.toMatchInlineSnapshot(
|
||||||
`[Error: Plugin with id "conflicting-id" is already registered!]`
|
`[Error: Plugin with id "conflicting-id" is already registered!]`
|
||||||
);
|
);
|
||||||
|
@ -288,16 +291,18 @@ describe('PluginsService', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function expectError() {
|
async function expectError() {
|
||||||
await expect(pluginsService.discover({ environment: environmentPreboot })).rejects.toThrow(
|
await expect(
|
||||||
|
pluginsService.discover({ environment: environmentPreboot, node: nodePreboot })
|
||||||
|
).rejects.toThrow(
|
||||||
`X-Pack plugin or bundle with id "xPackPlugin" is required by OSS plugin "sourcePlugin", which is prohibited. Consider making this an optional dependency instead.`
|
`X-Pack plugin or bundle with id "xPackPlugin" is required by OSS plugin "sourcePlugin", which is prohibited. Consider making this an optional dependency instead.`
|
||||||
);
|
);
|
||||||
expect(standardMockPluginSystem.addPlugin).not.toHaveBeenCalled();
|
expect(standardMockPluginSystem.addPlugin).not.toHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function expectSuccess() {
|
async function expectSuccess() {
|
||||||
await expect(pluginsService.discover({ environment: environmentPreboot })).resolves.toEqual(
|
await expect(
|
||||||
expect.anything()
|
pluginsService.discover({ environment: environmentPreboot, node: nodePreboot })
|
||||||
);
|
).resolves.toEqual(expect.anything());
|
||||||
expect(standardMockPluginSystem.addPlugin).toHaveBeenCalled();
|
expect(standardMockPluginSystem.addPlugin).toHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +438,7 @@ describe('PluginsService', () => {
|
||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
|
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
await pluginsService.preboot(prebootDeps);
|
await pluginsService.preboot(prebootDeps);
|
||||||
const setup = await pluginsService.setup(setupDeps);
|
const setup = await pluginsService.setup(setupDeps);
|
||||||
|
|
||||||
|
@ -521,6 +526,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
const { preboot, standard } = await pluginsService.discover({
|
const { preboot, standard } = await pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
});
|
});
|
||||||
expect(mockDiscover).toHaveBeenCalledTimes(1);
|
expect(mockDiscover).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
@ -562,6 +568,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
const { preboot, standard } = await pluginsService.discover({
|
const { preboot, standard } = await pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
});
|
});
|
||||||
expect(preboot.pluginTree).toBeUndefined();
|
expect(preboot.pluginTree).toBeUndefined();
|
||||||
expect(standard.pluginTree).toBeUndefined();
|
expect(standard.pluginTree).toBeUndefined();
|
||||||
|
@ -630,6 +637,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
const { standard, preboot } = await pluginsService.discover({
|
const { standard, preboot } = await pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
});
|
});
|
||||||
expect(mockDiscover).toHaveBeenCalledTimes(1);
|
expect(mockDiscover).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
@ -696,7 +704,7 @@ describe('PluginsService', () => {
|
||||||
plugin$: from([...prebootPlugins, ...standardPlugins]),
|
plugin$: from([...prebootPlugins, ...standardPlugins]),
|
||||||
});
|
});
|
||||||
|
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
expect(prebootMockPluginSystem.addPlugin).toHaveBeenCalledTimes(2);
|
expect(prebootMockPluginSystem.addPlugin).toHaveBeenCalledTimes(2);
|
||||||
for (const plugin of prebootPlugins) {
|
for (const plugin of prebootPlugins) {
|
||||||
expect(prebootMockPluginSystem.addPlugin).toHaveBeenCalledWith(plugin);
|
expect(prebootMockPluginSystem.addPlugin).toHaveBeenCalledWith(plugin);
|
||||||
|
@ -708,8 +716,8 @@ describe('PluginsService', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(mockDiscover).toHaveBeenCalledTimes(1);
|
expect(mockDiscover).toHaveBeenCalledTimes(1);
|
||||||
expect(mockDiscover).toHaveBeenCalledWith(
|
expect(mockDiscover).toHaveBeenCalledWith({
|
||||||
{
|
config: {
|
||||||
additionalPluginPaths: [],
|
additionalPluginPaths: [],
|
||||||
initialize: true,
|
initialize: true,
|
||||||
pluginSearchPaths: [
|
pluginSearchPaths: [
|
||||||
|
@ -719,9 +727,10 @@ describe('PluginsService', () => {
|
||||||
resolve(process.cwd(), '..', 'kibana-extra'),
|
resolve(process.cwd(), '..', 'kibana-extra'),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ coreId, env, logger, configService },
|
coreContext: { coreId, env, logger, configService },
|
||||||
{ uuid: 'uuid' }
|
instanceInfo: { uuid: 'uuid' },
|
||||||
);
|
nodeInfo: { roles: { backgroundTasks: true, ui: true } },
|
||||||
|
});
|
||||||
|
|
||||||
const logs = loggingSystemMock.collect(logger);
|
const logs = loggingSystemMock.collect(logger);
|
||||||
expect(logs.info).toHaveLength(0);
|
expect(logs.info).toHaveLength(0);
|
||||||
|
@ -756,7 +765,7 @@ describe('PluginsService', () => {
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
expect(configService.setSchema).toBeCalledWith('path-preboot', configSchema);
|
expect(configService.setSchema).toBeCalledWith('path-preboot', configSchema);
|
||||||
expect(configService.setSchema).toBeCalledWith('path-standard', configSchema);
|
expect(configService.setSchema).toBeCalledWith('path-standard', configSchema);
|
||||||
});
|
});
|
||||||
|
@ -794,7 +803,7 @@ describe('PluginsService', () => {
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
expect(configService.addDeprecationProvider).toBeCalledWith(
|
expect(configService.addDeprecationProvider).toBeCalledWith(
|
||||||
'config-path-preboot',
|
'config-path-preboot',
|
||||||
prebootDeprecationProvider
|
prebootDeprecationProvider
|
||||||
|
@ -837,6 +846,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
const { preboot, standard } = await pluginsService.discover({
|
const { preboot, standard } = await pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(preboot.pluginPaths).toEqual(['/plugin-A-path-preboot', '/plugin-B-path-preboot']);
|
expect(preboot.pluginPaths).toEqual(['/plugin-A-path-preboot', '/plugin-B-path-preboot']);
|
||||||
|
@ -926,7 +936,7 @@ describe('PluginsService', () => {
|
||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
|
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
|
|
||||||
// eslint-disable-next-line dot-notation
|
// eslint-disable-next-line dot-notation
|
||||||
expect(pluginsService['pluginConfigUsageDescriptors']).toMatchInlineSnapshot(`
|
expect(pluginsService['pluginConfigUsageDescriptors']).toMatchInlineSnapshot(`
|
||||||
|
@ -1008,6 +1018,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
const { preboot, standard } = await pluginsService.discover({
|
const { preboot, standard } = await pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
});
|
});
|
||||||
|
|
||||||
const prebootUIConfig$ = preboot.uiPlugins.browserConfigs.get('plugin-with-expose-preboot')!;
|
const prebootUIConfig$ = preboot.uiPlugins.browserConfigs.get('plugin-with-expose-preboot')!;
|
||||||
|
@ -1062,6 +1073,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
const { preboot, standard } = await pluginsService.discover({
|
const { preboot, standard } = await pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
});
|
});
|
||||||
expect(preboot.uiPlugins.browserConfigs.size).toBe(0);
|
expect(preboot.uiPlugins.browserConfigs.size).toBe(0);
|
||||||
expect(standard.uiPlugins.browserConfigs.size).toBe(0);
|
expect(standard.uiPlugins.browserConfigs.size).toBe(0);
|
||||||
|
@ -1125,6 +1137,7 @@ describe('PluginsService', () => {
|
||||||
await expect(
|
await expect(
|
||||||
pluginsService.discover({
|
pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
})
|
})
|
||||||
).resolves.not.toThrow(); // If the rename is not applied, it'll fail
|
).resolves.not.toThrow(); // If the rename is not applied, it'll fail
|
||||||
});
|
});
|
||||||
|
@ -1185,6 +1198,7 @@ describe('PluginsService', () => {
|
||||||
});
|
});
|
||||||
const { preboot, standard } = await pluginsService.discover({
|
const { preboot, standard } = await pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
});
|
});
|
||||||
expect(preboot.uiPlugins.internal).toMatchInlineSnapshot(`
|
expect(preboot.uiPlugins.internal).toMatchInlineSnapshot(`
|
||||||
Map {
|
Map {
|
||||||
|
@ -1228,6 +1242,7 @@ describe('PluginsService', () => {
|
||||||
});
|
});
|
||||||
const { preboot, standard } = await pluginsService.discover({
|
const { preboot, standard } = await pluginsService.discover({
|
||||||
environment: environmentPreboot,
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
});
|
});
|
||||||
expect([...preboot.uiPlugins.internal.keys()].sort()).toMatchInlineSnapshot(`
|
expect([...preboot.uiPlugins.internal.keys()].sort()).toMatchInlineSnapshot(`
|
||||||
Array [
|
Array [
|
||||||
|
@ -1245,7 +1260,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
it('#preboot does initialize `preboot` plugins if plugins.initialize is true', async () => {
|
it('#preboot does initialize `preboot` plugins if plugins.initialize is true', async () => {
|
||||||
config$.next({ plugins: { initialize: true } });
|
config$.next({ plugins: { initialize: true } });
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
await pluginsService.preboot(prebootDeps);
|
await pluginsService.preboot(prebootDeps);
|
||||||
|
|
||||||
expect(prebootMockPluginSystem.setupPlugins).toHaveBeenCalledTimes(1);
|
expect(prebootMockPluginSystem.setupPlugins).toHaveBeenCalledTimes(1);
|
||||||
|
@ -1255,7 +1270,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
it('#preboot does not initialize `preboot` plugins if plugins.initialize is false', async () => {
|
it('#preboot does not initialize `preboot` plugins if plugins.initialize is false', async () => {
|
||||||
config$.next({ plugins: { initialize: false } });
|
config$.next({ plugins: { initialize: false } });
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
await pluginsService.preboot(prebootDeps);
|
await pluginsService.preboot(prebootDeps);
|
||||||
|
|
||||||
expect(prebootMockPluginSystem.setupPlugins).not.toHaveBeenCalled();
|
expect(prebootMockPluginSystem.setupPlugins).not.toHaveBeenCalled();
|
||||||
|
@ -1264,7 +1279,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
it('#setup does initialize `standard` plugins if plugins.initialize is true', async () => {
|
it('#setup does initialize `standard` plugins if plugins.initialize is true', async () => {
|
||||||
config$.next({ plugins: { initialize: true } });
|
config$.next({ plugins: { initialize: true } });
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
await pluginsService.preboot(prebootDeps);
|
await pluginsService.preboot(prebootDeps);
|
||||||
|
|
||||||
const { initialized } = await pluginsService.setup(setupDeps);
|
const { initialized } = await pluginsService.setup(setupDeps);
|
||||||
|
@ -1275,7 +1290,7 @@ describe('PluginsService', () => {
|
||||||
|
|
||||||
it('#setup does not initialize `standard` plugins if plugins.initialize is false', async () => {
|
it('#setup does not initialize `standard` plugins if plugins.initialize is false', async () => {
|
||||||
config$.next({ plugins: { initialize: false } });
|
config$.next({ plugins: { initialize: false } });
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
await pluginsService.preboot(prebootDeps);
|
await pluginsService.preboot(prebootDeps);
|
||||||
const { initialized } = await pluginsService.setup(setupDeps);
|
const { initialized } = await pluginsService.setup(setupDeps);
|
||||||
expect(standardMockPluginSystem.setupPlugins).not.toHaveBeenCalled();
|
expect(standardMockPluginSystem.setupPlugins).not.toHaveBeenCalled();
|
||||||
|
@ -1312,7 +1327,7 @@ describe('PluginsService', () => {
|
||||||
it('does not try to stop `preboot` plugins and start `standard` ones if plugins.initialize is `false`', async () => {
|
it('does not try to stop `preboot` plugins and start `standard` ones if plugins.initialize is `false`', async () => {
|
||||||
config$.next({ plugins: { initialize: false } });
|
config$.next({ plugins: { initialize: false } });
|
||||||
|
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
await pluginsService.preboot(prebootDeps);
|
await pluginsService.preboot(prebootDeps);
|
||||||
await pluginsService.setup(setupDeps);
|
await pluginsService.setup(setupDeps);
|
||||||
|
|
||||||
|
@ -1325,7 +1340,7 @@ describe('PluginsService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('stops `preboot` plugins and starts `standard` ones', async () => {
|
it('stops `preboot` plugins and starts `standard` ones', async () => {
|
||||||
await pluginsService.discover({ environment: environmentPreboot });
|
await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
|
||||||
await pluginsService.preboot(prebootDeps);
|
await pluginsService.preboot(prebootDeps);
|
||||||
await pluginsService.setup(setupDeps);
|
await pluginsService.setup(setupDeps);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { Logger } from '@kbn/logging';
|
||||||
import type { IConfigService } from '@kbn/config';
|
import type { IConfigService } from '@kbn/config';
|
||||||
import type { CoreContext, CoreService } from '@kbn/core-base-server-internal';
|
import type { CoreContext, CoreService } from '@kbn/core-base-server-internal';
|
||||||
import type { PluginName } from '@kbn/core-base-common';
|
import type { PluginName } from '@kbn/core-base-common';
|
||||||
|
import type { InternalNodeServicePreboot } from '@kbn/core-node-server-internal';
|
||||||
import { discover, PluginDiscoveryError, PluginDiscoveryErrorType } from './discovery';
|
import { discover, PluginDiscoveryError, PluginDiscoveryErrorType } from './discovery';
|
||||||
import { PluginWrapper } from './plugin';
|
import { PluginWrapper } from './plugin';
|
||||||
import {
|
import {
|
||||||
|
@ -84,6 +85,7 @@ export type PluginsServiceStartDeps = InternalCoreStart;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export interface PluginsServiceDiscoverDeps {
|
export interface PluginsServiceDiscoverDeps {
|
||||||
environment: InternalEnvironmentServicePreboot;
|
environment: InternalEnvironmentServicePreboot;
|
||||||
|
node: InternalNodeServicePreboot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
|
@ -109,11 +111,21 @@ export class PluginsService implements CoreService<PluginsServiceSetup, PluginsS
|
||||||
this.standardPluginsSystem = new PluginsSystem(this.coreContext, PluginType.standard);
|
this.standardPluginsSystem = new PluginsSystem(this.coreContext, PluginType.standard);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async discover({ environment }: PluginsServiceDiscoverDeps): Promise<DiscoveredPlugins> {
|
public async discover({
|
||||||
|
environment,
|
||||||
|
node,
|
||||||
|
}: PluginsServiceDiscoverDeps): Promise<DiscoveredPlugins> {
|
||||||
const config = await firstValueFrom(this.config$);
|
const config = await firstValueFrom(this.config$);
|
||||||
|
|
||||||
const { error$, plugin$ } = discover(config, this.coreContext, {
|
const { error$, plugin$ } = discover({
|
||||||
uuid: environment.instanceUuid,
|
config,
|
||||||
|
coreContext: this.coreContext,
|
||||||
|
instanceInfo: {
|
||||||
|
uuid: environment.instanceUuid,
|
||||||
|
},
|
||||||
|
nodeInfo: {
|
||||||
|
roles: node.roles,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.handleDiscoveryErrors(error$);
|
await this.handleDiscoveryErrors(error$);
|
||||||
|
|
|
@ -18,6 +18,7 @@ import type {
|
||||||
ConfigDeprecationProvider,
|
ConfigDeprecationProvider,
|
||||||
} from '@kbn/config';
|
} from '@kbn/config';
|
||||||
import type { PluginName, PluginOpaqueId, PluginType } from '@kbn/core-base-common';
|
import type { PluginName, PluginOpaqueId, PluginType } from '@kbn/core-base-common';
|
||||||
|
import type { NodeInfo } from '@kbn/core-node-server';
|
||||||
|
|
||||||
import { ElasticsearchConfigType } from '../elasticsearch/elasticsearch_config';
|
import { ElasticsearchConfigType } from '../elasticsearch/elasticsearch_config';
|
||||||
import { SavedObjectsConfigType } from '../saved_objects/saved_objects_config';
|
import { SavedObjectsConfigType } from '../saved_objects/saved_objects_config';
|
||||||
|
@ -354,6 +355,29 @@ export interface PluginInitializerContext<ConfigSchema = unknown> {
|
||||||
instanceUuid: string;
|
instanceUuid: string;
|
||||||
configs: readonly string[];
|
configs: readonly string[];
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Access the configuration for this particular Kibana node.
|
||||||
|
* Can be used to determine which `roles` the current process was started with.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* // plugins/my-plugin/server/plugin.ts
|
||||||
|
*
|
||||||
|
* export class MyPlugin implements Plugin {
|
||||||
|
* constructor(private readonly initContext: PluginInitializerContext) {
|
||||||
|
* this.initContext = initContext;
|
||||||
|
* }
|
||||||
|
* setup() {
|
||||||
|
* if (this.initContext.node.roles.backgroundTasks) {
|
||||||
|
* // run background tasks
|
||||||
|
* } else if (this.initContext.node.roles.ui) {
|
||||||
|
* // register http routes, etc
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
node: NodeInfo;
|
||||||
/**
|
/**
|
||||||
* {@link LoggerFactory | logger factory} instance already bound to the plugin's logging context
|
* {@link LoggerFactory | logger factory} instance already bound to the plugin's logging context
|
||||||
*
|
*
|
||||||
|
|
|
@ -75,6 +75,13 @@ jest.doMock('./environment/environment_service', () => ({
|
||||||
EnvironmentService: jest.fn(() => mockEnvironmentService),
|
EnvironmentService: jest.fn(() => mockEnvironmentService),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
|
||||||
|
|
||||||
|
export const mockNodeService = nodeServiceMock.create();
|
||||||
|
jest.doMock('@kbn/core-node-server-internal', () => ({
|
||||||
|
NodeService: jest.fn(() => mockNodeService),
|
||||||
|
}));
|
||||||
|
|
||||||
import { metricsServiceMock } from './metrics/metrics_service.mock';
|
import { metricsServiceMock } from './metrics/metrics_service.mock';
|
||||||
|
|
||||||
export const mockMetricsService = metricsServiceMock.create();
|
export const mockMetricsService = metricsServiceMock.create();
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
mockLoggingService,
|
mockLoggingService,
|
||||||
mockI18nService,
|
mockI18nService,
|
||||||
mockEnvironmentService,
|
mockEnvironmentService,
|
||||||
|
mockNodeService,
|
||||||
mockPrebootService,
|
mockPrebootService,
|
||||||
mockDeprecationService,
|
mockDeprecationService,
|
||||||
mockDocLinksService,
|
mockDocLinksService,
|
||||||
|
@ -62,6 +63,7 @@ test('preboot services on "preboot"', async () => {
|
||||||
const server = new Server(rawConfigService, env, logger);
|
const server = new Server(rawConfigService, env, logger);
|
||||||
|
|
||||||
expect(mockEnvironmentService.preboot).not.toHaveBeenCalled();
|
expect(mockEnvironmentService.preboot).not.toHaveBeenCalled();
|
||||||
|
expect(mockNodeService.preboot).not.toHaveBeenCalled();
|
||||||
expect(mockContextService.preboot).not.toHaveBeenCalled();
|
expect(mockContextService.preboot).not.toHaveBeenCalled();
|
||||||
expect(mockHttpService.preboot).not.toHaveBeenCalled();
|
expect(mockHttpService.preboot).not.toHaveBeenCalled();
|
||||||
expect(mockI18nService.preboot).not.toHaveBeenCalled();
|
expect(mockI18nService.preboot).not.toHaveBeenCalled();
|
||||||
|
@ -75,6 +77,7 @@ test('preboot services on "preboot"', async () => {
|
||||||
await server.preboot();
|
await server.preboot();
|
||||||
|
|
||||||
expect(mockEnvironmentService.preboot).toHaveBeenCalledTimes(1);
|
expect(mockEnvironmentService.preboot).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockNodeService.preboot).toHaveBeenCalledTimes(1);
|
||||||
expect(mockContextService.preboot).toHaveBeenCalledTimes(1);
|
expect(mockContextService.preboot).toHaveBeenCalledTimes(1);
|
||||||
expect(mockHttpService.preboot).toHaveBeenCalledTimes(1);
|
expect(mockHttpService.preboot).toHaveBeenCalledTimes(1);
|
||||||
expect(mockI18nService.preboot).toHaveBeenCalledTimes(1);
|
expect(mockI18nService.preboot).toHaveBeenCalledTimes(1);
|
||||||
|
@ -201,6 +204,7 @@ test('stops services on "stop"', async () => {
|
||||||
expect(mockHttpService.stop).not.toHaveBeenCalled();
|
expect(mockHttpService.stop).not.toHaveBeenCalled();
|
||||||
expect(mockElasticsearchService.stop).not.toHaveBeenCalled();
|
expect(mockElasticsearchService.stop).not.toHaveBeenCalled();
|
||||||
expect(mockPluginsService.stop).not.toHaveBeenCalled();
|
expect(mockPluginsService.stop).not.toHaveBeenCalled();
|
||||||
|
expect(mockNodeService.stop).not.toHaveBeenCalled();
|
||||||
expect(mockSavedObjectsService.stop).not.toHaveBeenCalled();
|
expect(mockSavedObjectsService.stop).not.toHaveBeenCalled();
|
||||||
expect(mockUiSettingsService.stop).not.toHaveBeenCalled();
|
expect(mockUiSettingsService.stop).not.toHaveBeenCalled();
|
||||||
expect(mockMetricsService.stop).not.toHaveBeenCalled();
|
expect(mockMetricsService.stop).not.toHaveBeenCalled();
|
||||||
|
@ -212,6 +216,7 @@ test('stops services on "stop"', async () => {
|
||||||
expect(mockHttpService.stop).toHaveBeenCalledTimes(1);
|
expect(mockHttpService.stop).toHaveBeenCalledTimes(1);
|
||||||
expect(mockElasticsearchService.stop).toHaveBeenCalledTimes(1);
|
expect(mockElasticsearchService.stop).toHaveBeenCalledTimes(1);
|
||||||
expect(mockPluginsService.stop).toHaveBeenCalledTimes(1);
|
expect(mockPluginsService.stop).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockNodeService.stop).toHaveBeenCalledTimes(1);
|
||||||
expect(mockSavedObjectsService.stop).toHaveBeenCalledTimes(1);
|
expect(mockSavedObjectsService.stop).toHaveBeenCalledTimes(1);
|
||||||
expect(mockUiSettingsService.stop).toHaveBeenCalledTimes(1);
|
expect(mockUiSettingsService.stop).toHaveBeenCalledTimes(1);
|
||||||
expect(mockMetricsService.stop).toHaveBeenCalledTimes(1);
|
expect(mockMetricsService.stop).toHaveBeenCalledTimes(1);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
coreDeprecationProvider,
|
coreDeprecationProvider,
|
||||||
ensureValidConfiguration,
|
ensureValidConfiguration,
|
||||||
} from '@kbn/core-config-server-internal';
|
} from '@kbn/core-config-server-internal';
|
||||||
|
import { NodeService, nodeConfig } from '@kbn/core-node-server-internal';
|
||||||
import { AnalyticsService } from '@kbn/core-analytics-server-internal';
|
import { AnalyticsService } from '@kbn/core-analytics-server-internal';
|
||||||
import type { AnalyticsServiceSetup } from '@kbn/core-analytics-server';
|
import type { AnalyticsServiceSetup } from '@kbn/core-analytics-server';
|
||||||
import { CoreApp } from './core_app';
|
import { CoreApp } from './core_app';
|
||||||
|
@ -88,6 +89,7 @@ export class Server {
|
||||||
private readonly savedObjects: SavedObjectsService;
|
private readonly savedObjects: SavedObjectsService;
|
||||||
private readonly uiSettings: UiSettingsService;
|
private readonly uiSettings: UiSettingsService;
|
||||||
private readonly environment: EnvironmentService;
|
private readonly environment: EnvironmentService;
|
||||||
|
private readonly node: NodeService;
|
||||||
private readonly metrics: MetricsService;
|
private readonly metrics: MetricsService;
|
||||||
private readonly httpResources: HttpResourcesService;
|
private readonly httpResources: HttpResourcesService;
|
||||||
private readonly status: StatusService;
|
private readonly status: StatusService;
|
||||||
|
@ -132,6 +134,7 @@ export class Server {
|
||||||
this.uiSettings = new UiSettingsService(core);
|
this.uiSettings = new UiSettingsService(core);
|
||||||
this.capabilities = new CapabilitiesService(core);
|
this.capabilities = new CapabilitiesService(core);
|
||||||
this.environment = new EnvironmentService(core);
|
this.environment = new EnvironmentService(core);
|
||||||
|
this.node = new NodeService(core);
|
||||||
this.metrics = new MetricsService(core);
|
this.metrics = new MetricsService(core);
|
||||||
this.status = new StatusService(core);
|
this.status = new StatusService(core);
|
||||||
this.coreApp = new CoreApp(core);
|
this.coreApp = new CoreApp(core);
|
||||||
|
@ -159,9 +162,13 @@ export class Server {
|
||||||
const analyticsPreboot = this.analytics.preboot();
|
const analyticsPreboot = this.analytics.preboot();
|
||||||
|
|
||||||
const environmentPreboot = await this.environment.preboot({ analytics: analyticsPreboot });
|
const environmentPreboot = await this.environment.preboot({ analytics: analyticsPreboot });
|
||||||
|
const nodePreboot = await this.node.preboot();
|
||||||
|
|
||||||
// Discover any plugins before continuing. This allows other systems to utilize the plugin dependency graph.
|
// Discover any plugins before continuing. This allows other systems to utilize the plugin dependency graph.
|
||||||
this.discoveredPlugins = await this.plugins.discover({ environment: environmentPreboot });
|
this.discoveredPlugins = await this.plugins.discover({
|
||||||
|
environment: environmentPreboot,
|
||||||
|
node: nodePreboot,
|
||||||
|
});
|
||||||
|
|
||||||
// Immediately terminate in case of invalid configuration. This needs to be done after plugin discovery. We also
|
// Immediately terminate in case of invalid configuration. This needs to be done after plugin discovery. We also
|
||||||
// silent deprecation warnings until `setup` stage where we'll validate config once again.
|
// silent deprecation warnings until `setup` stage where we'll validate config once again.
|
||||||
|
@ -401,6 +408,7 @@ export class Server {
|
||||||
await this.metrics.stop();
|
await this.metrics.stop();
|
||||||
await this.status.stop();
|
await this.status.stop();
|
||||||
await this.logging.stop();
|
await this.logging.stop();
|
||||||
|
this.node.stop();
|
||||||
this.deprecations.stop();
|
this.deprecations.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,22 +420,23 @@ export class Server {
|
||||||
|
|
||||||
public setupCoreConfig() {
|
public setupCoreConfig() {
|
||||||
const configDescriptors: Array<ServiceConfigDescriptor<unknown>> = [
|
const configDescriptors: Array<ServiceConfigDescriptor<unknown>> = [
|
||||||
executionContextConfig,
|
|
||||||
pathConfig,
|
|
||||||
cspConfig,
|
cspConfig,
|
||||||
|
deprecationConfig,
|
||||||
elasticsearchConfig,
|
elasticsearchConfig,
|
||||||
|
executionContextConfig,
|
||||||
externalUrlConfig,
|
externalUrlConfig,
|
||||||
loggingConfig,
|
|
||||||
httpConfig,
|
httpConfig,
|
||||||
|
i18nConfig,
|
||||||
|
loggingConfig,
|
||||||
|
nodeConfig,
|
||||||
|
opsConfig,
|
||||||
|
pathConfig,
|
||||||
|
pidConfig,
|
||||||
pluginsConfig,
|
pluginsConfig,
|
||||||
savedObjectsConfig,
|
savedObjectsConfig,
|
||||||
savedObjectsMigrationConfig,
|
savedObjectsMigrationConfig,
|
||||||
uiSettingsConfig,
|
|
||||||
opsConfig,
|
|
||||||
statusConfig,
|
statusConfig,
|
||||||
pidConfig,
|
uiSettingsConfig,
|
||||||
i18nConfig,
|
|
||||||
deprecationConfig,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
this.configService.addDeprecationProvider(rootConfigPath, coreDeprecationProvider);
|
this.configService.addDeprecationProvider(rootConfigPath, coreDeprecationProvider);
|
||||||
|
|
|
@ -126,6 +126,7 @@ kibana_vars=(
|
||||||
monitoring.ui.max_bucket_size
|
monitoring.ui.max_bucket_size
|
||||||
monitoring.ui.min_interval_seconds
|
monitoring.ui.min_interval_seconds
|
||||||
newsfeed.enabled
|
newsfeed.enabled
|
||||||
|
node.roles
|
||||||
ops.cGroupOverrides.cpuAcctPath
|
ops.cGroupOverrides.cpuAcctPath
|
||||||
ops.cGroupOverrides.cpuPath
|
ops.cGroupOverrides.cpuPath
|
||||||
ops.interval
|
ops.interval
|
||||||
|
|
47
test/node_roles_functional/all.config.ts
Normal file
47
test/node_roles_functional/all.config.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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 { FtrConfigProviderContext } from '@kbn/test';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||||
|
const functionalConfig = await readConfigFile(require.resolve('../functional/config.base.js'));
|
||||||
|
|
||||||
|
return {
|
||||||
|
rootTags: ['runOutsideOfCiGroups'],
|
||||||
|
testFiles: [require.resolve('./test_suites/all')],
|
||||||
|
services: {
|
||||||
|
...functionalConfig.get('services'),
|
||||||
|
},
|
||||||
|
pageObjects: functionalConfig.get('pageObjects'),
|
||||||
|
servers: functionalConfig.get('servers'),
|
||||||
|
esTestCluster: {
|
||||||
|
...functionalConfig.get('esTestCluster'),
|
||||||
|
serverArgs: ['xpack.security.enabled=false'],
|
||||||
|
},
|
||||||
|
apps: functionalConfig.get('apps'),
|
||||||
|
screenshots: functionalConfig.get('screenshots'),
|
||||||
|
junit: {
|
||||||
|
reportName: 'Plugin Functional Tests - node roles - all',
|
||||||
|
},
|
||||||
|
kbnTestServer: {
|
||||||
|
...functionalConfig.get('kbnTestServer'),
|
||||||
|
serverArgs: [
|
||||||
|
...functionalConfig.get('kbnTestServer.serverArgs'),
|
||||||
|
|
||||||
|
// Required to load new platform plugins via `--plugin-path` flag.
|
||||||
|
'--env.name=development',
|
||||||
|
// for testing set buffer duration to 0 to immediately flush counters into saved objects.
|
||||||
|
'--usageCollection.usageCounters.bufferDuration=0',
|
||||||
|
|
||||||
|
`--plugin-path=${path.resolve(__dirname, 'plugins', 'core_plugin_initializer_context')}`,
|
||||||
|
'--node.roles=["*"]',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
47
test/node_roles_functional/background_tasks.config.ts
Normal file
47
test/node_roles_functional/background_tasks.config.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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 { FtrConfigProviderContext } from '@kbn/test';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||||
|
const functionalConfig = await readConfigFile(require.resolve('../functional/config.base.js'));
|
||||||
|
|
||||||
|
return {
|
||||||
|
rootTags: ['runOutsideOfCiGroups'],
|
||||||
|
testFiles: [require.resolve('./test_suites/background_tasks')],
|
||||||
|
services: {
|
||||||
|
...functionalConfig.get('services'),
|
||||||
|
},
|
||||||
|
pageObjects: functionalConfig.get('pageObjects'),
|
||||||
|
servers: functionalConfig.get('servers'),
|
||||||
|
esTestCluster: {
|
||||||
|
...functionalConfig.get('esTestCluster'),
|
||||||
|
serverArgs: ['xpack.security.enabled=false'],
|
||||||
|
},
|
||||||
|
apps: functionalConfig.get('apps'),
|
||||||
|
screenshots: functionalConfig.get('screenshots'),
|
||||||
|
junit: {
|
||||||
|
reportName: 'Plugin Functional Tests - node roles - background tasks',
|
||||||
|
},
|
||||||
|
kbnTestServer: {
|
||||||
|
...functionalConfig.get('kbnTestServer'),
|
||||||
|
serverArgs: [
|
||||||
|
...functionalConfig.get('kbnTestServer.serverArgs'),
|
||||||
|
|
||||||
|
// Required to load new platform plugins via `--plugin-path` flag.
|
||||||
|
'--env.name=development',
|
||||||
|
// for testing set buffer duration to 0 to immediately flush counters into saved objects.
|
||||||
|
'--usageCollection.usageCounters.bufferDuration=0',
|
||||||
|
|
||||||
|
`--plugin-path=${path.resolve(__dirname, 'plugins', 'core_plugin_initializer_context')}`,
|
||||||
|
'--node.roles=["background_tasks"]',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"id": "corePluginInitializerContext",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"kibanaVersion": "kibana",
|
||||||
|
"owner": {
|
||||||
|
"name": "Core",
|
||||||
|
"githubTeam": "kibana-core"
|
||||||
|
},
|
||||||
|
"configPath": ["core_plugin_initializer_context"],
|
||||||
|
"server": true,
|
||||||
|
"ui": false
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"name": "core_plugin_initializer_context",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "target/test/plugin_functional/plugins/core_plugin_initializer_context",
|
||||||
|
"kibana": {
|
||||||
|
"version": "kibana",
|
||||||
|
"templateVersion": "1.0.0"
|
||||||
|
},
|
||||||
|
"license": "SSPL-1.0 OR Elastic License 2.0",
|
||||||
|
"scripts": {
|
||||||
|
"kbn": "node ../../../../scripts/kbn.js",
|
||||||
|
"build": "rm -rf './target' && ../../../../node_modules/.bin/tsc"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* 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 { PluginInitializerContext } from '@kbn/core/server';
|
||||||
|
import { CorePluginInitializerContextPlugin } from './plugin';
|
||||||
|
|
||||||
|
export const plugin = (initializerContext: PluginInitializerContext) =>
|
||||||
|
new CorePluginInitializerContextPlugin(initializerContext);
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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 { Plugin, CoreSetup, PluginInitializerContext } from '@kbn/core/server';
|
||||||
|
|
||||||
|
export class CorePluginInitializerContextPlugin implements Plugin {
|
||||||
|
readonly initializerContext: PluginInitializerContext;
|
||||||
|
|
||||||
|
constructor(initializerContext: PluginInitializerContext) {
|
||||||
|
this.initializerContext = initializerContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setup(core: CoreSetup, deps: {}) {
|
||||||
|
const router = core.http.createRouter();
|
||||||
|
router.get(
|
||||||
|
{
|
||||||
|
path: '/core_plugin_initializer_context/node/roles',
|
||||||
|
validate: false,
|
||||||
|
options: {
|
||||||
|
authRequired: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async (context, req, res) => {
|
||||||
|
return res.ok({ body: this.initializerContext.node.roles });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public start() {}
|
||||||
|
public stop() {}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"extends": "../../../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./target/types"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"index.ts",
|
||||||
|
"server/**/*.ts",
|
||||||
|
"../../../../typings/**/*",
|
||||||
|
],
|
||||||
|
"exclude": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "../../../../src/core/tsconfig.json" }
|
||||||
|
]
|
||||||
|
}
|
11
test/node_roles_functional/services/index.ts
Normal file
11
test/node_roles_functional/services/index.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/*
|
||||||
|
* 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 { FtrProviderContext } from '../../functional/ftr_provider_context';
|
||||||
|
|
||||||
|
export type PluginFunctionalProviderContext = FtrProviderContext;
|
15
test/node_roles_functional/test_suites/all/index.ts
Normal file
15
test/node_roles_functional/test_suites/all/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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 { PluginFunctionalProviderContext } from '../../services';
|
||||||
|
|
||||||
|
export default function ({ loadTestFile }: PluginFunctionalProviderContext) {
|
||||||
|
describe('core plugins - initializer context - node roles - all', () => {
|
||||||
|
loadTestFile(require.resolve('./initializer_context'));
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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 { PluginFunctionalProviderContext } from '../../services';
|
||||||
|
import '@kbn/core-provider-plugin/types';
|
||||||
|
|
||||||
|
export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) {
|
||||||
|
const supertest = getService('supertest');
|
||||||
|
|
||||||
|
describe('initializer context', () => {
|
||||||
|
it('passes node roles to server PluginInitializerContext', async () => {
|
||||||
|
await supertest.get('/core_plugin_initializer_context/node/roles').expect(200, {
|
||||||
|
backgroundTasks: true,
|
||||||
|
ui: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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 { PluginFunctionalProviderContext } from '../../services';
|
||||||
|
|
||||||
|
export default function ({ loadTestFile }: PluginFunctionalProviderContext) {
|
||||||
|
describe('core plugins - initializer context - node roles - backgroundTasks', () => {
|
||||||
|
loadTestFile(require.resolve('./initializer_context'));
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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 { PluginFunctionalProviderContext } from '../../services';
|
||||||
|
import '@kbn/core-provider-plugin/types';
|
||||||
|
|
||||||
|
export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) {
|
||||||
|
const supertest = getService('supertest');
|
||||||
|
|
||||||
|
describe('initializer context', () => {
|
||||||
|
it('passes node roles to server PluginInitializerContext', async () => {
|
||||||
|
await supertest.get('/core_plugin_initializer_context/node/roles').expect(200, {
|
||||||
|
backgroundTasks: true,
|
||||||
|
ui: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
15
test/node_roles_functional/test_suites/ui/index.ts
Normal file
15
test/node_roles_functional/test_suites/ui/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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 { PluginFunctionalProviderContext } from '../../services';
|
||||||
|
|
||||||
|
export default function ({ loadTestFile }: PluginFunctionalProviderContext) {
|
||||||
|
describe('core plugins - initializer context - node roles - ui', () => {
|
||||||
|
loadTestFile(require.resolve('./initializer_context'));
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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 { PluginFunctionalProviderContext } from '../../services';
|
||||||
|
import '@kbn/core-provider-plugin/types';
|
||||||
|
|
||||||
|
export default function ({ getService, getPageObjects }: PluginFunctionalProviderContext) {
|
||||||
|
const supertest = getService('supertest');
|
||||||
|
|
||||||
|
describe('initializer context', () => {
|
||||||
|
it('passes node roles to server PluginInitializerContext', async () => {
|
||||||
|
await supertest.get('/core_plugin_initializer_context/node/roles').expect(200, {
|
||||||
|
backgroundTasks: false,
|
||||||
|
ui: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
47
test/node_roles_functional/ui.config.ts
Normal file
47
test/node_roles_functional/ui.config.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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 { FtrConfigProviderContext } from '@kbn/test';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||||
|
const functionalConfig = await readConfigFile(require.resolve('../functional/config.base.js'));
|
||||||
|
|
||||||
|
return {
|
||||||
|
rootTags: ['runOutsideOfCiGroups'],
|
||||||
|
testFiles: [require.resolve('./test_suites/ui')],
|
||||||
|
services: {
|
||||||
|
...functionalConfig.get('services'),
|
||||||
|
},
|
||||||
|
pageObjects: functionalConfig.get('pageObjects'),
|
||||||
|
servers: functionalConfig.get('servers'),
|
||||||
|
esTestCluster: {
|
||||||
|
...functionalConfig.get('esTestCluster'),
|
||||||
|
serverArgs: ['xpack.security.enabled=false'],
|
||||||
|
},
|
||||||
|
apps: functionalConfig.get('apps'),
|
||||||
|
screenshots: functionalConfig.get('screenshots'),
|
||||||
|
junit: {
|
||||||
|
reportName: 'Plugin Functional Tests - node roles - ui',
|
||||||
|
},
|
||||||
|
kbnTestServer: {
|
||||||
|
...functionalConfig.get('kbnTestServer'),
|
||||||
|
serverArgs: [
|
||||||
|
...functionalConfig.get('kbnTestServer.serverArgs'),
|
||||||
|
|
||||||
|
// Required to load new platform plugins via `--plugin-path` flag.
|
||||||
|
'--env.name=development',
|
||||||
|
// for testing set buffer duration to 0 to immediately flush counters into saved objects.
|
||||||
|
'--usageCollection.usageCounters.bufferDuration=0',
|
||||||
|
|
||||||
|
`--plugin-path=${path.resolve(__dirname, 'plugins', 'core_plugin_initializer_context')}`,
|
||||||
|
'--node.roles=["ui"]',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
24
yarn.lock
24
yarn.lock
|
@ -3167,6 +3167,18 @@
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
uid ""
|
uid ""
|
||||||
|
|
||||||
|
"@kbn/core-node-server-internal@link:bazel-bin/packages/core/node/core-node-server-internal":
|
||||||
|
version "0.0.0"
|
||||||
|
uid ""
|
||||||
|
|
||||||
|
"@kbn/core-node-server-mocks@link:bazel-bin/packages/core/node/core-node-server-mocks":
|
||||||
|
version "0.0.0"
|
||||||
|
uid ""
|
||||||
|
|
||||||
|
"@kbn/core-node-server@link:bazel-bin/packages/core/node/core-node-server":
|
||||||
|
version "0.0.0"
|
||||||
|
uid ""
|
||||||
|
|
||||||
"@kbn/core-theme-browser-internal@link:bazel-bin/packages/core/theme/core-theme-browser-internal":
|
"@kbn/core-theme-browser-internal@link:bazel-bin/packages/core/theme/core-theme-browser-internal":
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
uid ""
|
uid ""
|
||||||
|
@ -6634,6 +6646,18 @@
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
uid ""
|
uid ""
|
||||||
|
|
||||||
|
"@types/kbn__core-node-server-internal@link:bazel-bin/packages/core/node/core-node-server-internal/npm_module_types":
|
||||||
|
version "0.0.0"
|
||||||
|
uid ""
|
||||||
|
|
||||||
|
"@types/kbn__core-node-server-mocks@link:bazel-bin/packages/core/node/core-node-server-mocks/npm_module_types":
|
||||||
|
version "0.0.0"
|
||||||
|
uid ""
|
||||||
|
|
||||||
|
"@types/kbn__core-node-server@link:bazel-bin/packages/core/node/core-node-server/npm_module_types":
|
||||||
|
version "0.0.0"
|
||||||
|
uid ""
|
||||||
|
|
||||||
"@types/kbn__core-public-internal-base@link:bazel-bin/packages/core/public/internal-base/npm_module_types":
|
"@types/kbn__core-public-internal-base@link:bazel-bin/packages/core/public/internal-base/npm_module_types":
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
uid ""
|
uid ""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue