From 367fc7812263aaebcf25a63becefc16449d12aff Mon Sep 17 00:00:00 2001 From: Candace Park Date: Mon, 12 Jul 2021 16:50:28 -0400 Subject: [PATCH 1/3] add unenrolled state and show - when retrieving agent status initially --- .../common/endpoint/types/index.ts | 5 ++++ .../components/endpoint/agent_status.tsx | 2 +- .../detection_engine/alerts/translations.ts | 10 ------- .../alerts/use_host_isolation_status.tsx | 18 +++++------ .../endpoint_hosts/view/host_constants.ts | 1 + .../body/renderers/agent_statuses.tsx | 30 ++++++++++++------- .../timeline/body/renderers/translations.ts | 7 +++++ 7 files changed, 42 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/security_solution/common/endpoint/types/index.ts b/x-pack/plugins/security_solution/common/endpoint/types/index.ts index cf8c33d38f8fa9..3cd4a422a5fe84 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/index.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/index.ts @@ -400,6 +400,11 @@ export enum HostStatus { * Host is inactive as indicated by its checkin status during the last checkin window */ INACTIVE = 'inactive', + + /** + * Host is unenrolled + */ + UNENROLLED = 'unenrolled', } export type PolicyInfo = Immutable<{ diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/agent_status.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/agent_status.tsx index f93721349fdac0..d7091059012151 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/agent_status.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/agent_status.tsx @@ -20,7 +20,7 @@ export const AgentStatus = React.memo(({ hostStatus }: { hostStatus: HostStatus > diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/translations.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/translations.ts index d5234e719b869c..ed6a22375a7769 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/translations.ts @@ -37,13 +37,3 @@ export const CASES_FROM_ALERTS_FAILURE = i18n.translate( 'xpack.securitySolution.endpoint.hostIsolation.casesFromAlerts.title', { defaultMessage: 'Failed to find associated cases' } ); - -export const ISOLATION_STATUS_FAILURE = i18n.translate( - 'xpack.securitySolution.endpoint.hostIsolation.isolationStatus.title', - { defaultMessage: 'Failed to retrieve current isolation status' } -); - -export const ISOLATION_PENDING_FAILURE = i18n.translate( - 'xpack.securitySolution.endpoint.hostIsolation.isolationPending.title', - { defaultMessage: 'Failed to retrieve isolation pending statuses' } -); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_host_isolation_status.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_host_isolation_status.tsx index 259a377b10b796..6a40898d0a109f 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_host_isolation_status.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_host_isolation_status.tsx @@ -7,9 +7,7 @@ import { isEmpty } from 'lodash'; import { useEffect, useState } from 'react'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { getHostMetadata } from './api'; -import { ISOLATION_STATUS_FAILURE, ISOLATION_PENDING_FAILURE } from './translations'; import { fetchPendingActionsByAgentId } from '../../../../common/lib/endpoint_pending_actions'; import { isEndpointHostIsolated } from '../../../../common/utils/validators'; import { HostStatus } from '../../../../../common/endpoint/types'; @@ -17,7 +15,7 @@ import { HostStatus } from '../../../../../common/endpoint/types'; interface HostIsolationStatusResponse { loading: boolean; isIsolated: boolean; - agentStatus: HostStatus; + agentStatus: HostStatus | undefined; pendingIsolation: number; pendingUnisolation: number; } @@ -30,13 +28,11 @@ export const useHostIsolationStatus = ({ agentId: string; }): HostIsolationStatusResponse => { const [isIsolated, setIsIsolated] = useState(false); - const [agentStatus, setAgentStatus] = useState(HostStatus.UNHEALTHY); + const [agentStatus, setAgentStatus] = useState(); const [pendingIsolation, setPendingIsolation] = useState(0); const [pendingUnisolation, setPendingUnisolation] = useState(0); const [loading, setLoading] = useState(false); - const { addError } = useAppToasts(); - useEffect(() => { const abortCtrl = new AbortController(); // isMounted tracks if a component is mounted before changing state @@ -55,7 +51,10 @@ export const useHostIsolationStatus = ({ if (error.name === 'AbortError') { return; } - addError(error.message, { title: ISOLATION_STATUS_FAILURE }); + + if (isMounted && error.body.statusCode === 404) { + setAgentStatus(HostStatus.UNENROLLED); + } } try { @@ -65,7 +64,8 @@ export const useHostIsolationStatus = ({ setPendingUnisolation(data[0].pending_actions?.unisolate ?? 0); } } catch (error) { - addError(error.message, { title: ISOLATION_PENDING_FAILURE }); + // silently catch non-user initiated error + return; } if (isMounted) { @@ -87,6 +87,6 @@ export const useHostIsolationStatus = ({ isMounted = false; abortCtrl.abort(); }; - }, [addError, agentId]); + }, [agentId]); return { loading, isIsolated, agentStatus, pendingIsolation, pendingUnisolation }; }; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/host_constants.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/host_constants.ts index fb9661b509a33c..45cf7d725443d0 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/host_constants.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/host_constants.ts @@ -18,6 +18,7 @@ export const HOST_STATUS_TO_BADGE_COLOR = Object.freeze< [HostStatus.UPDATING]: 'primary', [HostStatus.OFFLINE]: 'default', [HostStatus.INACTIVE]: 'default', + [HostStatus.UNENROLLED]: 'default', }); export const POLICY_STATUS_TO_HEALTH_COLOR = Object.freeze< diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/agent_statuses.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/agent_statuses.tsx index 2c88b305c7d05f..5efd5eecda5599 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/agent_statuses.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/agent_statuses.tsx @@ -6,11 +6,12 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { DefaultDraggable } from '../../../../../common/components/draggables'; import { EndpointHostIsolationStatus } from '../../../../../common/components/endpoint/host_isolation'; import { useHostIsolationStatus } from '../../../../../detections/containers/detection_engine/alerts/use_host_isolation_status'; import { AgentStatus } from '../../../../../common/components/endpoint/agent_status'; +import { EMPTY_STATUS } from './translations'; export const AgentStatuses = React.memo( ({ @@ -31,18 +32,25 @@ export const AgentStatuses = React.memo( pendingUnisolation, } = useHostIsolationStatus({ agentId: value }); const isolationFieldName = 'host.isolation'; + console.log(agentStatus); return ( - - - - - + {agentStatus !== undefined ? ( + + + + + + ) : ( + +

{EMPTY_STATUS}

+
+ )} Date: Mon, 12 Jul 2021 17:07:42 -0400 Subject: [PATCH 2/3] remove console log --- .../components/timeline/body/renderers/agent_statuses.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/agent_statuses.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/agent_statuses.tsx index 5efd5eecda5599..dac10f46487841 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/agent_statuses.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/agent_statuses.tsx @@ -32,7 +32,6 @@ export const AgentStatuses = React.memo( pendingUnisolation, } = useHostIsolationStatus({ agentId: value }); const isolationFieldName = 'host.isolation'; - console.log(agentStatus); return ( {agentStatus !== undefined ? ( From f41375889f77fca65a6215883ebbf8380150f77d Mon Sep 17 00:00:00 2001 From: Candace Park Date: Mon, 12 Jul 2021 17:45:14 -0400 Subject: [PATCH 3/3] disable take action button --- .../components/host_isolation/take_action_dropdown.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/host_isolation/take_action_dropdown.tsx b/x-pack/plugins/security_solution/public/detections/components/host_isolation/take_action_dropdown.tsx index a10ad901441ea5..1404f7927d6ec8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/host_isolation/take_action_dropdown.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/host_isolation/take_action_dropdown.tsx @@ -10,6 +10,7 @@ import { EuiContextMenuItem, EuiContextMenuPanel, EuiButton, EuiPopover } from ' import { ISOLATE_HOST, UNISOLATE_HOST } from './translations'; import { TAKE_ACTION } from '../alerts_table/alerts_utility_bar/translations'; import { useHostIsolationStatus } from '../../containers/detection_engine/alerts/use_host_isolation_status'; +import { HostStatus } from '../../../../common/endpoint/types'; export const TakeActionDropdown = React.memo( ({ @@ -19,7 +20,9 @@ export const TakeActionDropdown = React.memo( onChange: (action: 'isolateHost' | 'unisolateHost') => void; agentId: string; }) => { - const { loading, isIsolated: isolationStatus } = useHostIsolationStatus({ agentId }); + const { loading, isIsolated: isolationStatus, agentStatus } = useHostIsolationStatus({ + agentId, + }); const [isPopoverOpen, setIsPopoverOpen] = useState(false); const closePopoverHandler = useCallback(() => { @@ -41,7 +44,7 @@ export const TakeActionDropdown = React.memo( iconSide="right" fill iconType="arrowDown" - disabled={loading} + disabled={loading || agentStatus === HostStatus.UNENROLLED} onClick={() => { setIsPopoverOpen(!isPopoverOpen); }} @@ -49,7 +52,7 @@ export const TakeActionDropdown = React.memo( {TAKE_ACTION} ); - }, [isPopoverOpen, loading]); + }, [isPopoverOpen, loading, agentStatus]); return (