Skip to content

Commit

Permalink
[Response Ops][Actions] Keep track of action execution source and sho…
Browse files Browse the repository at this point in the history
…w in connector exec log (elastic#152030)

Resolves elastic#143984

## Summary

This PR persists an execution source field to the action event log
`execute` document which indicates the source of the action. Currently,
we have 3 sources of action execution:
* `http_request` - these are executions triggered from the `_execute`
route in the actions API. This is used by the test connector
functionality in the UI but could also be used directly via curl
command. We do not differentiate between the two.
* `notification` - these are executions triggered by the notifications
service. currently, this only occurs when a case is assigned to a user.
* `saved_object` - these are executions triggered by another saved
object, like the `alert` saved object. Cases also triggers action
execution in `x-pack/plugins/cases/server/client/cases/push.ts`. The
source will be saved as the type of the saved object that triggered the
action

After persisting the source, we also updated the connector exec log to
show the source in a new column (hidden by default).

<img width="1710" alt="Screenshot 2023-03-01 at 4 12 35 PM"
src="https://user-images.githubusercontent.com/13104637/222266192-2877ad2b-0309-408e-ad44-ec37ef597afb.png">

## To Verify

1. Create a connector and run it via the Test Connector tab
2. Create a rule that will fire an action using the connector and let it
run
3. Create a case an assign it to a user (other than yourself)
4. Go to the connector exec log view, add the "Source" column and see
that it is populated. You can also inspect the event log docs for
`provider: "actions"` and see that `kibana.action.execution.source` is
populated.

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
2 people authored and bmorelli25 committed Mar 10, 2023
1 parent 8a85471 commit afa84db
Show file tree
Hide file tree
Showing 33 changed files with 809 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
expect(hashMap).toMatchInlineSnapshot(`
Object {
"action": "6cfc277ed3211639e37546ac625f4a68f2494215",
"action_task_params": "db2afea7d78e00e725486b791554d0d4e81956ef",
"action_task_params": "5f419caba96dd8c77d0f94013e71d43890e3d5d6",
"alert": "785240e3137f5eb1a0f8986e5b8eff99780fc04f",
"api_key_pending_invalidation": "16e7bcf8e78764102d7f525542d5b616809a21ee",
"apm-indices": "d19dd7fb51f2d2cbc1f8769481721e0953f9a6d2",
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/actions/common/execution_log_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface IExecutionLog {
connector_name: string;
connector_id: string;
timed_out: boolean;
source: string;
}

export interface IExecutionLogResult {
Expand Down
28 changes: 27 additions & 1 deletion x-pack/plugins/actions/server/actions_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import { ByteSizeValue } from '@kbn/config-schema';
import { ActionTypeRegistry, ActionTypeRegistryOpts } from './action_type_registry';
import { ActionsClient } from './actions_client';
import { ExecutorType, ActionType } from './types';
import { ActionExecutor, TaskRunnerFactory, ILicenseState } from './lib';
import {
ActionExecutor,
TaskRunnerFactory,
ILicenseState,
asHttpRequestExecutionSource,
} from './lib';
import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks';
import { actionsConfigMock } from './actions_config.mock';
import { getActionsConfigurationUtilities } from './actions_config';
Expand Down Expand Up @@ -2171,6 +2176,7 @@ describe('execute()', () => {
params: {
name: 'my name',
},
source: asHttpRequestExecutionSource(request),
});
expect(authorization.ensureAuthorized).toHaveBeenCalledWith('execute');
});
Expand All @@ -2189,6 +2195,7 @@ describe('execute()', () => {
params: {
name: 'my name',
},
source: asHttpRequestExecutionSource(request),
})
).rejects.toMatchInlineSnapshot(`[Error: Unauthorized to execute all actions]`);

Expand All @@ -2205,6 +2212,7 @@ describe('execute()', () => {
params: {
name: 'my name',
},
source: asHttpRequestExecutionSource(request),
});

expect(trackLegacyRBACExemption as jest.Mock).toBeCalledWith('execute', mockUsageCounter);
Expand All @@ -2221,6 +2229,7 @@ describe('execute()', () => {
params: {
name: 'my name',
},
source: asHttpRequestExecutionSource(request),
})
).resolves.toMatchObject({ status: 'ok', actionId });

Expand All @@ -2231,6 +2240,7 @@ describe('execute()', () => {
name: 'my name',
},
actionExecutionId,
source: asHttpRequestExecutionSource(request),
});

await expect(
Expand All @@ -2239,6 +2249,7 @@ describe('execute()', () => {
params: {
name: 'my name',
},
source: asHttpRequestExecutionSource(request),
relatedSavedObjects: [
{
id: 'some-id',
Expand All @@ -2263,6 +2274,7 @@ describe('execute()', () => {
},
],
actionExecutionId,
source: asHttpRequestExecutionSource(request),
});

await expect(
Expand All @@ -2271,6 +2283,7 @@ describe('execute()', () => {
params: {
name: 'my name',
},
source: asHttpRequestExecutionSource(request),
relatedSavedObjects: [
{
id: 'some-id',
Expand All @@ -2288,6 +2301,7 @@ describe('execute()', () => {
params: {
name: 'my name',
},
source: asHttpRequestExecutionSource(request),
relatedSavedObjects: [
{
id: 'some-id',
Expand All @@ -2313,6 +2327,7 @@ describe('enqueueExecution()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
});
expect(authorization.ensureAuthorized).toHaveBeenCalledWith('execute');
});
Expand All @@ -2332,6 +2347,7 @@ describe('enqueueExecution()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
})
).rejects.toMatchInlineSnapshot(`[Error: Unauthorized to execute all actions]`);

Expand All @@ -2349,6 +2365,7 @@ describe('enqueueExecution()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
});

expect(trackLegacyRBACExemption as jest.Mock).toBeCalledWith(
Expand All @@ -2365,6 +2382,7 @@ describe('enqueueExecution()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: Buffer.from('123:abc').toString('base64'),
source: asHttpRequestExecutionSource(request),
};
await expect(actionsClient.enqueueExecution(opts)).resolves.toMatchInlineSnapshot(`undefined`);

Expand All @@ -2385,13 +2403,15 @@ describe('bulkEnqueueExecution()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
{
id: uuidv4(),
params: {},
spaceId: 'default',
executionId: '456def',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
]);
expect(authorization.ensureAuthorized).toHaveBeenCalledWith('execute');
Expand All @@ -2413,13 +2433,15 @@ describe('bulkEnqueueExecution()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
{
id: uuidv4(),
params: {},
spaceId: 'default',
executionId: '456def',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
])
).rejects.toMatchInlineSnapshot(`[Error: Unauthorized to execute all actions]`);
Expand All @@ -2439,13 +2461,15 @@ describe('bulkEnqueueExecution()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
{
id: uuidv4(),
params: {},
spaceId: 'default',
executionId: '456def',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
]);

Expand All @@ -2468,13 +2492,15 @@ describe('bulkEnqueueExecution()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
{
id: uuidv4(),
params: {},
spaceId: 'default',
executionId: '456def',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
];
await expect(actionsClient.bulkEnqueueExecution(opts)).resolves.toMatchInlineSnapshot(
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/actions/server/constants/event_log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@ export const EVENT_LOG_PROVIDER = 'actions';
export const EVENT_LOG_ACTIONS = {
execute: 'execute',
executeStart: 'execute-start',
executeViaHttp: 'execute-via-http',
executeTimeout: 'execute-timeout',
};
18 changes: 18 additions & 0 deletions x-pack/plugins/actions/server/create_execute_function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ describe('execute()', () => {
actionId: '123',
params: { baz: false },
executionId: '123abc',
source: 'HTTP_REQUEST',
apiKey: Buffer.from('123:abc').toString('base64'),
},
{
Expand Down Expand Up @@ -151,6 +152,7 @@ describe('execute()', () => {
params: { baz: false },
executionId: '123abc',
consumer: 'test-consumer',
source: 'HTTP_REQUEST',
apiKey: Buffer.from('123:abc').toString('base64'),
},
{
Expand Down Expand Up @@ -213,6 +215,7 @@ describe('execute()', () => {
params: { baz: false },
apiKey: Buffer.from('123:abc').toString('base64'),
executionId: '123abc',
source: 'HTTP_REQUEST',
relatedSavedObjects: [
{
id: 'related_some-type_0',
Expand Down Expand Up @@ -303,6 +306,7 @@ describe('execute()', () => {
actionId: '123',
params: { baz: false },
executionId: '123abc',
source: 'SAVED_OBJECT',
apiKey: Buffer.from('123:abc').toString('base64'),
},
{
Expand Down Expand Up @@ -390,6 +394,7 @@ describe('execute()', () => {
params: { baz: false },
apiKey: Buffer.from('123:abc').toString('base64'),
executionId: '123abc',
source: 'SAVED_OBJECT',
relatedSavedObjects: [
{
id: 'related_some-type_0',
Expand Down Expand Up @@ -430,6 +435,7 @@ describe('execute()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Unable to execute action 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."`
Expand Down Expand Up @@ -460,6 +466,7 @@ describe('execute()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
})
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Unable to execute action because no secrets are defined for the \\"mock-action\\" connector."`
Expand Down Expand Up @@ -493,6 +500,7 @@ describe('execute()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
})
).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`);
});
Expand Down Expand Up @@ -537,6 +545,7 @@ describe('execute()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
});

expect(mockedActionTypeRegistry.ensureActionTypeEnabled).not.toHaveBeenCalled();
Expand Down Expand Up @@ -613,6 +622,7 @@ describe('bulkExecute()', () => {
actionId: '123',
params: { baz: false },
executionId: '123abc',
source: 'HTTP_REQUEST',
apiKey: Buffer.from('123:abc').toString('base64'),
},
references: [
Expand Down Expand Up @@ -703,6 +713,7 @@ describe('bulkExecute()', () => {
params: { baz: false },
executionId: '123abc',
consumer: 'test-consumer',
source: 'HTTP_REQUEST',
apiKey: Buffer.from('123:abc').toString('base64'),
},
references: [
Expand Down Expand Up @@ -778,6 +789,7 @@ describe('bulkExecute()', () => {
params: { baz: false },
apiKey: Buffer.from('123:abc').toString('base64'),
executionId: '123abc',
source: 'HTTP_REQUEST',
relatedSavedObjects: [
{
id: 'related_some-type_0',
Expand Down Expand Up @@ -885,6 +897,7 @@ describe('bulkExecute()', () => {
actionId: '123',
params: { baz: false },
executionId: '123abc',
source: 'SAVED_OBJECT',
apiKey: Buffer.from('123:abc').toString('base64'),
},
references: [
Expand Down Expand Up @@ -989,6 +1002,7 @@ describe('bulkExecute()', () => {
params: { baz: false },
apiKey: Buffer.from('123:abc').toString('base64'),
executionId: '123abc',
source: 'SAVED_OBJECT',
relatedSavedObjects: [
{
id: 'related_some-type_0',
Expand Down Expand Up @@ -1031,6 +1045,7 @@ describe('bulkExecute()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
])
).rejects.toThrowErrorMatchingInlineSnapshot(
Expand Down Expand Up @@ -1067,6 +1082,7 @@ describe('bulkExecute()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
])
).rejects.toThrowErrorMatchingInlineSnapshot(
Expand Down Expand Up @@ -1106,6 +1122,7 @@ describe('bulkExecute()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
])
).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`);
Expand Down Expand Up @@ -1162,6 +1179,7 @@ describe('bulkExecute()', () => {
spaceId: 'default',
executionId: '123abc',
apiKey: null,
source: asHttpRequestExecutionSource(request),
},
]);

Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/actions/server/create_execute_function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export function createExecutionEnqueuerFunction({
executionId,
consumer,
relatedSavedObjects: relatedSavedObjectWithRefs,
...(source ? { source: source.type } : {}),
},
{
references: taskReferences,
Expand Down Expand Up @@ -202,6 +203,7 @@ export function createBulkExecutionEnqueuerFunction({
executionId: actionToExecute.executionId,
consumer: actionToExecute.consumer,
relatedSavedObjects: relatedSavedObjectWithRefs,
...(actionToExecute.source ? { source: actionToExecute.source.type } : {}),
},
references: taskReferences,
};
Expand Down
Loading

0 comments on commit afa84db

Please sign in to comment.