mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Fleet] Fix error occurring when multiple package policies are upgraded (#141625)
* [Fleet] Fix error occurring when multiple package policies are upgraded * Add integration test * Fix test * Improve testing Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
fb136431c5
commit
ab00a75937
3 changed files with 172 additions and 15 deletions
|
@ -666,6 +666,158 @@ describe('Package policy service', () => {
|
|||
).rejects.toThrow('Saved object [abc/123] conflict');
|
||||
});
|
||||
|
||||
it('should fail to update if the name already exists on another policy', async () => {
|
||||
const savedObjectsClient = savedObjectsClientMock.create();
|
||||
savedObjectsClient.find.mockResolvedValue({
|
||||
total: 1,
|
||||
per_page: 1,
|
||||
page: 1,
|
||||
saved_objects: [
|
||||
{
|
||||
id: 'existing-package-policy',
|
||||
type: 'ingest-package-policies',
|
||||
score: 1,
|
||||
references: [],
|
||||
version: '1.0.0',
|
||||
attributes: {
|
||||
name: 'endpoint-1',
|
||||
description: '',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: 'policy-id-1',
|
||||
package: {
|
||||
name: 'endpoint',
|
||||
title: 'Elastic Endpoint',
|
||||
version: '0.9.0',
|
||||
},
|
||||
inputs: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
savedObjectsClient.get.mockResolvedValue({
|
||||
id: 'the-package-policy-id',
|
||||
type: 'abcd',
|
||||
references: [],
|
||||
version: 'test',
|
||||
attributes: {},
|
||||
});
|
||||
savedObjectsClient.update.mockImplementation(
|
||||
async (
|
||||
type: string,
|
||||
id: string,
|
||||
attrs: any
|
||||
): Promise<SavedObjectsUpdateResponse<PackagePolicySOAttributes>> => {
|
||||
savedObjectsClient.get.mockResolvedValue({
|
||||
id: 'the-package-policy-id',
|
||||
type,
|
||||
references: [],
|
||||
version: 'test',
|
||||
attributes: attrs,
|
||||
});
|
||||
return attrs;
|
||||
}
|
||||
);
|
||||
const elasticsearchClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
|
||||
await expect(
|
||||
packagePolicyService.update(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient,
|
||||
'the-package-policy-id',
|
||||
{
|
||||
name: 'endpoint-1',
|
||||
description: '',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: '93c46720-c217-11ea-9906-b5b8a21b268e',
|
||||
package: {
|
||||
name: 'endpoint',
|
||||
title: 'Elastic Endpoint',
|
||||
version: '0.9.0',
|
||||
},
|
||||
inputs: [],
|
||||
}
|
||||
)
|
||||
).rejects.toThrow(
|
||||
'An integration policy with the name endpoint-1 already exists. Please rename it or choose a different name.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not fail to update if skipUniqueNameVerification when the name already exists on another policy', async () => {
|
||||
const savedObjectsClient = savedObjectsClientMock.create();
|
||||
savedObjectsClient.find.mockResolvedValue({
|
||||
total: 1,
|
||||
per_page: 1,
|
||||
page: 1,
|
||||
saved_objects: [
|
||||
{
|
||||
id: 'existing-package-policy',
|
||||
type: 'ingest-package-policies',
|
||||
score: 1,
|
||||
references: [],
|
||||
version: '1.0.0',
|
||||
attributes: {
|
||||
name: 'endpoint-1',
|
||||
description: '',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: 'policy-id-1',
|
||||
package: {
|
||||
name: 'endpoint',
|
||||
title: 'Elastic Endpoint',
|
||||
version: '0.9.0',
|
||||
},
|
||||
inputs: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
savedObjectsClient.get.mockResolvedValue({
|
||||
id: 'the-package-policy-id',
|
||||
type: 'abcd',
|
||||
references: [],
|
||||
version: 'test',
|
||||
attributes: {},
|
||||
});
|
||||
savedObjectsClient.update.mockImplementation(
|
||||
async (
|
||||
type: string,
|
||||
id: string,
|
||||
attrs: any
|
||||
): Promise<SavedObjectsUpdateResponse<PackagePolicySOAttributes>> => {
|
||||
savedObjectsClient.get.mockResolvedValue({
|
||||
id: 'the-package-policy-id',
|
||||
type,
|
||||
references: [],
|
||||
version: 'test',
|
||||
attributes: attrs,
|
||||
});
|
||||
return attrs;
|
||||
}
|
||||
);
|
||||
const elasticsearchClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
|
||||
const result = await packagePolicyService.update(
|
||||
savedObjectsClient,
|
||||
elasticsearchClient,
|
||||
'the-package-policy-id',
|
||||
{
|
||||
name: 'endpoint-1',
|
||||
description: '',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: '93c46720-c217-11ea-9906-b5b8a21b268e',
|
||||
package: {
|
||||
name: 'endpoint',
|
||||
title: 'Elastic Endpoint',
|
||||
version: '0.9.0',
|
||||
},
|
||||
inputs: [],
|
||||
},
|
||||
{ skipUniqueNameVerification: true }
|
||||
);
|
||||
expect(result.name).toEqual('endpoint-1');
|
||||
});
|
||||
|
||||
it('should throw if the user try to update input vars that are frozen', async () => {
|
||||
const savedObjectsClient = savedObjectsClientMock.create();
|
||||
const mockPackagePolicy = createPackagePolicyMock();
|
||||
|
|
|
@ -469,7 +469,7 @@ class PackagePolicyClientImpl implements PackagePolicyClient {
|
|||
esClient: ElasticsearchClient,
|
||||
id: string,
|
||||
packagePolicyUpdate: UpdatePackagePolicy,
|
||||
options?: { user?: AuthenticatedUser; force?: boolean },
|
||||
options?: { user?: AuthenticatedUser; force?: boolean; skipUniqueNameVerification?: boolean },
|
||||
currentVersion?: string
|
||||
): Promise<PackagePolicy> {
|
||||
const packagePolicy = { ...packagePolicyUpdate, name: packagePolicyUpdate.name.trim() };
|
||||
|
@ -479,22 +479,22 @@ class PackagePolicyClientImpl implements PackagePolicyClient {
|
|||
if (packagePolicyUpdate.is_managed && !options?.force) {
|
||||
throw new PackagePolicyRestrictionRelatedError(`Cannot update package policy ${id}`);
|
||||
}
|
||||
|
||||
if (!oldPackagePolicy) {
|
||||
throw new Error('Package policy not found');
|
||||
}
|
||||
// Check that the name does not exist already but exclude the current package policy
|
||||
const existingPoliciesWithName = await this.list(soClient, {
|
||||
perPage: SO_SEARCH_LIMIT,
|
||||
kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.name:"${packagePolicy.name}"`,
|
||||
});
|
||||
|
||||
const filtered = (existingPoliciesWithName?.items || []).filter((p) => p.id !== id);
|
||||
|
||||
if (filtered.length > 0) {
|
||||
throw new FleetError(
|
||||
`An integration policy with the name ${packagePolicy.name} already exists. Please rename it or choose a different name.`
|
||||
);
|
||||
if (!options?.skipUniqueNameVerification) {
|
||||
// Check that the name does not exist already but exclude the current package policy
|
||||
const existingPoliciesWithName = await this.list(soClient, {
|
||||
perPage: SO_SEARCH_LIMIT,
|
||||
kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.name:"${packagePolicy.name}"`,
|
||||
});
|
||||
const filtered = (existingPoliciesWithName?.items || []).filter((p) => p.id !== id);
|
||||
if (filtered.length > 0) {
|
||||
throw new FleetError(
|
||||
`An integration policy with the name ${packagePolicy.name} already exists. Please rename it or choose a different name.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let inputs = restOfPackagePolicy.inputs.map((input) =>
|
||||
|
@ -929,12 +929,17 @@ class PackagePolicyClientImpl implements PackagePolicyClient {
|
|||
);
|
||||
updatePackagePolicy.elasticsearch = packageInfo.elasticsearch;
|
||||
|
||||
const updateOptions = {
|
||||
skipUniqueNameVerification: true,
|
||||
...options,
|
||||
};
|
||||
|
||||
await this.update(
|
||||
soClient,
|
||||
esClient,
|
||||
id,
|
||||
updatePackagePolicy,
|
||||
options,
|
||||
updateOptions,
|
||||
packagePolicy.package!.version
|
||||
);
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ export interface PackagePolicyClient {
|
|||
esClient: ElasticsearchClient,
|
||||
id: string,
|
||||
packagePolicyUpdate: UpdatePackagePolicy,
|
||||
options?: { user?: AuthenticatedUser; force?: boolean },
|
||||
options?: { user?: AuthenticatedUser; force?: boolean; skipUniqueNameVerification?: boolean },
|
||||
currentVersion?: string
|
||||
): Promise<PackagePolicy>;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue