[Fleet] Remove tags from dropdown on agent unenrollment (#134066)

* Remove tags when an agent is unenrolled

* Remove tags during bulk unenrollment
This commit is contained in:
Kyle Pollich 2022-06-09 14:39:31 -04:00 committed by GitHub
parent d1fe508f42
commit e09ff34b0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 77 deletions

View file

@ -36,7 +36,7 @@ export interface Props {
selectionMode: SelectionMode;
currentQuery: string;
selectedAgents: Agent[];
refreshAgents: () => void;
refreshAgents: (args?: { refreshTags?: boolean }) => void;
}
export const AgentBulkActions: React.FunctionComponent<Props> = ({
@ -163,7 +163,7 @@ export const AgentBulkActions: React.FunctionComponent<Props> = ({
agentCount={agentCount}
onClose={() => {
setIsUnenrollModalOpen(false);
refreshAgents();
refreshAgents({ refreshTags: true });
}}
/>
</EuiPortal>

View file

@ -87,7 +87,7 @@ export const SearchAndFilterBar: React.FunctionComponent<{
selectionMode: SelectionMode;
currentQuery: string;
selectedAgents: Agent[];
refreshAgents: () => void;
refreshAgents: (args?: { refreshTags?: boolean }) => void;
onClickAddAgent: () => void;
}> = ({
agentPolicies,

View file

@ -200,84 +200,87 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
// Request to fetch agents and agent status
const currentRequestRef = useRef<number>(0);
const fetchData = useCallback(() => {
async function fetchDataAsync() {
currentRequestRef.current++;
const currentRequest = currentRequestRef.current;
const fetchData = useCallback(
({ refreshTags = false }: { refreshTags?: boolean } = {}) => {
async function fetchDataAsync() {
currentRequestRef.current++;
const currentRequest = currentRequestRef.current;
try {
setIsLoading(true);
const [agentsRequest, agentsStatusRequest] = await Promise.all([
sendGetAgents({
page: pagination.currentPage,
perPage: pagination.pageSize,
kuery: kuery && kuery !== '' ? kuery : undefined,
showInactive,
showUpgradeable,
}),
sendGetAgentStatus({
kuery: kuery && kuery !== '' ? kuery : undefined,
}),
]);
// Return if a newer request as been triggered
if (currentRequestRef.current !== currentRequest) {
return;
}
if (agentsRequest.error) {
throw agentsRequest.error;
}
if (!agentsRequest.data) {
throw new Error('Invalid GET /agents response');
}
if (agentsStatusRequest.error) {
throw agentsStatusRequest.error;
}
if (!agentsStatusRequest.data) {
throw new Error('Invalid GET /agents-status response');
}
try {
setIsLoading(true);
const [agentsRequest, agentsStatusRequest] = await Promise.all([
sendGetAgents({
page: pagination.currentPage,
perPage: pagination.pageSize,
kuery: kuery && kuery !== '' ? kuery : undefined,
showInactive,
showUpgradeable,
}),
sendGetAgentStatus({
kuery: kuery && kuery !== '' ? kuery : undefined,
}),
]);
// Return if a newer request as been triggered
if (currentRequestRef.current !== currentRequest) {
return;
}
if (agentsRequest.error) {
throw agentsRequest.error;
}
if (!agentsRequest.data) {
throw new Error('Invalid GET /agents response');
}
if (agentsStatusRequest.error) {
throw agentsStatusRequest.error;
}
if (!agentsStatusRequest.data) {
throw new Error('Invalid GET /agents-status response');
}
setAgentsStatus({
healthy: agentsStatusRequest.data.results.online,
unhealthy: agentsStatusRequest.data.results.error,
offline: agentsStatusRequest.data.results.offline,
updating: agentsStatusRequest.data.results.updating,
inactive: agentsRequest.data.totalInactive,
});
setAgentsStatus({
healthy: agentsStatusRequest.data.results.online,
unhealthy: agentsStatusRequest.data.results.error,
offline: agentsStatusRequest.data.results.offline,
updating: agentsStatusRequest.data.results.updating,
inactive: agentsRequest.data.totalInactive,
});
const newAllTags = Array.from(
new Set(agentsRequest.data.items.flatMap((agent) => agent.tags ?? []))
);
const newAllTags = Array.from(
new Set(agentsRequest.data.items.flatMap((agent) => agent.tags ?? []))
);
// We only want to update the list of available tags if we've either received
// more tags than we currently have from the API (e.g. new agents have been enrolled)
// or we haven't set our list of tags yet. TODO: Would it be possible to remove a tag
// from the filterable list if an agent is unenrolled and no agents remain with that tag?
if (!allTags || newAllTags.length > allTags.length) {
setAllTags(newAllTags);
// We only want to update the list of available tags if
// - We haven't set any tags yet
// - We've received net-new tags from the API (e.g. more tags than we have rendered now)
// - We've received the "refreshTags" flag which will force a refresh of the tags list when an agent is unenrolled
if (!allTags || newAllTags.length > allTags.length || refreshTags) {
setAllTags(newAllTags);
}
setAgents(agentsRequest.data.items);
setTotalAgents(agentsRequest.data.total);
setTotalInactiveAgents(agentsRequest.data.totalInactive);
} catch (error) {
notifications.toasts.addError(error, {
title: i18n.translate('xpack.fleet.agentList.errorFetchingDataTitle', {
defaultMessage: 'Error fetching agents',
}),
});
}
setAgents(agentsRequest.data.items);
setTotalAgents(agentsRequest.data.total);
setTotalInactiveAgents(agentsRequest.data.totalInactive);
} catch (error) {
notifications.toasts.addError(error, {
title: i18n.translate('xpack.fleet.agentList.errorFetchingDataTitle', {
defaultMessage: 'Error fetching agents',
}),
});
setIsLoading(false);
}
setIsLoading(false);
}
fetchDataAsync();
}, [
pagination.currentPage,
pagination.pageSize,
kuery,
showInactive,
showUpgradeable,
allTags,
notifications.toasts,
]);
fetchDataAsync();
},
[
pagination.currentPage,
pagination.pageSize,
kuery,
showInactive,
showUpgradeable,
allTags,
notifications.toasts,
]
);
// Send request to get agent list and status
useEffect(() => {
@ -494,7 +497,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
agentCount={1}
onClose={() => {
setAgentToUnenroll(undefined);
fetchData();
fetchData({ refreshTags: true });
}}
useForceUnenroll={agentToUnenroll.status === 'unenrolling'}
hasFleetServer={agentToUnenrollHasFleetServer}
@ -551,7 +554,9 @@ export const AgentListPage: React.FunctionComponent<{}> = () => {
selectionMode={selectionMode}
currentQuery={kuery}
selectedAgents={selectedAgents}
refreshAgents={() => Promise.all([fetchData(), refreshUpgrades()])}
refreshAgents={({ refreshTags = false }: { refreshTags?: boolean } = {}) =>
Promise.all([fetchData({ refreshTags }), refreshUpgrades()])
}
onClickAddAgent={() => setEnrollmentFlyoutState({ isOpen: true })}
/>
<EuiSpacer size="m" />