-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution][Endpoint] Display better success and failure mess…
…ages for kill suspend process actions (#137353) * add map with endpoint action response code and associated i18n message * Add component to handle getting a failure message from a completed action * Add component to handle getting a failure message from a completed action * Correct type definition for ActionResponseOutput * New ActionSuccess component + use it in kill/suspend process * Change default failure message * add some jsdocs to the endpoint codes
- Loading branch information
1 parent
a40d241
commit cb4d6aa
Showing
16 changed files
with
304 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
...management/components/endpoint_action_failure_message/endpoint_action_failure_message.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* 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 { EuiSpacer } from '@elastic/eui'; | ||
import { FormattedMessage } from '@kbn/i18n-react'; | ||
import { i18n } from '@kbn/i18n'; | ||
import { endpointActionResponseCodes } from '../endpoint_responder/endpoint_action_response_codes'; | ||
import type { ActionDetails, MaybeImmutable } from '../../../../common/endpoint/types'; | ||
|
||
interface EndpointActionFailureMessageProps { | ||
action: MaybeImmutable<ActionDetails<{ code?: string }>>; | ||
} | ||
|
||
export const EndpointActionFailureMessage = memo<EndpointActionFailureMessageProps>( | ||
({ action }) => { | ||
return useMemo(() => { | ||
if (!action.isCompleted || action.wasSuccessful) { | ||
return null; | ||
} | ||
|
||
const errors: string[] = []; | ||
|
||
// Determine if each endpoint returned a response code and if so, | ||
// see if we have a localized message for it | ||
if (action.outputs) { | ||
for (const agent of action.agents) { | ||
const endpointAgentOutput = action.outputs[agent]; | ||
|
||
if ( | ||
endpointAgentOutput && | ||
endpointAgentOutput.type === 'json' && | ||
endpointAgentOutput.content.code && | ||
endpointActionResponseCodes[endpointAgentOutput.content.code] | ||
) { | ||
errors.push(endpointActionResponseCodes[endpointAgentOutput.content.code]); | ||
} | ||
} | ||
} | ||
|
||
if (!errors.length) { | ||
if (action.errors) { | ||
errors.push(...action.errors); | ||
} else { | ||
errors.push( | ||
i18n.translate('xpack.securitySolution.endpointActionFailureMessage.unknownFailure', { | ||
defaultMessage: 'Action failed', | ||
}) | ||
); | ||
} | ||
} | ||
|
||
return ( | ||
<> | ||
<FormattedMessage | ||
id="xpack.securitySolution.endpointResponseActions.actionError.errorMessage" | ||
defaultMessage="The following { errorCount, plural, =1 {error was} other {errors were}} encountered:" | ||
values={{ errorCount: errors.length }} | ||
/> | ||
<EuiSpacer size="s" /> | ||
<div>{errors.join(' | ')}</div> | ||
</> | ||
); | ||
}, [action]); | ||
} | ||
); | ||
EndpointActionFailureMessage.displayName = 'EndpointActionFailureMessage'; |
8 changes: 8 additions & 0 deletions
8
...s/security_solution/public/management/components/endpoint_action_failure_message/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
export { EndpointActionFailureMessage } from './endpoint_action_failure_message'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
...gins/security_solution/public/management/components/endpoint_responder/action_success.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* 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 { endpointActionResponseCodes } from './endpoint_action_response_codes'; | ||
import type { ActionDetails, MaybeImmutable } from '../../../../common/endpoint/types'; | ||
import type { CommandExecutionResultComponent, CommandExecutionResultProps } from '../console'; | ||
|
||
export interface ActionSuccessProps extends CommandExecutionResultProps { | ||
action: MaybeImmutable<ActionDetails<{ code?: string }>>; | ||
ResultComponent: CommandExecutionResultComponent; | ||
} | ||
|
||
/** | ||
* Display generic success message for all actions | ||
*/ | ||
export const ActionSuccess = memo<ActionSuccessProps>( | ||
({ action, ResultComponent, title: _title, ...props }) => { | ||
const title = useMemo(() => { | ||
if (_title) { | ||
return _title; | ||
} | ||
|
||
const firstAgentId = action.agents[0]; | ||
const actionOutputCode = action.outputs?.[firstAgentId]?.content?.code; | ||
|
||
return actionOutputCode ? endpointActionResponseCodes[actionOutputCode] : undefined; | ||
}, [_title, action.agents, action.outputs]); | ||
|
||
return <ResultComponent {...props} title={title} />; | ||
} | ||
); | ||
ActionSuccess.displayName = 'ActionSuccess'; |
69 changes: 69 additions & 0 deletions
69
...olution/public/management/components/endpoint_responder/endpoint_action_response_codes.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* 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 { i18n } from '@kbn/i18n'; | ||
|
||
const CODES = Object.freeze({ | ||
// ----------------------------------------------------------------- | ||
// SUSPEND-PROCESS CODES | ||
// ----------------------------------------------------------------- | ||
/** | ||
* Code will be used whenever you provide an entity_id or pid that isn't found. | ||
* suspend_process will always be an error because the process was not found to be suspended | ||
*/ | ||
'ra_suspend-process_error_not-found': i18n.translate( | ||
'xpack.securitySolution.endpointActionResponseCodes.suspendProcess.notFoundError', | ||
{ defaultMessage: 'The provided process was not found' } | ||
), | ||
|
||
/** | ||
* Code will be used when the provided process can not be killed (for stability reasons). | ||
* Example: This occurs if you try to kill Endpoint Security | ||
*/ | ||
'ra_suspend-process_error_not-permitted': i18n.translate( | ||
'xpack.securitySolution.endpointActionResponseCodes.suspendProcess.notPermittedSuccess', | ||
{ defaultMessage: 'The provided process cannot be suspended' } | ||
), | ||
|
||
// ----------------------------------------------------------------- | ||
// KILL-PROCESS CODES | ||
// ----------------------------------------------------------------- | ||
/** | ||
* Code will be used whenever you provide an entity_id that isn't found. Since entity_id is | ||
* unique, we can guarantee that it was legitimately not found and not just that the process | ||
* was already killed. | ||
*/ | ||
'ra_kill-process_error_not-found': i18n.translate( | ||
'xpack.securitySolution.endpointActionResponseCodes.killProcess.notFoundError', | ||
{ defaultMessage: 'The provided process was not found' } | ||
), | ||
|
||
/** | ||
* Code will be used whenever you provide a pid that isn't found. Since pid is reused, we aren't | ||
* sure if the process was already killed or just wasn't found. In either case, a process with | ||
* that pid will no longer be running. | ||
*/ | ||
'ra_kill-process_success_no-action': i18n.translate( | ||
'xpack.securitySolution.endpointActionResponseCodes.killProcess.noActionSuccess', | ||
{ defaultMessage: 'Action completed. The provided process was not found or already killed' } | ||
), | ||
|
||
/** | ||
* Code will be used when the provided process can not be killed (for stability reasons). | ||
* Example: This occurs if you try to kill Endpoint Security | ||
*/ | ||
'ra_kill-process_error_not-permitted': i18n.translate( | ||
'xpack.securitySolution.endpointActionResponseCodes.killProcess.notPermittedSuccess', | ||
{ defaultMessage: 'The provided process cannot be killed' } | ||
), | ||
}); | ||
|
||
/** | ||
* A map of possible code's that can be returned from the endpoint for response actions | ||
*/ | ||
export const endpointActionResponseCodes: Readonly<Record<string | keyof typeof CODES, string>> = | ||
CODES; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.