mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Fleet] added check for Enterprise license in package policy create/update APIs (#187467)
## Summary Relates https://github.com/elastic/ingest-dev/issues/3464 Added check to reject integration policy shared by multiple agent policies if Enterprise license is not available. ### Testing - Enable a local enterprise licence ([steps](46802910/Internal+License+-+X-Pack+and+Endgame
)) - Enable flag `enableReusableIntegrationPolicies` - Try create/update package policy API with multiple `policy_ids`, expect to work Repeat the steps with any lower licence, the API should reject the request with a 400 error. ``` POST kbn:/api/fleet/package_policies { "policy_ids": [ "policy-1", "policy-2" ], "package": { "name": "apache", "version": "1.20.0" }, "name": "apache-4", "description": "", "namespace": "", "inputs": [] } ``` Test with Basic license: <img width="910" alt="image" src="d99b3765
-0b0b-4abd-ae4c-dc9f396a465a"> Test with Enterprise license: <img width="910" alt="image" src="d42b761e
-32f0-46b6-95a8-0a565f898532"> ### 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:
parent
83a17990fe
commit
82d32a757f
3 changed files with 70 additions and 3 deletions
|
@ -12,7 +12,7 @@ import type { RouteConfig } from '@kbn/core/server';
|
|||
import type { FleetAuthzRouter } from '../../services/security';
|
||||
|
||||
import { PACKAGE_POLICY_API_ROUTES } from '../../../common/constants';
|
||||
import { appContextService, packagePolicyService } from '../../services';
|
||||
import { appContextService, licenseService, packagePolicyService } from '../../services';
|
||||
import { createAppContextStartContractMock, xpackMocks } from '../../mocks';
|
||||
import type { PackagePolicyClient, FleetRequestHandlerContext } from '../..';
|
||||
import type {
|
||||
|
@ -190,6 +190,29 @@ describe('When calling package policy', () => {
|
|||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw if no enterprise license and multiple policy_ids is provided', async () => {
|
||||
const request = getCreateKibanaRequest({ ...newPolicy, policy_ids: ['1', '2'] } as any);
|
||||
await createPackagePolicyHandler(context, request as any, response);
|
||||
expect(response.customError).toHaveBeenCalledWith({
|
||||
statusCode: 400,
|
||||
body: {
|
||||
message: 'Reusable integration policies are only available with an Enterprise license',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not throw if enterprise license and multiple policy_ids is provided', async () => {
|
||||
jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(true);
|
||||
const request = getCreateKibanaRequest({ ...newPolicy, policy_ids: ['1', '2'] } as any);
|
||||
await createPackagePolicyHandler(context, request as any, response);
|
||||
expect(response.customError).not.toHaveBeenCalledWith({
|
||||
statusCode: 400,
|
||||
body: {
|
||||
message: 'Reusable integration policies are only available with an Enterprise license',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('update api handler', () => {
|
||||
|
@ -338,6 +361,25 @@ describe('When calling package policy', () => {
|
|||
body: { item: { ...existingPolicy, namespace: 'namespace' } },
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw if no enterprise license and multiple policy_ids is provided', async () => {
|
||||
jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(false);
|
||||
const request = getUpdateKibanaRequest({ policy_ids: ['1', '2'] } as any);
|
||||
await routeHandler(context, request, response);
|
||||
expect(response.customError).toHaveBeenCalledWith({
|
||||
statusCode: 400,
|
||||
body: {
|
||||
message: 'Reusable integration policies are only available with an Enterprise license',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should not throw if enterprise license and multiple policy_ids is provided', async () => {
|
||||
jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(true);
|
||||
const request = getUpdateKibanaRequest({ policy_ids: ['1', '2'] } as any);
|
||||
await routeHandler(context, request, response);
|
||||
expect(response.ok).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('list api handler', () => {
|
||||
|
|
|
@ -62,7 +62,11 @@ import {
|
|||
|
||||
import type { SimplifiedPackagePolicy } from '../../../common/services/simplified_package_policy_helper';
|
||||
|
||||
import { isSimplifiedCreatePackagePolicyRequest, removeFieldsFromInputSchema } from './utils';
|
||||
import {
|
||||
canUseMultipleAgentPolicies,
|
||||
isSimplifiedCreatePackagePolicyRequest,
|
||||
removeFieldsFromInputSchema,
|
||||
} from './utils';
|
||||
|
||||
export const isNotNull = <T>(value: T | null): value is T => value !== null;
|
||||
|
||||
|
@ -246,6 +250,11 @@ export const createPackagePolicyHandler: FleetRequestHandler<
|
|||
throw new PackagePolicyRequestError('Either policy_id or policy_ids must be provided');
|
||||
}
|
||||
|
||||
const { canUseReusablePolicies, errorMessage } = canUseMultipleAgentPolicies();
|
||||
if ((newPolicy.policy_ids ?? []).length > 1 && !canUseReusablePolicies) {
|
||||
throw new PackagePolicyRequestError(errorMessage);
|
||||
}
|
||||
|
||||
let newPackagePolicy: NewPackagePolicy;
|
||||
if (isSimplifiedCreatePackagePolicyRequest(newPolicy)) {
|
||||
if (!pkg) {
|
||||
|
@ -407,6 +416,11 @@ export const updatePackagePolicyHandler: FleetRequestHandler<
|
|||
newData.overrides = overrides;
|
||||
}
|
||||
}
|
||||
const { canUseReusablePolicies, errorMessage } = canUseMultipleAgentPolicies();
|
||||
if ((newData.policy_ids ?? []).length > 1 && !canUseReusablePolicies) {
|
||||
throw new PackagePolicyRequestError(errorMessage);
|
||||
}
|
||||
|
||||
const updatedPackagePolicy = await packagePolicyService.update(
|
||||
soClient,
|
||||
esClient,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import type { TypeOf } from '@kbn/config-schema';
|
||||
|
||||
import type { CreatePackagePolicyRequestSchema, PackagePolicyInput } from '../../../types';
|
||||
|
||||
import { licenseService } from '../../../services';
|
||||
import type { SimplifiedPackagePolicy } from '../../../../common/services/simplified_package_policy_helper';
|
||||
|
||||
export function isSimplifiedCreatePackagePolicyRequest(
|
||||
|
@ -39,3 +39,14 @@ export function removeFieldsFromInputSchema(
|
|||
return newInput;
|
||||
});
|
||||
}
|
||||
|
||||
const LICENCE_FOR_MULTIPLE_AGENT_POLICIES = 'enterprise';
|
||||
|
||||
export function canUseMultipleAgentPolicies() {
|
||||
const hasEnterpriseLicence = licenseService.hasAtLeast(LICENCE_FOR_MULTIPLE_AGENT_POLICIES);
|
||||
|
||||
return {
|
||||
canUseReusablePolicies: hasEnterpriseLicence,
|
||||
errorMessage: 'Reusable integration policies are only available with an Enterprise license',
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue