[Fleet] hide changing agent policies when editing agentless integration policy (#190391)

## Summary

Related to https://github.com/elastic/kibana/issues/183863

Follow up from
https://github.com/elastic/kibana/pull/189934#discussion_r1712146040

Since the edit integration was re-enabled for agentless integration
policies, we have to make sure to hide the agent policy change option
when editing an agentless policy. This pr addresses that.

To verify:
- add CSPM integration with agentless setup technology
- edit the integration policy
- verify that the agent policies can't be modified
- upload another agentless package (instruction
[here](https://github.com/elastic/kibana/pull/189612))
- add Agentless integration with setup technology agentless
- edit the integration policly
- verify that the agent policies can't be modified

<img width="1526" alt="image"
src="https://github.com/user-attachments/assets/557cc6d4-37e7-43f6-b52a-3d5f4c073e1c">
<img width="1524" alt="image"
src="https://github.com/user-attachments/assets/e890efa8-4faf-4608-9228-32debadb895a">


### 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 2024-08-14 14:09:15 +02:00 committed by GitHub
parent 0e18fb39f3
commit 9cb49eac87
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 69 additions and 3 deletions

View file

@ -221,6 +221,34 @@ describe('useSetupTechnology', () => {
expect(sendGetOneAgentPolicy).toHaveBeenCalled();
});
it('should set agentless setup technology if agent policy supports agentless in edit page', async () => {
(useConfig as MockFn).mockReturnValue({
agentless: {
api: {
url: 'https://agentless.api.url',
},
},
} as any);
(useStartServices as MockFn).mockReturnValue({
cloud: {
isCloudEnabled: true,
},
});
const { result } = renderHook(() =>
useSetupTechnology({
setNewAgentPolicy,
newAgentPolicy: newAgentPolicyMock,
updateAgentPolicies: updateAgentPoliciesMock,
setSelectedPolicyTab: setSelectedPolicyTabMock,
packagePolicy: packagePolicyMock,
isEditPage: true,
agentPolicies: [{ id: 'agentless-policy-id', supports_agentless: true } as any],
})
);
expect(result.current.selectedSetupTechnology).toBe(SetupTechnology.AGENTLESS);
});
it('should create agentless policy if agentless feature is enabled and isCloud is true and agentless.api.url', async () => {
(useConfig as MockFn).mockReturnValue({
agentless: {
@ -232,7 +260,6 @@ describe('useSetupTechnology', () => {
} as any);
(useStartServices as MockFn).mockReturnValue({
cloud: {
// isServerlessEnabled: false,
isCloudEnabled: true,
},
});

View file

@ -79,6 +79,7 @@ export function useSetupTechnology({
packageInfo,
packagePolicy,
isEditPage,
agentPolicies,
}: {
setNewAgentPolicy: (policy: NewAgentPolicy) => void;
newAgentPolicy: NewAgentPolicy;
@ -87,6 +88,7 @@ export function useSetupTechnology({
packageInfo?: PackageInfo;
packagePolicy: NewPackagePolicy;
isEditPage?: boolean;
agentPolicies?: AgentPolicy[];
}) {
const { isAgentlessEnabled, isAgentlessCloudEnabled, isAgentlessServerlessEnabled } =
useAgentless();
@ -104,7 +106,8 @@ export function useSetupTechnology({
);
useEffect(() => {
if (isEditPage) {
if (isEditPage && agentPolicies && agentPolicies.some((policy) => policy.supports_agentless)) {
setSelectedSetupTechnology(SetupTechnology.AGENTLESS);
return;
}
if (isAgentlessCloudEnabled && selectedSetupTechnology === SetupTechnology.AGENTLESS) {
@ -126,6 +129,8 @@ export function useSetupTechnology({
selectedSetupTechnology,
updateAgentPolicies,
setNewAgentPolicy,
agentPolicies,
setSelectedSetupTechnology,
]);
// tech debt: remove this useEffect when Serverless uses the Agentless API

View file

@ -145,6 +145,7 @@ export function usePackagePolicySteps({
packageInfo,
packagePolicy,
isEditPage: true,
agentPolicies,
});
const stepSelectAgentPolicy = useMemo(

View file

@ -311,6 +311,7 @@ describe('When calling package policy', () => {
},
],
});
(agentPolicyService.get as jest.Mock).mockResolvedValue({ inputs: [] });
});
it('should use existing package policy props if not provided by request', async () => {
@ -371,6 +372,25 @@ describe('When calling package policy', () => {
});
});
it('should throw if policy_ids changed on agentless integration', async () => {
(agentPolicyService.get as jest.Mock).mockResolvedValue({
supports_agentless: true,
inputs: [],
});
jest.spyOn(licenseService, 'hasAtLeast').mockReturnValue(true);
jest
.spyOn(appContextService, 'getExperimentalFeatures')
.mockReturnValue({ enableReusableIntegrationPolicies: true } as any);
const request = getUpdateKibanaRequest({ policy_ids: ['1', '2'] } as any);
await routeHandler(context, request, response);
expect(response.customError).toHaveBeenCalledWith({
statusCode: 400,
body: {
message: 'Cannot change agent policies of an agentless integration',
},
});
});
it('should rename the agentless agent policy to sync with the package policy name if agentless is enabled', async () => {
jest.spyOn(appContextService, 'getCloud').mockReturnValue({ isCloudEnabled: true } as any);
jest.spyOn(appContextService, 'getConfig').mockReturnValue({

View file

@ -10,7 +10,7 @@ import type { TypeOf } from '@kbn/config-schema';
import { SavedObjectsErrorHelpers } from '@kbn/core/server';
import type { RequestHandler } from '@kbn/core/server';
import { groupBy, keyBy } from 'lodash';
import { groupBy, isEmpty, isEqual, keyBy } from 'lodash';
import { HTTPAuthorizationHeader } from '../../../common/http_authorization_header';
@ -410,6 +410,19 @@ export const updatePackagePolicyHandler: FleetRequestHandler<
throw new PackagePolicyRequestError('At least one agent policy id must be provided');
}
if (
newData.policy_ids &&
!isEmpty(packagePolicy.policy_ids) &&
!isEqual(newData.policy_ids, packagePolicy.policy_ids)
) {
const agentPolicy = await agentPolicyService.get(soClient, packagePolicy.policy_ids[0]);
if (agentPolicy?.supports_agentless) {
throw new PackagePolicyRequestError(
'Cannot change agent policies of an agentless integration'
);
}
}
await renameAgentlessAgentPolicy(soClient, esClient, packagePolicy, newData.name);
const updatedPackagePolicy = await packagePolicyService.update(