[Fleet] filter out hosted agents when finding common tags for bulk action (#137161)

* filter out hosted agents when finding common tags for bulk action

* fixed checks
This commit is contained in:
Julia Bardi 2022-07-26 14:18:53 +02:00 committed by GitHub
parent 56a870948e
commit 65c71a78ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 30 deletions

View file

@ -55,6 +55,7 @@ describe('AgentBulkActions', () => {
refreshAgents: () => undefined,
visibleAgents: [],
allTags: [],
agentPolicies: [],
};
const testBed = registerTestBed(TestComponent)(props);
const { exists } = testBed;
@ -84,6 +85,7 @@ describe('AgentBulkActions', () => {
refreshAgents: () => undefined,
visibleAgents: [],
allTags: [],
agentPolicies: [],
};
const testBed = registerTestBed(TestComponent)(props);
const { exists } = testBed;

View file

@ -18,7 +18,7 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import type { Agent } from '../../../../types';
import type { Agent, AgentPolicy } from '../../../../types';
import {
AgentReassignAgentPolicyModal,
AgentUnenrollAgentModal,
@ -44,6 +44,7 @@ export interface Props {
visibleAgents: Agent[];
refreshAgents: (args?: { refreshTags?: boolean }) => void;
allTags: string[];
agentPolicies: AgentPolicy[];
}
export const AgentBulkActions: React.FunctionComponent<Props> = ({
@ -55,6 +56,7 @@ export const AgentBulkActions: React.FunctionComponent<Props> = ({
visibleAgents,
refreshAgents,
allTags,
agentPolicies,
}) => {
const licenseService = useLicense();
const isLicenceAllowingScheduleUpgrade = licenseService.hasAtLeast(LICENSE_FOR_SCHEDULE_UPGRADE);
@ -173,8 +175,8 @@ export const AgentBulkActions: React.FunctionComponent<Props> = ({
];
const getSelectedTagsFromAgents = useMemo(
() => getCommonTags(agents, visibleAgents),
[agents, visibleAgents]
() => getCommonTags(agents, visibleAgents ?? [], agentPolicies),
[agents, visibleAgents, agentPolicies]
);
return (

View file

@ -374,6 +374,7 @@ export const SearchAndFilterBar: React.FunctionComponent<{
visibleAgents={visibleAgents}
refreshAgents={refreshAgents}
allTags={tags}
agentPolicies={agentPolicies}
/>
</EuiFlexItem>
</EuiFlexGroup>

View file

@ -5,28 +5,33 @@
* 2.0.
*/
import type { Agent } from '../../../../types';
import type { Agent, AgentPolicy } from '../../../../types';
import { getCommonTags } from './get_common_tags';
describe('getCommonTags', () => {
it('should return common tags from visibleAgents if agents is empty string', () => {
const result = getCommonTags('', [{ tags: ['tag1'] }, { tags: ['tag1', 'tag2'] }] as Agent[]);
const result = getCommonTags(
'',
[{ tags: ['tag1'] }, { tags: ['tag1', 'tag2'] }] as Agent[],
[]
);
expect(result).toEqual(['tag1']);
});
it('should return common tags from visibleAgents if agents is query', () => {
const result = getCommonTags('query', [
{ tags: ['tag1'] },
{ tags: ['tag1', 'tag2'] },
] as Agent[]);
const result = getCommonTags(
'query',
[{ tags: ['tag1'] }, { tags: ['tag1', 'tag2'] }] as Agent[],
[]
);
expect(result).toEqual(['tag1']);
});
it('should return empty common tags if visibleAgents not set', () => {
const result = getCommonTags('');
it('should return empty common tags if visibleAgents is empty', () => {
const result = getCommonTags('', [], []);
expect(result).toEqual([]);
});
@ -40,24 +45,47 @@ describe('getCommonTags', () => {
[
{ id: 'agent1', tags: ['oldTag', 'tag1'] },
{ id: 'agent2', tags: ['oldTag', 'tag1'] },
] as Agent[]
] as Agent[],
[]
);
expect(result).toEqual(['oldTag', 'tag1']);
});
it('should return common tags from old data if visibleAgents not set', () => {
const result = getCommonTags([
{ id: 'agent1', tags: ['oldTag'] },
{ id: 'agent2', tags: ['oldTag'] },
] as Agent[]);
it('should return common tags from old data if visibleAgents empty', () => {
const result = getCommonTags(
[
{ id: 'agent1', tags: ['oldTag'] },
{ id: 'agent2', tags: ['oldTag'] },
] as Agent[],
[],
[]
);
expect(result).toEqual(['oldTag']);
});
it('should return empty common tags if one agent has no tags set', () => {
const result = getCommonTags([{ id: 'agent1', tags: ['oldTag'] }, { id: 'agent2' }] as Agent[]);
const result = getCommonTags(
[{ id: 'agent1', tags: ['oldTag'] }, { id: 'agent2' }] as Agent[],
[],
[]
);
expect(result).toEqual([]);
});
it('should return common tags by excluding hosted agents', () => {
const result = getCommonTags(
'query',
[
{ id: 'agent1', tags: ['tag1'], policy_id: 'hosted' },
{ id: 'agent2', tags: ['tag2'], policy_id: 'policy2' },
{ id: 'agent3', tags: ['tag2'], policy_id: 'policy3' },
] as Agent[],
[{ id: 'hosted', is_managed: true } as AgentPolicy, { id: 'policy2' } as AgentPolicy]
);
expect(result).toEqual(['tag2']);
});
});

View file

@ -7,26 +7,41 @@
import { intersection } from 'lodash';
import type { Agent } from '../../../../types';
import type { Agent, AgentPolicy } from '../../../../types';
export const getCommonTags = (agents: string | Agent[], visibleAgents?: Agent[]): string[] => {
const commonSelectedTags = (agentList: Agent[]) =>
agentList.reduce(
(acc: string[], curr: Agent) =>
acc.length > 0 ? intersection(curr.tags ?? [], acc) : curr.tags ?? [],
[]
);
export const getCommonTags = (
agents: string | Agent[],
visibleAgents: Agent[],
agentPolicies: AgentPolicy[]
): string[] => {
const isManagedPolicy = (agent: Agent): boolean => {
const policy = agentPolicies.find((pol) => pol.id === agent.policy_id);
return !!policy && policy.is_managed;
};
const commonSelectedTags = (agentList: Agent[]): string[] =>
agentList.reduce((acc: string[], curr: Agent) => {
if (isManagedPolicy(curr)) {
return acc;
}
if (acc.length < 1) {
return curr.tags ?? [];
}
return intersection(curr.tags ?? [], acc);
}, []);
if (!Array.isArray(agents)) {
// in query mode, returning common tags of all agents in current page
// this is a simplification to avoid querying all agents from backend to determine common tags
return commonSelectedTags(visibleAgents ?? []);
return commonSelectedTags(visibleAgents);
}
// taking latest tags from freshly loaded agents data, as selected agents array does not contain the latest tags of agents
const freshSelectedAgentsData =
visibleAgents?.filter((newAgent) =>
agents.find((existingAgent) => existingAgent.id === newAgent.id)
) ?? agents;
visibleAgents.length > 0
? visibleAgents.filter((newAgent) =>
agents.find((existingAgent) => existingAgent.id === newAgent.id)
)
: agents;
return commonSelectedTags(freshSelectedAgentsData);
};