Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EDR Workflows] CrowdStrike RunScript: Log Actions and UI Output #204044

Merged
merged 18 commits into from
Dec 17, 2024
Prev Previous commit
Next Next commit
fix
tomsonpl committed Dec 17, 2024
commit 0b96a3fe8721c86a8aded3fcdc0ddaf2cddc1236
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* 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 React, { memo, useMemo } from 'react';

import { i18n } from '@kbn/i18n';
import { ExecuteActionHostResponse } from '../../endpoint_execute_action';
import { useSendRunScriptEndpoint } from '../../../hooks/response_actions/use_send_run_script_endpoint_request';
import type { RunScriptActionRequestBody } from '../../../../../common/api/endpoint';
import { useConsoleActionSubmitter } from '../hooks/use_console_action_submitter';
import type {
ResponseActionRunScriptOutputContent,
ResponseActionRunScriptParameters,
} from '../../../../../common/endpoint/types';
import type { ActionRequestComponentProps } from '../types';

export const RunScriptActionResult = memo<
ActionRequestComponentProps<
{
Raw?: string;
HostPath?: string;
CloudFile?: string;
CommandLine?: string;
Timeout?: number;
comment?: string;
},
ResponseActionRunScriptOutputContent,
ResponseActionRunScriptParameters
>
>(({ command, setStore, store, status, setStatus, ResultComponent }) => {
const actionCreator = useSendRunScriptEndpoint();
const actionRequestBody = useMemo<undefined | RunScriptActionRequestBody>(() => {
const { endpointId, agentType } = command.commandDefinition?.meta ?? {};

if (!endpointId) {
return;
}
return {
agent_type: agentType,
endpoint_ids: [endpointId],
parameters: {
raw: command.args.args.Raw?.[0],
hostPath: command.args.args.HostPath?.[0],
cloudFile: command.args.args.CloudFile?.[0],
commandLine: command.args.args.CommandLine?.[0],
timeout: command.args.args.Timeout?.[0],
},
comment: command.args.args?.comment?.[0],
};
}, [command]);

const { result, actionDetails: completedActionDetails } = useConsoleActionSubmitter<
RunScriptActionRequestBody,
ResponseActionRunScriptOutputContent,
ResponseActionRunScriptParameters
>({
ResultComponent,
setStore,
store,
status,
setStatus,
actionCreator,
actionRequestBody,
dataTestSubj: 'runscript',
});

if (!completedActionDetails || !completedActionDetails.wasSuccessful) {
return result;
}

return (
<ResultComponent
data-test-subj="executeSuccess"
showAs="success"
title={i18n.translate(
'xpack.securitySolution.endpointResponseActions.runScriptAction.successTitle',
{ defaultMessage: 'RunScript was successful.' }
)}
>
<ExecuteActionHostResponse
action={completedActionDetails}
canAccessFileDownloadLink={true}
agentId={command.commandDefinition?.meta?.endpointId}
textSize="s"
data-test-subj="console"
hideFile={false}
hideContext={false}
/>
</ResultComponent>
);
});
RunScriptActionResult.displayName = 'RunScriptActionResult';
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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 type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
import type { IHttpFetchError } from '@kbn/core-http-browser';
import { useMutation } from '@tanstack/react-query';
import type { RunScriptActionRequestBody } from '../../../../common/api/endpoint';
import { KibanaServices } from '../../../common/lib/kibana';
import { RUN_SCRIPT_ROUTE } from '../../../../common/endpoint/constants';
import type { ResponseActionApiResponse } from '../../../../common/endpoint/types';

export const useSendRunScriptEndpoint = (
options?: UseMutationOptions<
ResponseActionApiResponse,
IHttpFetchError,
RunScriptActionRequestBody
>
): UseMutationResult<ResponseActionApiResponse, IHttpFetchError, RunScriptActionRequestBody> => {
return useMutation<ResponseActionApiResponse, IHttpFetchError, RunScriptActionRequestBody>(
(runScriptActionReqBody) => {
return KibanaServices.get().http.post<ResponseActionApiResponse>(RUN_SCRIPT_ROUTE, {
body: JSON.stringify(runScriptActionReqBody),
version: '2023-10-31',
});
},
options
);
};