Skip to content

Commit

Permalink
[Security Solution][Endpoint][Host Isolation] Fixes bug to remove exc…
Browse files Browse the repository at this point in the history
…ess host metadata status toasts on non user initiated errors (#105331)
  • Loading branch information
parkiino committed Jul 13, 2021
1 parent 928cc97 commit 2dad900
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,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 enum MetadataQueryStrategyVersions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const AgentStatus = React.memo(({ hostStatus }: { hostStatus: HostStatus
>
<FormattedMessage
id="xpack.securitySolution.endpoint.list.hostStatusValue"
defaultMessage="{hostStatus, select, healthy {Healthy} unhealthy {Unhealthy} updating {Updating} offline {Offline} inactive {Inactive} other {Unhealthy}}"
defaultMessage="{hostStatus, select, healthy {Healthy} unhealthy {Unhealthy} updating {Updating} offline {Offline} inactive {Inactive} unenrolled {Unenrolled} other {Unhealthy}}"
values={{ hostStatus }}
/>
</EuiBadge>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
({
Expand All @@ -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(() => {
Expand All @@ -41,15 +44,15 @@ export const TakeActionDropdown = React.memo(
iconSide="right"
fill
iconType="arrowDown"
disabled={loading}
disabled={loading || agentStatus === HostStatus.UNENROLLED}
onClick={() => {
setIsPopoverOpen(!isPopoverOpen);
}}
>
{TAKE_ACTION}
</EuiButton>
);
}, [isPopoverOpen, loading]);
}, [isPopoverOpen, loading, agentStatus]);

return (
<EuiPopover
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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' }
);
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@

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';

interface HostIsolationStatusResponse {
loading: boolean;
isIsolated: boolean;
agentStatus: HostStatus;
agentStatus: HostStatus | undefined;
pendingIsolation: number;
pendingUnisolation: number;
}
Expand All @@ -30,13 +28,11 @@ export const useHostIsolationStatus = ({
agentId: string;
}): HostIsolationStatusResponse => {
const [isIsolated, setIsIsolated] = useState<boolean>(false);
const [agentStatus, setAgentStatus] = useState<HostStatus>(HostStatus.UNHEALTHY);
const [agentStatus, setAgentStatus] = useState<HostStatus>();
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
Expand All @@ -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 {
Expand All @@ -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) {
Expand All @@ -87,6 +87,6 @@ export const useHostIsolationStatus = ({
isMounted = false;
abortCtrl.abort();
};
}, [addError, agentId]);
}, [agentId]);
return { loading, isIsolated, agentStatus, pendingIsolation, pendingUnisolation };
};
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
({
Expand All @@ -33,16 +34,22 @@ export const AgentStatuses = React.memo(
const isolationFieldName = 'host.isolation';
return (
<EuiFlexGroup gutterSize="none">
<EuiFlexItem grow={false}>
<DefaultDraggable
field={fieldName}
id={`event-details-value-default-draggable-${contextId}-${eventId}-${fieldName}-${value}`}
tooltipContent={fieldName}
value={`${agentStatus}`}
>
<AgentStatus hostStatus={agentStatus} />
</DefaultDraggable>
</EuiFlexItem>
{agentStatus !== undefined ? (
<EuiFlexItem grow={false}>
<DefaultDraggable
field={fieldName}
id={`event-details-value-default-draggable-${contextId}-${eventId}-${fieldName}-${value}`}
tooltipContent={fieldName}
value={`${agentStatus}`}
>
<AgentStatus hostStatus={agentStatus} />
</DefaultDraggable>
</EuiFlexItem>
) : (
<EuiText>
<p>{EMPTY_STATUS}</p>
</EuiText>
)}
<EuiFlexItem grow={false}>
<DefaultDraggable
field={isolationFieldName}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ export const LINK_ELASTIC_ENDPOINT_SECURITY = i18n.translate(
defaultMessage: 'Open in Endpoint Security',
}
);

export const EMPTY_STATUS = i18n.translate(
'xpack.securitySolution.hostIsolation.agentStatuses.empty',
{
defaultMessage: '-',
}
);

0 comments on commit 2dad900

Please sign in to comment.