mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Fleet] Reuse shared integration policies when duplicating agent policies (#217872)
## Summary Closes https://github.com/elastic/kibana/issues/215335 Currently, when an agent policy is duplicated, shared integration policies are also duplicated. This PR adds logic where the duplicated agent policy also shares these integration policies. ### Testing * Run ES with an [Entreprise license](https://www.elastic.co/subscriptions) to avail of reusable integration policies. * Create an agent policy with a shared integration policy and a non-shared integration policy. * Duplicate the agent policy: the duplicated policy should only duplicate the non-shared integration policy and the shared integration policy should be reused. ### 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 - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) ### Identify risks Incorrect package policies in duplicated agent policies.
This commit is contained in:
parent
a3766fd1ef
commit
5c78ff1848
2 changed files with 130 additions and 22 deletions
|
@ -1251,6 +1251,98 @@ describe('Agent policy', () => {
|
|||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('should link shared package policies', async () => {
|
||||
agentPolicyService.requireUniqueName = async () => {};
|
||||
soClient = savedObjectsClientMock.create();
|
||||
const mockPolicy = {
|
||||
type: LEGACY_AGENT_POLICY_SAVED_OBJECT_TYPE,
|
||||
references: [],
|
||||
attributes: { revision: 1, package_policies: ['package-1'] } as any,
|
||||
};
|
||||
soClient.get.mockImplementation(async (type: string, id: string) => {
|
||||
return {
|
||||
id,
|
||||
...mockPolicy,
|
||||
};
|
||||
});
|
||||
soClient.find
|
||||
.mockImplementationOnce(async () => ({
|
||||
saved_objects: [
|
||||
{
|
||||
id: 'agent-policy-id',
|
||||
score: 1,
|
||||
...{ ...mockPolicy, name: 'mocked-policy' },
|
||||
},
|
||||
],
|
||||
total: 1,
|
||||
page: 1,
|
||||
per_page: 1,
|
||||
}))
|
||||
.mockImplementationOnce(async () => ({
|
||||
saved_objects: [
|
||||
{
|
||||
id: 'agent-policy-id-copy',
|
||||
score: 1,
|
||||
...{ ...mockPolicy, name: 'mocked-policy' },
|
||||
},
|
||||
],
|
||||
total: 1,
|
||||
page: 1,
|
||||
per_page: 1,
|
||||
}));
|
||||
soClient.create.mockImplementation(async (type, attributes) => {
|
||||
return {
|
||||
attributes: attributes as unknown as NewAgentPolicy,
|
||||
id: 'mocked',
|
||||
type: 'mocked',
|
||||
references: [],
|
||||
};
|
||||
});
|
||||
const packagePolicies = [
|
||||
{
|
||||
id: 'package-1',
|
||||
name: 'package-1',
|
||||
policy_id: 'policy_1',
|
||||
policy_ids: ['policy_1', 'policy_2'],
|
||||
},
|
||||
{
|
||||
id: 'package-2',
|
||||
name: 'package-2',
|
||||
policy_id: 'policy_1',
|
||||
policy_ids: ['policy_1'],
|
||||
},
|
||||
] as any;
|
||||
mockedPackagePolicyService.findAllForAgentPolicy.mockReturnValue(packagePolicies);
|
||||
mockedPackagePolicyService.list.mockResolvedValue({ items: packagePolicies } as any);
|
||||
await agentPolicyService.copy(soClient, esClient, 'mocked', {
|
||||
name: 'copy mocked',
|
||||
});
|
||||
expect(mockedPackagePolicyService.bulkCreate).toBeCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
[
|
||||
{
|
||||
name: 'package-2 (copy)',
|
||||
policy_id: 'policy_1',
|
||||
policy_ids: ['mocked'],
|
||||
},
|
||||
],
|
||||
expect.anything()
|
||||
);
|
||||
expect(mockedPackagePolicyService.bulkUpdate).toBeCalledWith(
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
[
|
||||
{
|
||||
id: 'package-1',
|
||||
name: 'package-1',
|
||||
policy_id: 'policy_1',
|
||||
policy_ids: ['policy_1', 'policy_2', 'mocked'],
|
||||
},
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deployPolicy', () => {
|
||||
|
|
|
@ -849,32 +849,48 @@ class AgentPolicyService {
|
|||
options
|
||||
);
|
||||
|
||||
// Copy all package policies and append (copy n) to their names
|
||||
if (baseAgentPolicy.package_policies) {
|
||||
const newPackagePolicies = await pMap(
|
||||
baseAgentPolicy.package_policies as PackagePolicy[],
|
||||
async (packagePolicy: PackagePolicy) => {
|
||||
const { id: packagePolicyId, version, ...newPackagePolicy } = packagePolicy;
|
||||
// Copy non-shared package policies and append (copy n) to their names.
|
||||
const basePackagePolicies = baseAgentPolicy.package_policies.filter(
|
||||
(packagePolicy) => packagePolicy.policy_ids.length < 2
|
||||
);
|
||||
if (basePackagePolicies.length > 0) {
|
||||
const newPackagePolicies = await pMap(
|
||||
basePackagePolicies,
|
||||
async (packagePolicy: PackagePolicy) => {
|
||||
const { id: packagePolicyId, version, ...newPackagePolicy } = packagePolicy;
|
||||
|
||||
const updatedPackagePolicy = {
|
||||
const updatedPackagePolicy = {
|
||||
...newPackagePolicy,
|
||||
name: await incrementPackagePolicyCopyName(soClient, packagePolicy.name),
|
||||
};
|
||||
return updatedPackagePolicy;
|
||||
}
|
||||
);
|
||||
await packagePolicyService.bulkCreate(
|
||||
soClient,
|
||||
esClient,
|
||||
newPackagePolicies.map((newPackagePolicy) => ({
|
||||
...newPackagePolicy,
|
||||
name: await incrementPackagePolicyCopyName(soClient, packagePolicy.name),
|
||||
};
|
||||
return updatedPackagePolicy;
|
||||
}
|
||||
);
|
||||
await packagePolicyService.bulkCreate(
|
||||
soClient,
|
||||
esClient,
|
||||
newPackagePolicies.map((newPackagePolicy) => ({
|
||||
...newPackagePolicy,
|
||||
policy_ids: [newAgentPolicy.id],
|
||||
})),
|
||||
{
|
||||
...options,
|
||||
bumpRevision: false,
|
||||
}
|
||||
policy_ids: [newAgentPolicy.id],
|
||||
})),
|
||||
{
|
||||
...options,
|
||||
bumpRevision: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
// Link shared package policies to new agent policy.
|
||||
const sharedBasePackagePolicies = baseAgentPolicy.package_policies.filter(
|
||||
(packagePolicy) => packagePolicy.policy_ids.length > 1
|
||||
);
|
||||
if (sharedBasePackagePolicies.length > 0) {
|
||||
const updatedSharedPackagePolicies = sharedBasePackagePolicies.map((packagePolicy) => ({
|
||||
...packagePolicy,
|
||||
policy_ids: [...packagePolicy.policy_ids, newAgentPolicy.id],
|
||||
}));
|
||||
await packagePolicyService.bulkUpdate(soClient, esClient, updatedSharedPackagePolicies);
|
||||
}
|
||||
}
|
||||
|
||||
// Tamper protection is dependent on endpoint package policy
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue