[Fleet] Fix reset agent policies without existing policies (#133215)

This commit is contained in:
Nicolas Chaulet 2022-05-31 17:24:12 +02:00 committed by GitHub
parent a15e5ddea9
commit e7fda713a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 128 additions and 14 deletions

View file

@ -0,0 +1,108 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { elasticsearchServiceMock, savedObjectsClientMock } from '@kbn/core/server/mocks';
import { agentPolicyService } from '../agent_policy';
import { packagePolicyService } from '../package_policy';
import { PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE } from '../../constants';
import { setupFleet } from '../setup';
import { getAgentsByKuery, forceUnenrollAgent } from '../agents';
import { listEnrollmentApiKeys, deleteEnrollmentApiKey } from '../api_keys';
import { resetPreconfiguredAgentPolicies } from './reset_agent_policies';
jest.mock('../agent_policy');
jest.mock('../package_policy');
jest.mock('../setup');
jest.mock('../agents');
jest.mock('../api_keys');
const mockedSetupFleet = setupFleet as jest.MockedFunction<typeof setupFleet>;
const mockedForceUnenrollAgent = forceUnenrollAgent as jest.MockedFunction<
typeof forceUnenrollAgent
>;
const mockedDeleteEnrollmentApiKey = deleteEnrollmentApiKey as jest.MockedFunction<
typeof deleteEnrollmentApiKey
>;
const mockedGetAgentsByKuery = getAgentsByKuery as jest.MockedFunction<typeof getAgentsByKuery>;
const mockedListEnrollmentApiKeys = listEnrollmentApiKeys as jest.MockedFunction<
typeof listEnrollmentApiKeys
>;
const mockedAgentPolicyService = agentPolicyService as jest.Mocked<typeof agentPolicyService>;
const mockedPackagePolicyService = packagePolicyService as jest.Mocked<typeof packagePolicyService>;
jest.mock('../app_context', () => ({
appContextService: {
getLogger: () =>
new Proxy(
{},
{
get() {
return jest.fn();
},
}
),
},
}));
describe('reset agent policies', () => {
it('should not unenroll agents or revoke enrollment api keys if there is no existing policies', async () => {
const soClient = savedObjectsClientMock.create();
const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
mockedAgentPolicyService.list.mockResolvedValueOnce({
items: [],
} as any);
mockedPackagePolicyService.list.mockResolvedValueOnce({
items: [],
} as any);
soClient.find.mockImplementation(async (option) => {
if (option.type === PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE) {
return { saved_objects: [] } as any;
}
throw new Error('not mocked');
});
await resetPreconfiguredAgentPolicies(soClient, esClient);
expect(mockedSetupFleet).toBeCalled();
expect(mockedForceUnenrollAgent).not.toBeCalled();
expect(mockedDeleteEnrollmentApiKey).not.toBeCalled();
});
it('should unenroll agents and revoke enrollment api keys if there is policies', async () => {
const soClient = savedObjectsClientMock.create();
const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
mockedAgentPolicyService.list.mockResolvedValueOnce({
items: [{ id: 'policy1' }],
} as any);
mockedPackagePolicyService.list.mockResolvedValueOnce({
items: [],
} as any);
mockedGetAgentsByKuery.mockResolvedValueOnce({
agents: [{ id: 'agent1' }],
} as any);
mockedListEnrollmentApiKeys.mockResolvedValueOnce({
items: [{ id: 'key1' }],
} as any);
soClient.find.mockImplementation(async (option) => {
if (option.type === PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE) {
return {
saved_objects: [],
} as any;
}
throw new Error('not mocked');
});
await resetPreconfiguredAgentPolicies(soClient, esClient);
expect(mockedSetupFleet).toBeCalled();
expect(mockedForceUnenrollAgent).toBeCalled();
expect(mockedDeleteEnrollmentApiKey).toBeCalled();
});
});

View file

@ -56,6 +56,10 @@ async function _deleteGhostPackagePolicies(
}, new Set<string>())
);
if (!policyIds.length) {
return;
}
const objects = policyIds.map((id) => ({ id, type: AGENT_POLICY_SAVED_OBJECT_TYPE }));
const agentPolicyExistsMap = (await soClient.bulkGet(objects)).saved_objects.reduce((acc, so) => {
if (so.error && so.error.statusCode === 404) {
@ -144,6 +148,10 @@ async function _deleteExistingData(
).items;
}
if (!existingPolicies.length) {
return;
}
// unenroll all the agents enroled in this policies
const { agents } = await getAgentsByKuery(esClient, {
showInactive: false,
@ -175,18 +183,16 @@ async function _deleteExistingData(
}
);
}
if (existingPolicies.length > 0) {
logger.info(`Deleting ${existingPolicies.length} agent policies`);
await pMap(
existingPolicies,
(policy) =>
agentPolicyService.delete(soClient, esClient, policy.id, {
force: true,
removeFleetServerDocuments: true,
}),
{
concurrency: 20,
}
);
}
logger.info(`Deleting ${existingPolicies.length} agent policies`);
await pMap(
existingPolicies,
(policy) =>
agentPolicyService.delete(soClient, esClient, policy.id, {
force: true,
removeFleetServerDocuments: true,
}),
{
concurrency: 20,
}
);
}