Skip to content

Commit

Permalink
Merge branch 'main' into alerting/faad-resources-common
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Feb 27, 2023
2 parents 18854e2 + a988cd4 commit af0428e
Show file tree
Hide file tree
Showing 116 changed files with 1,540 additions and 393 deletions.
1 change: 1 addition & 0 deletions .github/workflows/skip-failed-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
uses: ./actions/permission-check
with:
permission: admin
teams: appex-qa
token: ${{secrets.GITHUB_TOKEN}}

- name: Checkout kibana-operations
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
"@elastic/datemath": "5.0.3",
"@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.6.0-canary.3",
"@elastic/ems-client": "8.4.0",
"@elastic/eui": "75.1.0",
"@elastic/eui": "75.1.2",
"@elastic/filesaver": "1.1.2",
"@elastic/node-crypto": "1.2.1",
"@elastic/numeral": "^2.5.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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 { rolesConfig } from './node_config';

describe('rolesConfig', () => {
test('default', () => {
expect(rolesConfig.validate(undefined)).toEqual(['*']);
});
test('empty', () => {
expect(() => rolesConfig.validate([])).toThrow();
});
test('"ui" and "background_tasks" roles are allowed and can be combined', () => {
expect(() => rolesConfig.validate(['ui', 'background_tasks'])).not.toThrow();
expect(() => rolesConfig.validate(['ui'])).not.toThrow();
expect(() => rolesConfig.validate(['background_tasks'])).not.toThrow();
});
test('exlcusive "*"', () => {
const wildcardError = `wildcard ("*") cannot be used with other roles or specified more than once`;
expect(() => rolesConfig.validate(['*'])).not.toThrow();

expect(() => rolesConfig.validate(['*', 'ui'])).toThrow(wildcardError);
expect(() => rolesConfig.validate(['*', '*'])).toThrow(wildcardError);

expect(() => rolesConfig.validate(['*', 'unknown'])).toThrow();
});
test('exlcusive "migrator"', () => {
const migratorError = `"migrator" cannot be used with other roles or specified more than once`;
expect(() => rolesConfig.validate(['migrator'])).not.toThrow();

expect(() => rolesConfig.validate(['migrator', 'ui'])).toThrow(migratorError);
expect(() => rolesConfig.validate(['migrator', 'migrator'])).toThrow(migratorError);

expect(() => rolesConfig.validate(['migrator', 'unknown'])).toThrow();
});
});
61 changes: 48 additions & 13 deletions packages/core/node/core-node-server-internal/src/node_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,68 @@
* Side Public License, v 1.
*/

import { schema } from '@kbn/config-schema';
import { schema, TypeOf } from '@kbn/config-schema';
import type { ServiceConfigDescriptor } from '@kbn/core-base-server-internal';

/** @internal */
export const NODE_CONFIG_PATH = 'node' as const;
/**
* Wildchar is a special config option that implies all {@link NODE_DEFAULT_ROLES} roles.
* @internal
*/
export const NODE_WILDCARD_CHAR = '*' as const;
/** @internal */
export const NODE_BACKGROUND_TASKS_ROLE = 'background_tasks' as const;
/** @internal */
export const NODE_UI_ROLE = 'ui' as const;
/** @internal */
export const NODE_WILDCARD_CHAR = '*';
export const NODE_MIGRATOR_ROLE = 'migrator' as const;
/** @internal */
export const NODE_ACCEPTED_ROLES = ['background_tasks', 'ui'];
export const NODE_DEFAULT_ROLES = [NODE_BACKGROUND_TASKS_ROLE, NODE_UI_ROLE] as const;
/** @internal */
export const NODE_ALL_ROLES = [
NODE_UI_ROLE,
NODE_MIGRATOR_ROLE,
NODE_BACKGROUND_TASKS_ROLE,
] as const;

/** @internal */
export const rolesConfig = schema.arrayOf(
schema.oneOf([
schema.literal(NODE_BACKGROUND_TASKS_ROLE),
schema.literal(NODE_MIGRATOR_ROLE),
schema.literal(NODE_WILDCARD_CHAR),
schema.literal(NODE_UI_ROLE),
]),
{
defaultValue: [NODE_WILDCARD_CHAR],
validate: (value) => {
if (value.length > 1) {
if (value.includes(NODE_WILDCARD_CHAR)) {
return `wildcard ("*") cannot be used with other roles or specified more than once`;
}
if (value.includes(NODE_MIGRATOR_ROLE)) {
return `"migrator" cannot be used with other roles or specified more than once`;
}
}
},
minSize: 1,
}
);

/** @internal */
export type NodeRolesConfig = TypeOf<typeof rolesConfig>;

/** @internal */
export interface NodeConfigType {
roles: string[];
roles: NodeRolesConfig;
}

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],
}
),
roles: rolesConfig,
});

/** @internal */
export const nodeConfig: ServiceConfigDescriptor<NodeConfigType> = {
path: NODE_CONFIG_PATH,
schema: configSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import { BehaviorSubject } from 'rxjs';
import type { CoreContext } from '@kbn/core-base-server-internal';

import { NodeService } from './node_service';
import type { NodeRolesConfig } from './node_config';

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 getMockedConfigService = (nodeConfig: { roles: NodeRolesConfig }) => {
const configService = configServiceMock.create();
configService.atPath.mockImplementation((path) => {
if (path === 'node') {
Expand Down Expand Up @@ -51,6 +52,7 @@ describe('NodeService', () => {

expect(roles.backgroundTasks).toBe(true);
expect(roles.ui).toBe(true);
expect(roles.migrator).toBe(false);
});

it('returns correct roles when node is configured to `background_tasks`', async () => {
Expand All @@ -62,6 +64,7 @@ describe('NodeService', () => {

expect(roles.backgroundTasks).toBe(true);
expect(roles.ui).toBe(false);
expect(roles.migrator).toBe(false);
});

it('returns correct roles when node is configured to `ui`', async () => {
Expand All @@ -73,6 +76,7 @@ describe('NodeService', () => {

expect(roles.backgroundTasks).toBe(false);
expect(roles.ui).toBe(true);
expect(roles.migrator).toBe(false);
});

it('returns correct roles when node is configured to both `background_tasks` and `ui`', async () => {
Expand All @@ -84,6 +88,19 @@ describe('NodeService', () => {

expect(roles.backgroundTasks).toBe(true);
expect(roles.ui).toBe(true);
expect(roles.migrator).toBe(false);
});

it('returns correct roles when node is configured to `migrator`', async () => {
configService = getMockedConfigService({ roles: ['migrator'] });
coreContext = mockCoreContext.create({ logger, configService });

service = new NodeService(coreContext);
const { roles } = await service.preboot({ loggingSystem: logger });

expect(roles.backgroundTasks).toBe(false);
expect(roles.ui).toBe(false);
expect(roles.migrator).toBe(true);
});

it('logs the node roles', async () => {
Expand Down
17 changes: 10 additions & 7 deletions packages/core/node/core-node-server-internal/src/node_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import type { ILoggingSystem } from '@kbn/core-logging-server-internal';
import type { NodeRoles } from '@kbn/core-node-server';
import type { Logger } from '@kbn/logging';
import {
NodeConfigType,
NODE_WILDCARD_CHAR,
NODE_ACCEPTED_ROLES,
type NodeConfigType,
type NodeRolesConfig,
NODE_ALL_ROLES,
NODE_CONFIG_PATH,
NODE_WILDCARD_CHAR,
NODE_DEFAULT_ROLES,
} from './node_config';

const DEFAULT_ROLES = NODE_ACCEPTED_ROLES;
const DEFAULT_ROLES = [...NODE_DEFAULT_ROLES];
const containsWildcard = (roles: string[]) => roles.includes(NODE_WILDCARD_CHAR);

/**
Expand Down Expand Up @@ -66,8 +68,9 @@ export class NodeService {
loggingSystem.setGlobalContext({ service: { node: { roles } } });
this.log.info(`Kibana process configured with roles: [${roles.join(', ')}]`);

this.roles = NODE_ACCEPTED_ROLES.reduce((acc, curr) => {
return { ...acc, [camelCase(curr)]: roles.includes(curr) };
// We assume the combination of node roles has been validated and avoid doing additional checks here.
this.roles = NODE_ALL_ROLES.reduce((acc, curr) => {
return { ...acc, [camelCase(curr)]: (roles as string[]).includes(curr) };
}, {} as NodeRoles);

return {
Expand All @@ -86,7 +89,7 @@ export class NodeService {
// nothing to do here yet
}

private async getNodeRoles(): Promise<string[]> {
private async getNodeRoles(): Promise<NodeRolesConfig> {
const { roles } = await firstValueFrom(
this.configService.atPath<NodeConfigType>(NODE_CONFIG_PATH)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const createInternalPrebootContractMock = () => {
roles: {
backgroundTasks: true,
ui: true,
migrator: false,
},
};
return prebootContract;
Expand All @@ -27,15 +28,18 @@ const createInternalStartContractMock = (
{
ui,
backgroundTasks,
migrator,
}: {
ui: boolean;
backgroundTasks: boolean;
} = { ui: true, backgroundTasks: true }
migrator: boolean;
} = { ui: true, backgroundTasks: true, migrator: false }
) => {
const startContract: jest.Mocked<InternalNodeServiceStart> = {
roles: {
backgroundTasks,
ui,
migrator,
},
};
return startContract;
Expand Down
5 changes: 5 additions & 0 deletions packages/core/node/core-node-server/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,9 @@ export interface NodeRoles {
* to handle http traffic from the browser.
*/
ui: boolean;
/**
* Start Kibana with the specific purpose of completing the migrations phase then shutting down.
* @remark This role is special as it precludes the use of other roles.
*/
migrator: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ describe('plugins discovery system', () => {
roles: {
backgroundTasks: true,
ui: true,
migrator: false,
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ describe('createPluginInitializerContext', () => {
opaqueId,
manifest: createPluginManifest(),
instanceInfo,
nodeInfo: { roles: { backgroundTasks: false, ui: true } },
nodeInfo: { roles: { backgroundTasks: false, ui: true, migrator: false } },
});
expect(pluginInitializerContext.node.roles.backgroundTasks).toBe(false);
expect(pluginInitializerContext.node.roles.ui).toBe(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export function createPluginInitializerContext({
roles: {
backgroundTasks: nodeInfo.roles.backgroundTasks,
ui: nodeInfo.roles.ui,
migrator: nodeInfo.roles.migrator,
},
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ describe('PluginsService', () => {
},
coreContext: { coreId, env, logger, configService },
instanceInfo: { uuid: 'uuid' },
nodeInfo: { roles: { backgroundTasks: true, ui: true } },
nodeInfo: { roles: { backgroundTasks: true, ui: true, migrator: false } },
});

const logs = loggingSystemMock.collect(logger);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const REMOVED_TYPES: string[] = [
'maps-telemetry',
// Deprecated, no longer used since 8.7 https://github.com/elastic/kibana/pull/148530
'csp_rule',
// Removed in 8.8 https://github.com/elastic/kibana/pull/151116
'upgrade-assistant-telemetry',
].sort();

export const excludeUnusedTypesQuery: QueryDslQueryContainer = {
Expand Down
Loading

0 comments on commit af0428e

Please sign in to comment.