[Fleet] Warn when trying to unenroll agents with fleet server (#103671)

This commit is contained in:
Alejandro Fernández Gómez 2021-06-29 18:16:03 +02:00 committed by GitHub
parent bfd801078f
commit 16ae487a5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 5 deletions

View file

@ -9,7 +9,7 @@ import React, { memo, useState, useMemo } from 'react';
import { EuiPortal, EuiContextMenuItem } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import type { Agent } from '../../../../types';
import type { Agent, AgentPolicy, PackagePolicy } from '../../../../types';
import { useCapabilities, useKibanaVersion } from '../../../../hooks';
import { ContextMenuActions } from '../../../../components';
import {
@ -19,12 +19,14 @@ import {
} from '../../components';
import { useAgentRefresh } from '../hooks';
import { isAgentUpgradeable } from '../../../../services';
import { FLEET_SERVER_PACKAGE } from '../../../../constants';
export const AgentDetailsActionMenu: React.FunctionComponent<{
agent: Agent;
agentPolicy?: AgentPolicy;
assignFlyoutOpenByDefault?: boolean;
onCancelReassign?: () => void;
}> = memo(({ agent, assignFlyoutOpenByDefault = false, onCancelReassign }) => {
}> = memo(({ agent, assignFlyoutOpenByDefault = false, onCancelReassign, agentPolicy }) => {
const hasWriteCapabilites = useCapabilities().write;
const kibanaVersion = useKibanaVersion();
const refreshAgent = useAgentRefresh();
@ -33,6 +35,13 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{
const [isUpgradeModalOpen, setIsUpgradeModalOpen] = useState(false);
const isUnenrolling = agent.status === 'unenrolling';
const hasFleetServer =
agentPolicy &&
agentPolicy.package_policies.some(
(ap: string | PackagePolicy) =>
typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE
);
const onClose = useMemo(() => {
if (onCancelReassign) {
return onCancelReassign;
@ -58,6 +67,7 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{
refreshAgent();
}}
useForceUnenroll={isUnenrolling}
hasFleetServer={hasFleetServer}
/>
</EuiPortal>
)}

View file

@ -193,6 +193,7 @@ export const AgentDetailsPage: React.FunctionComponent = () => {
isAgentPolicyLoading || agentPolicyData?.item?.is_managed ? undefined : (
<AgentDetailsActionMenu
agent={agentData.item}
agentPolicy={agentPolicyData?.item}
assignFlyoutOpenByDefault={openReassignFlyoutOpenByDefault}
onCancelReassign={
routeState && routeState.onDoneNavigateTo

View file

@ -22,7 +22,7 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage, FormattedRelative } from '@kbn/i18n/react';
import type { Agent, AgentPolicy, SimplifiedAgentStatus } from '../../../types';
import type { Agent, AgentPolicy, PackagePolicy, SimplifiedAgentStatus } from '../../../types';
import {
usePagination,
useCapabilities,
@ -42,7 +42,7 @@ import {
ContextMenuActions,
} from '../../../components';
import { AgentStatusKueryHelper, isAgentUpgradeable } from '../../../services';
import { AGENT_SAVED_OBJECT_TYPE } from '../../../constants';
import { AGENT_SAVED_OBJECT_TYPE, FLEET_SERVER_PACKAGE } from '../../../constants';
import {
AgentReassignAgentPolicyModal,
AgentHealth,
@ -328,6 +328,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
const agentPoliciesRequest = useGetAgentPolicies({
page: 1,
perPage: 1000,
full: true,
});
const agentPolicies = useMemo(
@ -351,6 +352,23 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
return !isHosted;
};
const agentToUnenrollHasFleetServer = useMemo(() => {
if (!agentToUnenroll || !agentToUnenroll.policy_id) {
return false;
}
const agentPolicy = agentPoliciesIndexedById[agentToUnenroll.policy_id];
if (!agentPolicy) {
return false;
}
return agentPolicy.package_policies.some(
(ap: string | PackagePolicy) =>
typeof ap !== 'string' && ap.package?.name === FLEET_SERVER_PACKAGE
);
}, [agentToUnenroll, agentPoliciesIndexedById]);
const columns = [
{
field: 'local_metadata.host.hostname',
@ -512,6 +530,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
fetchData();
}}
useForceUnenroll={agentToUnenroll.status === 'unenrolling'}
hasFleetServer={agentToUnenrollHasFleetServer}
/>
</EuiPortal>
)}

View file

@ -7,7 +7,7 @@
import React, { useState } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiConfirmModal, EuiFormFieldset, EuiCheckbox } from '@elastic/eui';
import { EuiCallOut, EuiConfirmModal, EuiFormFieldset, EuiCheckbox, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import type { Agent } from '../../../../types';
@ -22,6 +22,7 @@ interface Props {
agents: Agent[] | string;
agentCount: number;
useForceUnenroll?: boolean;
hasFleetServer?: boolean;
}
export const AgentUnenrollAgentModal: React.FunctionComponent<Props> = ({
@ -29,6 +30,7 @@ export const AgentUnenrollAgentModal: React.FunctionComponent<Props> = ({
agents,
agentCount,
useForceUnenroll,
hasFleetServer = false,
}) => {
const { notifications } = useStartServices();
const [forceUnenroll, setForceUnenroll] = useState<boolean>(useForceUnenroll || false);
@ -123,6 +125,25 @@ export const AgentUnenrollAgentModal: React.FunctionComponent<Props> = ({
buttonColor="danger"
>
<p>
{hasFleetServer && isSingleAgent ? (
<>
<EuiCallOut
title={i18n.translate('xpack.fleet.unenrollAgents.unenrollFleetServerTitle', {
defaultMessage: 'This agent is running Fleet Server',
})}
color="warning"
iconType="alert"
>
<p>
<FormattedMessage
id="xpack.fleet.unenrollAgents.unenrollFleetServerDescription"
defaultMessage="Unenrolling this agent will disconnect a Fleet Server and prevent agents from sendind data if no other Fleet Servers exist."
/>
</p>
</EuiCallOut>
<EuiSpacer />
</>
) : null}
{isSingleAgent ? (
<FormattedMessage
id="xpack.fleet.unenrollAgents.deleteSingleDescription"