mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[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:
parent
56a870948e
commit
65c71a78ec
5 changed files with 78 additions and 30 deletions
|
@ -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;
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -374,6 +374,7 @@ export const SearchAndFilterBar: React.FunctionComponent<{
|
|||
visibleAgents={visibleAgents}
|
||||
refreshAgents={refreshAgents}
|
||||
allTags={tags}
|
||||
agentPolicies={agentPolicies}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -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']);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue