diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.test.ts index 474fff65795a5..30e594f35d1f8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.test.ts @@ -11,564 +11,196 @@ import { ALERTS_FEATURE_ID } from '../../../../alerting/common'; beforeEach(() => jest.resetAllMocks()); +const mockContextVariables = (withBraces: boolean = false) => [ + { + name: 'fooC', + description: 'fooC-description', + ...(withBraces && { useWithTripleBracesInTemplates: true }), + }, + { name: 'barC', description: 'barC-description' }, +]; + +const mockStateVariables = (withBraces: boolean = false) => [ + { name: 'fooS', description: 'fooS-description' }, + { + name: 'barS', + description: 'barS-description', + ...(withBraces && { useWithTripleBracesInTemplates: true }), + }, +]; + +const mockParamsVariables = (withBraces: boolean = false) => [ + { + name: 'fooP', + description: 'fooP-description', + ...(withBraces && { useWithTripleBracesInTemplates: true }), + }, +]; + +const expectedTransformResult = [ + { description: 'The ID of the rule.', name: 'rule.id' }, + { description: 'The name of the rule.', name: 'rule.name' }, + { description: 'The space ID of the rule.', name: 'rule.spaceId' }, + { description: 'The tags of the rule.', name: 'rule.tags' }, + { description: 'The type of rule.', name: 'rule.type' }, + { description: 'The date the rule scheduled the action.', name: 'date' }, + { description: 'The ID of the alert that scheduled actions for the rule.', name: 'alert.id' }, + { + description: 'The action group of the alert that scheduled actions for the rule.', + name: 'alert.actionGroup', + }, + { + description: 'The action subgroup of the alert that scheduled actions for the rule.', + name: 'alert.actionSubgroup', + }, + { + description: + 'The human readable name of the action group of the alert that scheduled actions for the rule.', + name: 'alert.actionGroupName', + }, + { + description: 'The configured server.publicBaseUrl value or empty string if not configured.', + name: 'kibanaBaseUrl', + }, + { + deprecated: true, + description: 'This has been deprecated in favor of rule.id.', + name: 'alertId', + }, + { + deprecated: true, + description: 'This has been deprecated in favor of rule.name.', + name: 'alertName', + }, + { + deprecated: true, + description: 'This has been deprecated in favor of alert.id.', + name: 'alertInstanceId', + }, + { + deprecated: true, + description: 'This has been deprecated in favor of alert.actionGroup.', + name: 'alertActionGroup', + }, + { + deprecated: true, + description: 'This has been deprecated in favor of alert.actionGroupName.', + name: 'alertActionGroupName', + }, + { + deprecated: true, + description: 'This has been deprecated in favor of alert.actionSubgroup.', + name: 'alertActionSubgroup', + }, + { + deprecated: true, + description: 'This has been deprecated in favor of rule.spaceId.', + name: 'spaceId', + }, + { + deprecated: true, + description: 'This has been deprecated in favor of rule.tags.', + name: 'tags', + }, +]; + +const expectedContextTransformResult = (withBraces: boolean = false) => [ + { + description: 'fooC-description', + name: 'context.fooC', + ...(withBraces && { useWithTripleBracesInTemplates: true }), + }, + { + description: 'barC-description', + name: 'context.barC', + }, +]; + +const expectedStateTransformResult = (withBraces: boolean = false) => [ + { description: 'fooS-description', name: 'state.fooS' }, + { + description: 'barS-description', + name: 'state.barS', + ...(withBraces && { useWithTripleBracesInTemplates: true }), + }, +]; + +const expectedParamsTransformResult = (withBraces: boolean = false) => [ + { + description: 'fooP-description', + name: 'params.fooP', + ...(withBraces && { useWithTripleBracesInTemplates: true }), + }, +]; + describe('transformActionVariables', () => { - test('should return correct variables when no state or context provided', async () => { + test('should return correct variables when no state, no context, no params provided', async () => { const alertType = getAlertType({ context: [], state: [], params: [] }); - expect(transformActionVariables(alertType.actionVariables)).toMatchInlineSnapshot(` - Array [ - Object { - "description": "The ID of the rule.", - "name": "rule.id", - }, - Object { - "description": "The name of the rule.", - "name": "rule.name", - }, - Object { - "description": "The space ID of the rule.", - "name": "rule.spaceId", - }, - Object { - "description": "The tags of the rule.", - "name": "rule.tags", - }, - Object { - "description": "The type of rule.", - "name": "rule.type", - }, - Object { - "description": "The date the rule scheduled the action.", - "name": "date", - }, - Object { - "description": "The ID of the alert that scheduled actions for the rule.", - "name": "alert.id", - }, - Object { - "description": "The action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroup", - }, - Object { - "description": "The action subgroup of the alert that scheduled actions for the rule.", - "name": "alert.actionSubgroup", - }, - Object { - "description": "The human readable name of the action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroupName", - }, - Object { - "description": "The configured server.publicBaseUrl value or empty string if not configured.", - "name": "kibanaBaseUrl", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.id.", - "name": "alertId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.name.", - "name": "alertName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.id.", - "name": "alertInstanceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroup.", - "name": "alertActionGroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroupName.", - "name": "alertActionGroupName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionSubgroup.", - "name": "alertActionSubgroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.spaceId.", - "name": "spaceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.tags.", - "name": "tags", - }, - ] - `); + expect(transformActionVariables(alertType.actionVariables)).toEqual(expectedTransformResult); }); - test('should return correct variables when no state provided', async () => { + test('should return correct variables when context is provided', async () => { const alertType = getAlertType({ - context: [ - { name: 'foo', description: 'foo-description' }, - { name: 'bar', description: 'bar-description' }, - ], + context: mockContextVariables(), state: [], params: [], }); - expect(transformActionVariables(alertType.actionVariables)).toMatchInlineSnapshot(` - Array [ - Object { - "description": "The ID of the rule.", - "name": "rule.id", - }, - Object { - "description": "The name of the rule.", - "name": "rule.name", - }, - Object { - "description": "The space ID of the rule.", - "name": "rule.spaceId", - }, - Object { - "description": "The tags of the rule.", - "name": "rule.tags", - }, - Object { - "description": "The type of rule.", - "name": "rule.type", - }, - Object { - "description": "The date the rule scheduled the action.", - "name": "date", - }, - Object { - "description": "The ID of the alert that scheduled actions for the rule.", - "name": "alert.id", - }, - Object { - "description": "The action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroup", - }, - Object { - "description": "The action subgroup of the alert that scheduled actions for the rule.", - "name": "alert.actionSubgroup", - }, - Object { - "description": "The human readable name of the action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroupName", - }, - Object { - "description": "The configured server.publicBaseUrl value or empty string if not configured.", - "name": "kibanaBaseUrl", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.id.", - "name": "alertId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.name.", - "name": "alertName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.id.", - "name": "alertInstanceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroup.", - "name": "alertActionGroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroupName.", - "name": "alertActionGroupName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionSubgroup.", - "name": "alertActionSubgroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.spaceId.", - "name": "spaceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.tags.", - "name": "tags", - }, - Object { - "description": "foo-description", - "name": "context.foo", - }, - Object { - "description": "bar-description", - "name": "context.bar", - }, - ] - `); + expect(transformActionVariables(alertType.actionVariables)).toEqual([ + ...expectedTransformResult, + ...expectedContextTransformResult(), + ]); }); - test('should return correct variables when no context provided', async () => { + test('should return correct variables when state is provided', async () => { const alertType = getAlertType({ context: [], - state: [ - { name: 'foo', description: 'foo-description' }, - { name: 'bar', description: 'bar-description' }, - ], + state: mockStateVariables(), params: [], }); - expect(transformActionVariables(alertType.actionVariables)).toMatchInlineSnapshot(` - Array [ - Object { - "description": "The ID of the rule.", - "name": "rule.id", - }, - Object { - "description": "The name of the rule.", - "name": "rule.name", - }, - Object { - "description": "The space ID of the rule.", - "name": "rule.spaceId", - }, - Object { - "description": "The tags of the rule.", - "name": "rule.tags", - }, - Object { - "description": "The type of rule.", - "name": "rule.type", - }, - Object { - "description": "The date the rule scheduled the action.", - "name": "date", - }, - Object { - "description": "The ID of the alert that scheduled actions for the rule.", - "name": "alert.id", - }, - Object { - "description": "The action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroup", - }, - Object { - "description": "The action subgroup of the alert that scheduled actions for the rule.", - "name": "alert.actionSubgroup", - }, - Object { - "description": "The human readable name of the action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroupName", - }, - Object { - "description": "The configured server.publicBaseUrl value or empty string if not configured.", - "name": "kibanaBaseUrl", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.id.", - "name": "alertId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.name.", - "name": "alertName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.id.", - "name": "alertInstanceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroup.", - "name": "alertActionGroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroupName.", - "name": "alertActionGroupName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionSubgroup.", - "name": "alertActionSubgroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.spaceId.", - "name": "spaceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.tags.", - "name": "tags", - }, - Object { - "description": "foo-description", - "name": "state.foo", - }, - Object { - "description": "bar-description", - "name": "state.bar", - }, - ] - `); + expect(transformActionVariables(alertType.actionVariables)).toEqual([ + ...expectedTransformResult, + ...expectedStateTransformResult(), + ]); }); - test('should return correct variables when both context and state provided', async () => { + test('should return correct variables when context, state and params are provided', async () => { const alertType = getAlertType({ - context: [ - { name: 'fooC', description: 'fooC-description' }, - { name: 'barC', description: 'barC-description' }, - ], - state: [ - { name: 'fooS', description: 'fooS-description' }, - { name: 'barS', description: 'barS-description' }, - ], - params: [{ name: 'fooP', description: 'fooP-description' }], + context: mockContextVariables(), + state: mockStateVariables(), + params: mockParamsVariables(), }); - expect(transformActionVariables(alertType.actionVariables)).toMatchInlineSnapshot(` - Array [ - Object { - "description": "The ID of the rule.", - "name": "rule.id", - }, - Object { - "description": "The name of the rule.", - "name": "rule.name", - }, - Object { - "description": "The space ID of the rule.", - "name": "rule.spaceId", - }, - Object { - "description": "The tags of the rule.", - "name": "rule.tags", - }, - Object { - "description": "The type of rule.", - "name": "rule.type", - }, - Object { - "description": "The date the rule scheduled the action.", - "name": "date", - }, - Object { - "description": "The ID of the alert that scheduled actions for the rule.", - "name": "alert.id", - }, - Object { - "description": "The action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroup", - }, - Object { - "description": "The action subgroup of the alert that scheduled actions for the rule.", - "name": "alert.actionSubgroup", - }, - Object { - "description": "The human readable name of the action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroupName", - }, - Object { - "description": "The configured server.publicBaseUrl value or empty string if not configured.", - "name": "kibanaBaseUrl", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.id.", - "name": "alertId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.name.", - "name": "alertName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.id.", - "name": "alertInstanceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroup.", - "name": "alertActionGroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroupName.", - "name": "alertActionGroupName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionSubgroup.", - "name": "alertActionSubgroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.spaceId.", - "name": "spaceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.tags.", - "name": "tags", - }, - Object { - "description": "fooC-description", - "name": "context.fooC", - }, - Object { - "description": "barC-description", - "name": "context.barC", - }, - Object { - "description": "fooP-description", - "name": "params.fooP", - }, - Object { - "description": "fooS-description", - "name": "state.fooS", - }, - Object { - "description": "barS-description", - "name": "state.barS", - }, - ] - `); + expect(transformActionVariables(alertType.actionVariables)).toEqual([ + ...expectedTransformResult, + ...expectedContextTransformResult(), + ...expectedParamsTransformResult(), + ...expectedStateTransformResult(), + ]); }); test('should return useWithTripleBracesInTemplates with action variables if specified', () => { const alertType = getAlertType({ - context: [ - { name: 'fooC', description: 'fooC-description', useWithTripleBracesInTemplates: true }, - { name: 'barC', description: 'barC-description' }, - ], - state: [ - { name: 'fooS', description: 'fooS-description' }, - { name: 'barS', description: 'barS-description', useWithTripleBracesInTemplates: true }, - ], - params: [ - { - name: 'fooP', - description: 'fooP-description', - useWithTripleBracesInTemplates: true, - }, - ], + context: mockContextVariables(true), + state: mockStateVariables(true), + params: mockParamsVariables(true), + }); + expect(transformActionVariables(alertType.actionVariables)).toEqual([ + ...expectedTransformResult, + ...expectedContextTransformResult(true), + ...expectedParamsTransformResult(true), + ...expectedStateTransformResult(true), + ]); + }); + + test('should return only the required action variables when omitOptionalMessageVariables is provided', () => { + const alertType = getAlertType({ + context: mockContextVariables(), + state: mockStateVariables(), + params: mockParamsVariables(), }); - expect(transformActionVariables(alertType.actionVariables)).toMatchInlineSnapshot(` - Array [ - Object { - "description": "The ID of the rule.", - "name": "rule.id", - }, - Object { - "description": "The name of the rule.", - "name": "rule.name", - }, - Object { - "description": "The space ID of the rule.", - "name": "rule.spaceId", - }, - Object { - "description": "The tags of the rule.", - "name": "rule.tags", - }, - Object { - "description": "The type of rule.", - "name": "rule.type", - }, - Object { - "description": "The date the rule scheduled the action.", - "name": "date", - }, - Object { - "description": "The ID of the alert that scheduled actions for the rule.", - "name": "alert.id", - }, - Object { - "description": "The action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroup", - }, - Object { - "description": "The action subgroup of the alert that scheduled actions for the rule.", - "name": "alert.actionSubgroup", - }, - Object { - "description": "The human readable name of the action group of the alert that scheduled actions for the rule.", - "name": "alert.actionGroupName", - }, - Object { - "description": "The configured server.publicBaseUrl value or empty string if not configured.", - "name": "kibanaBaseUrl", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.id.", - "name": "alertId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.name.", - "name": "alertName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.id.", - "name": "alertInstanceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroup.", - "name": "alertActionGroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionGroupName.", - "name": "alertActionGroupName", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of alert.actionSubgroup.", - "name": "alertActionSubgroup", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.spaceId.", - "name": "spaceId", - }, - Object { - "deprecated": true, - "description": "This has been deprecated in favor of rule.tags.", - "name": "tags", - }, - Object { - "description": "fooC-description", - "name": "context.fooC", - "useWithTripleBracesInTemplates": true, - }, - Object { - "description": "barC-description", - "name": "context.barC", - }, - Object { - "description": "fooP-description", - "name": "params.fooP", - "useWithTripleBracesInTemplates": true, - }, - Object { - "description": "fooS-description", - "name": "state.fooS", - }, - Object { - "description": "barS-description", - "name": "state.barS", - "useWithTripleBracesInTemplates": true, - }, - ] - `); + expect(transformActionVariables(alertType.actionVariables, true)).toEqual([ + ...expectedTransformResult, + ...expectedParamsTransformResult(), + ]); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.ts index 9722cc42ed396..2cf1df85a3447 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.ts @@ -6,17 +6,27 @@ */ import { i18n } from '@kbn/i18n'; -import { ActionVariables } from '../../types'; +import { pick } from 'lodash'; +import { ActionVariables, REQUIRED_ACTION_VARIABLES } from '../../types'; import { ActionVariable } from '../../../../alerting/common'; // return a "flattened" list of action variables for an alertType -export function transformActionVariables(actionVariables: ActionVariables): ActionVariable[] { +export function transformActionVariables( + actionVariables: ActionVariables, + omitOptionalMessageVariables?: boolean +): ActionVariable[] { + const filteredActionVariables: ActionVariables = omitOptionalMessageVariables + ? pick(actionVariables, ...REQUIRED_ACTION_VARIABLES) + : actionVariables; + const alwaysProvidedVars = getAlwaysProvidedActionVariables(); - const contextVars = actionVariables.context - ? prefixKeys(actionVariables.context, 'context.') + const paramsVars = prefixKeys(filteredActionVariables.params, 'params.'); + const contextVars = filteredActionVariables.context + ? prefixKeys(filteredActionVariables.context, 'context.') + : []; + const stateVars = filteredActionVariables.state + ? prefixKeys(filteredActionVariables.state, 'state.') : []; - const paramsVars = prefixKeys(actionVariables.params, 'params.'); - const stateVars = prefixKeys(actionVariables.state, 'state.'); return alwaysProvidedVars.concat(contextVars, paramsVars, stateVars); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx index 10244213614e2..4a4230c233dfa 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx @@ -24,7 +24,7 @@ import { EuiBadge, EuiErrorBoundary, } from '@elastic/eui'; -import { partition, pick } from 'lodash'; +import { partition } from 'lodash'; import { ActionVariable, AlertActionParam } from '../../../../../alerting/common'; import { IErrorObject, @@ -33,7 +33,6 @@ import { ActionConnector, ActionVariables, ActionTypeRegistryContract, - REQUIRED_ACTION_VARIABLES, } from '../../../types'; import { checkActionFormActionTypeEnabled } from '../../lib/check_action_type_enabled'; import { hasSaveActionsCapability } from '../../lib/capabilities'; @@ -346,9 +345,8 @@ function getAvailableActionVariables( actionGroup?: ActionGroupWithMessageVariables ) { const transformedActionVariables: ActionVariable[] = transformActionVariables( + actionVariables, actionGroup?.omitOptionalMessageVariables - ? pick(actionVariables, ...REQUIRED_ACTION_VARIABLES) - : actionVariables ); // partition deprecated items so they show up last diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index bfb1c9b6280c3..f4ff0254ce0ce 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -199,8 +199,8 @@ export type ActionConnectorTableItem = ActionConnector & { type AsActionVariables = { [Req in Keys]: ActionVariable[]; }; -export const REQUIRED_ACTION_VARIABLES = ['state', 'params'] as const; -export const OPTIONAL_ACTION_VARIABLES = ['context'] as const; +export const REQUIRED_ACTION_VARIABLES = ['params'] as const; +export const OPTIONAL_ACTION_VARIABLES = ['state', 'context'] as const; export type ActionVariables = AsActionVariables & Partial>;