[Fleet] fix reassign agent with spaces (#214748)

## Summary

Closes https://github.com/elastic/kibana/issues/214341

Updating agent spaces when reassigning to agent policy.

To verify:
- Enable space awareness
- Create an agent policy and enroll an agent to it
- Create another agent policy and assign 2 spaces to it
- Reassign agent to the second policy
- Verify that the agent is visible in both spaces
- Same behaviour with bulk reassign action

<img width="1789" alt="image"
src="https://github.com/user-attachments/assets/3c7e6f07-c8d1-4a26-9e05-483caea6da1e"
/>
<img width="1789" alt="image"
src="https://github.com/user-attachments/assets/b84d2f69-8ba7-4a38-9a80-9b9e8ab9b37a"
/>
<img width="1782" alt="image"
src="https://github.com/user-attachments/assets/1272c35b-25cc-4a55-af6d-61b442ff3e07"
/>
<img width="1489" alt="image"
src="https://github.com/user-attachments/assets/df23f420-63f5-4d4b-bdb2-721a381adb4e"
/>


### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
This commit is contained in:
Julia Bardi 2025-03-17 16:30:22 +01:00 committed by GitHub
parent 44d49a9501
commit 68749db959
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 29 additions and 2 deletions

View file

@ -86,11 +86,11 @@ export function createClientMock() {
};
const regularAgentPolicySO = {
id: 'regular-agent-policy',
attributes: { is_managed: false },
attributes: { is_managed: false, space_ids: ['space1'] },
} as SavedObject<AgentPolicy>;
const regularAgentPolicySO2 = {
id: 'regular-agent-policy-2',
attributes: { is_managed: false },
attributes: { is_managed: false, space_ids: ['space1', 'default'] },
} as SavedObject<AgentPolicy>;
const hostedAgentPolicySO = {
id: 'hosted-agent-policy',

View file

@ -71,6 +71,20 @@ describe('reassignAgent', () => {
// does not call ES update
expect(esClient.update).toBeCalledTimes(0);
});
it('update namespaces with reassign', async () => {
const { soClient, esClient, agentInRegularDoc, regularAgentPolicySO } = mocks;
await reassignAgent(soClient, esClient, agentInRegularDoc._id, regularAgentPolicySO.id);
// calls ES update with correct values
expect(esClient.update).toBeCalledTimes(1);
const calledWith = esClient.update.mock.calls[0];
expect(calledWith[0]?.id).toBe(agentInRegularDoc._id);
expect((calledWith[0] as estypes.UpdateRequest)?.doc).toHaveProperty('namespaces', [
'space1',
]);
});
});
describe('reassignAgents (plural)', () => {
@ -104,6 +118,10 @@ describe('reassignAgent', () => {
expect((calledWith as estypes.BulkRequest).operations?.length).toBe(2);
// @ts-expect-error
expect(calledWith.operations[0].update._id).toEqual(agentInRegularDoc._id);
expect((calledWith.operations?.[1] as any)?.doc).toHaveProperty('namespaces', [
'space1',
'default',
]);
// hosted policy is updated in action results with error
const calledWithActionResults = esClient.bulk.mock.calls[1][0] as estypes.BulkRequest;

View file

@ -73,9 +73,12 @@ export async function reassignAgent(
);
}
const newAgentPolicy = await agentPolicyService.get(soClient, newAgentPolicyId);
await updateAgent(esClient, agentId, {
policy_id: newAgentPolicyId,
policy_revision: null,
...(newAgentPolicy?.space_ids ? { namespaces: newAgentPolicy.space_ids } : {}),
});
const currentSpaceId = getCurrentNamespace(soClient);

View file

@ -13,6 +13,8 @@ import { AgentReassignmentError, HostedAgentPolicyRestrictionRelatedError } from
import { appContextService } from '../app_context';
import { agentPolicyService } from '../agent_policy';
import { ActionRunner } from './action_runner';
import { bulkUpdateAgents } from './crud';
@ -74,6 +76,8 @@ export async function reassignBatch(
throw new AgentReassignmentError('No agents to reassign, already assigned or hosted agents');
}
const newAgentPolicy = await agentPolicyService.get(soClient, options.newAgentPolicyId);
await bulkUpdateAgents(
esClient,
agentsToUpdate.map((agent) => ({
@ -81,6 +85,7 @@ export async function reassignBatch(
data: {
policy_id: options.newAgentPolicyId,
policy_revision: null,
...(newAgentPolicy?.space_ids ? { namespaces: newAgentPolicy.space_ids } : {}),
},
})),
errors

View file

@ -92,6 +92,7 @@ export interface AgentSOAttributes {
tags?: string[];
components?: FleetServerAgentComponent[];
packages?: string[];
namespaces?: string[];
}
export interface FleetProxySOAttributes {