From 1352e529d45bd24c208403bc74bfdb6df4776bd9 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 10:30:33 +0300 Subject: [PATCH 01/28] Add isSystemAction to ActionResult type and default it to false --- .../server/action_type_registry.test.ts | 1 + .../actions/server/actions_client.test.ts | 22 +++++++++++++++++++ .../plugins/actions/server/actions_client.ts | 6 +++++ .../server/create_execute_function.test.ts | 6 +++++ .../create_unsecured_execute_function.test.ts | 7 ++++++ .../server/lib/action_executor.test.ts | 2 ++ .../lib/is_connector_deprecated.test.ts | 3 ++- x-pack/plugins/actions/server/plugin.ts | 1 + .../alert_history_es_index.ts | 1 + .../actions/server/routes/create.test.ts | 5 +++++ .../plugins/actions/server/routes/create.ts | 2 ++ .../plugins/actions/server/routes/get.test.ts | 5 +++++ x-pack/plugins/actions/server/routes/get.ts | 2 ++ .../plugins/actions/server/routes/get_all.ts | 2 ++ .../server/routes/legacy/create.test.ts | 3 +++ .../actions/server/routes/legacy/get.test.ts | 4 ++++ .../server/routes/legacy/update.test.ts | 3 +++ .../actions/server/routes/update.test.ts | 4 ++++ .../plugins/actions/server/routes/update.ts | 2 ++ .../action_task_params_migrations.test.ts | 1 + x-pack/plugins/actions/server/types.ts | 1 + .../server/usage/actions_telemetry.test.ts | 5 +++++ 22 files changed, 87 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index 73911db9cece43..589ff24c77420a 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -45,6 +45,7 @@ describe('actionTypeRegistry', () => { secrets: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, }, ], }; diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index e09e3adf931404..14a295cfec325b 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -385,6 +385,7 @@ describe('create()', () => { expect(result).toEqual({ id: '1', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, name: 'my name', actionTypeId: 'my-action-type', @@ -532,6 +533,7 @@ describe('create()', () => { expect(result).toEqual({ id: '1', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, name: 'my name', actionTypeId: 'my-action-type', @@ -722,6 +724,7 @@ describe('create()', () => { }, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -799,6 +802,7 @@ describe('get()', () => { }, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -860,6 +864,7 @@ describe('get()', () => { }, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -950,6 +955,7 @@ describe('get()', () => { expect(result).toEqual({ id: '1', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, }); expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1); @@ -983,6 +989,7 @@ describe('get()', () => { }, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -999,6 +1006,7 @@ describe('get()', () => { actionTypeId: '.slack', isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', }); expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); @@ -1057,6 +1065,7 @@ describe('getAll()', () => { secrets: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -1200,6 +1209,7 @@ describe('getAll()', () => { secrets: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -1214,6 +1224,7 @@ describe('getAll()', () => { { id: '1', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, name: 'test', config: { @@ -1226,6 +1237,7 @@ describe('getAll()', () => { id: 'testPreconfigured', actionTypeId: '.slack', isPreconfigured: true, + isSystemAction: false, isDeprecated: false, name: 'test', referencedByCount: 2, @@ -1283,6 +1295,7 @@ describe('getBulk()', () => { secrets: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -1420,6 +1433,7 @@ describe('getBulk()', () => { secrets: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -1438,6 +1452,7 @@ describe('getBulk()', () => { }, id: 'testPreconfigured', isPreconfigured: true, + isSystemAction: false, isDeprecated: false, name: 'test', secrets: {}, @@ -1450,6 +1465,7 @@ describe('getBulk()', () => { id: '1', isMissingSecrets: false, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, name: 'test', }, @@ -1479,6 +1495,7 @@ describe('getOAuthAccessToken()', () => { actionTypeId: '.slack', secrets: {}, isPreconfigured: true, + isSystemAction: false, isDeprecated: false, name: 'test', config: { @@ -1982,6 +1999,7 @@ describe('update()', () => { expect(result).toEqual({ id: 'my-action', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, actionTypeId: 'my-action-type', isMissingSecrets: false, @@ -2060,6 +2078,7 @@ describe('update()', () => { expect(result).toEqual({ id: 'my-action', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, actionTypeId: 'my-action-type', isMissingSecrets: true, @@ -2217,6 +2236,7 @@ describe('update()', () => { expect(result).toEqual({ id: 'my-action', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, actionTypeId: 'my-action-type', isMissingSecrets: true, @@ -2703,6 +2723,7 @@ describe('isPreconfigured()', () => { }, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', @@ -2742,6 +2763,7 @@ describe('isPreconfigured()', () => { }, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'test', config: { foo: 'bar', diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 3efae4952692a9..7905b7a0da6df5 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -260,6 +260,7 @@ export class ActionsClient { name: result.attributes.name, config: result.attributes.config, isPreconfigured: false, + isSystemAction: false, isDeprecated: isConnectorDeprecated(result.attributes), }; } @@ -357,6 +358,7 @@ export class ActionsClient { name: result.attributes.name as string, config: result.attributes.config as Record, isPreconfigured: false, + isSystemAction: false, isDeprecated: isConnectorDeprecated(result.attributes), }; } @@ -394,6 +396,7 @@ export class ActionsClient { actionTypeId: preconfiguredActionsList.actionTypeId, name: preconfiguredActionsList.name, isPreconfigured: true, + isSystemAction: false, isDeprecated: isConnectorDeprecated(preconfiguredActionsList), }; } @@ -414,6 +417,7 @@ export class ActionsClient { name: result.attributes.name, config: result.attributes.config, isPreconfigured: false, + isSystemAction: false, isDeprecated: isConnectorDeprecated(result.attributes), }; } @@ -460,6 +464,7 @@ export class ActionsClient { name: preconfiguredAction.name, isPreconfigured: true, isDeprecated: isConnectorDeprecated(preconfiguredAction), + isSystemAction: false, })), ].sort((a, b) => a.name.localeCompare(b.name)); return await injectExtraFindData(this.kibanaIndices, this.scopedClusterClient, mergedResult); @@ -893,6 +898,7 @@ function actionFromSavedObject( ...savedObject.attributes, isPreconfigured: false, isDeprecated, + isSystemAction: false, }; } diff --git a/x-pack/plugins/actions/server/create_execute_function.test.ts b/x-pack/plugins/actions/server/create_execute_function.test.ts index e4787101b1cdef..ec746ee62862bf 100644 --- a/x-pack/plugins/actions/server/create_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_execute_function.test.ts @@ -254,6 +254,7 @@ describe('execute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -333,6 +334,7 @@ describe('execute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -519,6 +521,7 @@ describe('execute()', () => { name: 'Slack #xyz', secrets: {}, isPreconfigured: true, + isSystemAction: false, isDeprecated: false, }, ], @@ -829,6 +832,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -925,6 +929,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -1143,6 +1148,7 @@ describe('bulkExecute()', () => { secrets: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, }, ], }); diff --git a/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts b/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts index cd50be7558fea5..8e75a889c3410d 100644 --- a/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts @@ -32,6 +32,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -137,6 +138,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -254,6 +256,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -395,6 +398,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -430,6 +434,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -466,6 +471,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, @@ -475,6 +481,7 @@ describe('bulkExecute()', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, name: 'x', secrets: {}, }, diff --git a/x-pack/plugins/actions/server/lib/action_executor.test.ts b/x-pack/plugins/actions/server/lib/action_executor.test.ts index 8323428395e880..9b2e2f96390c79 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.test.ts @@ -64,6 +64,7 @@ actionExecutor.initialize({ }, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, }, ], }); @@ -988,6 +989,7 @@ test('should not throw error if action is preconfigured and isESOCanEncrypt is f }, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, }, ], }); diff --git a/x-pack/plugins/actions/server/lib/is_connector_deprecated.test.ts b/x-pack/plugins/actions/server/lib/is_connector_deprecated.test.ts index 8d2a698563b0c9..8306421f76f79f 100644 --- a/x-pack/plugins/actions/server/lib/is_connector_deprecated.test.ts +++ b/x-pack/plugins/actions/server/lib/is_connector_deprecated.test.ts @@ -14,7 +14,8 @@ describe('isConnectorDeprecated', () => { name: 'Test', config: { apiUrl: 'http://example.com', usesTableApi: false }, secrets: { username: 'test', password: 'test' }, - isPreconfigured: false as const, + isPreconfigured: false, + isSystemAction: false, }; it('returns false if the config is not defined', () => { diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index 8e44714129557b..ba4fec697b0c7b 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -253,6 +253,7 @@ export class ActionsPlugin implements Plugin { id: AlertHistoryEsIndexConnectorId, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, config: { index: AlertHistoryDefaultIndexName, }, diff --git a/x-pack/plugins/actions/server/routes/create.test.ts b/x-pack/plugins/actions/server/routes/create.test.ts index dc06a119ca2fa7..2161e68e3706bf 100644 --- a/x-pack/plugins/actions/server/routes/create.test.ts +++ b/x-pack/plugins/actions/server/routes/create.test.ts @@ -41,6 +41,7 @@ describe('createActionRoute', () => { isPreconfigured: false, isDeprecated: false, isMissingSecrets: false, + isSystemAction: false, }; const createApiResult = { @@ -49,11 +50,13 @@ describe('createActionRoute', () => { 'isPreconfigured', 'isDeprecated', 'isMissingSecrets', + 'isSystemAction', ]), connector_type_id: createResult.actionTypeId, is_preconfigured: createResult.isPreconfigured, is_deprecated: createResult.isDeprecated, is_missing_secrets: createResult.isMissingSecrets, + is_system_action: createResult.isSystemAction, }; const actionsClient = actionsClientMock.create(); @@ -113,6 +116,7 @@ describe('createActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }); const [context, req, res] = mockHandlerArguments( @@ -153,6 +157,7 @@ describe('createActionRoute', () => { isMissingSecrets: false, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }); const [context, req, res] = mockHandlerArguments( diff --git a/x-pack/plugins/actions/server/routes/create.ts b/x-pack/plugins/actions/server/routes/create.ts index c55661ce7b9214..c3928e72d042ba 100644 --- a/x-pack/plugins/actions/server/routes/create.ts +++ b/x-pack/plugins/actions/server/routes/create.ts @@ -35,6 +35,7 @@ const rewriteBodyRes: RewriteResponseCase = ({ isPreconfigured, isDeprecated, isMissingSecrets, + isSystemAction, ...res }) => ({ ...res, @@ -42,6 +43,7 @@ const rewriteBodyRes: RewriteResponseCase = ({ is_preconfigured: isPreconfigured, is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, }); export const createActionRoute = ( diff --git a/x-pack/plugins/actions/server/routes/get.test.ts b/x-pack/plugins/actions/server/routes/get.test.ts index 7f9736ad7dfb26..76dda602945c95 100644 --- a/x-pack/plugins/actions/server/routes/get.test.ts +++ b/x-pack/plugins/actions/server/routes/get.test.ts @@ -40,6 +40,7 @@ describe('getActionRoute', () => { isPreconfigured: false, isDeprecated: false, isMissingSecrets: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); @@ -62,6 +63,7 @@ describe('getActionRoute', () => { "is_deprecated": false, "is_missing_secrets": false, "is_preconfigured": false, + "is_system_action": false, "name": "action name", }, } @@ -79,6 +81,7 @@ describe('getActionRoute', () => { is_preconfigured: false, is_deprecated: false, is_missing_secrets: false, + is_system_action: false, }, }); }); @@ -99,6 +102,7 @@ describe('getActionRoute', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }); const [context, req, res] = mockHandlerArguments( @@ -134,6 +138,7 @@ describe('getActionRoute', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }); const [context, req, res] = mockHandlerArguments( diff --git a/x-pack/plugins/actions/server/routes/get.ts b/x-pack/plugins/actions/server/routes/get.ts index 207ed694f2985a..82aad7d371c72d 100644 --- a/x-pack/plugins/actions/server/routes/get.ts +++ b/x-pack/plugins/actions/server/routes/get.ts @@ -21,6 +21,7 @@ const rewriteBodyRes: RewriteResponseCase = ({ isPreconfigured, isMissingSecrets, isDeprecated, + isSystemAction, ...res }) => ({ ...res, @@ -28,6 +29,7 @@ const rewriteBodyRes: RewriteResponseCase = ({ is_preconfigured: isPreconfigured, is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, }); export const getActionRoute = ( diff --git a/x-pack/plugins/actions/server/routes/get_all.ts b/x-pack/plugins/actions/server/routes/get_all.ts index 61da031db99d4c..dec70257313e10 100644 --- a/x-pack/plugins/actions/server/routes/get_all.ts +++ b/x-pack/plugins/actions/server/routes/get_all.ts @@ -19,6 +19,7 @@ const rewriteBodyRes: RewriteResponseCase = (results) => { isDeprecated, referencedByCount, isMissingSecrets, + isSystemAction, ...res }) => ({ ...res, @@ -27,6 +28,7 @@ const rewriteBodyRes: RewriteResponseCase = (results) => { is_deprecated: isDeprecated, referenced_by_count: referencedByCount, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, }) ); }; diff --git a/x-pack/plugins/actions/server/routes/legacy/create.test.ts b/x-pack/plugins/actions/server/routes/legacy/create.test.ts index 656c24d118d300..0d285244342a67 100644 --- a/x-pack/plugins/actions/server/routes/legacy/create.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/create.test.ts @@ -48,6 +48,7 @@ describe('createActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); @@ -105,6 +106,7 @@ describe('createActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }); const [context, req, res] = mockHandlerArguments({ actionsClient }, {}); @@ -134,6 +136,7 @@ describe('createActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }); const [context, req, res] = mockHandlerArguments({ actionsClient }, {}); diff --git a/x-pack/plugins/actions/server/routes/legacy/get.test.ts b/x-pack/plugins/actions/server/routes/legacy/get.test.ts index a79185a4ea882b..be5cc1c819e3ac 100644 --- a/x-pack/plugins/actions/server/routes/legacy/get.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/get.test.ts @@ -47,6 +47,7 @@ describe('getActionRoute', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); @@ -68,6 +69,7 @@ describe('getActionRoute', () => { "id": "1", "isDeprecated": false, "isPreconfigured": false, + "isSystemAction": false, "name": "action name", }, } @@ -97,6 +99,7 @@ describe('getActionRoute', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }); const [context, req, res] = mockHandlerArguments( @@ -132,6 +135,7 @@ describe('getActionRoute', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }); const [context, req, res] = mockHandlerArguments( diff --git a/x-pack/plugins/actions/server/routes/legacy/update.test.ts b/x-pack/plugins/actions/server/routes/legacy/update.test.ts index 49bb0ff2b86e03..9158b4165a6604 100644 --- a/x-pack/plugins/actions/server/routes/legacy/update.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/update.test.ts @@ -47,6 +47,7 @@ describe('updateActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); @@ -105,6 +106,7 @@ describe('updateActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); @@ -149,6 +151,7 @@ describe('updateActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); diff --git a/x-pack/plugins/actions/server/routes/update.test.ts b/x-pack/plugins/actions/server/routes/update.test.ts index d22d16798376e6..ac9f3dc45f6606 100644 --- a/x-pack/plugins/actions/server/routes/update.test.ts +++ b/x-pack/plugins/actions/server/routes/update.test.ts @@ -39,6 +39,7 @@ describe('updateActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); @@ -67,6 +68,7 @@ describe('updateActionRoute', () => { config: { foo: true }, is_preconfigured: false, is_deprecated: false, + is_system_action: false, }, }); @@ -106,6 +108,7 @@ describe('updateActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); @@ -150,6 +153,7 @@ describe('updateActionRoute', () => { config: { foo: true }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const actionsClient = actionsClientMock.create(); diff --git a/x-pack/plugins/actions/server/routes/update.ts b/x-pack/plugins/actions/server/routes/update.ts index b0d233c5067672..a44c8ea7bb5b91 100644 --- a/x-pack/plugins/actions/server/routes/update.ts +++ b/x-pack/plugins/actions/server/routes/update.ts @@ -31,6 +31,7 @@ const rewriteBodyRes: RewriteResponseCase = ({ isPreconfigured, isMissingSecrets, isDeprecated, + isSystemAction, ...res }) => ({ ...res, @@ -38,6 +39,7 @@ const rewriteBodyRes: RewriteResponseCase = ({ is_preconfigured: isPreconfigured, is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, }); export const updateActionRoute = ( diff --git a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts index 3b19a9feb15a6c..7ef21c8fc84bd3 100644 --- a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts @@ -28,6 +28,7 @@ const preconfiguredActions = [ secrets: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, }, ]; diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index 4b568b949bef5a..061cdd2db3d901 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -81,6 +81,7 @@ export interface ActionResult Date: Wed, 28 Jun 2023 16:25:47 +0300 Subject: [PATCH 02/28] Disallow registering system actions --- .../plugins/actions/server/action_type_registry.ts | 12 ++++++++++++ x-pack/plugins/actions/server/types.ts | 3 +-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/actions/server/action_type_registry.ts b/x-pack/plugins/actions/server/action_type_registry.ts index 09f7fa5370fc0d..8404bafbd8994f 100644 --- a/x-pack/plugins/actions/server/action_type_registry.ts +++ b/x-pack/plugins/actions/server/action_type_registry.ts @@ -104,6 +104,18 @@ export class ActionTypeRegistry { Params extends ActionTypeParams = ActionTypeParams, ExecutorResultData = void >(actionType: ActionType) { + // TODO: Remove when system action are supported + if (actionType.isSystemAction) { + throw new Error( + i18n.translate( + 'xpack.actions.actionTypeRegistry.register.systemActionsNotSupportedErrorMessage', + { + defaultMessage: 'System actions are not supported', + } + ) + ); + } + if (this.has(actionType.id)) { throw new Error( i18n.translate( diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index 061cdd2db3d901..54f5f8327be65a 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -140,9 +140,8 @@ export interface ActionType< secrets: ValidatorType; connector?: (config: Config, secrets: Secrets) => string | null; }; - + isSystemAction?: boolean; renderParameterTemplates?: RenderParameterTemplates; - executor: ExecutorType; } From dc1a2c8692df8762e1582e230ce7950f8929e6d4 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 18:18:32 +0300 Subject: [PATCH 03/28] Add test --- .../server/action_type_registry.test.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index 589ff24c77420a..595461b137b593 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -216,6 +216,26 @@ describe('actionTypeRegistry', () => { }); expect(actionTypeRegistryParams.licensing.featureUsage.register).not.toHaveBeenCalled(); }); + + test('does not allows registering system actions', () => { + const actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams); + + expect(() => + actionTypeRegistry.register({ + id: 'my-action-type', + name: 'My action type', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + isSystemAction: true, + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, + }, + executor, + }) + ).toThrowErrorMatchingInlineSnapshot(`"System actions are not supported"`); + }); }); describe('get()', () => { From bb7e9a57c56480ca600670935ca42585b78fd557 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 18:27:20 +0300 Subject: [PATCH 04/28] Fix alerting types --- .../server/rules_client/tests/bulk_edit.test.ts | 1 + .../server/rules_client/tests/create.test.ts | 8 ++++++++ .../alerting/server/rules_client/tests/lib.ts | 3 +++ .../server/rules_client/tests/update.test.ts | 14 ++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts index 8a4978e78f28e2..1f6e86945b1b52 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts @@ -161,6 +161,7 @@ describe('bulkEdit()', () => { isMissingSecrets: false, name: 'email connector', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, }, ]); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index 7e21881410e746..8de37e55421e1d 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -132,6 +132,7 @@ describe('create()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); taskManager.schedule.mockResolvedValue({ @@ -740,6 +741,7 @@ describe('create()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '2', @@ -756,6 +758,7 @@ describe('create()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ @@ -912,6 +915,7 @@ describe('create()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '2', @@ -928,6 +932,7 @@ describe('create()', () => { name: 'another email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: 'preconfigured', @@ -944,6 +949,7 @@ describe('create()', () => { name: 'preconfigured email connector', isPreconfigured: true, isDeprecated: false, + isSystemAction: false, }, ]); actionsClient.isPreconfigured.mockReset(); @@ -2658,6 +2664,7 @@ describe('create()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( @@ -3163,6 +3170,7 @@ describe('create()', () => { name: 'Slack connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ diff --git a/x-pack/plugins/alerting/server/rules_client/tests/lib.ts b/x-pack/plugins/alerting/server/rules_client/tests/lib.ts index 337c09e087243e..25afdedf54d3c5 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/lib.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/lib.ts @@ -77,6 +77,7 @@ export function getBeforeSetup( { id: '1', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, actionTypeId: 'test', name: 'test', @@ -87,6 +88,7 @@ export function getBeforeSetup( { id: '2', isPreconfigured: false, + isSystemAction: false, isDeprecated: false, actionTypeId: 'test2', name: 'test2', @@ -98,6 +100,7 @@ export function getBeforeSetup( id: 'testPreconfigured', actionTypeId: '.slack', isPreconfigured: true, + isSystemAction: false, isDeprecated: false, name: 'test', }, diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index 775df48e8fc02e..51717f8bb78393 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -151,6 +151,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); rulesClientParams.getActionsClient.mockResolvedValue(actionsClient); @@ -200,6 +201,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '2', @@ -216,6 +218,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ @@ -476,6 +479,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '2', @@ -492,6 +496,7 @@ describe('update()', () => { name: 'another email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: 'preconfigured', @@ -508,6 +513,7 @@ describe('update()', () => { name: 'preconfigured email connector', isPreconfigured: true, isDeprecated: false, + isSystemAction: false, }, ]); actionsClient.isPreconfigured.mockReset(); @@ -1438,6 +1444,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '2', @@ -1454,6 +1461,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ @@ -2024,6 +2032,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '2', @@ -2040,6 +2049,7 @@ describe('update()', () => { name: 'another connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); @@ -2098,6 +2108,7 @@ describe('update()', () => { name: 'slack connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); actionsClient.isPreconfigured.mockReset(); @@ -2259,6 +2270,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '2', @@ -2275,6 +2287,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ @@ -2610,6 +2623,7 @@ describe('update()', () => { name: 'email connector', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ From 774b389ffebbd0028a7e1fe786c4ddf233ae19e8 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 18:49:57 +0300 Subject: [PATCH 05/28] Fix integration tests --- .../group2/tests/actions/connector_types/cases_webhook.ts | 2 ++ .../spaces_only/tests/actions/create.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts index 154b693ad6533e..de213332753278 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts @@ -112,6 +112,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { name: 'A casesWebhook action', connector_type_id: '.cases-webhook', is_missing_secrets: false, + is_system_action: false, config: simulatorConfig, }); @@ -126,6 +127,7 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { name: 'A casesWebhook action', connector_type_id: '.cases-webhook', is_missing_secrets: false, + is_system_action: false, config: simulatorConfig, }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index bf5318509bf994..a7239343b2c610 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -43,6 +43,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { name: 'My action', connector_type_id: 'test.index-record', is_missing_secrets: false, + is_system_action: false, config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -104,6 +105,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { name: 'My action', actionTypeId: 'test.index-record', isMissingSecrets: false, + isSystemAction: false, config: { unencrypted: `This value shouldn't get encrypted`, }, From 83ee74702594c4e2ea1c669c242aa331e249fb32 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 19:45:38 +0300 Subject: [PATCH 06/28] Fix triggers_actions_ui types --- x-pack/plugins/cases/public/common/mock/connectors.ts | 5 +++++ .../public/components/all_cases/use_cases_columns.test.tsx | 1 + .../components/configure_cases/connectors_dropdown.test.tsx | 1 + x-pack/plugins/cases/public/components/connectors/mock.ts | 1 + x-pack/plugins/cases/public/components/utils.test.ts | 1 + .../application/lib/action_connector_api/connectors.ts | 2 ++ .../public/application/lib/action_connector_api/create.ts | 2 ++ .../application/lib/action_connector_api/update.test.ts | 2 ++ .../public/application/lib/action_connector_api/update.ts | 2 ++ .../application/lib/check_action_type_enabled.test.tsx | 2 ++ .../public/application/lib/value_validators.test.ts | 3 +++ .../sections/action_connector_form/action_type_form.test.tsx | 3 +++ .../action_connector_form/connectors_selection.test.tsx | 1 + .../edit_connector_flyout/index.test.tsx | 1 + .../components/actions_connectors_list.test.tsx | 1 + x-pack/plugins/triggers_actions_ui/public/types.ts | 1 + 16 files changed, 29 insertions(+) diff --git a/x-pack/plugins/cases/public/common/mock/connectors.ts b/x-pack/plugins/cases/public/common/mock/connectors.ts index 4d733c4e660a84..3485af438a4d9f 100644 --- a/x-pack/plugins/cases/public/common/mock/connectors.ts +++ b/x-pack/plugins/cases/public/common/mock/connectors.ts @@ -19,6 +19,7 @@ export const connectorsMock: ActionConnector[] = [ apiUrl: 'https://instance1.service-now.com', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, }, { @@ -30,6 +31,7 @@ export const connectorsMock: ActionConnector[] = [ orgId: '201', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, }, { @@ -40,6 +42,7 @@ export const connectorsMock: ActionConnector[] = [ apiUrl: 'https://instance.atlassian.ne', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, }, { @@ -50,6 +53,7 @@ export const connectorsMock: ActionConnector[] = [ apiUrl: 'https://instance1.service-now.com', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, }, { @@ -61,6 +65,7 @@ export const connectorsMock: ActionConnector[] = [ usesTableApi: true, }, isPreconfigured: false, + isSystemAction: false, isDeprecated: true, }, ]; diff --git a/x-pack/plugins/cases/public/components/all_cases/use_cases_columns.test.tsx b/x-pack/plugins/cases/public/components/all_cases/use_cases_columns.test.tsx index 07163b1e1eb4fb..42a5ea4c1d1fc5 100644 --- a/x-pack/plugins/cases/public/components/all_cases/use_cases_columns.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/use_cases_columns.test.tsx @@ -791,6 +791,7 @@ describe('useCasesColumns ', () => { name: 'None', config: {}, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, }, ]} diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx index b659e5b1875201..d36ba676357cfc 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx @@ -252,6 +252,7 @@ describe('ConnectorsDropdown', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]} />, diff --git a/x-pack/plugins/cases/public/components/connectors/mock.ts b/x-pack/plugins/cases/public/components/connectors/mock.ts index c4739002e6f8c9..ef2b1c08eeb52b 100644 --- a/x-pack/plugins/cases/public/components/connectors/mock.ts +++ b/x-pack/plugins/cases/public/components/connectors/mock.ts @@ -14,6 +14,7 @@ export const connector = { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; export const swimlaneConnector = { diff --git a/x-pack/plugins/cases/public/components/utils.test.ts b/x-pack/plugins/cases/public/components/utils.test.ts index 3866b2503d63ff..6bef0b8585d4b8 100644 --- a/x-pack/plugins/cases/public/components/utils.test.ts +++ b/x-pack/plugins/cases/public/components/utils.test.ts @@ -28,6 +28,7 @@ describe('Utils', () => { config: { usesTableApi: false }, secrets: {}, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts index c08232ca5eea51..60f1e252956869 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts @@ -25,6 +25,7 @@ const transformConnector: RewriteRequestCase< is_deprecated: isDeprecated, referenced_by_count: referencedByCount, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, ...res }) => ({ actionTypeId, @@ -32,6 +33,7 @@ const transformConnector: RewriteRequestCase< isDeprecated, referencedByCount, isMissingSecrets, + isSystemAction, ...res, }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts index 287c27a1c0e3f2..1256497a5d4489 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts @@ -27,6 +27,7 @@ const rewriteBodyRes: RewriteRequestCase< is_preconfigured: isPreconfigured, is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, ...res }) => ({ ...res, @@ -34,6 +35,7 @@ const rewriteBodyRes: RewriteRequestCase< isPreconfigured, isDeprecated, isMissingSecrets, + isSystemAction, }); export async function createActionConnector({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.test.ts index 957f682d1fd6cf..1030e3375aa078 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.test.ts @@ -20,6 +20,7 @@ describe('updateActionConnector', () => { connector_type_id: 'te/st', is_preconfigured: false, is_deprecated: false, + is_system_action: false, name: 'My test', config: {}, secrets: {}, @@ -31,6 +32,7 @@ describe('updateActionConnector', () => { actionTypeId: 'te/st', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, name: 'My test', config: {}, secrets: {}, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts index 34aa1e127ad95e..7b65b534431985 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts @@ -20,6 +20,7 @@ const rewriteBodyRes: RewriteRequestCase< is_preconfigured: isPreconfigured, is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, ...res }) => ({ ...res, @@ -27,6 +28,7 @@ const rewriteBodyRes: RewriteRequestCase< isPreconfigured, isDeprecated, isMissingSecrets, + isSystemAction, }); export async function updateActionConnector({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx index 7152f5455a72ce..e2dc91214e783e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx @@ -102,6 +102,7 @@ describe('checkActionFormActionTypeEnabled', () => { actionTypeId: '1', id: 'test1', isPreconfigured: true, + isSystemAction: false, isDeprecated: true, name: 'test', referencedByCount: 0, @@ -111,6 +112,7 @@ describe('checkActionFormActionTypeEnabled', () => { id: 'test2', isPreconfigured: true, isDeprecated: true, + isSystemAction: false, name: 'test', referencedByCount: 0, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts index 4fdd9fe0893abe..97c9ba686435a9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts @@ -113,6 +113,7 @@ describe('getConnectorWithInvalidatedFields', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const secretsErrors = { webhookUrl: ['Webhook URL is required.'] }; const configErrors = {}; @@ -130,6 +131,7 @@ describe('getConnectorWithInvalidatedFields', () => { config: {} as any, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const secretsErrors = {}; const configErrors = { apiUrl: ['apiUrl is required'] }; @@ -149,6 +151,7 @@ describe('getConnectorWithInvalidatedFields', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; const secretsErrors = { webhookUrl: ['Webhook URL must start with https://.'] }; const configErrors = {}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx index 171636d060c9eb..807e5454f094fe 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx @@ -556,6 +556,7 @@ function getActionTypeForm({ id: 'test', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, name: 'test name', secrets: {}, }; @@ -579,6 +580,7 @@ function getActionTypeForm({ id: 'test', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, name: 'test name', secrets: {}, }, @@ -588,6 +590,7 @@ function getActionTypeForm({ actionTypeId: '.server-log', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, config: {}, secrets: {}, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx index 97742e22a9ae48..230f81e1531624 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx @@ -69,6 +69,7 @@ describe('connectors_selection', () => { id: 'testId', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, name: 'test pagerduty', secrets: {}, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.test.tsx index e13465b356f8eb..eed385f7ef11ff 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.test.tsx @@ -40,6 +40,7 @@ const connector: ActionConnector = { isDeprecated: false, isPreconfigured: false, isMissingSecrets: false, + isSystemAction: false, }; describe('EditConnectorFlyout', () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx index ce9e4e638b573b..90f4bcc1e6d137 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx @@ -318,6 +318,7 @@ describe('actions_connectors_list', () => { description: `My test ${index}`, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, config: {}, })) diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 923f3847df0781..3e4006e64ca7f0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -278,6 +278,7 @@ export interface ActionConnectorProps { config: Config; isPreconfigured: boolean; isDeprecated: boolean; + isSystemAction: boolean; isMissingSecrets?: boolean; } From d2b8e670f9f0d9ce0cbb12f33103b980e6230cb0 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 19:50:27 +0300 Subject: [PATCH 07/28] Fix cases types --- x-pack/plugins/cases/common/api/connectors/connector.ts | 1 + x-pack/plugins/cases/public/components/connectors/mock.ts | 1 + .../connectors/servicenow/use_get_choices.test.tsx | 1 + x-pack/plugins/cases/server/client/cases/utils.test.ts | 1 + x-pack/plugins/cases/server/client/configure/client.test.ts | 6 ++++++ 5 files changed, 10 insertions(+) diff --git a/x-pack/plugins/cases/common/api/connectors/connector.ts b/x-pack/plugins/cases/common/api/connectors/connector.ts index 66e5c5ada902b7..ebdc1d5db9bb69 100644 --- a/x-pack/plugins/cases/common/api/connectors/connector.ts +++ b/x-pack/plugins/cases/common/api/connectors/connector.ts @@ -102,6 +102,7 @@ const ActionConnectorResultRt = rt.intersection([ name: rt.string, isDeprecated: rt.boolean, isPreconfigured: rt.boolean, + isSystemAction: rt.boolean, referencedByCount: rt.number, }), rt.exact(rt.partial({ config: rt.record(rt.string, rt.unknown), isMissingSecrets: rt.boolean })), diff --git a/x-pack/plugins/cases/public/components/connectors/mock.ts b/x-pack/plugins/cases/public/components/connectors/mock.ts index ef2b1c08eeb52b..c66f11ebacff7b 100644 --- a/x-pack/plugins/cases/public/components/connectors/mock.ts +++ b/x-pack/plugins/cases/public/components/connectors/mock.ts @@ -32,6 +32,7 @@ export const swimlaneConnector = { }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; export const issues = [ diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/use_get_choices.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/use_get_choices.test.tsx index c8182ce9705955..06141f14dbeb85 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/use_get_choices.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/use_get_choices.test.tsx @@ -30,6 +30,7 @@ const connector = { name: 'ServiceNow', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, config: { apiUrl: 'https://dev94428.service-now.com/', }, diff --git a/x-pack/plugins/cases/server/client/cases/utils.test.ts b/x-pack/plugins/cases/server/client/cases/utils.test.ts index 1efea16801c17a..089af7f31c6983 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.test.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.test.ts @@ -85,6 +85,7 @@ describe('utils', () => { }, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }; it('creates an external incident correctly for Jira', async () => { diff --git a/x-pack/plugins/cases/server/client/configure/client.test.ts b/x-pack/plugins/cases/server/client/configure/client.test.ts index e344273b51baa1..1c2590251b90a8 100644 --- a/x-pack/plugins/cases/server/client/configure/client.test.ts +++ b/x-pack/plugins/cases/server/client/configure/client.test.ts @@ -72,6 +72,7 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, { @@ -81,6 +82,8 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, + referencedByCount: 1, }, { @@ -90,6 +93,7 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, ]; @@ -135,6 +139,7 @@ describe('client', () => { config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, ]); @@ -181,6 +186,7 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, ]); From 31f1f396c28bf8eb61e88ea1cbc8c3f157b8f41a Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 19:58:13 +0300 Subject: [PATCH 08/28] Fix cases tests --- .../server/action_type_registry.test.ts | 2 +- .../common/api/connectors/connector.test.ts | 2 ++ .../server/client/configure/client.test.ts | 7 +++++ .../spaces_only/tests/actions/get_all.ts | 28 +++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index 595461b137b593..613438579e13ef 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -226,7 +226,7 @@ describe('actionTypeRegistry', () => { name: 'My action type', minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], - isSystemAction: true, + isSystemAction: false, validate: { config: { schema: schema.object({}) }, secrets: { schema: schema.object({}) }, diff --git a/x-pack/plugins/cases/common/api/connectors/connector.test.ts b/x-pack/plugins/cases/common/api/connectors/connector.test.ts index 33208ab7222521..39640b16070240 100644 --- a/x-pack/plugins/cases/common/api/connectors/connector.test.ts +++ b/x-pack/plugins/cases/common/api/connectors/connector.test.ts @@ -160,6 +160,7 @@ describe('Connector', () => { referencedByCount: 0, config: { foo: 'bar' }, isMissingSecrets: false, + isSystemAction: false, }, { id: 'test-2', @@ -167,6 +168,7 @@ describe('Connector', () => { name: 'My connector 2', isDeprecated: false, isPreconfigured: false, + isSystemAction: false, referencedByCount: 0, }, ]; diff --git a/x-pack/plugins/cases/server/client/configure/client.test.ts b/x-pack/plugins/cases/server/client/configure/client.test.ts index 1c2590251b90a8..43e19a799b5e66 100644 --- a/x-pack/plugins/cases/server/client/configure/client.test.ts +++ b/x-pack/plugins/cases/server/client/configure/client.test.ts @@ -114,6 +114,7 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, { @@ -122,6 +123,7 @@ describe('client', () => { name: '2', config: {}, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, referencedByCount: 1, }, @@ -152,6 +154,7 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, { @@ -161,6 +164,7 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, { @@ -169,6 +173,7 @@ describe('client', () => { name: 'sn-preconfigured', config: {}, isPreconfigured: true, + isSystemAction: false, isDeprecated: false, referencedByCount: 1, }, @@ -199,6 +204,7 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, { @@ -208,6 +214,7 @@ describe('client', () => { config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, ]); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts index b2b208843c60e8..c34c314ade4c34 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -53,6 +53,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { connector_type_id: '.index', is_preconfigured: true, is_deprecated: false, + is_system_action: false, referenced_by_count: 0, }, { @@ -62,6 +63,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'My action', connector_type_id: 'test.index-record', is_missing_secrets: false, + is_system_action: false, config: { unencrypted: `This value shouldn't get encrypted`, }, @@ -72,6 +74,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'notification-email', is_deprecated: false, is_preconfigured: true, + is_system_action: false, name: 'Notification Email Connector', referenced_by_count: 0, }, @@ -79,6 +82,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'preconfigured-es-index-action', is_preconfigured: true, is_deprecated: false, + is_system_action: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', referenced_by_count: 0, @@ -88,6 +92,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow', is_deprecated: true, is_preconfigured: true, + is_system_action: false, name: 'ServiceNow#xyz', referenced_by_count: 0, }, @@ -96,6 +101,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow-default', is_preconfigured: true, is_deprecated: true, + is_system_action: false, name: 'ServiceNow#xyz', referenced_by_count: 0, }, @@ -104,6 +110,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { is_preconfigured: true, is_deprecated: false, connector_type_id: '.slack', + is_system_action: false, name: 'Slack#xyz', referenced_by_count: 0, }, @@ -112,6 +119,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { is_preconfigured: true, is_deprecated: false, connector_type_id: 'system-abc-action-type', + is_system_action: false, name: 'SystemABC', referenced_by_count: 0, }, @@ -120,6 +128,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { is_preconfigured: true, is_deprecated: false, connector_type_id: 'test.index-record', + is_system_action: false, name: 'Test:_Preconfigured_Index_Record', referenced_by_count: 0, }, @@ -168,6 +177,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { connector_type_id: '.index', is_preconfigured: true, is_deprecated: false, + is_system_action: false, referenced_by_count: 0, }, { @@ -175,6 +185,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'notification-email', is_deprecated: false, is_preconfigured: true, + is_system_action: false, name: 'Notification Email Connector', referenced_by_count: 0, }, @@ -182,6 +193,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'preconfigured-es-index-action', is_preconfigured: true, is_deprecated: false, + is_system_action: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', referenced_by_count: 0, @@ -191,6 +203,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow', is_deprecated: true, is_preconfigured: true, + is_system_action: false, name: 'ServiceNow#xyz', referenced_by_count: 0, }, @@ -199,6 +212,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow-default', is_preconfigured: true, is_deprecated: true, + is_system_action: false, name: 'ServiceNow#xyz', referenced_by_count: 0, }, @@ -206,6 +220,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-slack1', is_preconfigured: true, is_deprecated: false, + is_system_action: false, connector_type_id: '.slack', name: 'Slack#xyz', referenced_by_count: 0, @@ -214,6 +229,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'custom-system-abc-connector', is_preconfigured: true, is_deprecated: false, + is_system_action: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', referenced_by_count: 0, @@ -222,6 +238,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'preconfigured.test.index-record', is_preconfigured: true, is_deprecated: false, + is_system_action: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referenced_by_count: 0, @@ -230,6 +247,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-test-email', is_preconfigured: true, is_deprecated: false, + is_system_action: false, connector_type_id: '.email', name: 'TestEmail#xyz', referenced_by_count: 0, @@ -271,6 +289,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Alert history Elasticsearch index', actionTypeId: '.index', isPreconfigured: true, + isSystemAction: false, isDeprecated: false, referencedByCount: 0, }, @@ -278,6 +297,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: createdAction.id, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, name: 'My action', actionTypeId: 'test.index-record', isMissingSecrets: false, @@ -291,6 +311,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'notification-email', isDeprecated: false, isPreconfigured: true, + isSystemAction: false, name: 'Notification Email Connector', referencedByCount: 0, }, @@ -299,6 +320,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { isPreconfigured: true, isDeprecated: false, actionTypeId: '.index', + isSystemAction: false, name: 'preconfigured_es_index_action', referencedByCount: 0, }, @@ -307,6 +329,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow', isDeprecated: true, isPreconfigured: true, + isSystemAction: false, name: 'ServiceNow#xyz', referencedByCount: 0, }, @@ -315,6 +338,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow-default', isPreconfigured: true, isDeprecated: true, + isSystemAction: false, name: 'ServiceNow#xyz', referencedByCount: 0, }, @@ -323,6 +347,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { isPreconfigured: true, isDeprecated: false, actionTypeId: '.slack', + isSystemAction: false, name: 'Slack#xyz', referencedByCount: 0, }, @@ -331,6 +356,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { isPreconfigured: true, isDeprecated: false, actionTypeId: 'system-abc-action-type', + isSystemAction: false, name: 'SystemABC', referencedByCount: 0, }, @@ -339,6 +365,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { isPreconfigured: true, isDeprecated: false, actionTypeId: 'test.index-record', + isSystemAction: false, name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, }, @@ -347,6 +374,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { isPreconfigured: true, isDeprecated: false, actionTypeId: '.email', + isSystemAction: false, name: 'TestEmail#xyz', referencedByCount: 0, }, From 85ca6a4730de13c9b46f5b12ee468c5ea71dc5ec Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 20:54:40 +0300 Subject: [PATCH 09/28] Fix integration tests --- .../actions/connector_types/cases_webhook.ts | 4 +-- .../actions/connector_types/d3security.ts | 1 + .../tests/actions/connector_types/email.ts | 8 ++++++ .../tests/actions/connector_types/es_index.ts | 4 +++ .../tests/actions/connector_types/gen_ai.ts | 1 + .../tests/actions/connector_types/jira.ts | 2 ++ .../tests/actions/connector_types/opsgenie.ts | 1 + .../actions/connector_types/pagerduty.ts | 2 ++ .../actions/connector_types/resilient.ts | 2 ++ .../actions/connector_types/server_log.ts | 2 ++ .../connector_types/servicenow_itom.ts | 4 +++ .../connector_types/servicenow_itsm.ts | 4 +++ .../actions/connector_types/servicenow_sir.ts | 4 +++ .../actions/connector_types/slack_api.ts | 2 ++ .../actions/connector_types/slack_webhook.ts | 2 ++ .../tests/actions/connector_types/swimlane.ts | 2 ++ .../tests/actions/connector_types/tines.ts | 1 + .../tests/actions/connector_types/torq.ts | 1 + .../tests/actions/connector_types/webhook.ts | 4 +++ .../tests/actions/connector_types/xmatters.ts | 2 ++ .../group2/tests/actions/create.ts | 2 ++ .../group2/tests/actions/get.ts | 2 ++ .../group2/tests/actions/get_all.ts | 26 +++++++++++++++++++ .../actions/sub_action_framework/index.ts | 1 + .../group2/tests/actions/update.ts | 1 + .../actions/connector_types/stack/es_index.ts | 4 +++ .../spaces_only/tests/actions/get.ts | 6 +++++ .../spaces_only/tests/actions/get_all.ts | 1 + .../tests/actions/type_not_enabled.ts | 2 ++ .../spaces_only/tests/actions/update.ts | 2 ++ 30 files changed, 98 insertions(+), 2 deletions(-) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts index de213332753278..23410b83d10abb 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/cases_webhook.ts @@ -108,11 +108,11 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A casesWebhook action', connector_type_id: '.cases-webhook', is_missing_secrets: false, - is_system_action: false, config: simulatorConfig, }); @@ -123,11 +123,11 @@ export default function casesWebhookTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A casesWebhook action', connector_type_id: '.cases-webhook', is_missing_secrets: false, - is_system_action: false, config: simulatorConfig, }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts index 19bbdfc4daacb2..55d53c00f59dfc 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/d3security.ts @@ -72,6 +72,7 @@ export default function d3SecurityTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name, connector_type_id: connectorTypeId, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts index a6c889ff6e5561..cfffe90126fac1 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/email.ts @@ -45,6 +45,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdActionId, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An email action', connector_type_id: '.email', @@ -71,6 +72,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An email action', connector_type_id: '.email', @@ -377,6 +379,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An email action', connector_type_id: '.email', @@ -403,6 +406,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An email action', connector_type_id: '.email', @@ -443,6 +447,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An email action', connector_type_id: '.email', @@ -469,6 +474,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An email action', connector_type_id: '.email', @@ -514,6 +520,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdMSExchangeActionId, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An email action', connector_type_id: '.email', @@ -542,6 +549,7 @@ export default function emailTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An email action', connector_type_id: '.email', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/es_index.ts index fed3acba1147ef..46287db208b87c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/es_index.ts @@ -41,6 +41,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An index action', connector_type_id: '.index', @@ -61,6 +62,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'An index action', @@ -86,6 +88,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(createdActionWithIndex).to.eql({ id: createdActionWithIndex.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An index action with index config', connector_type_id: '.index', @@ -106,6 +109,7 @@ export default function indexTest({ getService }: FtrProviderContext) { expect(fetchedActionWithIndex).to.eql({ id: fetchedActionWithIndex.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An index action with index config', connector_type_id: '.index', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/gen_ai.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/gen_ai.ts index 828e19470f4fe5..45068d82b7c285 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/gen_ai.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/gen_ai.ts @@ -82,6 +82,7 @@ export default function genAiTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name, connector_type_id: connectorTypeId, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts index 87f69ffabbbb6d..11588f48a48de1 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/jira.ts @@ -75,6 +75,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A jira action', connector_type_id: '.jira', @@ -92,6 +93,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A jira action', connector_type_id: '.jira', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts index 1b9f001a2232c6..fb73f6a95089ea 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/opsgenie.ts @@ -55,6 +55,7 @@ export default function opsgenieTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An opsgenie action', connector_type_id: '.opsgenie', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/pagerduty.ts index 65336907622605..81a3c2ef966b93 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/pagerduty.ts @@ -61,6 +61,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A pagerduty action', connector_type_id: '.pagerduty', @@ -79,6 +80,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A pagerduty action', connector_type_id: '.pagerduty', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts index 3543c6a35c91db..8425de3b900ec0 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/resilient.ts @@ -78,6 +78,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An IBM Resilient action', connector_type_id: '.resilient', @@ -95,6 +96,7 @@ export default function resilientTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An IBM Resilient action', connector_type_id: '.resilient', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/server_log.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/server_log.ts index b8b12d6aac764c..a5f14e512ddb11 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/server_log.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/server_log.ts @@ -30,6 +30,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'A server.log action', @@ -46,6 +47,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A server.log action', connector_type_id: '.server-log', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts index 35cc75fbd08b5a..e9e70d879618bb 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itom.ts @@ -111,6 +111,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-itom', @@ -131,6 +132,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-itom', @@ -163,6 +165,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { expect(createdConnector).to.eql({ id: createdConnector.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-itom', @@ -183,6 +186,7 @@ export default function serviceNowITOMTest({ getService }: FtrProviderContext) { expect(fetchedConnector).to.eql({ id: fetchedConnector.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-itom', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts index 3833c39dd4618b..96f0694ef794b9 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_itsm.ts @@ -120,6 +120,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow', @@ -141,6 +142,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow', @@ -174,6 +176,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { expect(createdConnector).to.eql({ id: createdConnector.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow', @@ -195,6 +198,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { expect(fetchedConnector).to.eql({ id: fetchedConnector.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts index 7afb13b444eb72..2094ddd71cd7df 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/servicenow_sir.ts @@ -132,6 +132,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-sir', @@ -153,6 +154,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-sir', @@ -186,6 +188,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { expect(createdConnector).to.eql({ id: createdConnector.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-sir', @@ -207,6 +210,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { expect(fetchedConnector).to.eql({ id: fetchedConnector.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A servicenow action', connector_type_id: '.servicenow-sir', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_api.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_api.ts index 12c17d2a7a4f90..1a974eda92e715 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_api.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_api.ts @@ -29,6 +29,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'A slack api action', @@ -45,6 +46,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'A slack api action', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_webhook.ts index d9c32ccd643b04..4941bec1844ca2 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/slack_webhook.ts @@ -58,6 +58,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'A slack action', @@ -74,6 +75,7 @@ export default function slackTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'A slack action', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts index f0684db81f9cf2..5d6bb9e9b8145b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/swimlane.ts @@ -151,6 +151,7 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { id: createdAction.id, is_missing_secrets: false, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A swimlane action', }); @@ -164,6 +165,7 @@ export default function swimlaneTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'A swimlane action', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts index 4a745716ed08f6..99ba90f78dbebd 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/tines.ts @@ -83,6 +83,7 @@ export default function tinesTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name, connector_type_id: connectorTypeId, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/torq.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/torq.ts index 2dfbc3e8de6431..257378b406da5e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/torq.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/torq.ts @@ -88,6 +88,7 @@ export default function torqTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A Torq action', connector_type_id: '.torq', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/webhook.ts index c021733224a1cf..c7a8f1c1b2524e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/webhook.ts @@ -117,6 +117,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A generic Webhook action', connector_type_id: '.webhook', @@ -136,6 +137,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A generic Webhook action', connector_type_id: '.webhook', @@ -170,6 +172,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A generic Webhook action', connector_type_id: '.webhook', @@ -208,6 +211,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { expect(fetchedAction).to.eql({ id: fetchedAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'A generic Webhook action', connector_type_id: '.webhook', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/xmatters.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/xmatters.ts index 38bc73a3ad4521..4efacbf78f951c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/xmatters.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/xmatters.ts @@ -61,6 +61,7 @@ export default function xmattersTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An xmatters action', connector_type_id: '.xmatters', @@ -95,6 +96,7 @@ export default function xmattersTest({ getService }: FtrProviderContext) { expect(createdAction).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'An xmatters action', connector_type_id: '.xmatters', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts index dce40323e9e1c4..4c9db37fe35435 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts @@ -60,6 +60,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: response.body.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'My action', @@ -296,6 +297,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: predefinedId, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'My action', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts index f58481bb944125..3b04af22d2e96c 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts @@ -63,6 +63,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, connector_type_id: 'test.index-record', is_deprecated: false, is_missing_secrets: false, @@ -151,6 +152,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { connector_type_id: '.slack', name: 'Slack#xyz', is_preconfigured: true, + is_system_action: false, is_deprecated: false, }); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts index 1cf5b7bb303472..37475d7f191cad 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts @@ -70,6 +70,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'My action', connector_type_id: 'test.index-record', @@ -83,6 +84,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { connector_type_id: '.email', id: 'notification-email', is_deprecated: false, + is_system_action: false, is_preconfigured: true, name: 'Notification Email Connector', referenced_by_count: 0, @@ -90,6 +92,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured-es-index-action', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', @@ -99,6 +102,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', id: 'my-deprecated-servicenow', is_preconfigured: true, + is_system_action: false, is_deprecated: true, name: 'ServiceNow#xyz', referenced_by_count: 0, @@ -107,6 +111,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', id: 'my-deprecated-servicenow-default', is_preconfigured: true, + is_system_action: false, is_deprecated: true, name: 'ServiceNow#xyz', referenced_by_count: 0, @@ -114,6 +119,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'my-slack1', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', @@ -122,6 +128,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', @@ -130,6 +137,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', @@ -138,6 +146,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'my-test-email', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.email', name: 'TestEmail#xyz', @@ -221,6 +230,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, name: 'My action', connector_type_id: 'test.index-record', @@ -235,12 +245,14 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'notification-email', is_deprecated: false, is_preconfigured: true, + is_system_action: false, name: 'Notification Email Connector', referenced_by_count: 0, }, { id: 'preconfigured-es-index-action', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', @@ -251,6 +263,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow', is_deprecated: true, is_preconfigured: true, + is_system_action: false, name: 'ServiceNow#xyz', referenced_by_count: 0, }, @@ -258,6 +271,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', id: 'my-deprecated-servicenow-default', is_preconfigured: true, + is_system_action: false, is_deprecated: true, name: 'ServiceNow#xyz', referenced_by_count: 0, @@ -265,6 +279,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'my-slack1', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', @@ -273,6 +288,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', @@ -281,6 +297,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', @@ -289,6 +306,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'my-test-email', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.email', name: 'TestEmail#xyz', @@ -350,12 +368,14 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'notification-email', is_deprecated: false, is_preconfigured: true, + is_system_action: false, name: 'Notification Email Connector', referenced_by_count: 0, }, { id: 'preconfigured-es-index-action', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.index', name: 'preconfigured_es_index_action', @@ -365,6 +385,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', id: 'my-deprecated-servicenow', is_preconfigured: true, + is_system_action: false, is_deprecated: true, name: 'ServiceNow#xyz', referenced_by_count: 0, @@ -373,6 +394,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', id: 'my-deprecated-servicenow-default', is_preconfigured: true, + is_system_action: false, is_deprecated: true, name: 'ServiceNow#xyz', referenced_by_count: 0, @@ -380,6 +402,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'my-slack1', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.slack', name: 'Slack#xyz', @@ -388,6 +411,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'custom-system-abc-connector', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: 'system-abc-action-type', name: 'SystemABC', @@ -396,6 +420,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'preconfigured.test.index-record', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', @@ -404,6 +429,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { { id: 'my-test-email', is_preconfigured: true, + is_system_action: false, is_deprecated: false, connector_type_id: '.email', name: 'TestEmail#xyz', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts index 8b79bd2227f8d3..8bc8bc6a897578 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/sub_action_framework/index.ts @@ -91,6 +91,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(res.body).to.eql({ id: res.body.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, is_missing_secrets: false, name: 'My sub connector', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts index 0e4214a9138f6c..07d2e6064bc0bc 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts @@ -73,6 +73,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, connector_type_id: 'test.index-record', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/es_index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/es_index.ts index aa3b2b6780dc84..e25775755eb007 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/es_index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/es_index.ts @@ -57,6 +57,7 @@ export default function indexTest({ getService }: FtrProviderContext) { id: createdConnector.id, is_preconfigured: false, is_deprecated: false, + is_system_action: false, name: 'An index connector', connector_type_id: '.index', is_missing_secrets: false, @@ -78,6 +79,7 @@ export default function indexTest({ getService }: FtrProviderContext) { is_preconfigured: false, is_deprecated: false, is_missing_secrets: false, + is_system_action: false, name: 'An index connector', connector_type_id: '.index', config: { index: ES_TEST_INDEX_NAME, refresh: false, executionTimeField: null }, @@ -102,6 +104,7 @@ export default function indexTest({ getService }: FtrProviderContext) { id: createdConnectorWithIndex.id, is_preconfigured: false, is_deprecated: false, + is_system_action: false, name: 'An index connector with index config', connector_type_id: '.index', is_missing_secrets: false, @@ -122,6 +125,7 @@ export default function indexTest({ getService }: FtrProviderContext) { id: fetchedConnectorWithIndex.id, is_preconfigured: false, is_deprecated: false, + is_system_action: false, name: 'An index connector with index config', connector_type_id: '.index', is_missing_secrets: false, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index 6d923452faac5f..68d4512145118a 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -42,6 +42,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { is_preconfigured: false, is_deprecated: false, is_missing_secrets: false, + is_system_action: false, connector_type_id: 'test.index-record', name: 'My action', config: { @@ -83,6 +84,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { id: 'my-slack1', is_preconfigured: true, is_deprecated: false, + is_system_action: false, connector_type_id: '.slack', name: 'Slack#xyz', }); @@ -95,6 +97,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow', is_preconfigured: true, is_deprecated: true, + is_system_action: false, connector_type_id: '.servicenow', name: 'ServiceNow#xyz', }); @@ -107,6 +110,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { id: 'my-deprecated-servicenow-default', is_preconfigured: true, is_deprecated: true, + is_system_action: false, connector_type_id: '.servicenow', name: 'ServiceNow#xyz', }); @@ -136,6 +140,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { id: createdAction.id, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, actionTypeId: 'test.index-record', isMissingSecrets: false, name: 'My action', @@ -178,6 +183,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { id: 'my-slack1', isPreconfigured: true, isDeprecated: false, + isSystemAction: false, actionTypeId: '.slack', name: 'Slack#xyz', }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts index c34c314ade4c34..d4a43da31894e3 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -136,6 +136,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { id: 'my-test-email', is_preconfigured: true, is_deprecated: false, + is_system_action: false, connector_type_id: '.email', name: 'TestEmail#xyz', referenced_by_count: 0, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts index 0ab9baad0b5541..d0f7c8752d47c5 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts @@ -63,6 +63,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) id: 'uuid-actionId', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, isMissingSecrets: false, name: 'an action created before test.not-enabled was disabled', }); @@ -93,6 +94,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) isPreconfigured: false, isDeprecated: false, isMissingSecrets: false, + isSystemAction: false, name: 'an action created before test.not-enabled was disabled', }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index 5f6dffcc3c3e6c..d6f41e3037ad20 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -51,6 +51,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(200, { id: createdAction.id, is_preconfigured: false, + is_system_action: false, is_deprecated: false, connector_type_id: 'test.index-record', is_missing_secrets: false, @@ -215,6 +216,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { id: createdAction.id, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, actionTypeId: 'test.index-record', isMissingSecrets: false, name: 'My action updated', From b070bd9bb3182b87466fd335cbdd0bcaf6d59f56 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 28 Jun 2023 23:52:17 +0300 Subject: [PATCH 10/28] Fix cases tests --- .../plugins/actions/server/action_type_registry.test.ts | 2 +- .../tests/trial/configure/get_connectors.ts | 7 +++++++ .../spaces_only/tests/trial/configure/get_connectors.ts | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index 613438579e13ef..595461b137b593 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -226,7 +226,7 @@ describe('actionTypeRegistry', () => { name: 'My action type', minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], - isSystemAction: false, + isSystemAction: true, validate: { config: { schema: schema.object({}) }, secrets: { schema: schema.object({}) }, diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts index bd24b8852b716b..e75fed4f399b7c 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts @@ -82,6 +82,7 @@ export default ({ getService }: FtrProviderContext): void => { updateIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -95,6 +96,7 @@ export default ({ getService }: FtrProviderContext): void => { projectKey: 'pkey', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -107,6 +109,7 @@ export default ({ getService }: FtrProviderContext): void => { actionTypeId: '.servicenow', id: 'preconfigured-servicenow', isPreconfigured: true, + isSystemAction: false, isDeprecated: false, name: 'preconfigured-servicenow', referencedByCount: 0, @@ -120,6 +123,7 @@ export default ({ getService }: FtrProviderContext): void => { orgId: 'pkey', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -137,6 +141,7 @@ export default ({ getService }: FtrProviderContext): void => { userIdentifierValue: null, }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -154,6 +159,7 @@ export default ({ getService }: FtrProviderContext): void => { jwtKeyId: 'def', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -171,6 +177,7 @@ export default ({ getService }: FtrProviderContext): void => { userIdentifierValue: null, }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, diff --git a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts index c7b6f03d3526ec..5ddc3df6601423 100644 --- a/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/cases_api_integration/spaces_only/tests/trial/configure/get_connectors.ts @@ -116,6 +116,7 @@ export default ({ getService }: FtrProviderContext): void => { updateIncidentUrl: 'http://some.non.existent.com/{{{external.system.id}}}', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -129,6 +130,7 @@ export default ({ getService }: FtrProviderContext): void => { projectKey: 'pkey', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -141,6 +143,7 @@ export default ({ getService }: FtrProviderContext): void => { actionTypeId: '.servicenow', id: 'preconfigured-servicenow', isPreconfigured: true, + isSystemAction: false, isDeprecated: false, name: 'preconfigured-servicenow', referencedByCount: 0, @@ -154,6 +157,7 @@ export default ({ getService }: FtrProviderContext): void => { orgId: 'pkey', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -171,6 +175,7 @@ export default ({ getService }: FtrProviderContext): void => { userIdentifierValue: null, }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -188,6 +193,7 @@ export default ({ getService }: FtrProviderContext): void => { jwtKeyId: 'def', }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -205,6 +211,7 @@ export default ({ getService }: FtrProviderContext): void => { userIdentifierValue: null, }, isPreconfigured: false, + isSystemAction: false, isDeprecated: false, isMissingSecrets: false, referencedByCount: 0, @@ -270,6 +277,7 @@ export default ({ getService }: FtrProviderContext): void => { actionTypeId: '.servicenow', id: 'preconfigured-servicenow', isPreconfigured: true, + isSystemAction: false, isDeprecated: false, name: 'preconfigured-servicenow', referencedByCount: 0, From b50a3e0e7fd0a133927eef18e15b7a3070cdbf80 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Thu, 29 Jun 2023 11:44:22 +0300 Subject: [PATCH 11/28] Fix types from other plugins --- .../logic/export/get_export_all.test.ts | 2 ++ .../logic/export/get_export_by_object_ids.test.ts | 2 ++ .../import_rule_action_connectors.test.ts | 2 ++ .../rule_management/utils/utils.test.ts | 11 +++++++++++ .../connector_types/es_index/es_index_params.test.tsx | 2 ++ .../public/connector_types/gen_ai/params.test.tsx | 1 + .../public/connector_types/jira/jira_params.test.tsx | 1 + .../connector_types/lib/servicenow/helpers.test.ts | 1 + .../lib/servicenow/servicenow_connectors.tsx | 1 + .../lib/servicenow/use_choices.test.tsx | 1 + .../lib/servicenow/use_get_choices.test.tsx | 1 + .../public/connector_types/opsgenie/params.test.tsx | 1 + .../resilient/resilient_params.test.tsx | 1 + .../servicenow_itom/servicenow_itom_params.test.tsx | 1 + .../servicenow_itsm/servicenow_itsm_params.test.tsx | 1 + .../servicenow_sir/servicenow_sir_params.test.tsx | 1 + .../connector_types/swimlane/swimlane_params.test.tsx | 1 + .../public/apps/synthetics/state/settings/api.ts | 2 ++ .../lib/action_connector_api/connectors.ts | 3 ++- .../application/lib/action_connector_api/create.ts | 2 +- .../application/lib/action_connector_api/update.ts | 2 +- .../action_connector_form/action_type_form.test.tsx | 6 +++--- .../connectors_selection.test.tsx | 2 +- .../edit_connector_flyout/index.tsx | 2 +- x-pack/plugins/triggers_actions_ui/public/types.ts | 8 ++++++++ .../uptime/public/legacy_uptime/state/api/alerts.ts | 2 ++ 26 files changed, 52 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.test.ts index c86387f26f50a6..55f797e73ebc31 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.test.ts @@ -39,6 +39,7 @@ const connectors = [ config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, { @@ -47,6 +48,7 @@ const connectors = [ name: 'Email (preconfigured)', config: {}, isPreconfigured: true, + isSystemAction: false, isDeprecated: false, referencedByCount: 1, }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.test.ts index 35151f1b4b1d63..79aa4bfd3d88e7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.test.ts @@ -38,6 +38,7 @@ const connectors = [ config: {}, isPreconfigured: false, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, { @@ -47,6 +48,7 @@ const connectors = [ config: {}, isPreconfigured: true, isDeprecated: false, + isSystemAction: false, referencedByCount: 1, }, ]; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/action_connectors/import_rule_action_connectors.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/action_connectors/import_rule_action_connectors.test.ts index 54574c85f70365..19b4597f408df7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/action_connectors/import_rule_action_connectors.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/action_connectors/import_rule_action_connectors.test.ts @@ -317,6 +317,7 @@ describe('importRuleActionConnectors', () => { id: 'cabc78e0-9031-11ed-b076-53cc4d57aaf1', referencedByCount: 1, isDeprecated: false, + isSystemAction: false, }, ]); const actionsImporter2 = core.savedObjects.getImporter; @@ -358,6 +359,7 @@ describe('importRuleActionConnectors', () => { id: 'cabc78e0-9031-11ed-b076-53cc4d57aaf1', referencedByCount: 1, isDeprecated: false, + isSystemAction: false, }, ]); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.test.ts index 8e82965f2b5f91..89699de1316ade 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.test.ts @@ -874,6 +874,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -918,6 +919,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '789', @@ -926,6 +928,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -976,6 +979,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '789', @@ -984,6 +988,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -1041,6 +1046,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '789', @@ -1049,6 +1055,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -1108,6 +1115,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '789', @@ -1116,6 +1124,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); @@ -1216,6 +1225,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, { id: '789', @@ -1224,6 +1234,7 @@ describe('utils', () => { name: 'name', isPreconfigured: false, isDeprecated: false, + isSystemAction: false, }, ]); const [errors, output] = await getInvalidConnectors(rules, clients.actionsClient); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/es_index/es_index_params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/es_index/es_index_params.test.tsx index 44a6133cbefda0..6118efcfdb12c4 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/es_index/es_index_params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/es_index/es_index_params.test.tsx @@ -33,6 +33,7 @@ const actionConnector = { }, id: 'es index connector', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, name: 'test name', secrets: {}, @@ -45,6 +46,7 @@ const preconfiguredActionConnector = { }, id: AlertHistoryEsIndexConnectorId, isPreconfigured: true, + isSystemAction: false as const, isDeprecated: false, name: 'Alert history Elasticsearch index', secrets: {}, diff --git a/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/params.test.tsx index f37ab8b39d573b..ef418bd16965d4 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/params.test.tsx @@ -65,6 +65,7 @@ describe('Gen AI Params Fields renders', () => { id: 'test', actionTypeId: '.gen-ai', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, name: 'My GenAI Connector', config: { diff --git a/x-pack/plugins/stack_connectors/public/connector_types/jira/jira_params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/jira/jira_params.test.tsx index 3865da8ead3a7a..6deb820876b969 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/jira/jira_params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/jira/jira_params.test.tsx @@ -50,6 +50,7 @@ const connector: ActionConnector = { name: 'Test', isPreconfigured: false, isDeprecated: false, + isSystemAction: false as const, }; const editAction = jest.fn(); const defaultProps = { diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/helpers.test.ts b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/helpers.test.ts index 7700014e580216..17996ccf7fe653 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/helpers.test.ts +++ b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/helpers.test.ts @@ -23,6 +23,7 @@ const deprecatedConnector: ActionConnector = { name: 'Test', isPreconfigured: false, isDeprecated: true, + isSystemAction: false as const, }; const validConnector = { diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/servicenow_connectors.tsx b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/servicenow_connectors.tsx index f667847f6dd293..c08e97902746ac 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/servicenow_connectors.tsx @@ -131,6 +131,7 @@ const ServiceNowConnectorFields: React.FC = ({ ...connectorToUpdate, isDeprecated, isPreconfigured: false, + isSystemAction: false, actionTypeId, }); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_choices.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_choices.test.tsx index d3584cc38a2028..721897ece7266f 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_choices.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_choices.test.tsx @@ -27,6 +27,7 @@ const actionConnector = { actionTypeId: '.servicenow', name: 'ServiceNow ITSM', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, config: { apiUrl: 'https://dev94428.service-now.com/', diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_get_choices.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_get_choices.test.tsx index b4d204c117b50a..38ea6d55b4e17a 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_get_choices.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/lib/servicenow/use_get_choices.test.tsx @@ -28,6 +28,7 @@ const actionConnector = { actionTypeId: '.servicenow', name: 'ServiceNow ITSM', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, config: { apiUrl: 'https://dev94428.service-now.com/', diff --git a/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/params.test.tsx index 7a65a8b5fd790e..562fd66d031dd6 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/opsgenie/params.test.tsx @@ -45,6 +45,7 @@ describe('OpsgenieParamFields', () => { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.test.tsx index c6417660720f72..178cb86389d185 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/resilient/resilient_params.test.tsx @@ -39,6 +39,7 @@ const connector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itom/servicenow_itom_params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itom/servicenow_itom_params.test.tsx index 5ac0c36b0c7fcb..cc67186790be74 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itom/servicenow_itom_params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itom/servicenow_itom_params.test.tsx @@ -41,6 +41,7 @@ const connector: ActionConnector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itsm/servicenow_itsm_params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itsm/servicenow_itsm_params.test.tsx index 344cd73208fb63..5925724b7b8a98 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itsm/servicenow_itsm_params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_itsm/servicenow_itsm_params.test.tsx @@ -46,6 +46,7 @@ const connector: ActionConnector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_sir/servicenow_sir_params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_sir/servicenow_sir_params.test.tsx index a368c1564725db..8a62b6f09a7581 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/servicenow_sir/servicenow_sir_params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/servicenow_sir/servicenow_sir_params.test.tsx @@ -48,6 +48,7 @@ const connector: ActionConnector = { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/swimlane/swimlane_params.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/swimlane/swimlane_params.test.tsx index 302e5c80af15c1..a8575912ddc38f 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/swimlane/swimlane_params.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/swimlane/swimlane_params.test.tsx @@ -36,6 +36,7 @@ describe('SwimlaneParamsFields renders', () => { actionTypeId: '.test', name: 'Test', isPreconfigured: false, + isSystemAction: false as const, isDeprecated: false, }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/settings/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/settings/api.ts index 02efa016475c23..b7ae7884b178af 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/settings/api.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/settings/api.ts @@ -61,6 +61,7 @@ export const fetchConnectors = async (): Promise => { is_preconfigured: isPreconfigured, is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, ...res }) => ({ ...res, @@ -69,6 +70,7 @@ export const fetchConnectors = async (): Promise => { isDeprecated, isPreconfigured, isMissingSecrets, + isSystemAction, }) ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts index 60f1e252956869..6938654b294ac3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connectors.ts @@ -41,5 +41,6 @@ export async function loadAllActions({ http }: { http: HttpSetup }): Promise[0]>( `${BASE_ACTION_API_PATH}/connectors` ); - return rewriteResponseRes(res); + + return rewriteResponseRes(res) as ActionConnector[]; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts index 1256497a5d4489..32efba66d56be6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/create.ts @@ -49,5 +49,5 @@ export async function createActionConnector({ `${BASE_ACTION_API_PATH}/connector`, { body: JSON.stringify(rewriteBodyRequest(connector)) } ); - return rewriteBodyRes(res); + return rewriteBodyRes(res) as ActionConnector; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts index 7b65b534431985..c35378ebad17e7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts @@ -51,5 +51,5 @@ export async function updateActionConnector({ } ); - return rewriteBodyRes(res); + return rewriteBodyRes(res) as ActionConnector; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx index 807e5454f094fe..46dafc3c4fc033 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx @@ -556,7 +556,7 @@ function getActionTypeForm({ id: 'test', isPreconfigured: false, isDeprecated: false, - isSystemAction: false, + isSystemAction: false as const, name: 'test name', secrets: {}, }; @@ -580,7 +580,7 @@ function getActionTypeForm({ id: 'test', isPreconfigured: false, isDeprecated: false, - isSystemAction: false, + isSystemAction: false as const, name: 'test name', secrets: {}, }, @@ -590,7 +590,7 @@ function getActionTypeForm({ actionTypeId: '.server-log', isPreconfigured: false, isDeprecated: false, - isSystemAction: false, + isSystemAction: false as const, config: {}, secrets: {}, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx index 230f81e1531624..64a19d253740cd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connectors_selection.test.tsx @@ -69,7 +69,7 @@ describe('connectors_selection', () => { id: 'testId', isPreconfigured: false, isDeprecated: false, - isSystemAction: false, + isSystemAction: false as const, name: 'test pagerduty', secrets: {}, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx index e00349cecd62b4..343e0b01c4782d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/edit_connector_flyout/index.tsx @@ -260,7 +260,7 @@ const EditConnectorFlyoutComponent: React.FC = ({ /> {selectedTab === EditConnectorTabs.Configuration ? ( - !connector.isPreconfigured ? ( + !connector.isPreconfigured && !connector.isSystemAction ? ( <> {isEdit && ( <> diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 3e4006e64ca7f0..607ceef218508b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -287,6 +287,7 @@ export type PreConfiguredActionConnector = Omit< 'config' | 'secrets' > & { isPreconfigured: true; + isSystemAction: false; }; export type UserConfiguredActionConnector = ActionConnectorProps< @@ -294,10 +295,17 @@ export type UserConfiguredActionConnector = ActionConnectorProp Secrets > & { isPreconfigured: false; + isSystemAction: false; +}; + +export type SystemAction = Omit, 'config' | 'secrets'> & { + isSystemAction: true; + isPreconfigured: false; }; export type ActionConnector, Secrets = Record> = | PreConfiguredActionConnector + | SystemAction | UserConfiguredActionConnector; export type ActionConnectorWithoutId< diff --git a/x-pack/plugins/uptime/public/legacy_uptime/state/api/alerts.ts b/x-pack/plugins/uptime/public/legacy_uptime/state/api/alerts.ts index 9355cea954f988..8c623e914516b5 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/state/api/alerts.ts +++ b/x-pack/plugins/uptime/public/legacy_uptime/state/api/alerts.ts @@ -38,6 +38,7 @@ export const fetchConnectors = async (): Promise => { is_preconfigured: isPreconfigured, is_deprecated: isDeprecated, is_missing_secrets: isMissingSecrets, + is_system_action: isSystemAction, ...res }) => ({ ...res, @@ -46,6 +47,7 @@ export const fetchConnectors = async (): Promise => { isDeprecated, isPreconfigured, isMissingSecrets, + isSystemAction, }) ); }; From 1caf8742bceed23afd7196ad4f368b6416e83881 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Thu, 29 Jun 2023 11:55:50 +0300 Subject: [PATCH 12/28] Rename preconfiguredConnectors to inMemoryConnectors --- .../server/action_type_registry.test.ts | 2 +- .../actions/server/action_type_registry.ts | 13 +++-- .../actions/server/actions_client.test.ts | 30 ++++++------ .../plugins/actions/server/actions_client.ts | 44 ++++++++--------- .../server/create_execute_function.test.ts | 36 +++++++------- .../actions/server/create_execute_function.ts | 30 ++++++------ .../create_unsecured_execute_function.test.ts | 12 ++--- .../create_unsecured_execute_function.ts | 23 ++++----- x-pack/plugins/actions/server/index.ts | 2 +- .../server/lib/action_executor.test.ts | 6 +-- .../actions/server/lib/action_executor.ts | 18 +++---- .../server/lib/is_connector_deprecated.ts | 6 +-- .../server/lib/task_runner_factory.test.ts | 2 +- x-pack/plugins/actions/server/mocks.ts | 2 +- x-pack/plugins/actions/server/plugin.test.ts | 6 +-- x-pack/plugins/actions/server/plugin.ts | 48 +++++++++---------- .../alert_history_es_index.ts | 4 +- .../action_task_params_migrations.test.ts | 26 +++++----- .../action_task_params_migrations.ts | 18 +++---- .../actions/server/saved_objects/index.ts | 6 +-- x-pack/plugins/actions/server/types.ts | 2 +- .../actions/server/usage/actions_telemetry.ts | 18 +++---- x-pack/plugins/actions/server/usage/task.ts | 16 +++---- 23 files changed, 183 insertions(+), 187 deletions(-) diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index 595461b137b593..a36732c2c7e919 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -36,7 +36,7 @@ describe('actionTypeRegistry', () => { ), actionsConfigUtils: mockedActionsConfig, licenseState: mockedLicenseState, - preconfiguredActions: [ + inMemoryConnectors: [ { actionTypeId: 'foo', config: {}, diff --git a/x-pack/plugins/actions/server/action_type_registry.ts b/x-pack/plugins/actions/server/action_type_registry.ts index 8404bafbd8994f..7e9adcc99ac342 100644 --- a/x-pack/plugins/actions/server/action_type_registry.ts +++ b/x-pack/plugins/actions/server/action_type_registry.ts @@ -14,7 +14,7 @@ import { ActionsConfigurationUtilities } from './actions_config'; import { getActionTypeFeatureUsageName, TaskRunnerFactory, ILicenseState } from './lib'; import { ActionType, - PreConfiguredAction, + InMemoryConnector, ActionTypeConfig, ActionTypeSecrets, ActionTypeParams, @@ -26,7 +26,7 @@ export interface ActionTypeRegistryOpts { taskRunnerFactory: TaskRunnerFactory; actionsConfigUtils: ActionsConfigurationUtilities; licenseState: ILicenseState; - preconfiguredActions: PreConfiguredAction[]; + inMemoryConnectors: InMemoryConnector[]; } export class ActionTypeRegistry { @@ -35,7 +35,7 @@ export class ActionTypeRegistry { private readonly taskRunnerFactory: TaskRunnerFactory; private readonly actionsConfigUtils: ActionsConfigurationUtilities; private readonly licenseState: ILicenseState; - private readonly preconfiguredActions: PreConfiguredAction[]; + private readonly inMemoryConnectors: InMemoryConnector[]; private readonly licensing: LicensingPluginSetup; constructor(constructorParams: ActionTypeRegistryOpts) { @@ -43,7 +43,7 @@ export class ActionTypeRegistry { this.taskRunnerFactory = constructorParams.taskRunnerFactory; this.actionsConfigUtils = constructorParams.actionsConfigUtils; this.licenseState = constructorParams.licenseState; - this.preconfiguredActions = constructorParams.preconfiguredActions; + this.inMemoryConnectors = constructorParams.inMemoryConnectors; this.licensing = constructorParams.licensing; } @@ -89,9 +89,8 @@ export class ActionTypeRegistry { return ( actionTypeEnabled || (!actionTypeEnabled && - this.preconfiguredActions.find( - (preconfiguredAction) => preconfiguredAction.id === actionId - ) !== undefined) + this.inMemoryConnectors.find((inMemoryConnector) => inMemoryConnector.id === actionId) !== + undefined) ); } diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 14a295cfec325b..8ae4aeebabc8e2 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -133,7 +133,7 @@ beforeEach(() => { ), actionsConfigUtils: actionsConfigMock.create(), licenseState: mockedLicenseState, - preconfiguredActions: [], + inMemoryConnectors: [], }; actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams); actionsClient = new ActionsClient({ @@ -142,7 +142,7 @@ beforeEach(() => { unsecuredSavedObjectsClient, scopedClusterClient, kibanaIndices, - preconfiguredActions: [], + inMemoryConnectors: [], actionExecutor, executionEnqueuer, ephemeralExecutionEnqueuer, @@ -594,7 +594,7 @@ describe('create()', () => { ), actionsConfigUtils: localConfigUtils, licenseState: licenseStateMock.create(), - preconfiguredActions: [], + inMemoryConnectors: [], }; actionTypeRegistry = new ActionTypeRegistry(localActionTypeRegistryParams); @@ -604,7 +604,7 @@ describe('create()', () => { unsecuredSavedObjectsClient, scopedClusterClient, kibanaIndices, - preconfiguredActions: [], + inMemoryConnectors: [], actionExecutor, executionEnqueuer, ephemeralExecutionEnqueuer, @@ -715,7 +715,7 @@ describe('create()', () => { unsecuredSavedObjectsClient, scopedClusterClient, kibanaIndices, - preconfiguredActions: [ + inMemoryConnectors: [ { id: preDefinedId, actionTypeId: 'my-action-type', @@ -793,7 +793,7 @@ describe('get()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: 'my-action-type', @@ -855,7 +855,7 @@ describe('get()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: 'my-action-type', @@ -980,7 +980,7 @@ describe('get()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: '.slack', @@ -1058,7 +1058,7 @@ describe('getAll()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: '.slack', @@ -1202,7 +1202,7 @@ describe('getAll()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: '.slack', @@ -1288,7 +1288,7 @@ describe('getBulk()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: '.slack', @@ -1426,7 +1426,7 @@ describe('getBulk()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: '.slack', @@ -1489,7 +1489,7 @@ describe('getOAuthAccessToken()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: '.slack', @@ -2714,7 +2714,7 @@ describe('isPreconfigured()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: 'my-action-type', @@ -2754,7 +2754,7 @@ describe('isPreconfigured()', () => { bulkExecutionEnqueuer, request, authorization: authorization as unknown as ActionsAuthorization, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'testPreconfigured', actionTypeId: 'my-action-type', diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 7905b7a0da6df5..5366d71e301065 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -45,7 +45,7 @@ import { ActionResult, FindActionResult, RawAction, - PreConfiguredAction, + InMemoryConnector, ActionTypeExecutorResult, ConnectorTokenClientContract, } from './types'; @@ -115,7 +115,7 @@ interface ConstructorOptions { scopedClusterClient: IScopedClusterClient; actionTypeRegistry: ActionTypeRegistry; unsecuredSavedObjectsClient: SavedObjectsClientContract; - preconfiguredActions: PreConfiguredAction[]; + inMemoryConnectors: InMemoryConnector[]; actionExecutor: ActionExecutorContract; executionEnqueuer: ExecutionEnqueuer; ephemeralExecutionEnqueuer: ExecutionEnqueuer; @@ -139,7 +139,7 @@ export class ActionsClient { private readonly scopedClusterClient: IScopedClusterClient; private readonly unsecuredSavedObjectsClient: SavedObjectsClientContract; private readonly actionTypeRegistry: ActionTypeRegistry; - private readonly preconfiguredActions: PreConfiguredAction[]; + private readonly inMemoryConnectors: InMemoryConnector[]; private readonly actionExecutor: ActionExecutorContract; private readonly request: KibanaRequest; private readonly authorization: ActionsAuthorization; @@ -157,7 +157,7 @@ export class ActionsClient { kibanaIndices, scopedClusterClient, unsecuredSavedObjectsClient, - preconfiguredActions, + inMemoryConnectors, actionExecutor, executionEnqueuer, ephemeralExecutionEnqueuer, @@ -174,7 +174,7 @@ export class ActionsClient { this.unsecuredSavedObjectsClient = unsecuredSavedObjectsClient; this.scopedClusterClient = scopedClusterClient; this.kibanaIndices = kibanaIndices; - this.preconfiguredActions = preconfiguredActions; + this.inMemoryConnectors = inMemoryConnectors; this.actionExecutor = actionExecutor; this.executionEnqueuer = executionEnqueuer; this.ephemeralExecutionEnqueuer = ephemeralExecutionEnqueuer; @@ -196,7 +196,7 @@ export class ActionsClient { }: CreateOptions): Promise { const id = options?.id || SavedObjectsUtils.generateId(); - if (this.preconfiguredActions.some((preconfiguredAction) => preconfiguredAction.id === id)) { + if (this.inMemoryConnectors.some((inMemoryConnector) => inMemoryConnector.id === id)) { throw Boom.badRequest( i18n.translate('xpack.actions.serverSideErrors.predefinedIdConnectorAlreadyExists', { defaultMessage: 'This {id} already exist in preconfigured action.', @@ -273,7 +273,7 @@ export class ActionsClient { await this.authorization.ensureAuthorized('update'); if ( - this.preconfiguredActions.find((preconfiguredAction) => preconfiguredAction.id === id) !== + this.inMemoryConnectors.find((inMemoryConnector) => inMemoryConnector.id === id) !== undefined ) { throw new PreconfiguredActionDisabledModificationError( @@ -380,10 +380,10 @@ export class ActionsClient { throw error; } - const preconfiguredActionsList = this.preconfiguredActions.find( - (preconfiguredAction) => preconfiguredAction.id === id + const inMemoryConnectorsList = this.inMemoryConnectors.find( + (inMemoryConnector) => inMemoryConnector.id === id ); - if (preconfiguredActionsList !== undefined) { + if (inMemoryConnectorsList !== undefined) { this.auditLogger?.log( connectorAuditEvent({ action: ConnectorAuditAction.GET, @@ -393,11 +393,11 @@ export class ActionsClient { return { id, - actionTypeId: preconfiguredActionsList.actionTypeId, - name: preconfiguredActionsList.name, + actionTypeId: inMemoryConnectorsList.actionTypeId, + name: inMemoryConnectorsList.name, isPreconfigured: true, isSystemAction: false, - isDeprecated: isConnectorDeprecated(preconfiguredActionsList), + isDeprecated: isConnectorDeprecated(inMemoryConnectorsList), }; } @@ -458,12 +458,12 @@ export class ActionsClient { const mergedResult = [ ...savedObjectsActions, - ...this.preconfiguredActions.map((preconfiguredAction) => ({ - id: preconfiguredAction.id, - actionTypeId: preconfiguredAction.actionTypeId, - name: preconfiguredAction.name, + ...this.inMemoryConnectors.map((inMemoryConnector) => ({ + id: inMemoryConnector.id, + actionTypeId: inMemoryConnector.actionTypeId, + name: inMemoryConnector.name, isPreconfigured: true, - isDeprecated: isConnectorDeprecated(preconfiguredAction), + isDeprecated: isConnectorDeprecated(inMemoryConnector), isSystemAction: false, })), ].sort((a, b) => a.name.localeCompare(b.name)); @@ -491,8 +491,8 @@ export class ActionsClient { const actionResults = new Array(); for (const actionId of ids) { - const action = this.preconfiguredActions.find( - (preconfiguredAction) => preconfiguredAction.id === actionId + const action = this.inMemoryConnectors.find( + (inMemoryConnector) => inMemoryConnector.id === actionId ); if (action !== undefined) { actionResults.push(action); @@ -633,7 +633,7 @@ export class ActionsClient { await this.authorization.ensureAuthorized('delete'); if ( - this.preconfiguredActions.find((preconfiguredAction) => preconfiguredAction.id === id) !== + this.inMemoryConnectors.find((inMemoryConnector) => inMemoryConnector.id === id) !== undefined ) { throw new PreconfiguredActionDisabledModificationError( @@ -765,7 +765,7 @@ export class ActionsClient { } public isPreconfigured(connectorId: string): boolean { - return !!this.preconfiguredActions.find((preconfigured) => preconfigured.id === connectorId); + return !!this.inMemoryConnectors.find((preconfigured) => preconfigured.id === connectorId); } public async getGlobalExecutionLogWithAuth({ diff --git a/x-pack/plugins/actions/server/create_execute_function.test.ts b/x-pack/plugins/actions/server/create_execute_function.test.ts index ec746ee62862bf..55aa1758a70b79 100644 --- a/x-pack/plugins/actions/server/create_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_execute_function.test.ts @@ -32,7 +32,7 @@ describe('execute()', () => { taskManager: mockTaskManager, actionTypeRegistry, isESOCanEncrypt: true, - preconfiguredActions: [], + inMemoryConnectors: [], }); savedObjectsClient.get.mockResolvedValueOnce({ id: '123', @@ -103,7 +103,7 @@ describe('execute()', () => { taskManager: mockTaskManager, actionTypeRegistry, isESOCanEncrypt: true, - preconfiguredActions: [], + inMemoryConnectors: [], }); savedObjectsClient.get.mockResolvedValueOnce({ id: '123', @@ -176,7 +176,7 @@ describe('execute()', () => { taskManager: mockTaskManager, actionTypeRegistry, isESOCanEncrypt: true, - preconfiguredActions: [], + inMemoryConnectors: [], }); savedObjectsClient.get.mockResolvedValueOnce({ id: '123', @@ -247,7 +247,7 @@ describe('execute()', () => { taskManager: mockTaskManager, actionTypeRegistry: actionTypeRegistryMock.create(), isESOCanEncrypt: true, - preconfiguredActions: [ + inMemoryConnectors: [ { id: '123', actionTypeId: 'mock-action-preconfigured', @@ -327,7 +327,7 @@ describe('execute()', () => { taskManager: mockTaskManager, actionTypeRegistry: actionTypeRegistryMock.create(), isESOCanEncrypt: true, - preconfiguredActions: [ + inMemoryConnectors: [ { id: '123', actionTypeId: 'mock-action-preconfigured', @@ -428,7 +428,7 @@ describe('execute()', () => { taskManager: mockTaskManager, isESOCanEncrypt: false, actionTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredActions: [], + inMemoryConnectors: [], }); await expect( executeFn(savedObjectsClient, { @@ -449,7 +449,7 @@ describe('execute()', () => { taskManager: mockTaskManager, isESOCanEncrypt: true, actionTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredActions: [], + inMemoryConnectors: [], }); savedObjectsClient.get.mockResolvedValueOnce({ id: '123', @@ -481,7 +481,7 @@ describe('execute()', () => { taskManager: mockTaskManager, isESOCanEncrypt: true, actionTypeRegistry: mockedActionTypeRegistry, - preconfiguredActions: [], + inMemoryConnectors: [], }); mockedActionTypeRegistry.ensureActionTypeEnabled.mockImplementation(() => { throw new Error('Fail'); @@ -513,7 +513,7 @@ describe('execute()', () => { taskManager: mockTaskManager, isESOCanEncrypt: true, actionTypeRegistry: mockedActionTypeRegistry, - preconfiguredActions: [ + inMemoryConnectors: [ { actionTypeId: 'mock-action', config: {}, @@ -562,7 +562,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, actionTypeRegistry, isESOCanEncrypt: true, - preconfiguredActions: [], + inMemoryConnectors: [], }); savedObjectsClient.bulkGet.mockResolvedValueOnce({ saved_objects: [ @@ -650,7 +650,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, actionTypeRegistry, isESOCanEncrypt: true, - preconfiguredActions: [], + inMemoryConnectors: [], }); savedObjectsClient.bulkGet.mockResolvedValueOnce({ saved_objects: [ @@ -741,7 +741,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, actionTypeRegistry, isESOCanEncrypt: true, - preconfiguredActions: [], + inMemoryConnectors: [], }); savedObjectsClient.bulkGet.mockResolvedValueOnce({ saved_objects: [ @@ -825,7 +825,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, actionTypeRegistry: actionTypeRegistryMock.create(), isESOCanEncrypt: true, - preconfiguredActions: [ + inMemoryConnectors: [ { id: '123', actionTypeId: 'mock-action-preconfigured', @@ -922,7 +922,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, actionTypeRegistry: actionTypeRegistryMock.create(), isESOCanEncrypt: true, - preconfiguredActions: [ + inMemoryConnectors: [ { id: '123', actionTypeId: 'mock-action-preconfigured', @@ -1040,7 +1040,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, isESOCanEncrypt: false, actionTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredActions: [], + inMemoryConnectors: [], }); await expect( executeFn(savedObjectsClient, [ @@ -1063,7 +1063,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, isESOCanEncrypt: true, actionTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredActions: [], + inMemoryConnectors: [], }); savedObjectsClient.bulkGet.mockResolvedValueOnce({ saved_objects: [ @@ -1101,7 +1101,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, isESOCanEncrypt: true, actionTypeRegistry: mockedActionTypeRegistry, - preconfiguredActions: [], + inMemoryConnectors: [], }); mockedActionTypeRegistry.ensureActionTypeEnabled.mockImplementation(() => { throw new Error('Fail'); @@ -1139,7 +1139,7 @@ describe('bulkExecute()', () => { taskManager: mockTaskManager, isESOCanEncrypt: true, actionTypeRegistry: mockedActionTypeRegistry, - preconfiguredActions: [ + inMemoryConnectors: [ { actionTypeId: 'mock-action', config: {}, diff --git a/x-pack/plugins/actions/server/create_execute_function.ts b/x-pack/plugins/actions/server/create_execute_function.ts index c33bcc6923d8a2..5f4f4a72a7e648 100644 --- a/x-pack/plugins/actions/server/create_execute_function.ts +++ b/x-pack/plugins/actions/server/create_execute_function.ts @@ -10,7 +10,7 @@ import { RunNowResult, TaskManagerStartContract } from '@kbn/task-manager-plugin import { RawAction, ActionTypeRegistryContract, - PreConfiguredAction, + InMemoryConnector, ActionTaskExecutorParams, } from './types'; import { ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE } from './constants/saved_objects'; @@ -21,7 +21,7 @@ interface CreateExecuteFunctionOptions { taskManager: TaskManagerStartContract; isESOCanEncrypt: boolean; actionTypeRegistry: ActionTypeRegistryContract; - preconfiguredActions: PreConfiguredAction[]; + inMemoryConnectors: InMemoryConnector[]; } export interface ExecuteOptions @@ -39,7 +39,7 @@ interface ActionTaskParams } export interface GetConnectorsResult { - connector: PreConfiguredAction | RawAction; + connector: InMemoryConnector | RawAction; isPreconfigured: boolean; id: string; } @@ -58,7 +58,7 @@ export function createExecutionEnqueuerFunction({ taskManager, actionTypeRegistry, isESOCanEncrypt, - preconfiguredActions, + inMemoryConnectors, }: CreateExecuteFunctionOptions): ExecutionEnqueuer { return async function execute( unsecuredSavedObjectsClient: SavedObjectsClientContract, @@ -81,7 +81,7 @@ export function createExecutionEnqueuerFunction({ const { action, isPreconfigured } = await getAction( unsecuredSavedObjectsClient, - preconfiguredActions, + inMemoryConnectors, id ); validateCanActionBeUsed(action); @@ -139,7 +139,7 @@ export function createBulkExecutionEnqueuerFunction({ taskManager, actionTypeRegistry, isESOCanEncrypt, - preconfiguredActions, + inMemoryConnectors, }: CreateExecuteFunctionOptions): BulkExecutionEnqueuer { return async function execute( unsecuredSavedObjectsClient: SavedObjectsClientContract, @@ -157,7 +157,7 @@ export function createBulkExecutionEnqueuerFunction({ const connectorIds = [...new Set(actionsToExecute.map((action) => action.id))]; const connectors = await getConnectors( unsecuredSavedObjectsClient, - preconfiguredActions, + inMemoryConnectors, connectorIds ); connectors.forEach((c) => { @@ -229,13 +229,13 @@ export function createBulkExecutionEnqueuerFunction({ export function createEphemeralExecutionEnqueuerFunction({ taskManager, actionTypeRegistry, - preconfiguredActions, + inMemoryConnectors, }: CreateExecuteFunctionOptions): ExecutionEnqueuer { return async function execute( unsecuredSavedObjectsClient: SavedObjectsClientContract, { id, params, spaceId, source, consumer, apiKey, executionId }: ExecuteOptions ): Promise { - const { action } = await getAction(unsecuredSavedObjectsClient, preconfiguredActions, id); + const { action } = await getAction(unsecuredSavedObjectsClient, inMemoryConnectors, id); validateCanActionBeUsed(action); const { actionTypeId } = action; @@ -266,7 +266,7 @@ export function createEphemeralExecutionEnqueuerFunction({ }; } -function validateCanActionBeUsed(action: PreConfiguredAction | RawAction) { +function validateCanActionBeUsed(action: InMemoryConnector | RawAction) { const { name, isMissingSecrets } = action; if (isMissingSecrets) { throw new Error( @@ -290,10 +290,10 @@ function executionSourceAsSavedObjectReferences(executionSource: ActionExecutorO async function getAction( unsecuredSavedObjectsClient: SavedObjectsClientContract, - preconfiguredActions: PreConfiguredAction[], + inMemoryConnectors: InMemoryConnector[], actionId: string -): Promise<{ action: PreConfiguredAction | RawAction; isPreconfigured: boolean }> { - const pcAction = preconfiguredActions.find((action) => action.id === actionId); +): Promise<{ action: InMemoryConnector | RawAction; isPreconfigured: boolean }> { + const pcAction = inMemoryConnectors.find((action) => action.id === actionId); if (pcAction) { return { action: pcAction, isPreconfigured: true }; } @@ -304,14 +304,14 @@ async function getAction( async function getConnectors( unsecuredSavedObjectsClient: SavedObjectsClientContract, - preconfiguredConnectors: PreConfiguredAction[], + inMemoryConnectors: InMemoryConnector[], connectorIds: string[] ): Promise { const result: GetConnectorsResult[] = []; const connectorIdsToFetch = []; for (const connectorId of connectorIds) { - const pcConnector = preconfiguredConnectors.find((connector) => connector.id === connectorId); + const pcConnector = inMemoryConnectors.find((connector) => connector.id === connectorId); if (pcConnector) { result.push({ connector: pcConnector, isPreconfigured: true, id: connectorId }); } else { diff --git a/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts b/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts index 8e75a889c3410d..9eeb10e541f005 100644 --- a/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts @@ -25,7 +25,7 @@ describe('bulkExecute()', () => { const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ taskManager: mockTaskManager, connectorTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredConnectors: [ + inMemoryConnectors: [ { id: '123', actionTypeId: '.email', @@ -131,7 +131,7 @@ describe('bulkExecute()', () => { const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ taskManager: mockTaskManager, connectorTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredConnectors: [ + inMemoryConnectors: [ { id: '123', actionTypeId: '.email', @@ -249,7 +249,7 @@ describe('bulkExecute()', () => { const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ taskManager: mockTaskManager, connectorTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredConnectors: [ + inMemoryConnectors: [ { id: '123', actionTypeId: '.email', @@ -391,7 +391,7 @@ describe('bulkExecute()', () => { const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ taskManager: mockTaskManager, connectorTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredConnectors: [ + inMemoryConnectors: [ { id: '123', actionTypeId: '.email', @@ -427,7 +427,7 @@ describe('bulkExecute()', () => { const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ taskManager: mockTaskManager, connectorTypeRegistry: mockedConnectorTypeRegistry, - preconfiguredConnectors: [ + inMemoryConnectors: [ { id: '123', actionTypeId: '.email', @@ -464,7 +464,7 @@ describe('bulkExecute()', () => { const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ taskManager: mockTaskManager, connectorTypeRegistry: actionTypeRegistryMock.create(), - preconfiguredConnectors: [ + inMemoryConnectors: [ { id: '123', actionTypeId: '.email', diff --git a/x-pack/plugins/actions/server/create_unsecured_execute_function.ts b/x-pack/plugins/actions/server/create_unsecured_execute_function.ts index b1ad90d9093eb0..1db64a3e16121a 100644 --- a/x-pack/plugins/actions/server/create_unsecured_execute_function.ts +++ b/x-pack/plugins/actions/server/create_unsecured_execute_function.ts @@ -9,7 +9,7 @@ import { ISavedObjectsRepository, SavedObjectsBulkResponse } from '@kbn/core/ser import { TaskManagerStartContract } from '@kbn/task-manager-plugin/server'; import { ActionTypeRegistryContract as ConnectorTypeRegistryContract, - PreConfiguredAction as PreconfiguredConnector, + InMemoryConnector, } from './types'; import { ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE } from './constants/saved_objects'; import { ExecuteOptions as ActionExecutorOptions } from './lib/action_executor'; @@ -21,7 +21,7 @@ const ALLOWED_CONNECTOR_TYPE_IDS = ['.email']; interface CreateBulkUnsecuredExecuteFunctionOptions { taskManager: TaskManagerStartContract; connectorTypeRegistry: ConnectorTypeRegistryContract; - preconfiguredConnectors: PreconfiguredConnector[]; + inMemoryConnectors: InMemoryConnector[]; } export interface ExecuteOptions @@ -42,7 +42,7 @@ export type BulkUnsecuredExecutionEnqueuer = ( export function createBulkUnsecuredExecutionEnqueuerFunction({ taskManager, connectorTypeRegistry, - preconfiguredConnectors, + inMemoryConnectors, }: CreateBulkUnsecuredExecuteFunctionOptions): BulkUnsecuredExecutionEnqueuer { return async function execute( internalSavedObjectsRepository: ISavedObjectsRepository, @@ -51,24 +51,21 @@ export function createBulkUnsecuredExecutionEnqueuerFunction({ const connectorTypeIds: Record = {}; const connectorIds = [...new Set(actionsToExecute.map((action) => action.id))]; - const notPreconfiguredConnectors = connectorIds.filter( - (connectorId) => - preconfiguredConnectors.find((connector) => connector.id === connectorId) == null + const notInMemoryConnectors = connectorIds.filter( + (connectorId) => inMemoryConnectors.find((connector) => connector.id === connectorId) == null ); - if (notPreconfiguredConnectors.length > 0) { + if (notInMemoryConnectors.length > 0) { throw new Error( - `${notPreconfiguredConnectors.join( + `${notInMemoryConnectors.join( ',' )} are not preconfigured connectors and can't be scheduled for unsecured actions execution` ); } - const connectors: PreconfiguredConnector[] = connectorIds - .map((connectorId) => - preconfiguredConnectors.find((pConnector) => pConnector.id === connectorId) - ) - .filter(Boolean) as PreconfiguredConnector[]; + const connectors: InMemoryConnector[] = connectorIds + .map((connectorId) => inMemoryConnectors.find((pConnector) => pConnector.id === connectorId)) + .filter(Boolean) as InMemoryConnector[]; connectors.forEach((connector) => { const { id, actionTypeId } = connector; diff --git a/x-pack/plugins/actions/server/index.ts b/x-pack/plugins/actions/server/index.ts index 15f3c2fa7e20a3..3deddfc9c16c6a 100644 --- a/x-pack/plugins/actions/server/index.ts +++ b/x-pack/plugins/actions/server/index.ts @@ -22,7 +22,7 @@ export type { ActionResult, ActionTypeExecutorOptions, ActionType, - PreConfiguredAction, + InMemoryConnector, ActionsApiRequestHandlerContext, FindActionResult, } from './types'; diff --git a/x-pack/plugins/actions/server/lib/action_executor.test.ts b/x-pack/plugins/actions/server/lib/action_executor.test.ts index 9b2e2f96390c79..31f1ab76cb0e95 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.test.ts @@ -51,7 +51,7 @@ actionExecutor.initialize({ actionTypeRegistry, encryptedSavedObjectsClient, eventLogger, - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'preconfigured', name: 'Preconfigured', @@ -958,7 +958,7 @@ test('throws an error when passing isESOCanEncrypt with value of false', async ( actionTypeRegistry, encryptedSavedObjectsClient, eventLogger: eventLoggerMock.create(), - preconfiguredActions: [], + inMemoryConnectors: [], }); await expect( customActionExecutor.execute(executeParams) @@ -976,7 +976,7 @@ test('should not throw error if action is preconfigured and isESOCanEncrypt is f actionTypeRegistry, encryptedSavedObjectsClient, eventLogger: eventLoggerMock.create(), - preconfiguredActions: [ + inMemoryConnectors: [ { id: 'preconfigured', name: 'Preconfigured', diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts index 272d61943ac2ba..d5f6e9c3b14eaf 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.ts @@ -25,7 +25,7 @@ import { ActionTypeExecutorRawResult, ActionTypeRegistryContract, GetServicesFunction, - PreConfiguredAction, + InMemoryConnector, RawAction, ValidatorServices, } from '../types'; @@ -46,7 +46,7 @@ export interface ActionExecutorContext { encryptedSavedObjectsClient: EncryptedSavedObjectsClient; actionTypeRegistry: ActionTypeRegistryContract; eventLogger: IEventLogger; - preconfiguredActions: PreConfiguredAction[]; + inMemoryConnectors: InMemoryConnector[]; } export interface TaskInfo { @@ -118,7 +118,7 @@ export class ActionExecutor { encryptedSavedObjectsClient, actionTypeRegistry, eventLogger, - preconfiguredActions, + inMemoryConnectors, security, } = this.actionExecutorContext!; @@ -129,7 +129,7 @@ export class ActionExecutor { const actionInfo = await getActionInfoInternal( this.isESOCanEncrypt, encryptedSavedObjectsClient, - preconfiguredActions, + inMemoryConnectors, actionId, namespace.namespace ); @@ -341,7 +341,7 @@ export class ActionExecutor { source?: ActionExecutionSource; consumer?: string; }) { - const { spaces, encryptedSavedObjectsClient, preconfiguredActions, eventLogger } = + const { spaces, encryptedSavedObjectsClient, inMemoryConnectors, eventLogger } = this.actionExecutorContext!; const spaceId = spaces && spaces.getSpaceId(request); @@ -350,7 +350,7 @@ export class ActionExecutor { this.actionInfo = await getActionInfoInternal( this.isESOCanEncrypt, encryptedSavedObjectsClient, - preconfiguredActions, + inMemoryConnectors, actionId, namespace.namespace ); @@ -405,13 +405,13 @@ interface ActionInfo { async function getActionInfoInternal( isESOCanEncrypt: boolean, encryptedSavedObjectsClient: EncryptedSavedObjectsClient, - preconfiguredActions: PreConfiguredAction[], + inMemoryConnectors: InMemoryConnector[], actionId: string, namespace: string | undefined ): Promise { // check to see if it's a pre-configured action first - const pcAction = preconfiguredActions.find( - (preconfiguredAction) => preconfiguredAction.id === actionId + const pcAction = inMemoryConnectors.find( + (inMemoryConnector) => inMemoryConnector.id === actionId ); if (pcAction) { return { diff --git a/x-pack/plugins/actions/server/lib/is_connector_deprecated.ts b/x-pack/plugins/actions/server/lib/is_connector_deprecated.ts index db5138cddc53f6..4ebdeec7728eb8 100644 --- a/x-pack/plugins/actions/server/lib/is_connector_deprecated.ts +++ b/x-pack/plugins/actions/server/lib/is_connector_deprecated.ts @@ -6,10 +6,10 @@ */ import { isPlainObject } from 'lodash'; -import { PreConfiguredAction, RawAction } from '../types'; +import { InMemoryConnector, RawAction } from '../types'; -export type ConnectorWithOptionalDeprecation = Omit & - Pick, 'isDeprecated'>; +export type ConnectorWithOptionalDeprecation = Omit & + Pick, 'isDeprecated'>; const isObject = (obj: unknown): obj is Record => isPlainObject(obj); diff --git a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts index eae6cd5bc06c2b..fb764b2b6f74cd 100644 --- a/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts +++ b/x-pack/plugins/actions/server/lib/task_runner_factory.test.ts @@ -86,7 +86,7 @@ const actionExecutorInitializerParams = { getActionsClientWithRequest: jest.fn(async () => actionsClientMock.create()), encryptedSavedObjectsClient: mockedEncryptedSavedObjectsClient, eventLogger, - preconfiguredActions: [], + inMemoryConnectors: [], }; const taskRunnerFactoryInitializerParams = { spaceIdToNamespace, diff --git a/x-pack/plugins/actions/server/mocks.ts b/x-pack/plugins/actions/server/mocks.ts index d14c082f969056..14ae64391177f0 100644 --- a/x-pack/plugins/actions/server/mocks.ts +++ b/x-pack/plugins/actions/server/mocks.ts @@ -45,7 +45,7 @@ const createStartMock = () => { getActionsAuthorizationWithRequest: jest .fn() .mockReturnValue(actionsAuthorizationMock.create()), - preconfiguredActions: [], + inMemoryConnectors: [], renderActionParameterTemplates: jest.fn(), }; return mock; diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index 0136410920c663..a1a58bf14cb136 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -390,7 +390,7 @@ describe('Actions Plugin', () => { const pluginStart = await plugin.start(coreStart, pluginsStart); - expect(pluginStart.preconfiguredActions.length).toEqual(1); + expect(pluginStart.inMemoryConnectors.length).toEqual(1); expect(pluginStart.isActionExecutable('preconfiguredServerLog', '.server-log')).toBe(true); }); @@ -414,7 +414,7 @@ describe('Actions Plugin', () => { const pluginStart = await plugin.start(coreStart, pluginsStart); - expect(pluginStart.preconfiguredActions.length).toEqual(2); + expect(pluginStart.inMemoryConnectors.length).toEqual(2); expect( pluginStart.isActionExecutable('preconfigured-alert-history-es-index', '.index') ).toBe(true); @@ -438,7 +438,7 @@ describe('Actions Plugin', () => { await plugin.setup(coreSetup as any, pluginsSetup); const pluginStart = await plugin.start(coreStart, pluginsStart); - expect(pluginStart.preconfiguredActions.length).toEqual(0); + expect(pluginStart.inMemoryConnectors.length).toEqual(0); expect(context.logger.get().warn).toHaveBeenCalledWith( `Preconfigured connectors cannot have the id "${AlertHistoryEsIndexConnectorId}" because this is a reserved id.` ); diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index ba4fec697b0c7b..85cacdcd7a5a66 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -60,7 +60,7 @@ import { import { Services, ActionType, - PreConfiguredAction, + InMemoryConnector, ActionTypeConfig, ActionTypeSecrets, ActionTypeParams, @@ -147,7 +147,7 @@ export interface PluginStartContract { getActionsAuthorizationWithRequest(request: KibanaRequest): PublicMethodsOf; - preconfiguredActions: PreConfiguredAction[]; + inMemoryConnectors: InMemoryConnector[]; getUnsecuredActionsClient(): IUnsecuredActionsClient; @@ -200,7 +200,7 @@ export class ActionsPlugin implements Plugin()) ); this.telemetryLogger = initContext.logger.get('usage'); - this.preconfiguredActions = []; + this.inMemoryConnectors = []; this.inMemoryMetrics = new InMemoryMetrics(initContext.logger.get('in_memory_metrics')); } @@ -244,7 +244,7 @@ export class ActionsPlugin implements Plugin { - return !!this.preconfiguredActions.find( - (preconfigured) => preconfigured.id === connectorId + return !!this.inMemoryConnectors.find( + (inMemoryConnector) => inMemoryConnector.id === connectorId ); }, getSubActionConnectorClass: () => SubActionConnector, @@ -384,7 +384,7 @@ export class ActionsPlugin implements Plugin renderActionParameterTemplates(actionTypeRegistry, ...args), }; @@ -595,7 +595,7 @@ export class ActionsPlugin implements Plugin { +export function getAlertHistoryEsIndex(): Readonly { return Object.freeze({ name: i18n.translate('xpack.actions.alertHistoryEsIndexConnector.name', { defaultMessage: 'Alert history Elasticsearch index', diff --git a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts index 7ef21c8fc84bd3..80e3461e125295 100644 --- a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts @@ -19,7 +19,7 @@ import { SavedObjectsUtils } from '@kbn/core-saved-objects-utils-server'; const context = migrationMocks.createContext(); const encryptedSavedObjectsSetup = encryptedSavedObjectsMock.createSetup(); -const preconfiguredActions = [ +const inMemoryConnectors = [ { actionTypeId: 'foo', config: {}, @@ -41,7 +41,7 @@ describe('successful migrations', () => { describe('7.16.0', () => { test('adds actionId to references array if actionId is not preconfigured', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData(); const migratedActionTaskParam = migration716(actionTaskParam, context); @@ -59,7 +59,7 @@ describe('successful migrations', () => { test('does not add actionId to references array if actionId is preconfigured', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData({ actionId: 'my-slack1' }); const migratedActionTaskParam = migration716(actionTaskParam, context); @@ -71,7 +71,7 @@ describe('successful migrations', () => { test('handles empty relatedSavedObjects array', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData({ relatedSavedObjects: [] }); const migratedActionTaskParam = migration716(actionTaskParam, context); @@ -93,7 +93,7 @@ describe('successful migrations', () => { test('adds actionId and relatedSavedObjects to references array', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData({ relatedSavedObjects: [ @@ -136,7 +136,7 @@ describe('successful migrations', () => { test('only adds relatedSavedObjects to references array if action is preconfigured', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData({ actionId: 'my-slack1', @@ -175,7 +175,7 @@ describe('successful migrations', () => { test('adds actionId and multiple relatedSavedObjects to references array', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData({ relatedSavedObjects: [ @@ -233,7 +233,7 @@ describe('successful migrations', () => { test('does not overwrite existing references', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData( { @@ -290,7 +290,7 @@ describe('successful migrations', () => { test('does not overwrite existing references if relatedSavedObjects is undefined', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData({}, [ { @@ -319,7 +319,7 @@ describe('successful migrations', () => { test('does not overwrite existing references if relatedSavedObjects is empty', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData({ relatedSavedObjects: [] }, [ { @@ -373,7 +373,7 @@ describe('handles errors during migrations', () => { describe('7.16.0 throws if migration fails', () => { test('should show the proper exception', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( - getActionTaskParamsMigrations(encryptedSavedObjectsSetup, preconfiguredActions)['7.16.0'] + getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); const actionTaskParam = getMockData(); expect(() => { @@ -394,12 +394,12 @@ describe('handles errors during migrations', () => { describe('isPreconfiguredAction()', () => { test('returns true if actionId is preconfigured action', () => { expect( - isPreconfiguredAction(getMockData({ actionId: 'my-slack1' }), preconfiguredActions) + isPreconfiguredAction(getMockData({ actionId: 'my-slack1' }), inMemoryConnectors) ).toEqual(true); }); test('returns false if actionId is not preconfigured action', () => { - expect(isPreconfiguredAction(getMockData(), preconfiguredActions)).toEqual(false); + expect(isPreconfiguredAction(getMockData(), inMemoryConnectors)).toEqual(false); }); }); diff --git a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts index b0778d680e70eb..c686fa55d9fe62 100644 --- a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts +++ b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts @@ -15,7 +15,7 @@ import { } from '@kbn/core/server'; import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import type { IsMigrationNeededPredicate } from '@kbn/encrypted-saved-objects-plugin/server'; -import { ActionTaskParams, PreConfiguredAction } from '../types'; +import { ActionTaskParams, InMemoryConnector } from '../types'; import { RelatedSavedObjects } from '../lib/related_saved_objects'; interface ActionTaskParamsLogMeta extends LogMeta { @@ -40,12 +40,12 @@ function createEsoMigration( export function getActionTaskParamsMigrations( encryptedSavedObjects: EncryptedSavedObjectsPluginSetup, - preconfiguredActions: PreConfiguredAction[] + inMemoryConnectors: InMemoryConnector[] ): SavedObjectMigrationMap { const migrationActionTaskParamsSixteen = createEsoMigration( encryptedSavedObjects, (doc): doc is SavedObjectUnsanitizedDoc => true, - pipeMigrations(getUseSavedObjectReferencesFn(preconfiguredActions)) + pipeMigrations(getUseSavedObjectReferencesFn(inMemoryConnectors)) ); const migrationActionsTaskParams800 = createEsoMigration( @@ -88,20 +88,20 @@ function executeMigrationWithErrorHandling( export function isPreconfiguredAction( doc: SavedObjectUnsanitizedDoc, - preconfiguredActions: PreConfiguredAction[] + inMemoryConnectors: InMemoryConnector[] ): boolean { - return !!preconfiguredActions.find((action) => action.id === doc.attributes.actionId); + return !!inMemoryConnectors.find((action) => action.id === doc.attributes.actionId); } -function getUseSavedObjectReferencesFn(preconfiguredActions: PreConfiguredAction[]) { +function getUseSavedObjectReferencesFn(inMemoryConnectors: InMemoryConnector[]) { return (doc: SavedObjectUnsanitizedDoc) => { - return useSavedObjectReferences(doc, preconfiguredActions); + return useSavedObjectReferences(doc, inMemoryConnectors); }; } function useSavedObjectReferences( doc: SavedObjectUnsanitizedDoc, - preconfiguredActions: PreConfiguredAction[] + inMemoryConnectors: InMemoryConnector[] ): SavedObjectUnsanitizedDoc { const { attributes: { actionId, relatedSavedObjects }, @@ -111,7 +111,7 @@ function useSavedObjectReferences( const newReferences: SavedObjectReference[] = []; const relatedSavedObjectRefs: RelatedSavedObjects = []; - if (!isPreconfiguredAction(doc, preconfiguredActions)) { + if (!isPreconfiguredAction(doc, inMemoryConnectors)) { newReferences.push({ id: actionId, name: 'actionRef', diff --git a/x-pack/plugins/actions/server/saved_objects/index.ts b/x-pack/plugins/actions/server/saved_objects/index.ts index 5b38062265196d..d5125ecc134cd8 100644 --- a/x-pack/plugins/actions/server/saved_objects/index.ts +++ b/x-pack/plugins/actions/server/saved_objects/index.ts @@ -16,7 +16,7 @@ import { ALERTING_CASES_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-serve import { actionMappings, actionTaskParamsMappings, connectorTokenMappings } from './mappings'; import { getActionsMigrations } from './actions_migrations'; import { getActionTaskParamsMigrations } from './action_task_params_migrations'; -import { PreConfiguredAction, RawAction } from '../types'; +import { InMemoryConnector, RawAction } from '../types'; import { getImportWarnings } from './get_import_warnings'; import { transformConnectorsForExport } from './transform_connectors_for_export'; import { ActionTypeRegistry } from '../action_type_registry'; @@ -31,7 +31,7 @@ export function setupSavedObjects( encryptedSavedObjects: EncryptedSavedObjectsPluginSetup, actionTypeRegistry: ActionTypeRegistry, taskManagerIndex: string, - preconfiguredActions: PreConfiguredAction[] + inMemoryConnectors: InMemoryConnector[] ) { savedObjects.registerType({ name: ACTION_SAVED_OBJECT_TYPE, @@ -79,7 +79,7 @@ export function setupSavedObjects( namespaceType: 'multiple-isolated', convertToMultiNamespaceTypeVersion: '8.0.0', mappings: actionTaskParamsMappings, - migrations: getActionTaskParamsMigrations(encryptedSavedObjects, preconfiguredActions), + migrations: getActionTaskParamsMigrations(encryptedSavedObjects, inMemoryConnectors), excludeOnUpgrade: async ({ readonlyEsClient }) => { const oldestIdleActionTask = await getOldestIdleActionTask( readonlyEsClient, diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index 54f5f8327be65a..4e078af3868f6e 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -84,7 +84,7 @@ export interface ActionResult extends ActionResult { diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.ts index 6e2b4ebbfff80d..649f1109311af3 100644 --- a/x-pack/plugins/actions/server/usage/actions_telemetry.ts +++ b/x-pack/plugins/actions/server/usage/actions_telemetry.ts @@ -13,13 +13,13 @@ import { parseActionRunOutcomeByConnectorTypesBucket, } from './lib/parse_connector_type_bucket'; import { AlertHistoryEsIndexConnectorId } from '../../common'; -import { ActionResult, PreConfiguredAction } from '../types'; +import { ActionResult, InMemoryConnector } from '../types'; export async function getTotalCount( esClient: ElasticsearchClient, kibanaIndex: string, logger: Logger, - preconfiguredActions?: PreConfiguredAction[] + inMemoryConnectors?: InMemoryConnector[] ) { const scriptedMetric = { scripted_metric: { @@ -74,9 +74,9 @@ export async function getTotalCount( }, {} ); - if (preconfiguredActions && preconfiguredActions.length) { - for (const preconfiguredAction of preconfiguredActions) { - const actionTypeId = replaceFirstAndLastDotSymbols(preconfiguredAction.actionTypeId); + if (inMemoryConnectors && inMemoryConnectors.length) { + for (const inMemoryConnector of inMemoryConnectors) { + const actionTypeId = replaceFirstAndLastDotSymbols(inMemoryConnector.actionTypeId); countByType[actionTypeId] = countByType[actionTypeId] || 0; countByType[actionTypeId]++; } @@ -87,7 +87,7 @@ export async function getTotalCount( Object.keys(aggs).reduce( (total: number, key: string) => parseInt(aggs[key], 10) + total, 0 - ) + (preconfiguredActions?.length ?? 0), + ) + (inMemoryConnectors?.length ?? 0), countByType, }; } catch (err) { @@ -109,7 +109,7 @@ export async function getInUseTotalCount( kibanaIndex: string, logger: Logger, referenceType?: string, - preconfiguredActions?: PreConfiguredAction[] + inMemoryConnectors?: InMemoryConnector[] ): Promise<{ hasErrors: boolean; errorMessage?: string; @@ -363,9 +363,9 @@ export async function getInUseTotalCount( if (actionRef === `preconfigured:${AlertHistoryEsIndexConnectorId}`) { preconfiguredAlertHistoryConnectors++; } - if (preconfiguredActions && actionTypeId === '__email') { + if (inMemoryConnectors && actionTypeId === '__email') { const preconfiguredConnectorId = actionRef.split(':')[1]; - const service = (preconfiguredActions.find( + const service = (inMemoryConnectors.find( (preconfConnector) => preconfConnector.id === preconfiguredConnectorId )?.config?.service ?? 'other') as string; const currentCount = diff --git a/x-pack/plugins/actions/server/usage/task.ts b/x-pack/plugins/actions/server/usage/task.ts index 7faf443019c6b7..ef71d4ff46e3cf 100644 --- a/x-pack/plugins/actions/server/usage/task.ts +++ b/x-pack/plugins/actions/server/usage/task.ts @@ -12,7 +12,7 @@ import { TaskManagerStartContract, IntervalSchedule, } from '@kbn/task-manager-plugin/server'; -import { PreConfiguredAction } from '../types'; +import { InMemoryConnector } from '../types'; import { getTotalCount, getInUseTotalCount, getExecutionsPerDayCount } from './actions_telemetry'; export const TELEMETRY_TASK_TYPE = 'actions_telemetry'; @@ -24,10 +24,10 @@ export function initializeActionsTelemetry( logger: Logger, taskManager: TaskManagerSetupContract, core: CoreSetup, - preconfiguredActions: PreConfiguredAction[], + inMemoryConnectors: InMemoryConnector[], eventLogIndex: string ) { - registerActionsTelemetryTask(logger, taskManager, core, preconfiguredActions, eventLogIndex); + registerActionsTelemetryTask(logger, taskManager, core, inMemoryConnectors, eventLogIndex); } export function scheduleActionsTelemetry(logger: Logger, taskManager: TaskManagerStartContract) { @@ -38,14 +38,14 @@ function registerActionsTelemetryTask( logger: Logger, taskManager: TaskManagerSetupContract, core: CoreSetup, - preconfiguredActions: PreConfiguredAction[], + inMemoryConnectors: InMemoryConnector[], eventLogIndex: string ) { taskManager.registerTaskDefinitions({ [TELEMETRY_TASK_TYPE]: { title: 'Actions usage fetch task', timeout: '5m', - createTaskRunner: telemetryTaskRunner(logger, core, preconfiguredActions, eventLogIndex), + createTaskRunner: telemetryTaskRunner(logger, core, inMemoryConnectors, eventLogIndex), }, }); } @@ -67,7 +67,7 @@ async function scheduleTasks(logger: Logger, taskManager: TaskManagerStartContra export function telemetryTaskRunner( logger: Logger, core: CoreSetup, - preconfiguredActions: PreConfiguredAction[], + inMemoryConnectors: InMemoryConnector[], eventLogIndex: string ) { return ({ taskInstance }: RunContext) => { @@ -89,8 +89,8 @@ export function telemetryTaskRunner( const actionIndex = await getActionIndex(); const esClient = await getEsClient(); return Promise.all([ - getTotalCount(esClient, actionIndex, logger, preconfiguredActions), - getInUseTotalCount(esClient, actionIndex, logger, undefined, preconfiguredActions), + getTotalCount(esClient, actionIndex, logger, inMemoryConnectors), + getInUseTotalCount(esClient, actionIndex, logger, undefined, inMemoryConnectors), getExecutionsPerDayCount(esClient, eventLogIndex, logger), ]).then(([totalAggegations, totalInUse, totalExecutionsPerDay]) => { const hasErrors = From 2aabeed2fbc739272599fb58b3965964797d0b9d Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Thu, 29 Jun 2023 12:35:19 +0300 Subject: [PATCH 13/28] Create system actions --- x-pack/plugins/actions/common/types.ts | 1 + .../server/action_type_registry.test.ts | 2 +- .../actions/server/action_type_registry.ts | 3 +- .../server/create_system_actions.test.ts | 49 +++++ .../actions/server/create_system_actions.ts | 27 +++ .../server/lib/ensure_sufficient_license.ts | 3 +- x-pack/plugins/actions/server/plugin.test.ts | 181 ++++++++++++------ x-pack/plugins/actions/server/plugin.ts | 26 ++- x-pack/plugins/actions/server/types.ts | 2 +- 9 files changed, 219 insertions(+), 75 deletions(-) create mode 100644 x-pack/plugins/actions/server/create_system_actions.test.ts create mode 100644 x-pack/plugins/actions/server/create_system_actions.ts diff --git a/x-pack/plugins/actions/common/types.ts b/x-pack/plugins/actions/common/types.ts index 275a757597d281..c3e1b35777fff3 100644 --- a/x-pack/plugins/actions/common/types.ts +++ b/x-pack/plugins/actions/common/types.ts @@ -22,6 +22,7 @@ export interface ActionType { enabledInLicense: boolean; minimumLicenseRequired: LicenseType; supportedFeatureIds: string[]; + isSystemActionType: boolean; } export enum InvalidEmailReason { diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index a36732c2c7e919..e9079517eb7085 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -226,7 +226,7 @@ describe('actionTypeRegistry', () => { name: 'My action type', minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], - isSystemAction: true, + isSystemActionType: true, validate: { config: { schema: schema.object({}) }, secrets: { schema: schema.object({}) }, diff --git a/x-pack/plugins/actions/server/action_type_registry.ts b/x-pack/plugins/actions/server/action_type_registry.ts index 7e9adcc99ac342..a54aadd2e465a5 100644 --- a/x-pack/plugins/actions/server/action_type_registry.ts +++ b/x-pack/plugins/actions/server/action_type_registry.ts @@ -104,7 +104,7 @@ export class ActionTypeRegistry { ExecutorResultData = void >(actionType: ActionType) { // TODO: Remove when system action are supported - if (actionType.isSystemAction) { + if (actionType.isSystemActionType) { throw new Error( i18n.translate( 'xpack.actions.actionTypeRegistry.register.systemActionsNotSupportedErrorMessage', @@ -213,6 +213,7 @@ export class ActionTypeRegistry { enabledInConfig: this.actionsConfigUtils.isActionTypeEnabled(actionTypeId), enabledInLicense: !!this.licenseState.isLicenseValidForActionType(actionType).isValid, supportedFeatureIds: actionType.supportedFeatureIds, + isSystemActionType: !!actionType.isSystemActionType, })); } diff --git a/x-pack/plugins/actions/server/create_system_actions.test.ts b/x-pack/plugins/actions/server/create_system_actions.test.ts new file mode 100644 index 00000000000000..fd591f2c16429b --- /dev/null +++ b/x-pack/plugins/actions/server/create_system_actions.test.ts @@ -0,0 +1,49 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createSystemConnectors } from './create_system_actions'; + +const actionTypes = [ + { + id: 'action-type', + name: 'My action type', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic' as const, + supportedFeatureIds: ['alerting'], + isSystemActionType: false, + }, + { + id: 'system-action-type-2', + name: 'My system action type', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic' as const, + supportedFeatureIds: ['alerting'], + isSystemActionType: true, + }, +]; + +describe('createSystemConnectors', () => { + it('creates the system actions correctly', () => { + expect(createSystemConnectors(actionTypes)).toEqual([ + { + id: 'system-connector-system-action-type-2', + actionTypeId: 'system-action-type-2', + name: 'system-connector-system-action-type-2', + secrets: {}, + config: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, + ]); + }); +}); diff --git a/x-pack/plugins/actions/server/create_system_actions.ts b/x-pack/plugins/actions/server/create_system_actions.ts new file mode 100644 index 00000000000000..90a13104ff76dc --- /dev/null +++ b/x-pack/plugins/actions/server/create_system_actions.ts @@ -0,0 +1,27 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ActionType } from '../common'; +import { InMemoryConnector } from './types'; + +export const createSystemConnectors = (actionTypes: ActionType[]): InMemoryConnector[] => { + const systemActionTypes = actionTypes.filter((actionType) => actionType.isSystemActionType); + + const systemConnectors: InMemoryConnector[] = systemActionTypes.map((systemActionType) => ({ + id: `system-connector-${systemActionType.id}`, + actionTypeId: systemActionType.id, + name: `system-connector-${systemActionType.id}`, + isMissingSecrets: false, + config: {}, + secrets: {}, + isDeprecated: false, + isPreconfigured: false, + isSystemAction: true, + })); + + return systemConnectors; +}; diff --git a/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts b/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts index e7d781a7218bd5..9c28621034c616 100644 --- a/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts +++ b/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts @@ -9,9 +9,10 @@ import { LICENSE_TYPE } from '@kbn/licensing-plugin/common/types'; import { ActionType } from '../types'; import { ActionTypeConfig, ActionTypeSecrets, ActionTypeParams } from '../types'; -const CASE_ACTION_TYPE_ID = '.case'; +const CASE_ACTION_TYPE_ID = '.cases'; const ServerLogActionTypeId = '.server-log'; const IndexActionTypeId = '.index'; + const ACTIONS_SCOPED_WITHIN_STACK = new Set([ ServerLogActionTypeId, IndexActionTypeId, diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index a1a58bf14cb136..44418835a16098 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -323,7 +323,7 @@ describe('Actions Plugin', () => { }); }); - describe('Preconfigured connectors', () => { + describe('inMemoryConnectors', () => { function getConfig(overrides = {}) { return { enabled: true, @@ -370,78 +370,135 @@ describe('Actions Plugin', () => { }; } - it('should handle preconfigured actions', async () => { - setup(getConfig()); - // coreMock.createSetup doesn't support Plugin generics - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pluginSetup = await plugin.setup(coreSetup as any, pluginsSetup); - pluginSetup.registerType({ - id: '.server-log', - name: 'Server log', - minimumLicenseRequired: 'basic', - supportedFeatureIds: ['alerting'], - validate: { - config: { schema: schema.object({}) }, - secrets: { schema: schema.object({}) }, - params: { schema: schema.object({}) }, - }, - executor, + describe('Preconfigured connectors', () => { + it('should handle preconfigured actions', async () => { + setup(getConfig()); + // coreMock.createSetup doesn't support Plugin generics + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const pluginSetup = await plugin.setup(coreSetup as any, pluginsSetup); + pluginSetup.registerType({ + id: '.server-log', + name: 'Server log', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, + }, + executor, + }); + + const pluginStart = await plugin.start(coreStart, pluginsStart); + + expect(pluginStart.inMemoryConnectors.length).toEqual(1); + expect(pluginStart.isActionExecutable('preconfiguredServerLog', '.server-log')).toBe( + true + ); }); - const pluginStart = await plugin.start(coreStart, pluginsStart); + it('should handle preconfiguredAlertHistoryEsIndex = true', async () => { + setup(getConfig({ preconfiguredAlertHistoryEsIndex: true })); - expect(pluginStart.inMemoryConnectors.length).toEqual(1); - expect(pluginStart.isActionExecutable('preconfiguredServerLog', '.server-log')).toBe(true); - }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const pluginSetup = await plugin.setup(coreSetup as any, pluginsSetup); + pluginSetup.registerType({ + id: '.index', + name: 'ES Index', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, + }, + executor, + }); - it('should handle preconfiguredAlertHistoryEsIndex = true', async () => { - setup(getConfig({ preconfiguredAlertHistoryEsIndex: true })); + const pluginStart = await plugin.start(coreStart, pluginsStart); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pluginSetup = await plugin.setup(coreSetup as any, pluginsSetup); - pluginSetup.registerType({ - id: '.index', - name: 'ES Index', - minimumLicenseRequired: 'basic', - supportedFeatureIds: ['alerting'], - validate: { - config: { schema: schema.object({}) }, - secrets: { schema: schema.object({}) }, - params: { schema: schema.object({}) }, - }, - executor, + expect(pluginStart.inMemoryConnectors.length).toEqual(2); + expect( + pluginStart.isActionExecutable('preconfigured-alert-history-es-index', '.index') + ).toBe(true); }); - const pluginStart = await plugin.start(coreStart, pluginsStart); - - expect(pluginStart.inMemoryConnectors.length).toEqual(2); - expect( - pluginStart.isActionExecutable('preconfigured-alert-history-es-index', '.index') - ).toBe(true); + it('should not allow preconfigured connector with same ID as AlertHistoryEsIndexConnectorId', async () => { + setup( + getConfig({ + preconfigured: { + [AlertHistoryEsIndexConnectorId]: { + actionTypeId: '.index', + name: 'clashing preconfigured index connector', + config: {}, + secrets: {}, + }, + }, + }) + ); + // coreMock.createSetup doesn't support Plugin generics + // eslint-disable-next-line @typescript-eslint/no-explicit-any + await plugin.setup(coreSetup as any, pluginsSetup); + const pluginStart = await plugin.start(coreStart, pluginsStart); + + expect(pluginStart.inMemoryConnectors.length).toEqual(0); + expect(context.logger.get().warn).toHaveBeenCalledWith( + `Preconfigured connectors cannot have the id "${AlertHistoryEsIndexConnectorId}" because this is a reserved id.` + ); + }); }); - it('should not allow preconfigured connector with same ID as AlertHistoryEsIndexConnectorId', async () => { - setup( - getConfig({ - preconfigured: { - [AlertHistoryEsIndexConnectorId]: { - actionTypeId: '.index', - name: 'clashing preconfigured index connector', - config: {}, - secrets: {}, - }, + // TODO: Unskip when registering system actions is allowed + describe.skip('System actions', () => { + it('should handle system actions', async () => { + setup(getConfig()); + // coreMock.createSetup doesn't support Plugin generics + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const pluginSetup = await plugin.setup(coreSetup as any, pluginsSetup); + + pluginSetup.registerType({ + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, }, - }) - ); - // coreMock.createSetup doesn't support Plugin generics - // eslint-disable-next-line @typescript-eslint/no-explicit-any - await plugin.setup(coreSetup as any, pluginsSetup); - const pluginStart = await plugin.start(coreStart, pluginsStart); + isSystemActionType: true, + executor, + }); - expect(pluginStart.inMemoryConnectors.length).toEqual(0); - expect(context.logger.get().warn).toHaveBeenCalledWith( - `Preconfigured connectors cannot have the id "${AlertHistoryEsIndexConnectorId}" because this is a reserved id.` - ); + const pluginStart = await plugin.start(coreStart, pluginsStart); + + // inMemoryConnectors holds both preconfigure and system connectors + expect(pluginStart.inMemoryConnectors.length).toEqual(2); + expect(pluginStart.inMemoryConnectors).toEqual([ + { + id: 'preconfiguredServerLog', + actionTypeId: '.server-log', + name: 'preconfigured-server-log', + config: {}, + secrets: {}, + isDeprecated: false, + isPreconfigured: true, + isSystemAction: false, + }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, + ]); + expect(pluginStart.isActionExecutable('preconfiguredServerLog', '.cases')).toBe(true); + }); }); }); diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index 85cacdcd7a5a66..8fe4fe5928a507 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -106,6 +106,7 @@ import { UnsecuredActionsClient, } from './unsecured_actions_client/unsecured_actions_client'; import { createBulkUnsecuredExecutionEnqueuerFunction } from './create_unsecured_execute_function'; +import { createSystemConnectors } from './create_system_actions'; export interface PluginSetupContract { registerType< @@ -200,7 +201,7 @@ export class ActionsPlugin implements Plugin @@ -416,7 +424,7 @@ export class ActionsPlugin implements Plugin renderActionParameterTemplates(actionTypeRegistry, ...args), }; diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index 4e078af3868f6e..d51af5a37f8125 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -140,7 +140,7 @@ export interface ActionType< secrets: ValidatorType; connector?: (config: Config, secrets: Secrets) => string | null; }; - isSystemAction?: boolean; + isSystemActionType?: boolean; renderParameterTemplates?: RenderParameterTemplates; executor: ExecutorType; } From 3cf469a026c50cb930d50022a4d29a7b34458e1b Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 30 Jun 2023 12:56:15 +0300 Subject: [PATCH 14/28] Prevent create/update/delete of system actions --- .../server/action_type_registry.test.ts | 98 +++- .../actions/server/action_type_registry.ts | 18 +- .../actions/server/actions_client.test.ts | 459 +++++++++++++++++- .../plugins/actions/server/actions_client.ts | 87 +++- x-pack/plugins/actions/server/plugin.test.ts | 3 +- .../apps/synthetics/state/settings/api.ts | 2 + 6 files changed, 607 insertions(+), 60 deletions(-) diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index e9079517eb7085..d1c6989e39f17a 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -217,7 +217,7 @@ describe('actionTypeRegistry', () => { expect(actionTypeRegistryParams.licensing.featureUsage.register).not.toHaveBeenCalled(); }); - test('does not allows registering system actions', () => { + test('allows registering system actions', () => { const actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams); expect(() => @@ -234,7 +234,7 @@ describe('actionTypeRegistry', () => { }, executor, }) - ).toThrowErrorMatchingInlineSnapshot(`"System actions are not supported"`); + ).not.toThrow(); }); }); @@ -302,6 +302,7 @@ describe('actionTypeRegistry', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]); expect(mockedActionsConfig.isActionTypeEnabled).toHaveBeenCalled(); @@ -345,11 +346,46 @@ describe('actionTypeRegistry', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]); expect(mockedActionsConfig.isActionTypeEnabled).toHaveBeenCalled(); expect(mockedLicenseState.isLicenseValidForActionType).toHaveBeenCalled(); }); + + test('sets the isSystemActionType correctly for system actions', () => { + mockedLicenseState.isLicenseValidForActionType.mockReturnValue({ isValid: true }); + const actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams); + + actionTypeRegistry.register({ + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, + }, + isSystemActionType: true, + executor, + }); + + const actionTypes = actionTypeRegistry.list(); + + expect(actionTypes).toEqual([ + { + id: '.cases', + name: 'Cases', + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + isSystemActionType: true, + }, + ]); + }); }); describe('has()', () => { @@ -567,4 +603,62 @@ describe('actionTypeRegistry', () => { expect(result).toEqual(['foo']); }); }); + + describe('isSystemActionType()', () => { + it('should return true if the action type is a system action type', () => { + const registry = new ActionTypeRegistry(actionTypeRegistryParams); + + registry.register({ + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, + }, + isSystemActionType: true, + executor, + }); + + const result = registry.isSystemActionType('.cases'); + expect(result).toBe(true); + }); + + it('should return false if the action type is not a system action type', () => { + mockedLicenseState.isLicenseValidForActionType.mockReturnValue({ isValid: true }); + + const registry = new ActionTypeRegistry(actionTypeRegistryParams); + + registry.register({ + id: 'foo', + name: 'Foo', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, + }, + executor, + }); + + const allTypes = registry.getAllTypes(); + expect(allTypes.length).toBe(1); + + const result = registry.isSystemActionType('foo'); + expect(result).toBe(false); + }); + + it('should return false if the action type does not exists', () => { + const registry = new ActionTypeRegistry(actionTypeRegistryParams); + + const allTypes = registry.getAllTypes(); + expect(allTypes.length).toBe(0); + + const result = registry.isSystemActionType('not-exist'); + expect(result).toBe(false); + }); + }); }); diff --git a/x-pack/plugins/actions/server/action_type_registry.ts b/x-pack/plugins/actions/server/action_type_registry.ts index a54aadd2e465a5..0c14ba028ea904 100644 --- a/x-pack/plugins/actions/server/action_type_registry.ts +++ b/x-pack/plugins/actions/server/action_type_registry.ts @@ -94,6 +94,12 @@ export class ActionTypeRegistry { ); } + /** + * Returns true if the action type is a system action type + */ + public isSystemActionType = (actionTypeId: string): boolean => + Boolean(this.actionTypes.get(actionTypeId)?.isSystemActionType); + /** * Registers an action type to the action type registry */ @@ -103,18 +109,6 @@ export class ActionTypeRegistry { Params extends ActionTypeParams = ActionTypeParams, ExecutorResultData = void >(actionType: ActionType) { - // TODO: Remove when system action are supported - if (actionType.isSystemActionType) { - throw new Error( - i18n.translate( - 'xpack.actions.actionTypeRegistry.register.systemActionsNotSupportedErrorMessage', - { - defaultMessage: 'System actions are not supported', - } - ) - ); - } - if (this.has(actionType.id)) { throw new Error( i18n.translate( diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 8ae4aeebabc8e2..d272f776c991df 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -758,6 +758,35 @@ describe('create()', () => { `"This mySuperRadTestPreconfiguredId already exist in preconfigured action."` ); }); + + it('throws when creating a system connector', async () => { + actionTypeRegistry.register({ + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'basic', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, + }, + isSystemActionType: true, + executor, + }); + + await expect( + actionsClient.create({ + action: { + name: 'my name', + actionTypeId: '.cases', + config: {}, + secrets: {}, + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"System action creation is forbidden. Action type: .cases."` + ); + }); }); describe('get()', () => { @@ -1011,6 +1040,50 @@ describe('get()', () => { }); expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); }); + + it('return system action with id', async () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + inMemoryConnectors: [ + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, + ], + connectorTokenClient: connectorTokenClientMock.create(), + getEventLogClient, + }); + + const result = await actionsClient.get({ id: 'system-connector-.cases' }); + + expect(result).toEqual({ + id: 'system-connector-.cases', + actionTypeId: '.cases', + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + name: 'system-connector-.cases', + }); + + expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); + }); }); describe('getAll()', () => { @@ -1158,7 +1231,7 @@ describe('getAll()', () => { }); }); - test('calls unsecuredSavedObjectsClient with parameters', async () => { + test('calls unsecuredSavedObjectsClient with parameters and returns inMemoryConnectors correctly', async () => { const expectedResult = { total: 1, per_page: 10, @@ -1186,6 +1259,7 @@ describe('getAll()', () => { aggregations: { '1': { doc_count: 6 }, testPreconfigured: { doc_count: 2 }, + 'system-connector-.cases': { doc_count: 2 }, }, } ); @@ -1215,31 +1289,51 @@ describe('getAll()', () => { foo: 'bar', }, }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, ], connectorTokenClient: connectorTokenClientMock.create(), getEventLogClient, }); + const result = await actionsClient.getAll(); + expect(result).toEqual([ { - id: '1', + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', isPreconfigured: false, - isSystemAction: false, isDeprecated: false, + isSystemAction: true, + referencedByCount: 2, + }, + { + id: '1', name: 'test', - config: { - foo: 'bar', - }, isMissingSecrets: false, + config: { foo: 'bar' }, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: false, referencedByCount: 6, }, { id: 'testPreconfigured', actionTypeId: '.slack', + name: 'test', isPreconfigured: true, - isSystemAction: false, isDeprecated: false, - name: 'test', + isSystemAction: false, referencedByCount: 2, }, ]); @@ -1386,7 +1480,7 @@ describe('getBulk()', () => { }); }); - test('calls getBulk unsecuredSavedObjectsClient with parameters', async () => { + test('calls getBulk unsecuredSavedObjectsClient with parameters and return inMemoryConnectors correctly', async () => { unsecuredSavedObjectsClient.bulkGet.mockResolvedValueOnce({ saved_objects: [ { @@ -1410,6 +1504,7 @@ describe('getBulk()', () => { aggregations: { '1': { doc_count: 6 }, testPreconfigured: { doc_count: 2 }, + 'system-connector-.cases': { doc_count: 2 }, }, } ); @@ -1439,35 +1534,59 @@ describe('getBulk()', () => { foo: 'bar', }, }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, ], connectorTokenClient: connectorTokenClientMock.create(), getEventLogClient, }); - const result = await actionsClient.getBulk(['1', 'testPreconfigured']); + + const result = await actionsClient.getBulk([ + '1', + 'testPreconfigured', + 'system-connector-.cases', + ]); + expect(result).toEqual([ { - actionTypeId: '.slack', - config: { - foo: 'bar', - }, id: 'testPreconfigured', + actionTypeId: '.slack', + secrets: {}, isPreconfigured: true, - isSystemAction: false, isDeprecated: false, + isSystemAction: false, name: 'test', + config: { foo: 'bar' }, + }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, }, { - actionTypeId: 'test', - config: { - foo: 'bar', - }, id: '1', + actionTypeId: 'test', + name: 'test', + config: { foo: 'bar' }, isMissingSecrets: false, isPreconfigured: false, - isSystemAction: false, isDeprecated: false, - name: 'test', + isSystemAction: false, }, ]); }); @@ -1842,6 +1961,83 @@ describe('delete()', () => { ] `); }); + + it('throws when trying to delete a system connector', async () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + inMemoryConnectors: [ + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, + ], + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + connectorTokenClient: connectorTokenClientMock.create(), + getEventLogClient, + }); + + await expect( + actionsClient.delete({ id: 'system-connector-.cases' }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"System action system-connector-.cases is not allowed to delete."` + ); + }); + + it('throws when trying to delete a preconfigured connector', async () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + inMemoryConnectors: [ + { + id: 'testPreconfigured', + actionTypeId: 'my-action-type', + secrets: { + test: 'test1', + }, + isPreconfigured: true, + isDeprecated: false, + isSystemAction: false, + name: 'test', + config: { + foo: 'bar', + }, + }, + ], + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + connectorTokenClient: connectorTokenClientMock.create(), + getEventLogClient, + }); + + await expect( + actionsClient.delete({ id: 'testPreconfigured' }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Preconfigured action testPreconfigured is not allowed to delete."` + ); + }); }); describe('update()', () => { @@ -2318,6 +2514,97 @@ describe('update()', () => { }) ).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`); }); + + it('throws when trying to update a system connector', async () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + inMemoryConnectors: [ + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, + ], + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + connectorTokenClient: connectorTokenClientMock.create(), + getEventLogClient, + }); + + await expect( + actionsClient.update({ + id: 'system-connector-.cases', + action: { + name: 'my name', + config: {}, + secrets: {}, + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"System action system-connector-.cases is not allowed to update."` + ); + }); + + it('throws when trying to update a preconfigured connector', async () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + inMemoryConnectors: [ + { + id: 'testPreconfigured', + actionTypeId: 'my-action-type', + secrets: { + test: 'test1', + }, + isPreconfigured: true, + isDeprecated: false, + isSystemAction: false, + name: 'test', + config: { + foo: 'bar', + }, + }, + ], + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + connectorTokenClient: connectorTokenClientMock.create(), + getEventLogClient, + }); + + await expect( + actionsClient.update({ + id: 'testPreconfigured', + action: { + name: 'my name', + config: {}, + secrets: {}, + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Preconfigured action testPreconfigured is not allowed to update."` + ); + }); }); describe('execute()', () => { @@ -2701,7 +2988,7 @@ describe('isActionTypeEnabled()', () => { }); describe('isPreconfigured()', () => { - test('should return true if connector id is in list of preconfigured connectors', () => { + test('should return true if the connector is a preconfigured connector', () => { actionsClient = new ActionsClient({ logger, actionTypeRegistry, @@ -2729,6 +3016,17 @@ describe('isPreconfigured()', () => { foo: 'bar', }, }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, ], connectorTokenClient: new ConnectorTokenClient({ unsecuredSavedObjectsClient: savedObjectsClientMock.create(), @@ -2741,7 +3039,7 @@ describe('isPreconfigured()', () => { expect(actionsClient.isPreconfigured('testPreconfigured')).toEqual(true); }); - test('should return false if connector id is not in list of preconfigured connectors', () => { + test('should return false if the connector is not preconfigured connector', () => { actionsClient = new ActionsClient({ logger, actionTypeRegistry, @@ -2769,6 +3067,17 @@ describe('isPreconfigured()', () => { foo: 'bar', }, }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, ], connectorTokenClient: new ConnectorTokenClient({ unsecuredSavedObjectsClient: savedObjectsClientMock.create(), @@ -2782,6 +3091,110 @@ describe('isPreconfigured()', () => { }); }); +describe('isSystemAction()', () => { + test('should return true if the connector is a system connectors', () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + inMemoryConnectors: [ + { + id: 'testPreconfigured', + actionTypeId: 'my-action-type', + secrets: { + test: 'test1', + }, + isPreconfigured: true, + isDeprecated: false, + isSystemAction: false, + name: 'test', + config: { + foo: 'bar', + }, + }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, + ], + connectorTokenClient: new ConnectorTokenClient({ + unsecuredSavedObjectsClient: savedObjectsClientMock.create(), + encryptedSavedObjectsClient: encryptedSavedObjectsMock.createClient(), + logger, + }), + getEventLogClient, + }); + + expect(actionsClient.isSystemAction('system-connector-.cases')).toEqual(true); + }); + + test('should return false if connector id is not in list of preconfigured connectors', () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + inMemoryConnectors: [ + { + id: 'testPreconfigured', + actionTypeId: 'my-action-type', + secrets: { + test: 'test1', + }, + isPreconfigured: true, + isDeprecated: false, + isSystemAction: false, + name: 'test', + config: { + foo: 'bar', + }, + }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'system-connector-.cases', + config: {}, + secrets: {}, + isDeprecated: false, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, + }, + ], + connectorTokenClient: new ConnectorTokenClient({ + unsecuredSavedObjectsClient: savedObjectsClientMock.create(), + encryptedSavedObjectsClient: encryptedSavedObjectsMock.createClient(), + logger, + }), + getEventLogClient, + }); + + expect(actionsClient.isSystemAction(uuidv4())).toEqual(false); + }); +}); + describe('getGlobalExecutionLogWithAuth()', () => { const opts: GetGlobalExecutionLogParams = { dateStart: '2023-01-09T08:55:56-08:00', diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 5366d71e301065..fe54f29b2efde5 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -194,9 +194,24 @@ export class ActionsClient { action: { actionTypeId, name, config, secrets }, options, }: CreateOptions): Promise { + if (this.actionTypeRegistry.isSystemActionType(actionTypeId)) { + throw Boom.badRequest( + i18n.translate('xpack.actions.serverSideErrors.systemActionCreationForbidden', { + defaultMessage: 'System action creation is forbidden. Action type: {actionTypeId}.', + values: { + actionTypeId, + }, + }) + ); + } + const id = options?.id || SavedObjectsUtils.generateId(); - if (this.inMemoryConnectors.some((inMemoryConnector) => inMemoryConnector.id === id)) { + if ( + this.inMemoryConnectors.some( + (inMemoryConnector) => inMemoryConnector.isPreconfigured && inMemoryConnector.id === id + ) + ) { throw Boom.badRequest( i18n.translate('xpack.actions.serverSideErrors.predefinedIdConnectorAlreadyExists', { defaultMessage: 'This {id} already exist in preconfigured action.', @@ -272,10 +287,20 @@ export class ActionsClient { try { await this.authorization.ensureAuthorized('update'); - if ( - this.inMemoryConnectors.find((inMemoryConnector) => inMemoryConnector.id === id) !== - undefined - ) { + const inMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); + + if (inMemoryConnector?.isSystemAction) { + throw Boom.badRequest( + i18n.translate('xpack.actions.serverSideErrors.systemActionCreationForbidden', { + defaultMessage: 'System action {id} is not allowed to update.', + values: { + id, + }, + }) + ); + } + + if (inMemoryConnector?.isPreconfigured) { throw new PreconfiguredActionDisabledModificationError( i18n.translate('xpack.actions.serverSideErrors.predefinedActionUpdateDisabled', { defaultMessage: 'Preconfigured action {id} is not allowed to update.', @@ -380,10 +405,9 @@ export class ActionsClient { throw error; } - const inMemoryConnectorsList = this.inMemoryConnectors.find( - (inMemoryConnector) => inMemoryConnector.id === id - ); - if (inMemoryConnectorsList !== undefined) { + const inMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); + + if (inMemoryConnector !== undefined) { this.auditLogger?.log( connectorAuditEvent({ action: ConnectorAuditAction.GET, @@ -393,11 +417,11 @@ export class ActionsClient { return { id, - actionTypeId: inMemoryConnectorsList.actionTypeId, - name: inMemoryConnectorsList.name, - isPreconfigured: true, - isSystemAction: false, - isDeprecated: isConnectorDeprecated(inMemoryConnectorsList), + actionTypeId: inMemoryConnector.actionTypeId, + name: inMemoryConnector.name, + isPreconfigured: inMemoryConnector.isPreconfigured, + isSystemAction: inMemoryConnector.isSystemAction, + isDeprecated: isConnectorDeprecated(inMemoryConnector), }; } @@ -462,9 +486,9 @@ export class ActionsClient { id: inMemoryConnector.id, actionTypeId: inMemoryConnector.actionTypeId, name: inMemoryConnector.name, - isPreconfigured: true, + isPreconfigured: inMemoryConnector.isPreconfigured, isDeprecated: isConnectorDeprecated(inMemoryConnector), - isSystemAction: false, + isSystemAction: inMemoryConnector.isSystemAction, })), ].sort((a, b) => a.name.localeCompare(b.name)); return await injectExtraFindData(this.kibanaIndices, this.scopedClusterClient, mergedResult); @@ -490,10 +514,12 @@ export class ActionsClient { } const actionResults = new Array(); + for (const actionId of ids) { const action = this.inMemoryConnectors.find( (inMemoryConnector) => inMemoryConnector.id === actionId ); + if (action !== undefined) { actionResults.push(action); } @@ -531,6 +557,7 @@ export class ActionsClient { } actionResults.push(actionFromSavedObject(action, isConnectorDeprecated(action.attributes))); } + return actionResults; } @@ -632,10 +659,20 @@ export class ActionsClient { try { await this.authorization.ensureAuthorized('delete'); - if ( - this.inMemoryConnectors.find((inMemoryConnector) => inMemoryConnector.id === id) !== - undefined - ) { + const inMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); + + if (inMemoryConnector?.isSystemAction) { + throw Boom.badRequest( + i18n.translate('xpack.actions.serverSideErrors.systemActionCreationForbidden', { + defaultMessage: 'System action {id} is not allowed to delete.', + values: { + id, + }, + }) + ); + } + + if (inMemoryConnector?.isPreconfigured) { throw new PreconfiguredActionDisabledModificationError( i18n.translate('xpack.actions.serverSideErrors.predefinedActionDeleteDisabled', { defaultMessage: 'Preconfigured action {id} is not allowed to delete.', @@ -765,7 +802,15 @@ export class ActionsClient { } public isPreconfigured(connectorId: string): boolean { - return !!this.inMemoryConnectors.find((preconfigured) => preconfigured.id === connectorId); + return !!this.inMemoryConnectors.find( + (connector) => connector.isPreconfigured && connector.id === connectorId + ); + } + + public isSystemAction(connectorId: string): boolean { + return !!this.inMemoryConnectors.find( + (connector) => connector.isSystemAction && connector.id === connectorId + ); } public async getGlobalExecutionLogWithAuth({ diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index 44418835a16098..88821032227055 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -448,8 +448,7 @@ describe('Actions Plugin', () => { }); }); - // TODO: Unskip when registering system actions is allowed - describe.skip('System actions', () => { + describe('System actions', () => { it('should handle system actions', async () => { setup(getConfig()); // coreMock.createSetup doesn't support Plugin generics diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/state/settings/api.ts b/x-pack/plugins/synthetics/public/apps/synthetics/state/settings/api.ts index b7ae7884b178af..da8855f531ef9d 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/state/settings/api.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/state/settings/api.ts @@ -85,6 +85,7 @@ export const fetchActionTypes = async (): Promise => { enabled_in_license: enabledInLicense, minimum_license_required: minimumLicenseRequired, supported_feature_ids: supportedFeatureIds, + is_system_action_type: isSystemActionType, ...res }: AsApiContract) => ({ ...res, @@ -92,6 +93,7 @@ export const fetchActionTypes = async (): Promise => { enabledInLicense, minimumLicenseRequired, supportedFeatureIds, + isSystemActionType, }) ); }; From 8c1246c775d29f74bf5157fd6ead0ff0d0ce3591 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 30 Jun 2023 14:19:43 +0300 Subject: [PATCH 15/28] Fix types --- x-pack/plugins/actions/server/action_type_registry.mock.ts | 1 + x-pack/plugins/actions/server/actions_client.mock.ts | 1 + .../plugins/actions/server/routes/connector_types.test.ts | 6 ++++++ x-pack/plugins/actions/server/routes/connector_types.ts | 2 ++ .../actions/server/routes/legacy/list_action_types.test.ts | 4 ++++ 5 files changed, 14 insertions(+) diff --git a/x-pack/plugins/actions/server/action_type_registry.mock.ts b/x-pack/plugins/actions/server/action_type_registry.mock.ts index 922fc39ada8a26..532b192001e7a8 100644 --- a/x-pack/plugins/actions/server/action_type_registry.mock.ts +++ b/x-pack/plugins/actions/server/action_type_registry.mock.ts @@ -17,6 +17,7 @@ const createActionTypeRegistryMock = () => { ensureActionTypeEnabled: jest.fn(), isActionTypeEnabled: jest.fn(), isActionExecutable: jest.fn(), + isSystemActionType: jest.fn(), getUtils: jest.fn(), }; return mocked; diff --git a/x-pack/plugins/actions/server/actions_client.mock.ts b/x-pack/plugins/actions/server/actions_client.mock.ts index b80914c309b253..3fb08e50087939 100644 --- a/x-pack/plugins/actions/server/actions_client.mock.ts +++ b/x-pack/plugins/actions/server/actions_client.mock.ts @@ -27,6 +27,7 @@ const createActionsClientMock = () => { listTypes: jest.fn(), isActionTypeEnabled: jest.fn(), isPreconfigured: jest.fn(), + isSystemAction: jest.fn(), getGlobalExecutionKpiWithAuth: jest.fn(), getGlobalExecutionLogWithAuth: jest.fn(), }; diff --git a/x-pack/plugins/actions/server/routes/connector_types.test.ts b/x-pack/plugins/actions/server/routes/connector_types.test.ts index 8a4639cf3f4a2a..4b1ce8189c2a16 100644 --- a/x-pack/plugins/actions/server/routes/connector_types.test.ts +++ b/x-pack/plugins/actions/server/routes/connector_types.test.ts @@ -42,6 +42,7 @@ describe('connectorTypesRoute', () => { enabledInLicense: true, minimumLicenseRequired: 'gold' as LicenseType, supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]; @@ -57,6 +58,7 @@ describe('connectorTypesRoute', () => { "enabled_in_config": true, "enabled_in_license": true, "id": "1", + "is_system_action_type": false, "minimum_license_required": "gold", "name": "name", "supported_feature_ids": Array [ @@ -101,6 +103,7 @@ describe('connectorTypesRoute', () => { enabledInLicense: true, supportedFeatureIds: ['alerting'], minimumLicenseRequired: 'gold' as LicenseType, + isSystemActionType: false, }, ]; @@ -124,6 +127,7 @@ describe('connectorTypesRoute', () => { "enabled_in_config": true, "enabled_in_license": true, "id": "1", + "is_system_action_type": false, "minimum_license_required": "gold", "name": "name", "supported_feature_ids": Array [ @@ -175,6 +179,7 @@ describe('connectorTypesRoute', () => { enabledInLicense: true, supportedFeatureIds: ['alerting'], minimumLicenseRequired: 'gold' as LicenseType, + isSystemActionType: false, }, ]; @@ -217,6 +222,7 @@ describe('connectorTypesRoute', () => { enabledInLicense: true, supportedFeatureIds: ['alerting'], minimumLicenseRequired: 'gold' as LicenseType, + isSystemActionType: false, }, ]; diff --git a/x-pack/plugins/actions/server/routes/connector_types.ts b/x-pack/plugins/actions/server/routes/connector_types.ts index 6d014a4eba61c0..39c24b6c178c8e 100644 --- a/x-pack/plugins/actions/server/routes/connector_types.ts +++ b/x-pack/plugins/actions/server/routes/connector_types.ts @@ -23,6 +23,7 @@ const rewriteBodyRes: RewriteResponseCase = (results) => { enabledInLicense, minimumLicenseRequired, supportedFeatureIds, + isSystemActionType, ...res }) => ({ ...res, @@ -30,6 +31,7 @@ const rewriteBodyRes: RewriteResponseCase = (results) => { enabled_in_license: enabledInLicense, minimum_license_required: minimumLicenseRequired, supported_feature_ids: supportedFeatureIds, + is_system_action_type: isSystemActionType, }) ); }; diff --git a/x-pack/plugins/actions/server/routes/legacy/list_action_types.test.ts b/x-pack/plugins/actions/server/routes/legacy/list_action_types.test.ts index 045ad01719e934..4674bbb9936a69 100644 --- a/x-pack/plugins/actions/server/routes/legacy/list_action_types.test.ts +++ b/x-pack/plugins/actions/server/routes/legacy/list_action_types.test.ts @@ -50,6 +50,7 @@ describe('listActionTypesRoute', () => { enabledInLicense: true, minimumLicenseRequired: 'gold' as LicenseType, supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]; @@ -65,6 +66,7 @@ describe('listActionTypesRoute', () => { "enabledInConfig": true, "enabledInLicense": true, "id": "1", + "isSystemActionType": false, "minimumLicenseRequired": "gold", "name": "name", "supportedFeatureIds": Array [ @@ -99,6 +101,7 @@ describe('listActionTypesRoute', () => { enabledInLicense: true, minimumLicenseRequired: 'gold' as LicenseType, supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]; @@ -141,6 +144,7 @@ describe('listActionTypesRoute', () => { enabledInLicense: true, minimumLicenseRequired: 'gold' as LicenseType, supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]; From 52ef0e5103282fda1ad32927fb4df8f62f60996f Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 30 Jun 2023 21:13:14 +0300 Subject: [PATCH 16/28] Fix types --- .../impl/connectorland/connector_selector/index.tsx | 1 + .../impl/connectorland/connector_setup/index.tsx | 1 + x-pack/plugins/actions/server/actions_client.test.ts | 4 ---- x-pack/plugins/cases/public/common/mock/connectors.ts | 6 ++++++ x-pack/plugins/cases/server/client/configure/client.test.ts | 4 ++++ 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_selector/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_selector/index.tsx index c9c514a4f4254a..010b4be5ad4b0f 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_selector/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_selector/index.tsx @@ -50,6 +50,7 @@ export const ConnectorSelector: React.FC = React.memo( enabledInLicense: true, minimumLicenseRequired: 'platinum', supportedFeatureIds: ['general'], + isSystemActionType: false, id: '.gen-ai', name: 'Generative AI', enabled: true, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_setup/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_setup/index.tsx index 66c58e2b9ac61f..c430355051ce0f 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_setup/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_setup/index.tsx @@ -92,6 +92,7 @@ export const useConnectorSetup = ({ actionTypes?.find((at) => at.id === GEN_AI_CONNECTOR_ID) ?? { enabledInConfig: true, enabledInLicense: true, + isSystemActionType: false, minimumLicenseRequired: 'platinum', supportedFeatureIds: ['general'], id: '.gen-ai', diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index f69152a9549739..7083d089731498 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -1315,7 +1315,6 @@ describe('getAll()', () => { isPreconfigured: false, isSystemAction: false, isDeprecated: false, - isSystemAction: true, referencedByCount: 2, }, { @@ -1335,7 +1334,6 @@ describe('getAll()', () => { isPreconfigured: true, isSystemAction: false, isDeprecated: false, - isSystemAction: false, referencedByCount: 2, }, ]); @@ -1566,7 +1564,6 @@ describe('getBulk()', () => { isPreconfigured: true, isSystemAction: false, isDeprecated: false, - isSystemAction: false, name: 'test', config: { foo: 'bar' }, }, @@ -1590,7 +1587,6 @@ describe('getBulk()', () => { isPreconfigured: false, isSystemAction: false, isDeprecated: false, - isSystemAction: false, }, ]); }); diff --git a/x-pack/plugins/cases/public/common/mock/connectors.ts b/x-pack/plugins/cases/public/common/mock/connectors.ts index 3485af438a4d9f..f1ba88deedd14e 100644 --- a/x-pack/plugins/cases/public/common/mock/connectors.ts +++ b/x-pack/plugins/cases/public/common/mock/connectors.ts @@ -79,6 +79,7 @@ export const actionTypesMock: ActionTypeConnector[] = [ enabledInConfig: true, enabledInLicense: true, supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, { id: '.index', @@ -88,6 +89,7 @@ export const actionTypesMock: ActionTypeConnector[] = [ enabledInConfig: true, enabledInLicense: true, supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, { id: '.servicenow', @@ -97,6 +99,7 @@ export const actionTypesMock: ActionTypeConnector[] = [ enabledInConfig: true, enabledInLicense: true, supportedFeatureIds: ['alerting', 'cases'], + isSystemActionType: false, }, { id: '.jira', @@ -106,6 +109,7 @@ export const actionTypesMock: ActionTypeConnector[] = [ enabledInConfig: true, enabledInLicense: true, supportedFeatureIds: ['alerting', 'cases'], + isSystemActionType: false, }, { id: '.resilient', @@ -115,6 +119,7 @@ export const actionTypesMock: ActionTypeConnector[] = [ enabledInConfig: true, enabledInLicense: true, supportedFeatureIds: ['alerting', 'cases'], + isSystemActionType: false, }, { id: '.servicenow-sir', @@ -124,6 +129,7 @@ export const actionTypesMock: ActionTypeConnector[] = [ enabledInConfig: true, enabledInLicense: true, supportedFeatureIds: ['alerting', 'cases'], + isSystemActionType: false, }, ]; diff --git a/x-pack/plugins/cases/server/client/configure/client.test.ts b/x-pack/plugins/cases/server/client/configure/client.test.ts index 43e19a799b5e66..f87cfa40c4765c 100644 --- a/x-pack/plugins/cases/server/client/configure/client.test.ts +++ b/x-pack/plugins/cases/server/client/configure/client.test.ts @@ -34,6 +34,7 @@ describe('client', () => { enabledInLicense: true, minimumLicenseRequired: 'basic' as const, supportedFeatureIds: ['alerting', 'cases'], + isSystemActionType: false, }, { id: '.servicenow', @@ -43,6 +44,7 @@ describe('client', () => { enabledInLicense: true, minimumLicenseRequired: 'basic' as const, supportedFeatureIds: ['alerting', 'cases'], + isSystemActionType: false, }, { id: '.unsupported', @@ -52,6 +54,7 @@ describe('client', () => { enabledInLicense: true, minimumLicenseRequired: 'basic' as const, supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, { id: '.swimlane', @@ -61,6 +64,7 @@ describe('client', () => { enabledInLicense: false, minimumLicenseRequired: 'basic' as const, supportedFeatureIds: ['alerting', 'cases'], + isSystemActionType: false, }, ]; From d7631611b4b4aac0090e785b2f5ca4eca1654374 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sat, 1 Jul 2023 13:16:38 +0300 Subject: [PATCH 17/28] Remove cases from basic --- .../actions/server/lib/ensure_sufficient_license.test.ts | 3 --- .../actions/server/lib/ensure_sufficient_license.ts | 7 +------ 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/x-pack/plugins/actions/server/lib/ensure_sufficient_license.test.ts b/x-pack/plugins/actions/server/lib/ensure_sufficient_license.test.ts index 06e5380c04f97c..5cd2fec223ffc4 100644 --- a/x-pack/plugins/actions/server/lib/ensure_sufficient_license.test.ts +++ b/x-pack/plugins/actions/server/lib/ensure_sufficient_license.test.ts @@ -32,9 +32,6 @@ describe('ensureSufficientLicense()', () => { }); it('allows licenses below gold for allowed connectors', () => { - expect(() => - ensureSufficientLicense({ ...sampleActionType, id: '.case', minimumLicenseRequired: 'basic' }) - ).not.toThrow(); expect(() => ensureSufficientLicense({ ...sampleActionType, diff --git a/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts b/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts index 9c28621034c616..5d1988cdd8fa01 100644 --- a/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts +++ b/x-pack/plugins/actions/server/lib/ensure_sufficient_license.ts @@ -9,15 +9,10 @@ import { LICENSE_TYPE } from '@kbn/licensing-plugin/common/types'; import { ActionType } from '../types'; import { ActionTypeConfig, ActionTypeSecrets, ActionTypeParams } from '../types'; -const CASE_ACTION_TYPE_ID = '.cases'; const ServerLogActionTypeId = '.server-log'; const IndexActionTypeId = '.index'; -const ACTIONS_SCOPED_WITHIN_STACK = new Set([ - ServerLogActionTypeId, - IndexActionTypeId, - CASE_ACTION_TYPE_ID, -]); +const ACTIONS_SCOPED_WITHIN_STACK = new Set([ServerLogActionTypeId, IndexActionTypeId]); export function ensureSufficientLicense< Config extends ActionTypeConfig, From 5c3245e9753868c8eef892c125d5796d7cdd8205 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sat, 1 Jul 2023 13:21:57 +0300 Subject: [PATCH 18/28] Convert preconfigured to in-memory --- .../server/action_type_registry.test.ts | 34 +- .../actions/server/action_type_registry.ts | 14 +- .../actions/server/actions_client.test.ts | 243 ++++-- .../plugins/actions/server/actions_client.ts | 52 +- .../server/create_execute_function.test.ts | 446 +++++++++++ .../actions/server/create_execute_function.ts | 27 +- .../server/create_system_actions.test.ts | 2 +- .../actions/server/create_system_actions.ts | 2 +- .../create_unsecured_execute_function.test.ts | 724 +++++++++--------- .../create_unsecured_execute_function.ts | 2 +- .../server/lib/action_executor.test.ts | 331 ++++++++ .../actions/server/lib/action_executor.ts | 23 +- .../lib/action_task_params_utils.test.ts | 4 +- .../server/lib/action_task_params_utils.ts | 6 +- ...ate_action_event_log_record_object.test.ts | 4 +- .../create_action_event_log_record_object.ts | 6 +- x-pack/plugins/actions/server/plugin.test.ts | 4 +- x-pack/plugins/actions/server/plugin.ts | 3 +- .../server/routes/connector_types.test.ts | 2 + .../action_task_params_migrations.test.ts | 25 +- .../action_task_params_migrations.ts | 4 +- .../task_runner/execution_handler.test.ts | 2 +- 22 files changed, 1457 insertions(+), 503 deletions(-) diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index d1c6989e39f17a..60b1cf75bc79f0 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -47,6 +47,16 @@ describe('actionTypeRegistry', () => { isDeprecated: false, isSystemAction: false, }, + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, ], }; }); @@ -360,7 +370,7 @@ describe('actionTypeRegistry', () => { actionTypeRegistry.register({ id: '.cases', name: 'Cases', - minimumLicenseRequired: 'basic', + minimumLicenseRequired: 'platinum', supportedFeatureIds: ['alerting'], validate: { config: { schema: schema.object({}) }, @@ -380,7 +390,7 @@ describe('actionTypeRegistry', () => { enabled: true, enabledInConfig: true, enabledInLicense: true, - minimumLicenseRequired: 'basic', + minimumLicenseRequired: 'platinum', supportedFeatureIds: ['alerting'], isSystemActionType: true, }, @@ -414,6 +424,7 @@ describe('actionTypeRegistry', () => { describe('isActionTypeEnabled', () => { let actionTypeRegistry: ActionTypeRegistry; + const fooActionType: ActionType = { id: 'foo', name: 'Foo', @@ -429,9 +440,17 @@ describe('actionTypeRegistry', () => { }, }; + const systemActionType: ActionType = { + ...fooActionType, + id: 'system-action-type', + name: 'System action type', + isSystemActionType: true, + }; + beforeEach(() => { actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams); actionTypeRegistry.register(fooActionType); + actionTypeRegistry.register(systemActionType); }); test('should call isActionTypeEnabled of the actions config', async () => { @@ -453,6 +472,15 @@ describe('actionTypeRegistry', () => { expect(actionTypeRegistry.isActionExecutable('my-slack1', 'foo')).toEqual(true); }); + test('should return true when isActionTypeEnabled is false and isLicenseValidForActionType is true and it has system connectors', async () => { + mockedActionsConfig.isActionTypeEnabled.mockReturnValue(false); + mockedLicenseState.isLicenseValidForActionType.mockReturnValue({ isValid: true }); + + expect(actionTypeRegistry.isActionExecutable('my-slack1', 'system-action-type')).toEqual( + true + ); + }); + test('should call isLicenseValidForActionType of the license state with notifyUsage false by default', async () => { mockedLicenseState.isLicenseValidForActionType.mockReturnValue({ isValid: true }); actionTypeRegistry.isActionTypeEnabled('foo'); @@ -611,7 +639,7 @@ describe('actionTypeRegistry', () => { registry.register({ id: '.cases', name: 'Cases', - minimumLicenseRequired: 'basic', + minimumLicenseRequired: 'platinum', supportedFeatureIds: ['alerting'], validate: { config: { schema: schema.object({}) }, diff --git a/x-pack/plugins/actions/server/action_type_registry.ts b/x-pack/plugins/actions/server/action_type_registry.ts index 31edcf4c224195..1b133af7584b68 100644 --- a/x-pack/plugins/actions/server/action_type_registry.ts +++ b/x-pack/plugins/actions/server/action_type_registry.ts @@ -78,7 +78,7 @@ export class ActionTypeRegistry { } /** - * Returns true if action type is enabled or it is a preconfigured action type. + * Returns true if action type is enabled or it is an in memory action type. */ public isActionExecutable( actionId: string, @@ -109,18 +109,6 @@ export class ActionTypeRegistry { Params extends ActionTypeParams = ActionTypeParams, ExecutorResultData = void >(actionType: ActionType) { - // TODO: Remove when system action are supported - if (actionType.isSystemAction) { - throw new Error( - i18n.translate( - 'xpack.actions.actionTypeRegistry.register.systemActionsNotSupportedErrorMessage', - { - defaultMessage: 'System actions are not supported', - } - ) - ); - } - if (this.has(actionType.id)) { throw new Error( i18n.translate( diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 7083d089731498..465e3f7ff4f857 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -763,7 +763,7 @@ describe('create()', () => { actionTypeRegistry.register({ id: '.cases', name: 'Cases', - minimumLicenseRequired: 'basic', + minimumLicenseRequired: 'platinum', supportedFeatureIds: ['alerting'], validate: { config: { schema: schema.object({}) }, @@ -787,6 +787,47 @@ describe('create()', () => { `"System action creation is forbidden. Action type: .cases."` ); }); + + it('throws when creating a system connector where the action type is not registered by a system connector exists in the in-memory list', async () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + connectorTokenClient: connectorTokenClientMock.create(), + getEventLogClient, + }); + + await expect( + actionsClient.create({ + action: { + name: 'my name', + actionTypeId: '.cases', + config: {}, + secrets: {}, + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Action type \\".cases\\" is not registered."`); + }); }); describe('get()', () => { @@ -847,6 +888,40 @@ describe('get()', () => { expect(authorization.ensureAuthorized).toHaveBeenCalledWith('get'); }); + test('ensures user is authorised to get a system action', async () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + connectorTokenClient: connectorTokenClientMock.create(), + getEventLogClient, + }); + + await actionsClient.get({ id: 'system-connector-.cases' }); + + expect(authorization.ensureAuthorized).toHaveBeenCalledWith('get'); + }); + test('throws when user is not authorised to get the type of action', async () => { unsecuredSavedObjectsClient.get.mockResolvedValueOnce({ id: '1', @@ -914,6 +989,48 @@ describe('get()', () => { expect(authorization.ensureAuthorized).toHaveBeenCalledWith('get'); }); + + test('throws when user is not authorised to get a system action', async () => { + actionsClient = new ActionsClient({ + logger, + actionTypeRegistry, + unsecuredSavedObjectsClient, + scopedClusterClient, + kibanaIndices, + actionExecutor, + executionEnqueuer, + ephemeralExecutionEnqueuer, + bulkExecutionEnqueuer, + request, + authorization: authorization as unknown as ActionsAuthorization, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + connectorTokenClient: connectorTokenClientMock.create(), + getEventLogClient, + }); + + authorization.ensureAuthorized.mockRejectedValue( + new Error(`Unauthorized to get a "system-connector-.cases" action`) + ); + + await expect( + actionsClient.get({ id: 'system-connector-.cases' }) + ).rejects.toMatchInlineSnapshot( + `[Error: Unauthorized to get a "system-connector-.cases" action]` + ); + + expect(authorization.ensureAuthorized).toHaveBeenCalledWith('get'); + }); }); describe('auditLogger', () => { @@ -1058,7 +1175,7 @@ describe('get()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, @@ -1079,7 +1196,7 @@ describe('get()', () => { isPreconfigured: false, isDeprecated: false, isSystemAction: true, - name: 'system-connector-.cases', + name: 'System action: .cases', }); expect(unsecuredSavedObjectsClient.get).not.toHaveBeenCalled(); @@ -1292,7 +1409,7 @@ describe('getAll()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, @@ -1311,9 +1428,9 @@ describe('getAll()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', isPreconfigured: false, - isSystemAction: false, + isSystemAction: true, isDeprecated: false, referencedByCount: 2, }, @@ -1537,7 +1654,7 @@ describe('getBulk()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, @@ -1570,7 +1687,7 @@ describe('getBulk()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, @@ -1962,7 +2079,7 @@ describe('delete()', () => { `); }); - it('throws when trying to delete a system connector', async () => { + it('throws when trying to delete a preconfigured connector', async () => { actionsClient = new ActionsClient({ logger, actionTypeRegistry, @@ -1971,15 +2088,18 @@ describe('delete()', () => { kibanaIndices, inMemoryConnectors: [ { - id: 'system-connector-.cases', - actionTypeId: '.cases', - name: 'system-connector-.cases', - config: {}, - secrets: {}, + id: 'testPreconfigured', + actionTypeId: 'my-action-type', + secrets: { + test: 'test1', + }, + isPreconfigured: true, isDeprecated: false, - isMissingSecrets: false, - isPreconfigured: false, - isSystemAction: true, + isSystemAction: false, + name: 'test', + config: { + foo: 'bar', + }, }, ], actionExecutor, @@ -1993,13 +2113,13 @@ describe('delete()', () => { }); await expect( - actionsClient.delete({ id: 'system-connector-.cases' }) + actionsClient.delete({ id: 'testPreconfigured' }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"System action system-connector-.cases is not allowed to delete."` + `"Preconfigured action testPreconfigured is not allowed to delete."` ); }); - it('throws when trying to delete a preconfigured connector', async () => { + it('throws when trying to delete a system connector', async () => { actionsClient = new ActionsClient({ logger, actionTypeRegistry, @@ -2008,18 +2128,15 @@ describe('delete()', () => { kibanaIndices, inMemoryConnectors: [ { - id: 'testPreconfigured', - actionTypeId: 'my-action-type', - secrets: { - test: 'test1', - }, - isPreconfigured: true, + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'System action: .cases', + config: {}, + secrets: {}, isDeprecated: false, - isSystemAction: false, - name: 'test', - config: { - foo: 'bar', - }, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, }, ], actionExecutor, @@ -2033,9 +2150,9 @@ describe('delete()', () => { }); await expect( - actionsClient.delete({ id: 'testPreconfigured' }) + actionsClient.delete({ id: 'system-connector-.cases' }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Preconfigured action testPreconfigured is not allowed to delete."` + `"System action system-connector-.cases is not allowed to delete."` ); }); }); @@ -2515,7 +2632,7 @@ describe('update()', () => { ).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`); }); - it('throws when trying to update a system connector', async () => { + it('throws when trying to update a preconfigured connector', async () => { actionsClient = new ActionsClient({ logger, actionTypeRegistry, @@ -2524,15 +2641,18 @@ describe('update()', () => { kibanaIndices, inMemoryConnectors: [ { - id: 'system-connector-.cases', - actionTypeId: '.cases', - name: 'system-connector-.cases', - config: {}, - secrets: {}, + id: 'testPreconfigured', + actionTypeId: 'my-action-type', + secrets: { + test: 'test1', + }, + isPreconfigured: true, isDeprecated: false, - isMissingSecrets: false, - isPreconfigured: false, - isSystemAction: true, + isSystemAction: false, + name: 'test', + config: { + foo: 'bar', + }, }, ], actionExecutor, @@ -2547,7 +2667,7 @@ describe('update()', () => { await expect( actionsClient.update({ - id: 'system-connector-.cases', + id: 'testPreconfigured', action: { name: 'my name', config: {}, @@ -2555,11 +2675,11 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"System action system-connector-.cases is not allowed to update."` + `"Preconfigured action testPreconfigured is not allowed to update."` ); }); - it('throws when trying to update a preconfigured connector', async () => { + it('throws when trying to update a system connector', async () => { actionsClient = new ActionsClient({ logger, actionTypeRegistry, @@ -2568,18 +2688,15 @@ describe('update()', () => { kibanaIndices, inMemoryConnectors: [ { - id: 'testPreconfigured', - actionTypeId: 'my-action-type', - secrets: { - test: 'test1', - }, - isPreconfigured: true, + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'System action: .cases', + config: {}, + secrets: {}, isDeprecated: false, - isSystemAction: false, - name: 'test', - config: { - foo: 'bar', - }, + isMissingSecrets: false, + isPreconfigured: false, + isSystemAction: true, }, ], actionExecutor, @@ -2594,7 +2711,7 @@ describe('update()', () => { await expect( actionsClient.update({ - id: 'testPreconfigured', + id: 'system-connector-.cases', action: { name: 'my name', config: {}, @@ -2602,7 +2719,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Preconfigured action testPreconfigured is not allowed to update."` + `"System action system-connector-.cases is not allowed to update."` ); }); }); @@ -3019,7 +3136,7 @@ describe('isPreconfigured()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, @@ -3070,7 +3187,7 @@ describe('isPreconfigured()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, @@ -3123,7 +3240,7 @@ describe('isSystemAction()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, @@ -3143,7 +3260,7 @@ describe('isSystemAction()', () => { expect(actionsClient.isSystemAction('system-connector-.cases')).toEqual(true); }); - test('should return false if connector id is not in list of preconfigured connectors', () => { + test('should return false if connector id is not a system action', () => { actionsClient = new ActionsClient({ logger, actionTypeRegistry, @@ -3174,7 +3291,7 @@ describe('isSystemAction()', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index fe54f29b2efde5..9bad5235fc6ab2 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -194,7 +194,13 @@ export class ActionsClient { action: { actionTypeId, name, config, secrets }, options, }: CreateOptions): Promise { - if (this.actionTypeRegistry.isSystemActionType(actionTypeId)) { + const id = options?.id || SavedObjectsUtils.generateId(); + const foundInMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); + + if ( + this.actionTypeRegistry.isSystemActionType(actionTypeId) || + foundInMemoryConnector?.isSystemAction + ) { throw Boom.badRequest( i18n.translate('xpack.actions.serverSideErrors.systemActionCreationForbidden', { defaultMessage: 'System action creation is forbidden. Action type: {actionTypeId}.', @@ -205,13 +211,7 @@ export class ActionsClient { ); } - const id = options?.id || SavedObjectsUtils.generateId(); - - if ( - this.inMemoryConnectors.some( - (inMemoryConnector) => inMemoryConnector.isPreconfigured && inMemoryConnector.id === id - ) - ) { + if (foundInMemoryConnector?.isPreconfigured) { throw Boom.badRequest( i18n.translate('xpack.actions.serverSideErrors.predefinedIdConnectorAlreadyExists', { defaultMessage: 'This {id} already exist in preconfigured action.', @@ -287,9 +287,11 @@ export class ActionsClient { try { await this.authorization.ensureAuthorized('update'); - const inMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); + const foundInMemoryConnector = this.inMemoryConnectors.find( + (connector) => connector.id === id + ); - if (inMemoryConnector?.isSystemAction) { + if (foundInMemoryConnector?.isSystemAction) { throw Boom.badRequest( i18n.translate('xpack.actions.serverSideErrors.systemActionCreationForbidden', { defaultMessage: 'System action {id} is not allowed to update.', @@ -300,7 +302,7 @@ export class ActionsClient { ); } - if (inMemoryConnector?.isPreconfigured) { + if (foundInMemoryConnector?.isPreconfigured) { throw new PreconfiguredActionDisabledModificationError( i18n.translate('xpack.actions.serverSideErrors.predefinedActionUpdateDisabled', { defaultMessage: 'Preconfigured action {id} is not allowed to update.', @@ -405,9 +407,9 @@ export class ActionsClient { throw error; } - const inMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); + const foundInMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); - if (inMemoryConnector !== undefined) { + if (foundInMemoryConnector !== undefined) { this.auditLogger?.log( connectorAuditEvent({ action: ConnectorAuditAction.GET, @@ -417,11 +419,11 @@ export class ActionsClient { return { id, - actionTypeId: inMemoryConnector.actionTypeId, - name: inMemoryConnector.name, - isPreconfigured: inMemoryConnector.isPreconfigured, - isSystemAction: inMemoryConnector.isSystemAction, - isDeprecated: isConnectorDeprecated(inMemoryConnector), + actionTypeId: foundInMemoryConnector.actionTypeId, + name: foundInMemoryConnector.name, + isPreconfigured: foundInMemoryConnector.isPreconfigured, + isSystemAction: foundInMemoryConnector.isSystemAction, + isDeprecated: isConnectorDeprecated(foundInMemoryConnector), }; } @@ -447,7 +449,7 @@ export class ActionsClient { } /** - * Get all actions with preconfigured list + * Get all actions with in-memory connectors */ public async getAll(): Promise { try { @@ -495,7 +497,7 @@ export class ActionsClient { } /** - * Get bulk actions with preconfigured list + * Get bulk actions with in-memory list */ public async getBulk(ids: string[]): Promise { try { @@ -526,7 +528,7 @@ export class ActionsClient { } // Fetch action objects in bulk - // Excluding preconfigured actions to avoid an not found error, which is already added + // Excluding in-memory actions to avoid an not found error, which is already added const actionSavedObjectsIds = [ ...new Set( ids.filter( @@ -659,9 +661,11 @@ export class ActionsClient { try { await this.authorization.ensureAuthorized('delete'); - const inMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); + const foundInMemoryConnector = this.inMemoryConnectors.find( + (connector) => connector.id === id + ); - if (inMemoryConnector?.isSystemAction) { + if (foundInMemoryConnector?.isSystemAction) { throw Boom.badRequest( i18n.translate('xpack.actions.serverSideErrors.systemActionCreationForbidden', { defaultMessage: 'System action {id} is not allowed to delete.', @@ -672,7 +676,7 @@ export class ActionsClient { ); } - if (inMemoryConnector?.isPreconfigured) { + if (foundInMemoryConnector?.isPreconfigured) { throw new PreconfiguredActionDisabledModificationError( i18n.translate('xpack.actions.serverSideErrors.predefinedActionDeleteDisabled', { defaultMessage: 'Preconfigured action {id} is not allowed to delete.', diff --git a/x-pack/plugins/actions/server/create_execute_function.test.ts b/x-pack/plugins/actions/server/create_execute_function.test.ts index 55aa1758a70b79..7fb737d2b53419 100644 --- a/x-pack/plugins/actions/server/create_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_execute_function.test.ts @@ -322,6 +322,89 @@ describe('execute()', () => { ); }); + test('schedules the action with all given parameters with a system action', async () => { + const executeFn = createExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + actionTypeRegistry: actionTypeRegistryMock.create(), + isESOCanEncrypt: true, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + }); + const source = { type: 'alert', id: uuidv4() }; + + savedObjectsClient.get.mockResolvedValueOnce({ + id: '123', + type: 'action', + attributes: { + actionTypeId: 'mock-action', + }, + references: [], + }); + + savedObjectsClient.create.mockResolvedValueOnce({ + id: '234', + type: 'action_task_params', + attributes: {}, + references: [], + }); + + await executeFn(savedObjectsClient, { + id: 'system-connector-.cases', + params: { baz: false }, + spaceId: 'default', + executionId: 'system-connector-.casesabc', + apiKey: Buffer.from('system-connector-.cases:abc').toString('base64'), + source: asSavedObjectExecutionSource(source), + }); + + expect(mockTaskManager.schedule).toHaveBeenCalledTimes(1); + expect(mockTaskManager.schedule.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "params": Object { + "actionTaskParamsId": "234", + "spaceId": "default", + }, + "scope": Array [ + "actions", + ], + "state": Object {}, + "taskType": "actions:.cases", + }, + ] + `); + expect(savedObjectsClient.get).not.toHaveBeenCalled(); + expect(savedObjectsClient.create).toHaveBeenCalledWith( + 'action_task_params', + { + actionId: 'system-connector-.cases', + params: { baz: false }, + executionId: 'system-connector-.casesabc', + source: 'SAVED_OBJECT', + apiKey: Buffer.from('system-connector-.cases:abc').toString('base64'), + }, + { + references: [ + { + id: source.id, + name: 'source', + type: source.type, + }, + ], + } + ); + }); + test('schedules the action with all given parameters with a preconfigured action and relatedSavedObjects', async () => { const executeFn = createExecutionEnqueuerFunction({ taskManager: mockTaskManager, @@ -423,6 +506,107 @@ describe('execute()', () => { ); }); + test('schedules the action with all given parameters with a system action and relatedSavedObjects', async () => { + const executeFn = createExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + actionTypeRegistry: actionTypeRegistryMock.create(), + isESOCanEncrypt: true, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + }); + const source = { type: 'alert', id: uuidv4() }; + + savedObjectsClient.get.mockResolvedValueOnce({ + id: '123', + type: 'action', + attributes: { + actionTypeId: 'mock-action', + }, + references: [], + }); + savedObjectsClient.create.mockResolvedValueOnce({ + id: '234', + type: 'action_task_params', + attributes: {}, + references: [], + }); + await executeFn(savedObjectsClient, { + id: 'system-connector-.cases', + params: { baz: false }, + spaceId: 'default', + apiKey: Buffer.from('system-connector-.cases:abc').toString('base64'), + source: asSavedObjectExecutionSource(source), + executionId: 'system-connector-.casesabc', + relatedSavedObjects: [ + { + id: 'some-id', + namespace: 'some-namespace', + type: 'some-type', + typeId: 'some-typeId', + }, + ], + }); + expect(mockTaskManager.schedule).toHaveBeenCalledTimes(1); + expect(mockTaskManager.schedule.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "params": Object { + "actionTaskParamsId": "234", + "spaceId": "default", + }, + "scope": Array [ + "actions", + ], + "state": Object {}, + "taskType": "actions:.cases", + }, + ] + `); + expect(savedObjectsClient.get).not.toHaveBeenCalled(); + expect(savedObjectsClient.create).toHaveBeenCalledWith( + 'action_task_params', + { + actionId: 'system-connector-.cases', + params: { baz: false }, + apiKey: Buffer.from('system-connector-.cases:abc').toString('base64'), + executionId: 'system-connector-.casesabc', + source: 'SAVED_OBJECT', + relatedSavedObjects: [ + { + id: 'related_some-type_0', + namespace: 'some-namespace', + type: 'some-type', + typeId: 'some-typeId', + }, + ], + }, + { + references: [ + { + id: source.id, + name: 'source', + type: source.type, + }, + { + id: 'some-id', + name: 'related_some-type_0', + type: 'some-type', + }, + ], + } + ); + }); + test('throws when passing isESOCanEncrypt with false as a value', async () => { const executeFn = createExecutionEnqueuerFunction({ taskManager: mockTaskManager, @@ -553,6 +737,53 @@ describe('execute()', () => { expect(mockedActionTypeRegistry.ensureActionTypeEnabled).not.toHaveBeenCalled(); }); + + test('should skip ensure action type if action type is system action and license is valid', async () => { + const mockedActionTypeRegistry = actionTypeRegistryMock.create(); + const executeFn = createExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + isESOCanEncrypt: true, + actionTypeRegistry: mockedActionTypeRegistry, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + }); + mockedActionTypeRegistry.isActionExecutable.mockImplementation(() => true); + savedObjectsClient.get.mockResolvedValueOnce({ + id: '123', + type: 'action', + attributes: { + actionTypeId: 'mock-action', + }, + references: [], + }); + savedObjectsClient.create.mockResolvedValueOnce({ + id: '234', + type: 'action_task_params', + attributes: {}, + references: [], + }); + + await executeFn(savedObjectsClient, { + id: 'system-connector-.case', + params: { baz: false }, + spaceId: 'default', + executionId: 'system-connector-.caseabc', + apiKey: null, + source: asHttpRequestExecutionSource(request), + }); + + expect(mockedActionTypeRegistry.ensureActionTypeEnabled).not.toHaveBeenCalled(); + }); }); describe('bulkExecute()', () => { @@ -917,6 +1148,103 @@ describe('bulkExecute()', () => { ); }); + test('schedules the action with all given parameters with a system action', async () => { + const executeFn = createBulkExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + actionTypeRegistry: actionTypeRegistryMock.create(), + isESOCanEncrypt: true, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + }); + const source = { type: 'alert', id: uuidv4() }; + + savedObjectsClient.bulkGet.mockResolvedValueOnce({ + saved_objects: [ + { + id: '123', + type: 'action', + attributes: { + actionTypeId: 'mock-action', + }, + references: [], + }, + ], + }); + savedObjectsClient.bulkCreate.mockResolvedValueOnce({ + saved_objects: [ + { + id: '234', + type: 'action_task_params', + attributes: { + actionId: 'system-connector-.cases', + }, + references: [], + }, + ], + }); + await executeFn(savedObjectsClient, [ + { + id: 'system-connector-.cases', + params: { baz: false }, + spaceId: 'default', + executionId: 'system-connector-.casesabc', + apiKey: Buffer.from('system-connector-.cases:abc').toString('base64'), + source: asSavedObjectExecutionSource(source), + }, + ]); + expect(mockTaskManager.bulkSchedule).toHaveBeenCalledTimes(1); + expect(mockTaskManager.bulkSchedule.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "params": Object { + "actionTaskParamsId": "234", + "spaceId": "default", + }, + "scope": Array [ + "actions", + ], + "state": Object {}, + "taskType": "actions:.cases", + }, + ], + ] + `); + expect(savedObjectsClient.get).not.toHaveBeenCalled(); + expect(savedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + { + type: 'action_task_params', + attributes: { + actionId: 'system-connector-.cases', + params: { baz: false }, + executionId: 'system-connector-.casesabc', + source: 'SAVED_OBJECT', + apiKey: Buffer.from('system-connector-.cases:abc').toString('base64'), + }, + references: [ + { + id: source.id, + name: 'source', + type: source.type, + }, + ], + }, + ], + { refresh: false } + ); + }); + test('schedules the action with all given parameters with a preconfigured action and relatedSavedObjects', async () => { const executeFn = createBulkExecutionEnqueuerFunction({ taskManager: mockTaskManager, @@ -1035,6 +1363,124 @@ describe('bulkExecute()', () => { ); }); + test('schedules the action with all given parameters with a system action and relatedSavedObjects', async () => { + const executeFn = createBulkExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + actionTypeRegistry: actionTypeRegistryMock.create(), + isESOCanEncrypt: true, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + }); + const source = { type: 'alert', id: uuidv4() }; + + savedObjectsClient.bulkGet.mockResolvedValueOnce({ + saved_objects: [ + { + id: '123', + type: 'action', + attributes: { + actionTypeId: 'mock-action', + }, + references: [], + }, + ], + }); + savedObjectsClient.bulkCreate.mockResolvedValueOnce({ + saved_objects: [ + { + id: '234', + type: 'action_task_params', + attributes: { + actionId: 'system-connector-.cases', + }, + references: [], + }, + ], + }); + await executeFn(savedObjectsClient, [ + { + id: 'system-connector-.cases', + params: { baz: false }, + spaceId: 'default', + apiKey: Buffer.from('system-connector-.cases:abc').toString('base64'), + source: asSavedObjectExecutionSource(source), + executionId: 'system-connector-.casesabc', + relatedSavedObjects: [ + { + id: 'some-id', + namespace: 'some-namespace', + type: 'some-type', + typeId: 'some-typeId', + }, + ], + }, + ]); + expect(mockTaskManager.bulkSchedule).toHaveBeenCalledTimes(1); + expect(mockTaskManager.bulkSchedule.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "params": Object { + "actionTaskParamsId": "234", + "spaceId": "default", + }, + "scope": Array [ + "actions", + ], + "state": Object {}, + "taskType": "actions:.cases", + }, + ], + ] + `); + expect(savedObjectsClient.get).not.toHaveBeenCalled(); + expect(savedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + { + type: 'action_task_params', + attributes: { + actionId: 'system-connector-.cases', + params: { baz: false }, + apiKey: Buffer.from('system-connector-.cases:abc').toString('base64'), + executionId: 'system-connector-.casesabc', + source: 'SAVED_OBJECT', + relatedSavedObjects: [ + { + id: 'related_some-type_0', + namespace: 'some-namespace', + type: 'some-type', + typeId: 'some-typeId', + }, + ], + }, + references: [ + { + id: source.id, + name: 'source', + type: source.type, + }, + { + id: 'some-id', + name: 'related_some-type_0', + type: 'some-type', + }, + ], + }, + ], + { refresh: false } + ); + }); + test('throws when passing isESOCanEncrypt with false as a value', async () => { const executeFn = createBulkExecutionEnqueuerFunction({ taskManager: mockTaskManager, diff --git a/x-pack/plugins/actions/server/create_execute_function.ts b/x-pack/plugins/actions/server/create_execute_function.ts index 5f4f4a72a7e648..c25db5d7281e78 100644 --- a/x-pack/plugins/actions/server/create_execute_function.ts +++ b/x-pack/plugins/actions/server/create_execute_function.ts @@ -40,7 +40,7 @@ interface ActionTaskParams export interface GetConnectorsResult { connector: InMemoryConnector | RawAction; - isPreconfigured: boolean; + isInMemory: boolean; id: string; } @@ -79,7 +79,7 @@ export function createExecutionEnqueuerFunction({ ); } - const { action, isPreconfigured } = await getAction( + const { action, isInMemory } = await getAction( unsecuredSavedObjectsClient, inMemoryConnectors, id @@ -94,7 +94,7 @@ export function createExecutionEnqueuerFunction({ // Get saved object references from action ID and relatedSavedObjects const { references, relatedSavedObjectWithRefs } = extractSavedObjectReferences( id, - isPreconfigured, + isInMemory, relatedSavedObjects ); const executionSourceReference = executionSourceAsSavedObjectReferences(source); @@ -153,15 +153,16 @@ export function createBulkExecutionEnqueuerFunction({ const actionTypeIds: Record = {}; const spaceIds: Record = {}; - const connectorIsPreconfigured: Record = {}; + const connectorIsInMemory: Record = {}; const connectorIds = [...new Set(actionsToExecute.map((action) => action.id))]; const connectors = await getConnectors( unsecuredSavedObjectsClient, inMemoryConnectors, connectorIds ); + connectors.forEach((c) => { - const { id, connector, isPreconfigured } = c; + const { id, connector, isInMemory } = c; validateCanActionBeUsed(connector); const { actionTypeId } = connector; @@ -170,16 +171,17 @@ export function createBulkExecutionEnqueuerFunction({ } actionTypeIds[id] = actionTypeId; - connectorIsPreconfigured[id] = isPreconfigured; + connectorIsInMemory[id] = isInMemory; }); const actions = actionsToExecute.map((actionToExecute) => { // Get saved object references from action ID and relatedSavedObjects const { references, relatedSavedObjectWithRefs } = extractSavedObjectReferences( actionToExecute.id, - connectorIsPreconfigured[actionToExecute.id], + connectorIsInMemory[actionToExecute.id], actionToExecute.relatedSavedObjects ); + const executionSourceReference = executionSourceAsSavedObjectReferences( actionToExecute.source ); @@ -292,14 +294,14 @@ async function getAction( unsecuredSavedObjectsClient: SavedObjectsClientContract, inMemoryConnectors: InMemoryConnector[], actionId: string -): Promise<{ action: InMemoryConnector | RawAction; isPreconfigured: boolean }> { +): Promise<{ action: InMemoryConnector | RawAction; isInMemory: boolean }> { const pcAction = inMemoryConnectors.find((action) => action.id === actionId); if (pcAction) { - return { action: pcAction, isPreconfigured: true }; + return { action: pcAction, isInMemory: true }; } const { attributes } = await unsecuredSavedObjectsClient.get('action', actionId); - return { action: attributes, isPreconfigured: false }; + return { action: attributes, isInMemory: false }; } async function getConnectors( @@ -312,8 +314,9 @@ async function getConnectors( const connectorIdsToFetch = []; for (const connectorId of connectorIds) { const pcConnector = inMemoryConnectors.find((connector) => connector.id === connectorId); + if (pcConnector) { - result.push({ connector: pcConnector, isPreconfigured: true, id: connectorId }); + result.push({ connector: pcConnector, isInMemory: true, id: connectorId }); } else { connectorIdsToFetch.push(connectorId); } @@ -330,7 +333,7 @@ async function getConnectors( for (const item of bulkGetResult.saved_objects) { if (item.error) throw item.error; result.push({ - isPreconfigured: false, + isInMemory: false, connector: item.attributes, id: item.id, }); diff --git a/x-pack/plugins/actions/server/create_system_actions.test.ts b/x-pack/plugins/actions/server/create_system_actions.test.ts index fd591f2c16429b..55b7d43bf5631f 100644 --- a/x-pack/plugins/actions/server/create_system_actions.test.ts +++ b/x-pack/plugins/actions/server/create_system_actions.test.ts @@ -36,7 +36,7 @@ describe('createSystemConnectors', () => { { id: 'system-connector-system-action-type-2', actionTypeId: 'system-action-type-2', - name: 'system-connector-system-action-type-2', + name: 'System action: system-action-type-2', secrets: {}, config: {}, isDeprecated: false, diff --git a/x-pack/plugins/actions/server/create_system_actions.ts b/x-pack/plugins/actions/server/create_system_actions.ts index 90a13104ff76dc..f6079ea9402223 100644 --- a/x-pack/plugins/actions/server/create_system_actions.ts +++ b/x-pack/plugins/actions/server/create_system_actions.ts @@ -14,7 +14,7 @@ export const createSystemConnectors = (actionTypes: ActionType[]): InMemoryConne const systemConnectors: InMemoryConnector[] = systemActionTypes.map((systemActionType) => ({ id: `system-connector-${systemActionType.id}`, actionTypeId: systemActionType.id, - name: `system-connector-${systemActionType.id}`, + name: `System action: ${systemActionType.id}`, isMissingSecrets: false, config: {}, secrets: {}, diff --git a/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts b/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts index 9eeb10e541f005..2bbfab40b7318d 100644 --- a/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_unsecured_execute_function.test.ts @@ -21,58 +21,63 @@ const internalSavedObjectsRepository = savedObjectsRepositoryMock.create(); beforeEach(() => jest.resetAllMocks()); describe('bulkExecute()', () => { - test('schedules the actions with all given parameters with a preconfigured connector', async () => { - const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ - taskManager: mockTaskManager, - connectorTypeRegistry: actionTypeRegistryMock.create(), - inMemoryConnectors: [ - { - id: '123', - actionTypeId: '.email', - config: {}, - isPreconfigured: true, - isDeprecated: false, - isSystemAction: false, - name: 'x', - secrets: {}, - }, - ], - }); + test.each([ + [true, false], + [false, true], + ])( + 'schedules the actions with all given parameters with an in-memory connector: isPreconfigured: %s, isSystemAction: %s', + async (isPreconfigured, isSystemAction) => { + const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + connectorTypeRegistry: actionTypeRegistryMock.create(), + inMemoryConnectors: [ + { + id: '123', + actionTypeId: '.email', + config: {}, + isPreconfigured, + isDeprecated: false, + isSystemAction, + name: 'x', + secrets: {}, + }, + ], + }); - internalSavedObjectsRepository.bulkCreate.mockResolvedValueOnce({ - saved_objects: [ - { - id: '234', - type: 'action_task_params', - attributes: { - actionId: '123', + internalSavedObjectsRepository.bulkCreate.mockResolvedValueOnce({ + saved_objects: [ + { + id: '234', + type: 'action_task_params', + attributes: { + actionId: '123', + }, + references: [], }, - references: [], + { + id: '345', + type: 'action_task_params', + attributes: { + actionId: '123', + }, + references: [], + }, + ], + }); + await executeFn(internalSavedObjectsRepository, [ + { + id: '123', + params: { baz: false }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), }, { - id: '345', - type: 'action_task_params', - attributes: { - actionId: '123', - }, - references: [], + id: '123', + params: { baz: true }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), }, - ], - }); - await executeFn(internalSavedObjectsRepository, [ - { - id: '123', - params: { baz: false }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - { - id: '123', - params: { baz: true }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - ]); - expect(mockTaskManager.bulkSchedule).toHaveBeenCalledTimes(1); - expect(mockTaskManager.bulkSchedule.mock.calls[0]).toMatchInlineSnapshot(` + ]); + expect(mockTaskManager.bulkSchedule).toHaveBeenCalledTimes(1); + expect(mockTaskManager.bulkSchedule.mock.calls[0]).toMatchInlineSnapshot(` Array [ Array [ Object { @@ -101,90 +106,96 @@ describe('bulkExecute()', () => { ] `); - expect(internalSavedObjectsRepository.bulkCreate).toHaveBeenCalledWith([ - { - type: 'action_task_params', - attributes: { - actionId: '123', - params: { baz: false }, - apiKey: null, - source: 'NOTIFICATION', - }, - references: [], - }, - { - type: 'action_task_params', - attributes: { - actionId: '123', - params: { baz: true }, - apiKey: null, - source: 'NOTIFICATION', - }, - references: [], - }, - ]); - }); - - test('schedules the actions with all given parameters with a preconfigured connector and source specified', async () => { - const sourceUuid = uuidv4(); - const source = { type: 'alert', id: sourceUuid }; - const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ - taskManager: mockTaskManager, - connectorTypeRegistry: actionTypeRegistryMock.create(), - inMemoryConnectors: [ - { - id: '123', - actionTypeId: '.email', - config: {}, - isPreconfigured: true, - isDeprecated: false, - isSystemAction: false, - name: 'x', - secrets: {}, - }, - ], - }); - - internalSavedObjectsRepository.bulkCreate.mockResolvedValueOnce({ - saved_objects: [ + expect(internalSavedObjectsRepository.bulkCreate).toHaveBeenCalledWith([ { - id: '234', type: 'action_task_params', attributes: { actionId: '123', + params: { baz: false }, + apiKey: null, + source: 'NOTIFICATION', }, - references: [ - { - id: sourceUuid, - name: 'source', - type: 'alert', - }, - ], + references: [], }, { - id: '345', type: 'action_task_params', attributes: { actionId: '123', + params: { baz: true }, + apiKey: null, + source: 'NOTIFICATION', }, references: [], }, - ], - }); - await executeFn(internalSavedObjectsRepository, [ - { - id: '123', - params: { baz: false }, - source: asSavedObjectExecutionSource(source), - }, - { - id: '123', - params: { baz: true }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - ]); - expect(mockTaskManager.bulkSchedule).toHaveBeenCalledTimes(1); - expect(mockTaskManager.bulkSchedule.mock.calls[0]).toMatchInlineSnapshot(` + ]); + } + ); + + test.each([ + [true, false], + [false, true], + ])( + 'schedules the actions with all given parameters with an in-memory connector and source specified: isPreconfigured: %s, isSystemAction: %s', + async (isPreconfigured, isSystemAction) => { + const sourceUuid = uuidv4(); + const source = { type: 'alert', id: sourceUuid }; + const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + connectorTypeRegistry: actionTypeRegistryMock.create(), + inMemoryConnectors: [ + { + id: '123', + actionTypeId: '.email', + config: {}, + isPreconfigured, + isDeprecated: false, + isSystemAction, + name: 'x', + secrets: {}, + }, + ], + }); + + internalSavedObjectsRepository.bulkCreate.mockResolvedValueOnce({ + saved_objects: [ + { + id: '234', + type: 'action_task_params', + attributes: { + actionId: '123', + }, + references: [ + { + id: sourceUuid, + name: 'source', + type: 'alert', + }, + ], + }, + { + id: '345', + type: 'action_task_params', + attributes: { + actionId: '123', + }, + references: [], + }, + ], + }); + await executeFn(internalSavedObjectsRepository, [ + { + id: '123', + params: { baz: false }, + source: asSavedObjectExecutionSource(source), + }, + { + id: '123', + params: { baz: true }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), + }, + ]); + expect(mockTaskManager.bulkSchedule).toHaveBeenCalledTimes(1); + expect(mockTaskManager.bulkSchedule.mock.calls[0]).toMatchInlineSnapshot(` Array [ Array [ Object { @@ -213,63 +224,14 @@ describe('bulkExecute()', () => { ] `); - expect(internalSavedObjectsRepository.bulkCreate).toHaveBeenCalledWith([ - { - type: 'action_task_params', - attributes: { - actionId: '123', - params: { baz: false }, - apiKey: null, - source: 'SAVED_OBJECT', - }, - references: [ - { - id: sourceUuid, - name: 'source', - type: 'alert', - }, - ], - }, - { - type: 'action_task_params', - attributes: { - actionId: '123', - params: { baz: true }, - apiKey: null, - source: 'NOTIFICATION', - }, - references: [], - }, - ]); - }); - - test('schedules the actions with all given parameters with a preconfigured connector and relatedSavedObjects specified', async () => { - const sourceUuid = uuidv4(); - const source = { type: 'alert', id: sourceUuid }; - const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ - taskManager: mockTaskManager, - connectorTypeRegistry: actionTypeRegistryMock.create(), - inMemoryConnectors: [ - { - id: '123', - actionTypeId: '.email', - config: {}, - isPreconfigured: true, - isDeprecated: false, - isSystemAction: false, - name: 'x', - secrets: {}, - }, - ], - }); - - internalSavedObjectsRepository.bulkCreate.mockResolvedValueOnce({ - saved_objects: [ + expect(internalSavedObjectsRepository.bulkCreate).toHaveBeenCalledWith([ { - id: '234', type: 'action_task_params', attributes: { actionId: '123', + params: { baz: false }, + apiKey: null, + source: 'SAVED_OBJECT', }, references: [ { @@ -280,42 +242,97 @@ describe('bulkExecute()', () => { ], }, { - id: '345', type: 'action_task_params', attributes: { actionId: '123', + params: { baz: true }, + apiKey: null, + source: 'NOTIFICATION', }, - references: [ + references: [], + }, + ]); + } + ); + + test.each([ + [true, false], + [false, true], + ])( + 'schedules the actions with all given parameters with an in-memory connector and relatedSavedObjects specified: isPreconfigured: %s, isSystemAction: %s', + async (isPreconfigured, isSystemAction) => { + const sourceUuid = uuidv4(); + const source = { type: 'alert', id: sourceUuid }; + const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + connectorTypeRegistry: actionTypeRegistryMock.create(), + inMemoryConnectors: [ + { + id: '123', + actionTypeId: '.email', + config: {}, + isPreconfigured, + isDeprecated: false, + isSystemAction, + name: 'x', + secrets: {}, + }, + ], + }); + + internalSavedObjectsRepository.bulkCreate.mockResolvedValueOnce({ + saved_objects: [ + { + id: '234', + type: 'action_task_params', + attributes: { + actionId: '123', + }, + references: [ + { + id: sourceUuid, + name: 'source', + type: 'alert', + }, + ], + }, + { + id: '345', + type: 'action_task_params', + attributes: { + actionId: '123', + }, + references: [ + { + id: 'some-id', + name: 'related_some-type_0', + type: 'some-type', + }, + ], + }, + ], + }); + await executeFn(internalSavedObjectsRepository, [ + { + id: '123', + params: { baz: false }, + source: asSavedObjectExecutionSource(source), + }, + { + id: '123', + params: { baz: true }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), + relatedSavedObjects: [ { id: 'some-id', - name: 'related_some-type_0', + namespace: 'some-namespace', type: 'some-type', }, ], }, - ], - }); - await executeFn(internalSavedObjectsRepository, [ - { - id: '123', - params: { baz: false }, - source: asSavedObjectExecutionSource(source), - }, - { - id: '123', - params: { baz: true }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - relatedSavedObjects: [ - { - id: 'some-id', - namespace: 'some-namespace', - type: 'some-type', - }, - ], - }, - ]); - expect(mockTaskManager.bulkSchedule).toHaveBeenCalledTimes(1); - expect(mockTaskManager.bulkSchedule.mock.calls[0]).toMatchInlineSnapshot(` + ]); + expect(mockTaskManager.bulkSchedule).toHaveBeenCalledTimes(1); + expect(mockTaskManager.bulkSchedule.mock.calls[0]).toMatchInlineSnapshot(` Array [ Array [ Object { @@ -344,164 +361,183 @@ describe('bulkExecute()', () => { ] `); - expect(internalSavedObjectsRepository.bulkCreate).toHaveBeenCalledWith([ - { - type: 'action_task_params', - attributes: { - actionId: '123', - params: { baz: false }, - apiKey: null, - source: 'SAVED_OBJECT', + expect(internalSavedObjectsRepository.bulkCreate).toHaveBeenCalledWith([ + { + type: 'action_task_params', + attributes: { + actionId: '123', + params: { baz: false }, + apiKey: null, + source: 'SAVED_OBJECT', + }, + references: [ + { + id: sourceUuid, + name: 'source', + type: 'alert', + }, + ], }, - references: [ - { - id: sourceUuid, - name: 'source', - type: 'alert', + { + type: 'action_task_params', + attributes: { + actionId: '123', + params: { baz: true }, + apiKey: null, + source: 'NOTIFICATION', + relatedSavedObjects: [ + { + id: 'related_some-type_0', + namespace: 'some-namespace', + type: 'some-type', + }, + ], }, - ], - }, - { - type: 'action_task_params', - attributes: { - actionId: '123', - params: { baz: true }, - apiKey: null, - source: 'NOTIFICATION', - relatedSavedObjects: [ + references: [ { - id: 'related_some-type_0', - namespace: 'some-namespace', + id: 'some-id', + name: 'related_some-type_0', type: 'some-type', }, ], }, - references: [ + ]); + } + ); + + test.each([ + [true, false], + [false, true], + ])( + 'throws when scheduling action using non in-memory connector: isPreconfigured: %s, isSystemAction: %s', + async (isPreconfigured, isSystemAction) => { + const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + connectorTypeRegistry: actionTypeRegistryMock.create(), + inMemoryConnectors: [ { - id: 'some-id', - name: 'related_some-type_0', - type: 'some-type', + id: '123', + actionTypeId: '.email', + config: {}, + isPreconfigured, + isDeprecated: false, + isSystemAction, + name: 'x', + secrets: {}, }, ], - }, - ]); - }); - - test('throws when scheduling action using non preconfigured connector', async () => { - const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ - taskManager: mockTaskManager, - connectorTypeRegistry: actionTypeRegistryMock.create(), - inMemoryConnectors: [ - { - id: '123', - actionTypeId: '.email', - config: {}, - isPreconfigured: true, - isDeprecated: false, - isSystemAction: false, - name: 'x', - secrets: {}, - }, - ], - }); - await expect( - executeFn(internalSavedObjectsRepository, [ - { - id: '123', - params: { baz: false }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - { - id: 'not-preconfigured', - params: { baz: true }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - ]) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"not-preconfigured are not preconfigured connectors and can't be scheduled for unsecured actions execution"` - ); - }); + }); + await expect( + executeFn(internalSavedObjectsRepository, [ + { + id: '123', + params: { baz: false }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), + }, + { + id: 'not-preconfigured', + params: { baz: true }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), + }, + ]) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"not-preconfigured are not in-memory connectors and can't be scheduled for unsecured actions execution"` + ); + } + ); - test('throws when connector type is not enabled', async () => { - const mockedConnectorTypeRegistry = actionTypeRegistryMock.create(); - const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ - taskManager: mockTaskManager, - connectorTypeRegistry: mockedConnectorTypeRegistry, - inMemoryConnectors: [ - { - id: '123', - actionTypeId: '.email', - config: {}, - isPreconfigured: true, - isDeprecated: false, - isSystemAction: false, - name: 'x', - secrets: {}, - }, - ], - }); - mockedConnectorTypeRegistry.ensureActionTypeEnabled.mockImplementation(() => { - throw new Error('Fail'); - }); + test.each([ + [true, false], + [false, true], + ])( + 'throws when connector type is not enabled: isPreconfigured: %s, isSystemAction: %s', + async (isPreconfigured, isSystemAction) => { + const mockedConnectorTypeRegistry = actionTypeRegistryMock.create(); + const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + connectorTypeRegistry: mockedConnectorTypeRegistry, + inMemoryConnectors: [ + { + id: '123', + actionTypeId: '.email', + config: {}, + isPreconfigured, + isDeprecated: false, + isSystemAction, + name: 'x', + secrets: {}, + }, + ], + }); + mockedConnectorTypeRegistry.ensureActionTypeEnabled.mockImplementation(() => { + throw new Error('Fail'); + }); - await expect( - executeFn(internalSavedObjectsRepository, [ - { - id: '123', - params: { baz: false }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - { - id: '123', - params: { baz: true }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - ]) - ).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`); - }); + await expect( + executeFn(internalSavedObjectsRepository, [ + { + id: '123', + params: { baz: false }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), + }, + { + id: '123', + params: { baz: true }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), + }, + ]) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`); + } + ); - test('throws when scheduling action using non allow-listed preconfigured connector', async () => { - const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ - taskManager: mockTaskManager, - connectorTypeRegistry: actionTypeRegistryMock.create(), - inMemoryConnectors: [ - { - id: '123', - actionTypeId: '.email', - config: {}, - isPreconfigured: true, - isDeprecated: false, - isSystemAction: false, - name: 'x', - secrets: {}, - }, - { - id: '456', - actionTypeId: 'not-in-allowlist', - config: {}, - isPreconfigured: true, - isDeprecated: false, - isSystemAction: false, - name: 'x', - secrets: {}, - }, - ], - }); - await expect( - executeFn(internalSavedObjectsRepository, [ - { - id: '123', - params: { baz: false }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - { - id: '456', - params: { baz: true }, - source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), - }, - ]) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"not-in-allowlist actions cannot be scheduled for unsecured actions execution"` - ); - }); + test.each([ + [true, false], + [false, true], + ])( + 'throws when scheduling action using non allow-listed in-memory connector: isPreconfigured: %s, isSystemAction: %s', + async (isPreconfigured, isSystemAction) => { + const executeFn = createBulkUnsecuredExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + connectorTypeRegistry: actionTypeRegistryMock.create(), + inMemoryConnectors: [ + { + id: '123', + actionTypeId: '.email', + config: {}, + isPreconfigured, + isDeprecated: false, + isSystemAction, + name: 'x', + secrets: {}, + }, + { + id: '456', + actionTypeId: 'not-in-allowlist', + config: {}, + isPreconfigured: true, + isDeprecated: false, + isSystemAction: false, + name: 'x', + secrets: {}, + }, + ], + }); + await expect( + executeFn(internalSavedObjectsRepository, [ + { + id: '123', + params: { baz: false }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), + }, + { + id: '456', + params: { baz: true }, + source: asNotificationExecutionSource({ connectorId: 'abc', requesterId: 'foo' }), + }, + ]) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"not-in-allowlist actions cannot be scheduled for unsecured actions execution"` + ); + } + ); }); diff --git a/x-pack/plugins/actions/server/create_unsecured_execute_function.ts b/x-pack/plugins/actions/server/create_unsecured_execute_function.ts index 1db64a3e16121a..bd4b947e532481 100644 --- a/x-pack/plugins/actions/server/create_unsecured_execute_function.ts +++ b/x-pack/plugins/actions/server/create_unsecured_execute_function.ts @@ -59,7 +59,7 @@ export function createBulkUnsecuredExecutionEnqueuerFunction({ throw new Error( `${notInMemoryConnectors.join( ',' - )} are not preconfigured connectors and can't be scheduled for unsecured actions execution` + )} are not in-memory connectors and can't be scheduled for unsecured actions execution` ); } diff --git a/x-pack/plugins/actions/server/lib/action_executor.test.ts b/x-pack/plugins/actions/server/lib/action_executor.test.ts index 31f1ab76cb0e95..af39f914fc720c 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.test.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.test.ts @@ -66,6 +66,16 @@ actionExecutor.initialize({ isDeprecated: false, isSystemAction: false, }, + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, ], }); @@ -662,6 +672,133 @@ test('successfully executes with preconfigured connector', async () => { `); }); +test('successfully executes with system connector', async () => { + const actionType: jest.Mocked = { + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'platinum', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.any() }, + secrets: { schema: schema.any() }, + params: { schema: schema.any() }, + }, + executor: jest.fn(), + }; + + actionTypeRegistry.get.mockReturnValueOnce(actionType); + await actionExecutor.execute({ ...executeParams, actionId: 'system-connector-.cases' }); + + expect(encryptedSavedObjectsClient.getDecryptedAsInternalUser).not.toHaveBeenCalled(); + + expect(actionTypeRegistry.get).toHaveBeenCalledWith('.cases'); + expect(actionTypeRegistry.isActionExecutable).toHaveBeenCalledWith( + 'system-connector-.cases', + '.cases', + { + notifyUsage: true, + } + ); + + expect(actionType.executor).toHaveBeenCalledWith({ + actionId: 'system-connector-.cases', + services: expect.anything(), + config: {}, + secrets: {}, + params: { foo: true }, + logger: loggerMock, + }); + + expect(loggerMock.debug).toBeCalledWith( + 'executing action .cases:system-connector-.cases: System action: .cases' + ); + expect(eventLogger.logEvent.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "event": Object { + "action": "execute-start", + "kind": "action", + }, + "kibana": Object { + "action": Object { + "execution": Object { + "uuid": "2", + }, + "id": "system-connector-.cases", + "name": "System action: .cases", + }, + "alert": Object { + "rule": Object { + "execution": Object { + "uuid": "123abc", + }, + }, + }, + "saved_objects": Array [ + Object { + "id": "system-connector-.cases", + "namespace": "some-namespace", + "rel": "primary", + "space_agnostic": true, + "type": "action", + "type_id": ".cases", + }, + ], + "space_ids": Array [ + "some-namespace", + ], + }, + "message": "action started: .cases:system-connector-.cases: System action: .cases", + }, + ], + Array [ + Object { + "event": Object { + "action": "execute", + "kind": "action", + "outcome": "success", + }, + "kibana": Object { + "action": Object { + "execution": Object { + "uuid": "2", + }, + "id": "system-connector-.cases", + "name": "System action: .cases", + }, + "alert": Object { + "rule": Object { + "execution": Object { + "uuid": "123abc", + }, + }, + }, + "saved_objects": Array [ + Object { + "id": "system-connector-.cases", + "namespace": "some-namespace", + "rel": "primary", + "space_agnostic": true, + "type": "action", + "type_id": ".cases", + }, + ], + "space_ids": Array [ + "some-namespace", + ], + }, + "message": "action executed: .cases:system-connector-.cases: System action: .cases", + "user": Object { + "id": "123", + "name": "coolguy", + }, + }, + ], + ] + `); +}); + test('successfully executes as a task', async () => { const actionType: jest.Mocked = { id: 'test', @@ -949,6 +1086,51 @@ test('should not throws an error if actionType is preconfigured', async () => { }); }); +test('should not throws an error if actionType is system action', async () => { + const actionType: jest.Mocked = { + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'platinum', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.any() }, + secrets: { schema: schema.any() }, + params: { schema: schema.any() }, + }, + executor: jest.fn(), + }; + + const actionSavedObject = { + id: '1', + type: 'action', + attributes: { + name: '1', + actionTypeId: '.cases', + config: {}, + secrets: {}, + }, + references: [], + }; + + encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce(actionSavedObject); + actionTypeRegistry.get.mockReturnValueOnce(actionType); + actionTypeRegistry.ensureActionTypeEnabled.mockImplementationOnce(() => { + throw new Error('not enabled for test'); + }); + actionTypeRegistry.isActionExecutable.mockImplementationOnce(() => true); + await actionExecutor.execute(executeParams); + + expect(actionTypeRegistry.ensureActionTypeEnabled).toHaveBeenCalledTimes(0); + expect(actionType.executor).toHaveBeenCalledWith({ + actionId: '1', + services: expect.anything(), + config: {}, + secrets: {}, + params: { foo: true }, + logger: loggerMock, + }); +}); + test('throws an error when passing isESOCanEncrypt with value of false', async () => { const customActionExecutor = new ActionExecutor({ isESOCanEncrypt: false }); customActionExecutor.initialize({ @@ -1117,6 +1299,155 @@ test('should not throw error if action is preconfigured and isESOCanEncrypt is f `); }); +test('should not throw error if action is system action and isESOCanEncrypt is false', async () => { + const customActionExecutor = new ActionExecutor({ isESOCanEncrypt: false }); + customActionExecutor.initialize({ + logger: loggingSystemMock.create().get(), + spaces: spacesMock, + getServices: () => services, + actionTypeRegistry, + encryptedSavedObjectsClient, + eventLogger: eventLoggerMock.create(), + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + }); + + const actionType: jest.Mocked = { + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'platinum', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.any() }, + secrets: { schema: schema.any() }, + params: { schema: schema.any() }, + }, + executor: jest.fn(), + }; + + actionTypeRegistry.get.mockReturnValueOnce(actionType); + await actionExecutor.execute({ ...executeParams, actionId: 'system-connector-.cases' }); + + expect(encryptedSavedObjectsClient.getDecryptedAsInternalUser).not.toHaveBeenCalled(); + + expect(actionTypeRegistry.get).toHaveBeenCalledWith('.cases'); + expect(actionTypeRegistry.isActionExecutable).toHaveBeenCalledWith( + 'system-connector-.cases', + '.cases', + { + notifyUsage: true, + } + ); + + expect(actionType.executor).toHaveBeenCalledWith({ + actionId: 'system-connector-.cases', + services: expect.anything(), + config: {}, + secrets: {}, + params: { foo: true }, + logger: loggerMock, + }); + + expect(loggerMock.debug).toBeCalledWith( + 'executing action .cases:system-connector-.cases: System action: .cases' + ); + expect(eventLogger.logEvent.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + Object { + "event": Object { + "action": "execute-start", + "kind": "action", + }, + "kibana": Object { + "action": Object { + "execution": Object { + "uuid": "2", + }, + "id": "system-connector-.cases", + "name": "System action: .cases", + }, + "alert": Object { + "rule": Object { + "execution": Object { + "uuid": "123abc", + }, + }, + }, + "saved_objects": Array [ + Object { + "id": "system-connector-.cases", + "namespace": "some-namespace", + "rel": "primary", + "space_agnostic": true, + "type": "action", + "type_id": ".cases", + }, + ], + "space_ids": Array [ + "some-namespace", + ], + }, + "message": "action started: .cases:system-connector-.cases: System action: .cases", + }, + ], + Array [ + Object { + "event": Object { + "action": "execute", + "kind": "action", + "outcome": "success", + }, + "kibana": Object { + "action": Object { + "execution": Object { + "uuid": "2", + }, + "id": "system-connector-.cases", + "name": "System action: .cases", + }, + "alert": Object { + "rule": Object { + "execution": Object { + "uuid": "123abc", + }, + }, + }, + "saved_objects": Array [ + Object { + "id": "system-connector-.cases", + "namespace": "some-namespace", + "rel": "primary", + "space_agnostic": true, + "type": "action", + "type_id": ".cases", + }, + ], + "space_ids": Array [ + "some-namespace", + ], + }, + "message": "action executed: .cases:system-connector-.cases: System action: .cases", + "user": Object { + "id": "123", + "name": "coolguy", + }, + }, + ], + ] + `); +}); + test('does not log warning when alert executor succeeds', async () => { const executorMock = setupActionExecutorMock(); executorMock.mockResolvedValue({ diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts index d5f6e9c3b14eaf..4fe18f6ecd5e55 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.ts @@ -186,7 +186,7 @@ export class ActionExecutor { relatedSavedObjects, name, actionExecutionId, - isPreconfigured: this.actionInfo.isPreconfigured, + isInMemory: this.actionInfo.isInMemory, ...(source ? { source } : {}), }); @@ -385,7 +385,7 @@ export class ActionExecutor { ], relatedSavedObjects, actionExecutionId, - isPreconfigured: this.actionInfo.isPreconfigured, + isInMemory: this.actionInfo.isInMemory, ...(source ? { source } : {}), }); @@ -399,7 +399,7 @@ interface ActionInfo { config: unknown; secrets: unknown; actionId: string; - isPreconfigured?: boolean; + isInMemory?: boolean; } async function getActionInfoInternal( @@ -409,18 +409,19 @@ async function getActionInfoInternal( actionId: string, namespace: string | undefined ): Promise { - // check to see if it's a pre-configured action first - const pcAction = inMemoryConnectors.find( + // check to see if it's in memory action first + const inMemoryAction = inMemoryConnectors.find( (inMemoryConnector) => inMemoryConnector.id === actionId ); - if (pcAction) { + + if (inMemoryAction) { return { - actionTypeId: pcAction.actionTypeId, - name: pcAction.name, - config: pcAction.config, - secrets: pcAction.secrets, + actionTypeId: inMemoryAction.actionTypeId, + name: inMemoryAction.name, + config: inMemoryAction.config, + secrets: inMemoryAction.secrets, actionId, - isPreconfigured: true, + isInMemory: true, }; } diff --git a/x-pack/plugins/actions/server/lib/action_task_params_utils.test.ts b/x-pack/plugins/actions/server/lib/action_task_params_utils.test.ts index 98a425ff6fd391..ab2d4305b36d84 100644 --- a/x-pack/plugins/actions/server/lib/action_task_params_utils.test.ts +++ b/x-pack/plugins/actions/server/lib/action_task_params_utils.test.ts @@ -87,13 +87,13 @@ describe('extractSavedObjectReferences()', () => { }); }); - test('correctly skips extracting action id if action is preconfigured', () => { + test('correctly skips extracting action id if action is in-memory', () => { expect(extractSavedObjectReferences('my-action-id', true)).toEqual({ references: [], }); }); - test('correctly extracts related saved object into references array if isPreconfigured is true', () => { + test('correctly extracts related saved object into references array if isInMemory is true', () => { const relatedSavedObjects = [ { id: 'abc', diff --git a/x-pack/plugins/actions/server/lib/action_task_params_utils.ts b/x-pack/plugins/actions/server/lib/action_task_params_utils.ts index 425e8dfb107f2f..98288ef4d06c2e 100644 --- a/x-pack/plugins/actions/server/lib/action_task_params_utils.ts +++ b/x-pack/plugins/actions/server/lib/action_task_params_utils.ts @@ -12,7 +12,7 @@ export const ACTION_REF_NAME = `actionRef`; export function extractSavedObjectReferences( actionId: string, - isPreconfigured: boolean, + isInMemory: boolean, relatedSavedObjects?: RelatedSavedObjects ): { references: SavedObjectReference[]; @@ -21,8 +21,8 @@ export function extractSavedObjectReferences( const references: SavedObjectReference[] = []; const relatedSavedObjectWithRefs: RelatedSavedObjects = []; - // Add action saved object to reference if it is not preconfigured - if (!isPreconfigured) { + // Add action saved object to reference if it is not in-memory action + if (!isInMemory) { references.push({ id: actionId, name: ACTION_REF_NAME, diff --git a/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.test.ts b/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.test.ts index 28c3a96e145075..cb6390a4b33352 100644 --- a/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.test.ts +++ b/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.test.ts @@ -413,7 +413,7 @@ describe('createActionEventLogRecordObject', () => { }); }); - test('created action event "execute" for preconfigured connector with space_agnostic true', async () => { + test('created action event "execute" for in-memory connector with space_agnostic true', async () => { expect( createActionEventLogRecordObject({ actionId: '1', @@ -432,7 +432,7 @@ describe('createActionEventLogRecordObject', () => { }, ], actionExecutionId: '123abc', - isPreconfigured: true, + isInMemory: true, }) ).toStrictEqual({ event: { diff --git a/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts b/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts index 46dcddd9b55c57..d29cd670c514cb 100644 --- a/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts +++ b/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts @@ -35,7 +35,7 @@ interface CreateActionEventLogRecordParams { relation?: string; }>; relatedSavedObjects?: RelatedSavedObjects; - isPreconfigured?: boolean; + isInMemory?: boolean; source?: ActionExecutionSource; } @@ -51,7 +51,7 @@ export function createActionEventLogRecordObject(params: CreateActionEventLogRec relatedSavedObjects, name, actionExecutionId, - isPreconfigured, + isInMemory, actionId, source, } = params; @@ -81,7 +81,7 @@ export function createActionEventLogRecordObject(params: CreateActionEventLogRec id: so.id, type_id: so.typeId, // set space_agnostic to true for preconfigured connectors - ...(so.type === 'action' && isPreconfigured ? { space_agnostic: isPreconfigured } : {}), + ...(so.type === 'action' && isInMemory ? { space_agnostic: isInMemory } : {}), ...(namespace ? { namespace } : {}), })), ...(spaceId ? { space_ids: [spaceId] } : {}), diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index 88821032227055..34069165890489 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -458,7 +458,7 @@ describe('Actions Plugin', () => { pluginSetup.registerType({ id: '.cases', name: 'Cases', - minimumLicenseRequired: 'basic', + minimumLicenseRequired: 'platinum', supportedFeatureIds: ['alerting'], validate: { config: { schema: schema.object({}) }, @@ -487,7 +487,7 @@ describe('Actions Plugin', () => { { id: 'system-connector-.cases', actionTypeId: '.cases', - name: 'system-connector-.cases', + name: 'System action: .cases', config: {}, secrets: {}, isDeprecated: false, diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index 8fe4fe5928a507..3d5ba29e71fa5b 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -363,7 +363,8 @@ export class ActionsPlugin implements Plugin { return !!this.inMemoryConnectors.find( - (inMemoryConnector) => inMemoryConnector.id === connectorId + (inMemoryConnector) => + inMemoryConnector.isPreconfigured && inMemoryConnector.id === connectorId ); }, getSubActionConnectorClass: () => SubActionConnector, diff --git a/x-pack/plugins/actions/server/routes/connector_types.test.ts b/x-pack/plugins/actions/server/routes/connector_types.test.ts index 4b1ce8189c2a16..51fa8c1630d5fb 100644 --- a/x-pack/plugins/actions/server/routes/connector_types.test.ts +++ b/x-pack/plugins/actions/server/routes/connector_types.test.ts @@ -79,6 +79,7 @@ describe('connectorTypesRoute', () => { enabled_in_license: true, supported_feature_ids: ['alerting'], minimum_license_required: 'gold', + is_system_action_type: false, }, ], }); @@ -155,6 +156,7 @@ describe('connectorTypesRoute', () => { enabled_in_license: true, supported_feature_ids: ['alerting'], minimum_license_required: 'gold', + is_system_action_type: false, }, ], }); diff --git a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts index 80e3461e125295..798bcbbaacd25a 100644 --- a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.test.ts @@ -6,10 +6,7 @@ */ import { v4 as uuidv4 } from 'uuid'; -import { - getActionTaskParamsMigrations, - isPreconfiguredAction, -} from './action_task_params_migrations'; +import { getActionTaskParamsMigrations, isInMemoryAction } from './action_task_params_migrations'; import { ActionTaskParams } from '../types'; import { SavedObjectReference, SavedObjectUnsanitizedDoc } from '@kbn/core/server'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; @@ -39,7 +36,7 @@ describe('successful migrations', () => { }); describe('7.16.0', () => { - test('adds actionId to references array if actionId is not preconfigured', () => { + test('adds actionId to references array if actionId is not in-memory', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); @@ -57,7 +54,7 @@ describe('successful migrations', () => { }); }); - test('does not add actionId to references array if actionId is preconfigured', () => { + test('does not add actionId to references array if actionId is in-memory', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); @@ -134,7 +131,7 @@ describe('successful migrations', () => { }); }); - test('only adds relatedSavedObjects to references array if action is preconfigured', () => { + test('only adds relatedSavedObjects to references array if action is in-memory', () => { const migration716 = SavedObjectsUtils.getMigrationFunction( getActionTaskParamsMigrations(encryptedSavedObjectsSetup, inMemoryConnectors)['7.16.0'] ); @@ -391,15 +388,15 @@ describe('handles errors during migrations', () => { }); }); -describe('isPreconfiguredAction()', () => { - test('returns true if actionId is preconfigured action', () => { - expect( - isPreconfiguredAction(getMockData({ actionId: 'my-slack1' }), inMemoryConnectors) - ).toEqual(true); +describe('isInMemoryAction()', () => { + test('returns true if actionId is in-memory action', () => { + expect(isInMemoryAction(getMockData({ actionId: 'my-slack1' }), inMemoryConnectors)).toEqual( + true + ); }); - test('returns false if actionId is not preconfigured action', () => { - expect(isPreconfiguredAction(getMockData(), inMemoryConnectors)).toEqual(false); + test('returns false if actionId is not in-memory action', () => { + expect(isInMemoryAction(getMockData(), inMemoryConnectors)).toEqual(false); }); }); diff --git a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts index c686fa55d9fe62..3ef9bb0299d7ef 100644 --- a/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts +++ b/x-pack/plugins/actions/server/saved_objects/action_task_params_migrations.ts @@ -86,7 +86,7 @@ function executeMigrationWithErrorHandling( }; } -export function isPreconfiguredAction( +export function isInMemoryAction( doc: SavedObjectUnsanitizedDoc, inMemoryConnectors: InMemoryConnector[] ): boolean { @@ -111,7 +111,7 @@ function useSavedObjectReferences( const newReferences: SavedObjectReference[] = []; const relatedSavedObjectRefs: RelatedSavedObjects = []; - if (!isPreconfiguredAction(doc, inMemoryConnectors)) { + if (!isInMemoryAction(doc, inMemoryConnectors)) { newReferences.push({ id: actionId, name: 'actionRef', diff --git a/x-pack/plugins/alerting/server/task_runner/execution_handler.test.ts b/x-pack/plugins/alerting/server/task_runner/execution_handler.test.ts index 2eacd29a39db61..90c7ec1dc095ca 100644 --- a/x-pack/plugins/alerting/server/task_runner/execution_handler.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/execution_handler.test.ts @@ -354,7 +354,7 @@ describe('Execution Handler', () => { }); test('throw error message when action type is disabled', async () => { - mockActionsPlugin.preconfiguredActions = []; + mockActionsPlugin.inMemoryConnectors = []; mockActionsPlugin.isActionExecutable.mockReturnValue(false); mockActionsPlugin.isActionTypeEnabled.mockReturnValue(false); const executionHandler = new ExecutionHandler( From d35a7f9af6d007e75563484c99d82ef59fc2ab63 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sat, 1 Jul 2023 19:49:19 +0300 Subject: [PATCH 19/28] Get in-memory connectors after they have been created in the route context --- x-pack/plugins/actions/server/plugin.test.ts | 175 +++++++++++++------ x-pack/plugins/actions/server/plugin.ts | 19 +- 2 files changed, 140 insertions(+), 54 deletions(-) diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index 34069165890489..458ff70955c6d5 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -29,6 +29,31 @@ const executor: ExecutorType<{}, {}, {}, void> = async (options) => { return { status: 'ok', actionId: options.actionId }; }; +function getConfig(overrides = {}) { + return { + enabled: true, + enabledActionTypes: ['*'], + allowedHosts: ['*'], + preconfiguredAlertHistoryEsIndex: false, + preconfigured: { + preconfiguredServerLog: { + actionTypeId: '.server-log', + name: 'preconfigured-server-log', + config: {}, + secrets: {}, + }, + }, + proxyRejectUnauthorizedCertificates: true, + proxyBypassHosts: undefined, + proxyOnlyHosts: undefined, + rejectUnauthorized: true, + maxResponseContentLength: new ByteSizeValue(1000000), + responseTimeout: moment.duration('60s'), + enableFooterInEmail: true, + ...overrides, + }; +} + describe('Actions Plugin', () => { describe('setup()', () => { let context: PluginInitializerContext; @@ -136,6 +161,106 @@ describe('Actions Plugin', () => { `"Unable to create actions client because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command."` ); }); + + it('the actions client should have the correct in-memory connectors', async () => { + context = coreMock.createPluginInitializerContext(getConfig()); + const pluginWithPreconfiguredConnectors = new ActionsPlugin(context); + + const coreStart = coreMock.createStart(); + const pluginsStart = { + licensing: licensingMock.createStart(), + taskManager: taskManagerMock.createStart(), + encryptedSavedObjects: encryptedSavedObjectsMock.createStart(), + eventLog: eventLogMock.createStart(), + }; + + /** + * 1. In the setup of the actions plugin + * the preconfigured connectors are being + * set up. Also, the action router handler context + * is registered + */ + const pluginSetup = await pluginWithPreconfiguredConnectors.setup(coreSetup, { + ...pluginsSetup, + encryptedSavedObjects: { + ...pluginsSetup.encryptedSavedObjects, + canEncrypt: true, + }, + }); + + /** + * 2. We simulate the registration of + * a system action by another plugin + * in the setup + */ + pluginSetup.registerType({ + id: '.cases', + name: 'Cases', + minimumLicenseRequired: 'platinum', + supportedFeatureIds: ['alerting'], + validate: { + config: { schema: schema.object({}) }, + secrets: { schema: schema.object({}) }, + params: { schema: schema.object({}) }, + }, + isSystemActionType: true, + executor, + }); + + const handler = coreSetup.http.registerRouteHandlerContext.mock.calls[0]; + + /** + * 3. On start the system actions are being + * created based on the system action types + * that got registered on step 2 + */ + await pluginWithPreconfiguredConnectors.start(coreStart, pluginsStart); + + const actionsContextHandler = (await handler[1]( + { + core: { + savedObjects: { + client: {}, + }, + elasticsearch: { + client: jest.fn(), + }, + }, + } as unknown as RequestHandlerContext, + httpServerMock.createKibanaRequest(), + httpServerMock.createResponseFactory() + )) as unknown as ActionsApiRequestHandlerContext; + + /** + * 4. We verify that the actions client inside + * the router context has the correct system connectors + * that got set up on start (step 3). + */ + // @ts-expect-error: inMemoryConnectors can be accessed + expect(actionsContextHandler.getActionsClient().inMemoryConnectors).toEqual([ + { + id: 'preconfiguredServerLog', + actionTypeId: '.server-log', + name: 'preconfigured-server-log', + config: {}, + secrets: {}, + isDeprecated: false, + isPreconfigured: true, + isSystemAction: false, + }, + { + id: 'system-connector-.cases', + actionTypeId: '.cases', + name: 'System action: .cases', + config: {}, + secrets: {}, + isDeprecated: false, + isPreconfigured: false, + isSystemAction: true, + isMissingSecrets: false, + }, + ]); + }); }); describe('registerType()', () => { @@ -199,31 +324,6 @@ describe('Actions Plugin', () => { }); describe('isPreconfiguredConnector', () => { - function getConfig(overrides = {}) { - return { - enabled: true, - enabledActionTypes: ['*'], - allowedHosts: ['*'], - preconfiguredAlertHistoryEsIndex: false, - preconfigured: { - preconfiguredServerLog: { - actionTypeId: '.server-log', - name: 'preconfigured-server-log', - config: {}, - secrets: {}, - }, - }, - proxyRejectUnauthorizedCertificates: true, - proxyBypassHosts: undefined, - proxyOnlyHosts: undefined, - rejectUnauthorized: true, - maxResponseContentLength: new ByteSizeValue(1000000), - responseTimeout: moment.duration('60s'), - enableFooterInEmail: true, - ...overrides, - }; - } - function setup(config: ActionsConfig) { context = coreMock.createPluginInitializerContext(config); plugin = new ActionsPlugin(context); @@ -324,31 +424,6 @@ describe('Actions Plugin', () => { }); describe('inMemoryConnectors', () => { - function getConfig(overrides = {}) { - return { - enabled: true, - enabledActionTypes: ['*'], - allowedHosts: ['*'], - preconfiguredAlertHistoryEsIndex: false, - preconfigured: { - preconfiguredServerLog: { - actionTypeId: '.server-log', - name: 'preconfigured-server-log', - config: {}, - secrets: {}, - }, - }, - proxyRejectUnauthorizedCertificates: true, - proxyBypassHosts: undefined, - proxyOnlyHosts: undefined, - rejectUnauthorized: true, - maxResponseContentLength: new ByteSizeValue(1000000), - responseTimeout: moment.duration('60s'), - enableFooterInEmail: true, - ...overrides, - }; - } - function setup(config: ActionsConfig) { context = coreMock.createPluginInitializerContext(config); plugin = new ActionsPlugin(context); diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index 3d5ba29e71fa5b..25b03b41413ee9 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -397,12 +397,14 @@ export class ActionsPlugin implements Plugin this.inMemoryConnectors; + + private setSystemActions = () => { + const systemConnectors = createSystemConnectors(this.actionTypeRegistry?.list() ?? []); + this.inMemoryConnectors = [...this.inMemoryConnectors, ...systemConnectors]; + }; + private createRouteHandlerContext = ( core: CoreSetup ): IContextProvider => { const { actionTypeRegistry, isESOCanEncrypt, - inMemoryConnectors, + getInMemoryConnectors, actionExecutor, instantiateAuthorization, security, @@ -615,7 +624,9 @@ export class ActionsPlugin implements Plugin { From 34ee2ab2338bbb327083f8a986d4ac9bb9fc7978 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sat, 1 Jul 2023 19:51:32 +0300 Subject: [PATCH 20/28] Register test system action in integration tests --- .../alerting_api_integration/common/config.ts | 1 + .../plugins/alerts/server/action_types.ts | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 851bc653d62525..fe84d1b0f50baf 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -64,6 +64,7 @@ const enabledActionTypes = [ 'test.throw', 'test.excluded', 'test.capped', + 'test-system-action', ]; export function createTestConfig(name: string, options: CreateTestConfigOptions) { diff --git a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/action_types.ts b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/action_types.ts index d04fb52b7637a0..d452c68101fdcc 100644 --- a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/action_types.ts +++ b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/action_types.ts @@ -74,6 +74,7 @@ export function defineActionTypes( actions.registerType(getNoAttemptsRateLimitedActionType()); actions.registerType(getAuthorizationActionType(core)); actions.registerType(getExcludedActionType()); + actions.registerType(getSystemActionType()); /** Sub action framework */ @@ -399,3 +400,29 @@ function getExcludedActionType() { }; return result; } + +function getSystemActionType() { + const result: ActionType<{}, {}, {}> = { + id: 'test-system-action', + name: 'Test system action', + minimumLicenseRequired: 'platinum', + supportedFeatureIds: ['alerting'], + validate: { + params: { + schema: schema.any(), + }, + config: { + schema: schema.any(), + }, + secrets: { + schema: schema.any(), + }, + }, + isSystemActionType: true, + async executor({ config, secrets, params, services, actionId }) { + return { status: 'ok', actionId }; + }, + }; + + return result; +} From 86b279cc86dafdc3897a0d332a5348dc210cedd1 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sat, 1 Jul 2023 20:39:22 +0300 Subject: [PATCH 21/28] Add integration tests --- .../plugins/actions/server/actions_client.ts | 27 +++---- .../group2/tests/actions/create.ts | 76 +++++++++++++++++++ .../group2/tests/actions/delete.ts | 37 ++++++++- .../group2/tests/actions/get.ts | 37 +++++++++ .../group2/tests/actions/get_all.ts | 27 +++++++ .../group2/tests/actions/update.ts | 46 ++++++++++- .../spaces_only/tests/actions/create.ts | 34 +++++++++ .../spaces_only/tests/actions/delete.ts | 34 ++++++++- .../spaces_only/tests/actions/get.ts | 40 +++++++++- .../spaces_only/tests/actions/get_all.ts | 27 +++++++ .../actions/schedule_unsecured_action.ts | 4 +- .../spaces_only/tests/actions/update.ts | 52 ++++++++++++- 12 files changed, 417 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 9bad5235fc6ab2..6ec173dabb7683 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -195,6 +195,20 @@ export class ActionsClient { options, }: CreateOptions): Promise { const id = options?.id || SavedObjectsUtils.generateId(); + + try { + await this.authorization.ensureAuthorized('create', actionTypeId); + } catch (error) { + this.auditLogger?.log( + connectorAuditEvent({ + action: ConnectorAuditAction.CREATE, + savedObject: { type: 'action', id }, + error, + }) + ); + throw error; + } + const foundInMemoryConnector = this.inMemoryConnectors.find((connector) => connector.id === id); if ( @@ -222,19 +236,6 @@ export class ActionsClient { ); } - try { - await this.authorization.ensureAuthorized('create', actionTypeId); - } catch (error) { - this.auditLogger?.log( - connectorAuditEvent({ - action: ConnectorAuditAction.CREATE, - savedObject: { type: 'action', id }, - error, - }) - ); - throw error; - } - const actionType = this.actionTypeRegistry.get(actionTypeId); const configurationUtilities = this.actionTypeRegistry.getUtils(); const validatedActionTypeConfig = validateConfig(actionType, config, { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts index 4c9db37fe35435..e14bb493d7fc6a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts @@ -319,6 +319,82 @@ export default function createActionTests({ getService }: FtrProviderContext) { throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); + + it(`shouldn't create a preconfigured action with the same id as an existing one`, async () => { + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(space.id)}/api/actions/connector/custom-system-abc-connector`) + .auth(user.username, user.password) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action', + connector_type_id: 'system-abc-action-type', + config: {}, + secrets: {}, + }); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'global_read at space1': + case 'space_1_all_alerts_none_actions at space1': + case 'space_1_all at space2': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unauthorized to create a "system-abc-action-type" action', + }); + break; + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: 'This custom-system-abc-connector already exist in preconfigured action.', + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); + + it(`shouldn't create a system action`, async () => { + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(space.id)}/api/actions/connector`) + .auth(user.username, user.password) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My system action', + connector_type_id: 'test-system-action', + config: {}, + secrets: {}, + }); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'global_read at space1': + case 'space_1_all_alerts_none_actions at space1': + case 'space_1_all at space2': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unauthorized to create a "test-system-action" action', + }); + break; + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: 'System action creation is forbidden. Action type: test-system-action.', + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); }); } }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts index b0cfffdd2f464a..dd8ab655475634 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts @@ -146,7 +146,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { } }); - it(`shouldn't delete action from preconfigured list`, async () => { + it(`shouldn't delete preconfigured action`, async () => { const response = await supertestWithoutAuth .delete(`${getUrlPrefix(space.id)}/api/actions/connector/my-slack1`) .auth(user.username, user.password) @@ -177,6 +177,41 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); + + it(`shouldn't delete system action`, async () => { + const response = await supertestWithoutAuth + .delete( + `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test-system-action` + ) + .auth(user.username, user.password) + .set('kbn-xsrf', 'foo'); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all_alerts_none_actions at space1': + case 'global_read at space1': + case 'space_1_all at space2': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unauthorized to delete actions', + }); + break; + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'System action system-connector-test-system-action is not allowed to delete.', + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); }); } }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts index 3b04af22d2e96c..ac16586f3bb6ee 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts @@ -160,6 +160,43 @@ export default function getActionTests({ getService }: FtrProviderContext) { throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); + + it('should handle get system action request appropriately', async () => { + const response = await supertestWithoutAuth + .get( + `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test-system-action` + ) + .auth(user.username, user.password); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all_alerts_none_actions at space1': + case 'space_1_all at space2': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unauthorized to get actions', + }); + break; + case 'global_read at space1': + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.statusCode).to.eql(200); + expect(response.body).to.eql({ + id: 'system-connector-test-system-action', + connector_type_id: 'test-system-action', + name: 'System action: test-system-action', + is_preconfigured: false, + is_system_action: true, + is_deprecated: false, + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); }); } }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts index 37475d7f191cad..9e0702d83eb482 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts @@ -125,6 +125,15 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Slack#xyz', referenced_by_count: 0, }, + { + connector_type_id: 'test-system-action', + id: 'system-connector-test-system-action', + is_deprecated: false, + is_preconfigured: false, + is_system_action: true, + name: 'System action: test-system-action', + referenced_by_count: 0, + }, { id: 'custom-system-abc-connector', is_preconfigured: true, @@ -285,6 +294,15 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Slack#xyz', referenced_by_count: 0, }, + { + connector_type_id: 'test-system-action', + id: 'system-connector-test-system-action', + is_deprecated: false, + is_preconfigured: false, + is_system_action: true, + name: 'System action: test-system-action', + referenced_by_count: 0, + }, { id: 'custom-system-abc-connector', is_preconfigured: true, @@ -408,6 +426,15 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Slack#xyz', referenced_by_count: 0, }, + { + connector_type_id: 'test-system-action', + id: 'system-connector-test-system-action', + is_deprecated: false, + is_preconfigured: false, + is_system_action: true, + name: 'System action: test-system-action', + referenced_by_count: 0, + }, { id: 'custom-system-abc-connector', is_preconfigured: true, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts index 07d2e6064bc0bc..220feb7b3fa342 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts @@ -312,7 +312,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { } }); - it(`shouldn't update action from preconfigured list`, async () => { + it(`shouldn't update a preconfigured action`, async () => { const response = await supertestWithoutAuth .put(`${getUrlPrefix(space.id)}/api/actions/connector/custom-system-abc-connector`) .auth(user.username, user.password) @@ -387,6 +387,50 @@ export default function updateActionTests({ getService }: FtrProviderContext) { throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); } }); + + it(`shouldn't update a system action`, async () => { + const response = await supertestWithoutAuth + .put( + `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test-system-action` + ) + .auth(user.username, user.password) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action updated', + config: { + unencrypted: `This value shouldn't get encrypted`, + }, + secrets: { + encrypted: 'This value should be encrypted', + }, + }); + + switch (scenario.id) { + case 'no_kibana_privileges at space1': + case 'space_1_all_alerts_none_actions at space1': + case 'space_1_all at space2': + case 'global_read at space1': + expect(response.statusCode).to.eql(403); + expect(response.body).to.eql({ + statusCode: 403, + error: 'Forbidden', + message: 'Unauthorized to update actions', + }); + break; + case 'superuser at space1': + case 'space_1_all at space1': + case 'space_1_all_with_restricted_fixture at space1': + expect(response.body).to.eql({ + statusCode: 400, + error: 'Bad Request', + message: + 'System action system-connector-test-system-action is not allowed to update.', + }); + break; + default: + throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); + } + }); }); } }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index a7239343b2c610..d0e3e50eaa672d 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -80,6 +80,40 @@ export default function createActionTests({ getService }: FtrProviderContext) { }); }); + it(`shouldn't create a preconfigured action with the same id as an existing one`, async () => { + await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/custom-system-abc-connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action', + connector_type_id: 'system-abc-action-type', + config: {}, + secrets: {}, + }) + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: 'This custom-system-abc-connector already exist in preconfigured action.', + }); + }); + + it(`shouldn't create a system action`, async () => { + await supertest + .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My system action', + connector_type_id: 'test-system-action', + config: {}, + secrets: {}, + }) + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: 'System action creation is forbidden. Action type: test-system-action.', + }); + }); + describe('legacy', () => { it('should handle create action request appropriately', async () => { const response = await supertest diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts index 66ae047e5151b0..4ac03f29356274 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts @@ -78,7 +78,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { }); }); - it(`shouldn't delete action from preconfigured list`, async () => { + it(`shouldn't delete a preconfigured action`, async () => { await supertest .delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/my-slack1`) .set('kbn-xsrf', 'foo') @@ -89,6 +89,21 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { }); }); + it(`shouldn't delete a system action`, async () => { + await supertest + .delete( + `${getUrlPrefix( + Spaces.space1.id + )}/api/actions/connector/system-connector-test-system-action` + ) + .set('kbn-xsrf', 'foo') + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: 'System action system-connector-test-system-action is not allowed to delete.', + }); + }); + describe('legacy', () => { it('should handle delete action request appropriately', async () => { const { body: createdAction } = await supertest @@ -150,7 +165,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { }); }); - it(`shouldn't delete action from preconfigured list`, async () => { + it(`shouldn't delete a preconfigured action`, async () => { await supertest .delete(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/my-slack1`) .set('kbn-xsrf', 'foo') @@ -160,6 +175,21 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { message: `Preconfigured action my-slack1 is not allowed to delete.`, }); }); + + it(`shouldn't delete a system action`, async () => { + await supertest + .delete( + `${getUrlPrefix( + Spaces.space1.id + )}/api/actions/action/system-connector-test-system-action` + ) + .set('kbn-xsrf', 'foo') + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: 'System action system-connector-test-system-action is not allowed to delete.', + }); + }); }); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index 68d4512145118a..eaf7a6c4344963 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -77,7 +77,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { }); }); - it('should handle get action request from preconfigured list', async () => { + it('should handle get a preconfigured connector', async () => { await supertest .get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/my-slack1`) .expect(200, { @@ -90,7 +90,24 @@ export default function getActionTests({ getService }: FtrProviderContext) { }); }); - it('should handle get action request for deprecated connectors from preconfigured list', async () => { + it('should handle get a system connector', async () => { + await supertest + .get( + `${getUrlPrefix( + Spaces.space1.id + )}/api/actions/connector/system-connector-test-system-action` + ) + .expect(200, { + id: 'system-connector-test-system-action', + connector_type_id: 'test-system-action', + name: 'System action: test-system-action', + is_preconfigured: false, + is_system_action: true, + is_deprecated: false, + }); + }); + + it('should handle get a deprecated connector', async () => { await supertest .get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/my-deprecated-servicenow`) .expect(200, { @@ -176,7 +193,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { }); }); - it('should handle get action request from preconfigured list', async () => { + it('should handle get a preconfigured connector', async () => { await supertest .get(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/my-slack1`) .expect(200, { @@ -188,6 +205,23 @@ export default function getActionTests({ getService }: FtrProviderContext) { name: 'Slack#xyz', }); }); + + it('should handle get a system connector', async () => { + await supertest + .get( + `${getUrlPrefix( + Spaces.space1.id + )}/api/actions/action/system-connector-test-system-action` + ) + .expect(200, { + id: 'system-connector-test-system-action', + connector_type_id: 'test-system-action', + name: 'System action: test-system-action', + is_preconfigured: false, + is_system_action: true, + is_deprecated: false, + }); + }); }); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts index d4a43da31894e3..528b2a6c59997e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -114,6 +114,15 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Slack#xyz', referenced_by_count: 0, }, + { + connector_type_id: 'test-system-action', + id: 'system-connector-test-system-action', + is_deprecated: false, + is_preconfigured: false, + is_system_action: true, + name: 'System action: test-system-action', + referenced_by_count: 0, + }, { id: 'custom-system-abc-connector', is_preconfigured: true, @@ -226,6 +235,15 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Slack#xyz', referenced_by_count: 0, }, + { + connector_type_id: 'test-system-action', + id: 'system-connector-test-system-action', + is_deprecated: false, + is_preconfigured: false, + is_system_action: true, + name: 'System action: test-system-action', + referenced_by_count: 0, + }, { id: 'custom-system-abc-connector', is_preconfigured: true, @@ -352,6 +370,15 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { name: 'Slack#xyz', referencedByCount: 0, }, + { + actionTypeId: 'test-system-action', + id: 'system-connector-test-system-action', + isDeprecated: false, + isPreconfigured: false, + isSystemAction: true, + name: 'System action: test-system-action', + referencedByCount: 0, + }, { id: 'custom-system-abc-connector', isPreconfigured: true, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/schedule_unsecured_action.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/schedule_unsecured_action.ts index 9a5719b7fa7000..409e56e7b1fd85 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/schedule_unsecured_action.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/schedule_unsecured_action.ts @@ -149,7 +149,7 @@ export default function createUnsecuredActionTests({ getService }: FtrProviderCo ); }); - it('should not allow scheduling action from non preconfigured connectors', async () => { + it('should not allow scheduling action from non in-memory connectors', async () => { const response = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) .set('kbn-xsrf', 'foo') @@ -184,7 +184,7 @@ export default function createUnsecuredActionTests({ getService }: FtrProviderCo .expect(200); expect(result.status).to.eql('error'); expect(result.error).to.eql( - `Error: ${connectorId} are not preconfigured connectors and can't be scheduled for unsecured actions execution` + `Error: ${connectorId} are not in-memory connectors and can't be scheduled for unsecured actions execution` ); }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index d6f41e3037ad20..04122a6d8267bc 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -106,7 +106,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { }); }); - it(`shouldn't update action from preconfigured list`, async () => { + it(`shouldn't update a preconfigured connector`, async () => { await supertest .put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector/custom-system-abc-connector`) .set('kbn-xsrf', 'foo') @@ -126,6 +126,30 @@ export default function updateActionTests({ getService }: FtrProviderContext) { }); }); + it(`shouldn't update a system connector`, async () => { + await supertest + .put( + `${getUrlPrefix( + Spaces.space1.id + )}/api/actions/connector/system-connector-test-system-action` + ) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action updated', + config: { + unencrypted: `This value shouldn't get encrypted`, + }, + secrets: { + encrypted: 'This value should be encrypted', + }, + }) + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: 'System action system-connector-test-system-action is not allowed to update.', + }); + }); + it('should notify feature usage when editing a gold action type', async () => { const { body: createdAction } = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) @@ -270,7 +294,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { }); }); - it(`shouldn't update action from preconfigured list`, async () => { + it(`shouldn't update a preconfigured connector`, async () => { await supertest .put(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action/custom-system-abc-connector`) .set('kbn-xsrf', 'foo') @@ -290,6 +314,30 @@ export default function updateActionTests({ getService }: FtrProviderContext) { }); }); + it(`shouldn't update a system connector`, async () => { + await supertest + .put( + `${getUrlPrefix( + Spaces.space1.id + )}/api/actions/action/system-connector-test-system-action` + ) + .set('kbn-xsrf', 'foo') + .send({ + name: 'My action updated', + config: { + unencrypted: `This value shouldn't get encrypted`, + }, + secrets: { + encrypted: 'This value should be encrypted', + }, + }) + .expect(400, { + statusCode: 400, + error: 'Bad Request', + message: 'System action system-connector-test-system-action is not allowed to update.', + }); + }); + it('should notify feature usage when editing a gold action type', async () => { const { body: createdAction } = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/action`) From 57b4d3af1daf856ffc399ec284ecf4c92be025ee Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sun, 2 Jul 2023 14:11:28 +0300 Subject: [PATCH 22/28] Fix i18n --- x-pack/plugins/actions/server/actions_client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 6ec173dabb7683..ce82913cd749c3 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -294,7 +294,7 @@ export class ActionsClient { if (foundInMemoryConnector?.isSystemAction) { throw Boom.badRequest( - i18n.translate('xpack.actions.serverSideErrors.systemActionCreationForbidden', { + i18n.translate('xpack.actions.serverSideErrors.systemActionUpdateForbidden', { defaultMessage: 'System action {id} is not allowed to update.', values: { id, @@ -668,7 +668,7 @@ export class ActionsClient { if (foundInMemoryConnector?.isSystemAction) { throw Boom.badRequest( - i18n.translate('xpack.actions.serverSideErrors.systemActionCreationForbidden', { + i18n.translate('xpack.actions.serverSideErrors.systemActionDeletionForbidden', { defaultMessage: 'System action {id} is not allowed to delete.', values: { id, From a16216378ec21854499cdb3365fcceabde1971a2 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sun, 2 Jul 2023 14:17:39 +0300 Subject: [PATCH 23/28] Fix types --- .../lib/action_connector_api/connector_types.test.ts | 2 ++ .../lib/action_connector_api/connector_types.ts | 2 ++ .../public/application/lib/action_type_compare.test.ts | 8 ++++++++ .../application/lib/check_action_type_enabled.test.tsx | 5 +++++ .../action_connector_form/action_type_form.test.tsx | 2 ++ .../action_connector_form/connector_add_modal.test.tsx | 3 +++ .../action_connector_form/connectors_selection.test.tsx | 1 + .../rule_details/components/rule_details.test.tsx | 5 +++++ 8 files changed, 28 insertions(+) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.test.ts index 69b8975a9768f2..3dbf3e5d20822f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.test.ts @@ -37,6 +37,7 @@ describe('loadActionTypes', () => { enabledInLicense: true, supportedFeatureIds: ['alerting'], minimumLicenseRequired: 'basic', + isSystemActionType: false, }, ]; @@ -72,6 +73,7 @@ describe('loadActionTypes', () => { enabledInLicense: true, supportedFeatureIds: ['alerting'], minimumLicenseRequired: 'basic', + isSystemActionType: false, }, ]; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.ts index 191ae96acc8b66..be16cfc65309e9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.ts @@ -19,12 +19,14 @@ const rewriteBodyReq: RewriteRequestCase = ({ enabled_in_license: enabledInLicense, minimum_license_required: minimumLicenseRequired, supported_feature_ids: supportedFeatureIds, + is_system_action_type: isSystemActionType, ...res }: AsApiContract) => ({ enabledInConfig, enabledInLicense, minimumLicenseRequired, supportedFeatureIds, + isSystemActionType, ...res, }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_type_compare.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_type_compare.test.ts index ffc6594d596518..8c9e71bb7d03b4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_type_compare.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_type_compare.test.ts @@ -18,6 +18,7 @@ test('should sort enabled action types first', async () => { enabled: true, enabledInConfig: true, enabledInLicense: true, + isSystemActionType: false, }, { id: '2', @@ -27,6 +28,7 @@ test('should sort enabled action types first', async () => { enabled: false, enabledInConfig: true, enabledInLicense: false, + isSystemActionType: false, }, { id: '3', @@ -36,6 +38,7 @@ test('should sort enabled action types first', async () => { enabled: true, enabledInConfig: true, enabledInLicense: true, + isSystemActionType: false, }, { id: '4', @@ -45,6 +48,7 @@ test('should sort enabled action types first', async () => { enabled: true, enabledInConfig: false, enabledInLicense: true, + isSystemActionType: false, }, ]; const result = [...actionTypes].sort(actionTypeCompare); @@ -64,6 +68,7 @@ test('should sort by name when all enabled', async () => { enabled: true, enabledInConfig: true, enabledInLicense: true, + isSystemActionType: false, }, { id: '2', @@ -73,6 +78,7 @@ test('should sort by name when all enabled', async () => { enabled: true, enabledInConfig: true, enabledInLicense: true, + isSystemActionType: false, }, { id: '3', @@ -82,6 +88,7 @@ test('should sort by name when all enabled', async () => { enabled: true, enabledInConfig: true, enabledInLicense: true, + isSystemActionType: false, }, { id: '4', @@ -91,6 +98,7 @@ test('should sort by name when all enabled', async () => { enabled: true, enabledInConfig: false, enabledInLicense: true, + isSystemActionType: false, }, ]; const result = [...actionTypes].sort(actionTypeCompare); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx index e2dc91214e783e..2cdd25267de0eb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx @@ -29,6 +29,7 @@ describe('checkActionTypeEnabled', () => { enabled: true, enabledInConfig: true, enabledInLicense: true, + isSystemActionType: false, }; expect(checkActionTypeEnabled(actionType)).toMatchInlineSnapshot(` Object { @@ -46,6 +47,7 @@ describe('checkActionTypeEnabled', () => { enabled: false, enabledInConfig: true, enabledInLicense: false, + isSystemActionType: false, }; expect(checkActionTypeEnabled(actionType)).toMatchInlineSnapshot(` Object { @@ -81,6 +83,7 @@ describe('checkActionTypeEnabled', () => { enabled: false, enabledInConfig: false, enabledInLicense: true, + isSystemActionType: false, }; expect(checkActionTypeEnabled(actionType)).toMatchInlineSnapshot(` Object { @@ -127,6 +130,7 @@ describe('checkActionFormActionTypeEnabled', () => { enabled: true, enabledInConfig: false, enabledInLicense: true, + isSystemActionType: false, }; expect(checkActionFormActionTypeEnabled(actionType, preconfiguredConnectors)) @@ -146,6 +150,7 @@ describe('checkActionFormActionTypeEnabled', () => { enabled: true, enabledInConfig: false, enabledInLicense: true, + isSystemActionType: false, }; expect(checkActionFormActionTypeEnabled(actionType, preconfiguredConnectors)) .toMatchInlineSnapshot(` diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx index 46dafc3c4fc033..4cfe807ecd7284 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx @@ -605,6 +605,7 @@ function getActionTypeForm({ enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, '.server-log': { id: '.server-log', @@ -614,6 +615,7 @@ function getActionTypeForm({ enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx index fcc80ace505ffe..6efbf023e76d61 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx @@ -58,6 +58,7 @@ describe('connector_add_modal', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }; const wrapper = mountWithIntl( @@ -100,6 +101,7 @@ describe('connector_add_modal', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }; const wrapper = mountWithIntl( { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }; const wrapper = mountWithIntl( { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx index b2edd76a394015..3bd45741714a01 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_details.test.tsx @@ -216,6 +216,7 @@ describe('rule_details', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]; @@ -259,6 +260,7 @@ describe('rule_details', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, { id: '.email', @@ -268,6 +270,7 @@ describe('rule_details', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]; @@ -338,6 +341,7 @@ describe('rule_details', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]; ruleTypeRegistry.has.mockReturnValue(true); @@ -468,6 +472,7 @@ describe('rule_details', () => { enabledInLicense: true, minimumLicenseRequired: 'basic', supportedFeatureIds: ['alerting'], + isSystemActionType: false, }, ]; ruleTypeRegistry.has.mockReturnValue(true); From 2ea3c9c45b7192a1afe19fa9a5886bb1ce775b71 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sun, 2 Jul 2023 14:19:37 +0300 Subject: [PATCH 24/28] Fix integration test --- .../spaces_only/tests/actions/get.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index eaf7a6c4344963..87dedc46327e07 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -215,11 +215,11 @@ export default function getActionTests({ getService }: FtrProviderContext) { ) .expect(200, { id: 'system-connector-test-system-action', - connector_type_id: 'test-system-action', + actionTypeId: 'test-system-action', name: 'System action: test-system-action', - is_preconfigured: false, - is_system_action: true, - is_deprecated: false, + isPreconfigured: false, + isSystemAction: true, + isDeprecated: false, }); }); }); From 7362b97da2164211e18c7cafc4aaedd7dbb5b3ce Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Sun, 2 Jul 2023 16:14:59 +0300 Subject: [PATCH 25/28] Fixes --- .../connector_types.test.ts | 2 ++ .../legacy_uptime/pages/settings.test.tsx | 1 + .../public/legacy_uptime/state/api/alerts.ts | 2 ++ .../alerting_api_integration/common/config.ts | 2 +- .../plugins/alerts/server/action_types.ts | 2 +- .../group2/tests/actions/create.ts | 6 +++--- .../group2/tests/actions/delete.ts | 4 ++-- .../group2/tests/actions/get.ts | 8 ++++---- .../group2/tests/actions/get_all.ts | 18 +++++++++--------- .../group2/tests/actions/update.ts | 4 ++-- .../spaces_only/tests/actions/create.ts | 4 ++-- .../spaces_only/tests/actions/delete.ts | 8 ++++---- .../spaces_only/tests/actions/get.ts | 16 ++++++++-------- .../spaces_only/tests/actions/get_all.ts | 18 +++++++++--------- .../spaces_only/tests/actions/update.ts | 8 ++++---- 15 files changed, 54 insertions(+), 49 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.test.ts index 3dbf3e5d20822f..182abc1507a346 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/connector_types.test.ts @@ -24,6 +24,7 @@ describe('loadActionTypes', () => { enabled_in_license: true, supported_feature_ids: ['alerting'], minimum_license_required: 'basic', + is_system_action_type: false, }, ]; http.get.mockResolvedValueOnce(apiResponseValue); @@ -60,6 +61,7 @@ describe('loadActionTypes', () => { enabled_in_license: true, supported_feature_ids: ['alerting'], minimum_license_required: 'basic', + is_system_action_type: false, }, ]; http.get.mockResolvedValueOnce(apiResponseValue); diff --git a/x-pack/plugins/uptime/public/legacy_uptime/pages/settings.test.tsx b/x-pack/plugins/uptime/public/legacy_uptime/pages/settings.test.tsx index 8a87ff2969974d..5c8fb95448fca0 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/pages/settings.test.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/pages/settings.test.tsx @@ -24,6 +24,7 @@ describe('settings', () => { minimumLicenseRequired: 'gold', name: 'Slack', supportedFeatureIds: ['uptime'], + isSystemActionType: false, }, ]); }); diff --git a/x-pack/plugins/uptime/public/legacy_uptime/state/api/alerts.ts b/x-pack/plugins/uptime/public/legacy_uptime/state/api/alerts.ts index 8c623e914516b5..9ca6a386997ec3 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/state/api/alerts.ts +++ b/x-pack/plugins/uptime/public/legacy_uptime/state/api/alerts.ts @@ -172,6 +172,7 @@ export const fetchActionTypes = async (): Promise => { enabled_in_license: enabledInLicense, minimum_license_required: minimumLicenseRequired, supported_feature_ids: supportedFeatureIds, + is_system_action_type: isSystemActionType, ...res }: AsApiContract) => ({ ...res, @@ -179,6 +180,7 @@ export const fetchActionTypes = async (): Promise => { enabledInLicense, minimumLicenseRequired, supportedFeatureIds, + isSystemActionType, }) ); }; diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index fe84d1b0f50baf..3e48a3b273019d 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -64,7 +64,7 @@ const enabledActionTypes = [ 'test.throw', 'test.excluded', 'test.capped', - 'test-system-action', + 'test.system-action', ]; export function createTestConfig(name: string, options: CreateTestConfigOptions) { diff --git a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/action_types.ts b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/action_types.ts index d452c68101fdcc..cddf1002050586 100644 --- a/x-pack/test/alerting_api_integration/common/plugins/alerts/server/action_types.ts +++ b/x-pack/test/alerting_api_integration/common/plugins/alerts/server/action_types.ts @@ -403,7 +403,7 @@ function getExcludedActionType() { function getSystemActionType() { const result: ActionType<{}, {}, {}> = { - id: 'test-system-action', + id: 'test.system-action', name: 'Test system action', minimumLicenseRequired: 'platinum', supportedFeatureIds: ['alerting'], diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts index e14bb493d7fc6a..6be435b569a977 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts @@ -365,7 +365,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ name: 'My system action', - connector_type_id: 'test-system-action', + connector_type_id: 'test.system-action', config: {}, secrets: {}, }); @@ -379,7 +379,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 403, error: 'Forbidden', - message: 'Unauthorized to create a "test-system-action" action', + message: 'Unauthorized to create a "test.system-action" action', }); break; case 'superuser at space1': @@ -388,7 +388,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: 'System action creation is forbidden. Action type: test-system-action.', + message: 'System action creation is forbidden. Action type: test.system-action.', }); break; default: diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts index dd8ab655475634..b5b11036a3dfd8 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/delete.ts @@ -181,7 +181,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { it(`shouldn't delete system action`, async () => { const response = await supertestWithoutAuth .delete( - `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test-system-action` + `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test.system-action` ) .auth(user.username, user.password) .set('kbn-xsrf', 'foo'); @@ -205,7 +205,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'System action system-connector-test-system-action is not allowed to delete.', + 'System action system-connector-test.system-action is not allowed to delete.', }); break; default: diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts index ac16586f3bb6ee..42cfce82cb2e1a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get.ts @@ -164,7 +164,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { it('should handle get system action request appropriately', async () => { const response = await supertestWithoutAuth .get( - `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test-system-action` + `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test.system-action` ) .auth(user.username, user.password); @@ -185,9 +185,9 @@ export default function getActionTests({ getService }: FtrProviderContext) { case 'space_1_all_with_restricted_fixture at space1': expect(response.statusCode).to.eql(200); expect(response.body).to.eql({ - id: 'system-connector-test-system-action', - connector_type_id: 'test-system-action', - name: 'System action: test-system-action', + id: 'system-connector-test.system-action', + connector_type_id: 'test.system-action', + name: 'System action: test.system-action', is_preconfigured: false, is_system_action: true, is_deprecated: false, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts index 9e0702d83eb482..bc3444b5a32b3e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/get_all.ts @@ -126,12 +126,12 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { referenced_by_count: 0, }, { - connector_type_id: 'test-system-action', - id: 'system-connector-test-system-action', + connector_type_id: 'test.system-action', + id: 'system-connector-test.system-action', is_deprecated: false, is_preconfigured: false, is_system_action: true, - name: 'System action: test-system-action', + name: 'System action: test.system-action', referenced_by_count: 0, }, { @@ -295,12 +295,12 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { referenced_by_count: 0, }, { - connector_type_id: 'test-system-action', - id: 'system-connector-test-system-action', + connector_type_id: 'test.system-action', + id: 'system-connector-test.system-action', is_deprecated: false, is_preconfigured: false, is_system_action: true, - name: 'System action: test-system-action', + name: 'System action: test.system-action', referenced_by_count: 0, }, { @@ -427,12 +427,12 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { referenced_by_count: 0, }, { - connector_type_id: 'test-system-action', - id: 'system-connector-test-system-action', + connector_type_id: 'test.system-action', + id: 'system-connector-test.system-action', is_deprecated: false, is_preconfigured: false, is_system_action: true, - name: 'System action: test-system-action', + name: 'System action: test.system-action', referenced_by_count: 0, }, { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts index 220feb7b3fa342..c27208860fcfa8 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts @@ -391,7 +391,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { it(`shouldn't update a system action`, async () => { const response = await supertestWithoutAuth .put( - `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test-system-action` + `${getUrlPrefix(space.id)}/api/actions/connector/system-connector-test.system-action` ) .auth(user.username, user.password) .set('kbn-xsrf', 'foo') @@ -424,7 +424,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'System action system-connector-test-system-action is not allowed to update.', + 'System action system-connector-test.system-action is not allowed to update.', }); break; default: diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index d0e3e50eaa672d..614c130cc7120f 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -103,14 +103,14 @@ export default function createActionTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send({ name: 'My system action', - connector_type_id: 'test-system-action', + connector_type_id: 'test.system-action', config: {}, secrets: {}, }) .expect(400, { statusCode: 400, error: 'Bad Request', - message: 'System action creation is forbidden. Action type: test-system-action.', + message: 'System action creation is forbidden. Action type: test.system-action.', }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts index 4ac03f29356274..5d3a5f0c32ecb7 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts @@ -94,13 +94,13 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { .delete( `${getUrlPrefix( Spaces.space1.id - )}/api/actions/connector/system-connector-test-system-action` + )}/api/actions/connector/system-connector-test.system-action` ) .set('kbn-xsrf', 'foo') .expect(400, { statusCode: 400, error: 'Bad Request', - message: 'System action system-connector-test-system-action is not allowed to delete.', + message: 'System action system-connector-test.system-action is not allowed to delete.', }); }); @@ -181,13 +181,13 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { .delete( `${getUrlPrefix( Spaces.space1.id - )}/api/actions/action/system-connector-test-system-action` + )}/api/actions/action/system-connector-test.system-action` ) .set('kbn-xsrf', 'foo') .expect(400, { statusCode: 400, error: 'Bad Request', - message: 'System action system-connector-test-system-action is not allowed to delete.', + message: 'System action system-connector-test.system-action is not allowed to delete.', }); }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index 87dedc46327e07..dc99597a901e12 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -95,12 +95,12 @@ export default function getActionTests({ getService }: FtrProviderContext) { .get( `${getUrlPrefix( Spaces.space1.id - )}/api/actions/connector/system-connector-test-system-action` + )}/api/actions/connector/system-connector-test.system-action` ) .expect(200, { - id: 'system-connector-test-system-action', - connector_type_id: 'test-system-action', - name: 'System action: test-system-action', + id: 'system-connector-test.system-action', + connector_type_id: 'test.system-action', + name: 'System action: test.system-action', is_preconfigured: false, is_system_action: true, is_deprecated: false, @@ -211,12 +211,12 @@ export default function getActionTests({ getService }: FtrProviderContext) { .get( `${getUrlPrefix( Spaces.space1.id - )}/api/actions/action/system-connector-test-system-action` + )}/api/actions/action/system-connector-test.system-action` ) .expect(200, { - id: 'system-connector-test-system-action', - actionTypeId: 'test-system-action', - name: 'System action: test-system-action', + id: 'system-connector-test.system-action', + actionTypeId: 'test.system-action', + name: 'System action: test.system-action', isPreconfigured: false, isSystemAction: true, isDeprecated: false, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts index 528b2a6c59997e..2366c392c4e4d0 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -115,12 +115,12 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { referenced_by_count: 0, }, { - connector_type_id: 'test-system-action', - id: 'system-connector-test-system-action', + connector_type_id: 'test.system-action', + id: 'system-connector-test.system-action', is_deprecated: false, is_preconfigured: false, is_system_action: true, - name: 'System action: test-system-action', + name: 'System action: test.system-action', referenced_by_count: 0, }, { @@ -236,12 +236,12 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { referenced_by_count: 0, }, { - connector_type_id: 'test-system-action', - id: 'system-connector-test-system-action', + connector_type_id: 'test.system-action', + id: 'system-connector-test.system-action', is_deprecated: false, is_preconfigured: false, is_system_action: true, - name: 'System action: test-system-action', + name: 'System action: test.system-action', referenced_by_count: 0, }, { @@ -371,12 +371,12 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { referencedByCount: 0, }, { - actionTypeId: 'test-system-action', - id: 'system-connector-test-system-action', + actionTypeId: 'test.system-action', + id: 'system-connector-test.system-action', isDeprecated: false, isPreconfigured: false, isSystemAction: true, - name: 'System action: test-system-action', + name: 'System action: test.system-action', referencedByCount: 0, }, { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index 04122a6d8267bc..5dd515395994c4 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -131,7 +131,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .put( `${getUrlPrefix( Spaces.space1.id - )}/api/actions/connector/system-connector-test-system-action` + )}/api/actions/connector/system-connector-test.system-action` ) .set('kbn-xsrf', 'foo') .send({ @@ -146,7 +146,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(400, { statusCode: 400, error: 'Bad Request', - message: 'System action system-connector-test-system-action is not allowed to update.', + message: 'System action system-connector-test.system-action is not allowed to update.', }); }); @@ -319,7 +319,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .put( `${getUrlPrefix( Spaces.space1.id - )}/api/actions/action/system-connector-test-system-action` + )}/api/actions/action/system-connector-test.system-action` ) .set('kbn-xsrf', 'foo') .send({ @@ -334,7 +334,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(400, { statusCode: 400, error: 'Bad Request', - message: 'System action system-connector-test-system-action is not allowed to update.', + message: 'System action system-connector-test.system-action is not allowed to update.', }); }); From a1b5d516cc4236317c353bcdcbd6afd5eee18036 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Mon, 3 Jul 2023 14:02:17 +0300 Subject: [PATCH 26/28] Filtered out system connectors in telemetry --- .../server/action_type_registry.test.ts | 6 +- .../actions/server/actions_client.test.ts | 2 +- .../server/create_execute_function.test.ts | 69 +++++++++++++++++-- .../actions/server/create_execute_function.ts | 7 +- .../create_unsecured_execute_function.ts | 4 +- .../create_action_event_log_record_object.ts | 2 +- x-pack/plugins/actions/server/plugin.ts | 2 +- x-pack/plugins/actions/server/usage/task.ts | 18 +++-- 8 files changed, 90 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index 60b1cf75bc79f0..6988307b01b7e0 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -476,9 +476,9 @@ describe('actionTypeRegistry', () => { mockedActionsConfig.isActionTypeEnabled.mockReturnValue(false); mockedLicenseState.isLicenseValidForActionType.mockReturnValue({ isValid: true }); - expect(actionTypeRegistry.isActionExecutable('my-slack1', 'system-action-type')).toEqual( - true - ); + expect( + actionTypeRegistry.isActionExecutable('system-connector-.cases', 'system-action-type') + ).toEqual(true); }); test('should call isLicenseValidForActionType of the license state with notifyUsage false by default', async () => { diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 465e3f7ff4f857..1c5ecdc175cc92 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -788,7 +788,7 @@ describe('create()', () => { ); }); - it('throws when creating a system connector where the action type is not registered by a system connector exists in the in-memory list', async () => { + it('throws when creating a system connector where the action type is not registered but a system connector exists in the in-memory list', async () => { actionsClient = new ActionsClient({ logger, actionTypeRegistry, diff --git a/x-pack/plugins/actions/server/create_execute_function.test.ts b/x-pack/plugins/actions/server/create_execute_function.test.ts index 7fb737d2b53419..75a1ecf333311a 100644 --- a/x-pack/plugins/actions/server/create_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_execute_function.test.ts @@ -346,7 +346,7 @@ describe('execute()', () => { id: '123', type: 'action', attributes: { - actionTypeId: 'mock-action', + actionTypeId: '.cases', }, references: [], }); @@ -530,7 +530,7 @@ describe('execute()', () => { id: '123', type: 'action', attributes: { - actionTypeId: 'mock-action', + actionTypeId: '.cases', }, references: [], }); @@ -762,7 +762,7 @@ describe('execute()', () => { id: '123', type: 'action', attributes: { - actionTypeId: 'mock-action', + actionTypeId: '.cases', }, references: [], }); @@ -1174,7 +1174,7 @@ describe('bulkExecute()', () => { id: '123', type: 'action', attributes: { - actionTypeId: 'mock-action', + actionTypeId: '.cases', }, references: [], }, @@ -1389,7 +1389,7 @@ describe('bulkExecute()', () => { id: '123', type: 'action', attributes: { - actionTypeId: 'mock-action', + actionTypeId: '.cases', }, references: [], }, @@ -1637,4 +1637,63 @@ describe('bulkExecute()', () => { expect(mockedActionTypeRegistry.ensureActionTypeEnabled).not.toHaveBeenCalled(); }); + + test('should skip ensure action type if action type is system action and license is valid', async () => { + const mockedActionTypeRegistry = actionTypeRegistryMock.create(); + const executeFn = createBulkExecutionEnqueuerFunction({ + taskManager: mockTaskManager, + isESOCanEncrypt: true, + actionTypeRegistry: mockedActionTypeRegistry, + inMemoryConnectors: [ + { + actionTypeId: '.cases', + config: {}, + id: 'system-connector-.cases', + name: 'System action: .cases', + secrets: {}, + isPreconfigured: false, + isDeprecated: false, + isSystemAction: true, + }, + ], + }); + mockedActionTypeRegistry.isActionExecutable.mockImplementation(() => true); + savedObjectsClient.bulkGet.mockResolvedValueOnce({ + saved_objects: [ + { + id: '123', + type: 'action', + attributes: { + actionTypeId: '.cases', + }, + references: [], + }, + ], + }); + savedObjectsClient.bulkCreate.mockResolvedValueOnce({ + saved_objects: [ + { + id: '234', + type: 'action_task_params', + attributes: { + actionId: '123', + }, + references: [], + }, + ], + }); + + await executeFn(savedObjectsClient, [ + { + id: '123', + params: { baz: false }, + spaceId: 'default', + executionId: '123abc', + apiKey: null, + source: asHttpRequestExecutionSource(request), + }, + ]); + + expect(mockedActionTypeRegistry.ensureActionTypeEnabled).not.toHaveBeenCalled(); + }); }); diff --git a/x-pack/plugins/actions/server/create_execute_function.ts b/x-pack/plugins/actions/server/create_execute_function.ts index c25db5d7281e78..6752b17fd5ffde 100644 --- a/x-pack/plugins/actions/server/create_execute_function.ts +++ b/x-pack/plugins/actions/server/create_execute_function.ts @@ -295,9 +295,10 @@ async function getAction( inMemoryConnectors: InMemoryConnector[], actionId: string ): Promise<{ action: InMemoryConnector | RawAction; isInMemory: boolean }> { - const pcAction = inMemoryConnectors.find((action) => action.id === actionId); - if (pcAction) { - return { action: pcAction, isInMemory: true }; + const inMemoryAction = inMemoryConnectors.find((action) => action.id === actionId); + + if (inMemoryAction) { + return { action: inMemoryAction, isInMemory: true }; } const { attributes } = await unsecuredSavedObjectsClient.get('action', actionId); diff --git a/x-pack/plugins/actions/server/create_unsecured_execute_function.ts b/x-pack/plugins/actions/server/create_unsecured_execute_function.ts index bd4b947e532481..585f442c68e2f0 100644 --- a/x-pack/plugins/actions/server/create_unsecured_execute_function.ts +++ b/x-pack/plugins/actions/server/create_unsecured_execute_function.ts @@ -64,7 +64,9 @@ export function createBulkUnsecuredExecutionEnqueuerFunction({ } const connectors: InMemoryConnector[] = connectorIds - .map((connectorId) => inMemoryConnectors.find((pConnector) => pConnector.id === connectorId)) + .map((connectorId) => + inMemoryConnectors.find((inMemoryConnector) => inMemoryConnector.id === connectorId) + ) .filter(Boolean) as InMemoryConnector[]; connectors.forEach((connector) => { diff --git a/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts b/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts index d29cd670c514cb..4f8bf08966c59d 100644 --- a/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts +++ b/x-pack/plugins/actions/server/lib/create_action_event_log_record_object.ts @@ -80,7 +80,7 @@ export function createActionEventLogRecordObject(params: CreateActionEventLogRec type: so.type, id: so.id, type_id: so.typeId, - // set space_agnostic to true for preconfigured connectors + // set space_agnostic to true for in-memory connectors ...(so.type === 'action' && isInMemory ? { space_agnostic: isInMemory } : {}), ...(namespace ? { namespace } : {}), })), diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index 25b03b41413ee9..bc29c3e9ad2467 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -308,7 +308,7 @@ export class ActionsPlugin implements Plugin InMemoryConnector[], eventLogIndex: string ) { - registerActionsTelemetryTask(logger, taskManager, core, inMemoryConnectors, eventLogIndex); + registerActionsTelemetryTask(logger, taskManager, core, getInMemoryConnectors, eventLogIndex); } export function scheduleActionsTelemetry(logger: Logger, taskManager: TaskManagerStartContract) { @@ -38,14 +38,14 @@ function registerActionsTelemetryTask( logger: Logger, taskManager: TaskManagerSetupContract, core: CoreSetup, - inMemoryConnectors: InMemoryConnector[], + getInMemoryConnectors: () => InMemoryConnector[], eventLogIndex: string ) { taskManager.registerTaskDefinitions({ [TELEMETRY_TASK_TYPE]: { title: 'Actions usage fetch task', timeout: '5m', - createTaskRunner: telemetryTaskRunner(logger, core, inMemoryConnectors, eventLogIndex), + createTaskRunner: telemetryTaskRunner(logger, core, getInMemoryConnectors, eventLogIndex), }, }); } @@ -67,9 +67,17 @@ async function scheduleTasks(logger: Logger, taskManager: TaskManagerStartContra export function telemetryTaskRunner( logger: Logger, core: CoreSetup, - inMemoryConnectors: InMemoryConnector[], + getInMemoryConnectors: () => InMemoryConnector[], eventLogIndex: string ) { + /** + * Filter out system actions from the + * inMemoryConnectors list. + */ + const inMemoryConnectors = getInMemoryConnectors().filter( + (inMemoryConnector) => inMemoryConnector.isPreconfigured + ); + return ({ taskInstance }: RunContext) => { const { state } = taskInstance; const getEsClient = () => From a080d94cfe5905b802b499312868d3673cd6651b Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 7 Jul 2023 18:01:23 +0300 Subject: [PATCH 27/28] PR feedback --- x-pack/plugins/actions/server/actions_client.test.ts | 4 ++-- x-pack/plugins/actions/server/actions_client.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index 1c5ecdc175cc92..d553a6080dfd31 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -755,7 +755,7 @@ describe('create()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"This mySuperRadTestPreconfiguredId already exist in preconfigured action."` + `"This mySuperRadTestPreconfiguredId already exists in a preconfigured action."` ); }); @@ -2719,7 +2719,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"System action system-connector-.cases is not allowed to update."` + `"System action system-connector-.cases can not be updated."` ); }); }); diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index ce82913cd749c3..9a4349601216a2 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -228,7 +228,7 @@ export class ActionsClient { if (foundInMemoryConnector?.isPreconfigured) { throw Boom.badRequest( i18n.translate('xpack.actions.serverSideErrors.predefinedIdConnectorAlreadyExists', { - defaultMessage: 'This {id} already exist in preconfigured action.', + defaultMessage: 'This {id} already exists in a preconfigured action.', values: { id, }, @@ -295,7 +295,7 @@ export class ActionsClient { if (foundInMemoryConnector?.isSystemAction) { throw Boom.badRequest( i18n.translate('xpack.actions.serverSideErrors.systemActionUpdateForbidden', { - defaultMessage: 'System action {id} is not allowed to update.', + defaultMessage: 'System action {id} can not be updated.', values: { id, }, From abc6014d4d45d834308d9ef908cf144457995e35 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 7 Jul 2023 18:54:00 +0300 Subject: [PATCH 28/28] Fix tests --- x-pack/plugins/actions/server/actions_client.test.ts | 2 +- x-pack/plugins/actions/server/actions_client.ts | 2 +- .../security_and_spaces/group2/tests/actions/create.ts | 3 ++- .../security_and_spaces/group2/tests/actions/update.ts | 5 ++--- .../spaces_only/tests/actions/create.ts | 2 +- .../spaces_only/tests/actions/update.ts | 8 ++++---- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index d553a6080dfd31..a18a8adada424d 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -2675,7 +2675,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Preconfigured action testPreconfigured is not allowed to update."` + `"Preconfigured action testPreconfigured can not be updated."` ); }); diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 9a4349601216a2..db25e302a4ac02 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -306,7 +306,7 @@ export class ActionsClient { if (foundInMemoryConnector?.isPreconfigured) { throw new PreconfiguredActionDisabledModificationError( i18n.translate('xpack.actions.serverSideErrors.predefinedActionUpdateDisabled', { - defaultMessage: 'Preconfigured action {id} is not allowed to update.', + defaultMessage: 'Preconfigured action {id} can not be updated.', values: { id, }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts index 6be435b569a977..017fd3e45999bd 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/create.ts @@ -350,7 +350,8 @@ export default function createActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: 'This custom-system-abc-connector already exist in preconfigured action.', + message: + 'This custom-system-abc-connector already exists in a preconfigured action.', }); break; default: diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts index c27208860fcfa8..7c3c00534f11d5 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/update.ts @@ -345,7 +345,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: `Preconfigured action custom-system-abc-connector is not allowed to update.`, + message: `Preconfigured action custom-system-abc-connector can not be updated.`, }); break; default: @@ -423,8 +423,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: - 'System action system-connector-test.system-action is not allowed to update.', + message: 'System action system-connector-test.system-action can not be updated.', }); break; default: diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index 614c130cc7120f..6941aa6f180255 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -93,7 +93,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { .expect(400, { statusCode: 400, error: 'Bad Request', - message: 'This custom-system-abc-connector already exist in preconfigured action.', + message: 'This custom-system-abc-connector already exists in a preconfigured action.', }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index 5dd515395994c4..d64ccc15c49994 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -122,7 +122,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(400, { statusCode: 400, error: 'Bad Request', - message: `Preconfigured action custom-system-abc-connector is not allowed to update.`, + message: `Preconfigured action custom-system-abc-connector can not be updated.`, }); }); @@ -146,7 +146,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(400, { statusCode: 400, error: 'Bad Request', - message: 'System action system-connector-test.system-action is not allowed to update.', + message: 'System action system-connector-test.system-action can not be updated.', }); }); @@ -310,7 +310,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(400, { statusCode: 400, error: 'Bad Request', - message: `Preconfigured action custom-system-abc-connector is not allowed to update.`, + message: `Preconfigured action custom-system-abc-connector can not be updated.`, }); }); @@ -334,7 +334,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { .expect(400, { statusCode: 400, error: 'Bad Request', - message: 'System action system-connector-test.system-action is not allowed to update.', + message: 'System action system-connector-test.system-action can not be updated.', }); });