mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
enables actions scoped within the stack to register at Basic license (#82931)
Enables actions scoped within the stack to register at Basic license
This commit is contained in:
parent
6e9177caac
commit
3151e7e5e4
8 changed files with 115 additions and 12 deletions
|
@ -39,10 +39,11 @@ const ParamsSchema = schema.object({
|
|||
documents: schema.arrayOf(schema.recordOf(schema.string(), schema.any())),
|
||||
});
|
||||
|
||||
export const ES_INDEX_ACTION_TYPE_ID = '.index';
|
||||
// action type definition
|
||||
export function getActionType({ logger }: { logger: Logger }): ESIndexActionType {
|
||||
return {
|
||||
id: '.index',
|
||||
id: ES_INDEX_ACTION_TYPE_ID,
|
||||
minimumLicenseRequired: 'basic',
|
||||
name: i18n.translate('xpack.actions.builtin.esIndexTitle', {
|
||||
defaultMessage: 'Index',
|
||||
|
|
|
@ -38,10 +38,11 @@ const ParamsSchema = schema.object({
|
|||
),
|
||||
});
|
||||
|
||||
export const SERVER_LOG_ACTION_TYPE_ID = '.server-log';
|
||||
// action type definition
|
||||
export function getActionType({ logger }: { logger: Logger }): ServerLogActionType {
|
||||
return {
|
||||
id: '.server-log',
|
||||
id: SERVER_LOG_ACTION_TYPE_ID,
|
||||
minimumLicenseRequired: 'basic',
|
||||
name: i18n.translate('xpack.actions.builtin.serverLogTitle', {
|
||||
defaultMessage: 'Server log',
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { ActionType } from '../types';
|
||||
import { ensureSufficientLicense } from './ensure_sufficient_license';
|
||||
|
||||
const sampleActionType: ActionType = {
|
||||
id: 'test',
|
||||
name: 'test',
|
||||
minimumLicenseRequired: 'basic',
|
||||
async executor({ actionId }) {
|
||||
return { status: 'ok', actionId };
|
||||
},
|
||||
};
|
||||
|
||||
describe('ensureSufficientLicense()', () => {
|
||||
it('throws for licenses below gold', () => {
|
||||
expect(() => ensureSufficientLicense(sampleActionType)).toThrowErrorMatchingInlineSnapshot(
|
||||
`"Third party action type \\"test\\" can only set minimumLicenseRequired to a gold license or higher"`
|
||||
);
|
||||
});
|
||||
|
||||
it('allows licenses below gold for allowed connectors', () => {
|
||||
expect(() =>
|
||||
ensureSufficientLicense({ ...sampleActionType, id: '.case', minimumLicenseRequired: 'basic' })
|
||||
).not.toThrow();
|
||||
expect(() =>
|
||||
ensureSufficientLicense({
|
||||
...sampleActionType,
|
||||
id: '.server-log',
|
||||
minimumLicenseRequired: 'basic',
|
||||
})
|
||||
).not.toThrow();
|
||||
expect(() =>
|
||||
ensureSufficientLicense({
|
||||
...sampleActionType,
|
||||
id: '.index',
|
||||
minimumLicenseRequired: 'basic',
|
||||
})
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('allows licenses at gold', () => {
|
||||
expect(() =>
|
||||
ensureSufficientLicense({ ...sampleActionType, minimumLicenseRequired: 'gold' })
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('allows licenses above gold', () => {
|
||||
expect(() =>
|
||||
ensureSufficientLicense({ ...sampleActionType, minimumLicenseRequired: 'platinum' })
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('throws when license type is invalid', async () => {
|
||||
expect(() =>
|
||||
ensureSufficientLicense({
|
||||
...sampleActionType,
|
||||
// we're faking an invalid value, this requires stripping the typing
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
minimumLicenseRequired: 'foo' as any,
|
||||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(`"\\"foo\\" is not a valid license type"`);
|
||||
});
|
||||
});
|
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { ActionType } from '../types';
|
||||
import { LICENSE_TYPE } from '../../../licensing/common/types';
|
||||
import { SERVER_LOG_ACTION_TYPE_ID } from '../builtin_action_types/server_log';
|
||||
import { ES_INDEX_ACTION_TYPE_ID } from '../builtin_action_types/es_index';
|
||||
import { CASE_ACTION_TYPE_ID } from '../../../case/server';
|
||||
import { ActionTypeConfig, ActionTypeSecrets, ActionTypeParams } from '../types';
|
||||
|
||||
const ACTIONS_SCOPED_WITHIN_STACK = new Set([
|
||||
SERVER_LOG_ACTION_TYPE_ID,
|
||||
ES_INDEX_ACTION_TYPE_ID,
|
||||
CASE_ACTION_TYPE_ID,
|
||||
]);
|
||||
|
||||
export function ensureSufficientLicense<
|
||||
Config extends ActionTypeConfig,
|
||||
Secrets extends ActionTypeSecrets,
|
||||
Params extends ActionTypeParams,
|
||||
ExecutorResultData
|
||||
>(actionType: ActionType<Config, Secrets, Params, ExecutorResultData>) {
|
||||
if (!(actionType.minimumLicenseRequired in LICENSE_TYPE)) {
|
||||
throw new Error(`"${actionType.minimumLicenseRequired}" is not a valid license type`);
|
||||
}
|
||||
if (
|
||||
LICENSE_TYPE[actionType.minimumLicenseRequired] < LICENSE_TYPE.gold &&
|
||||
!ACTIONS_SCOPED_WITHIN_STACK.has(actionType.id)
|
||||
) {
|
||||
throw new Error(
|
||||
`Third party action type "${actionType.id}" can only set minimumLicenseRequired to a gold license or higher`
|
||||
);
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@ import {
|
|||
} from '../../encrypted_saved_objects/server';
|
||||
import { TaskManagerSetupContract, TaskManagerStartContract } from '../../task_manager/server';
|
||||
import { LicensingPluginSetup, LicensingPluginStart } from '../../licensing/server';
|
||||
import { LICENSE_TYPE } from '../../licensing/common/types';
|
||||
import { SpacesPluginSetup, SpacesServiceSetup } from '../../spaces/server';
|
||||
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
|
||||
import { SecurityPluginSetup } from '../../security/server';
|
||||
|
@ -75,6 +74,7 @@ import {
|
|||
getAuthorizationModeBySource,
|
||||
AuthorizationMode,
|
||||
} from './authorization/get_authorization_mode_by_source';
|
||||
import { ensureSufficientLicense } from './lib/ensure_sufficient_license';
|
||||
|
||||
const EVENT_LOG_PROVIDER = 'actions';
|
||||
export const EVENT_LOG_ACTIONS = {
|
||||
|
@ -260,14 +260,7 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
|
|||
>(
|
||||
actionType: ActionType<Config, Secrets, Params, ExecutorResultData>
|
||||
) => {
|
||||
if (!(actionType.minimumLicenseRequired in LICENSE_TYPE)) {
|
||||
throw new Error(`"${actionType.minimumLicenseRequired}" is not a valid license type`);
|
||||
}
|
||||
if (LICENSE_TYPE[actionType.minimumLicenseRequired] < LICENSE_TYPE.gold) {
|
||||
throw new Error(
|
||||
`Third party action type "${actionType.id}" can only set minimumLicenseRequired to a gold license or higher`
|
||||
);
|
||||
}
|
||||
ensureSufficientLicense(actionType);
|
||||
actionTypeRegistry.register(actionType);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ import { GetActionTypeParams } from '..';
|
|||
|
||||
const supportedSubActions: string[] = ['create', 'update', 'addComment'];
|
||||
|
||||
export const CASE_ACTION_TYPE_ID = '.case';
|
||||
// action type definition
|
||||
export function getActionType({
|
||||
logger,
|
||||
|
@ -31,7 +32,7 @@ export function getActionType({
|
|||
userActionService,
|
||||
}: GetActionTypeParams): CaseActionType {
|
||||
return {
|
||||
id: '.case',
|
||||
id: CASE_ACTION_TYPE_ID,
|
||||
minimumLicenseRequired: 'gold',
|
||||
name: i18n.NAME,
|
||||
validate: {
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
} from '../services';
|
||||
|
||||
import { getActionType as getCaseConnector } from './case';
|
||||
export { CASE_ACTION_TYPE_ID } from './case';
|
||||
|
||||
export interface GetActionTypeParams {
|
||||
logger: Logger;
|
||||
|
|
|
@ -8,6 +8,8 @@ import { PluginInitializerContext } from '../../../../src/core/server';
|
|||
import { ConfigSchema } from './config';
|
||||
import { CasePlugin } from './plugin';
|
||||
|
||||
export { CASE_ACTION_TYPE_ID } from './connectors';
|
||||
export { CaseRequestContext } from './types';
|
||||
export const config = { schema: ConfigSchema };
|
||||
export const plugin = (initializerContext: PluginInitializerContext) =>
|
||||
new CasePlugin(initializerContext);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue