[Cloud Posture] fix sequence count when integration is in edit mode (#155678)

## Summary

Summarize your PR. If it involves visual changes include a screenshot or
gif.
Before, if we add another subsequent CSP integration, then the
integration name sequence number doesn't increase. The current
implementation always takes the first default digit which is 1. This
causes errors to be thrown. We need to make the integration name unique.

- The proposed solution is to find the current integration's
`installedPackagePolicies` using the`useCspSetupStatusApi` hook. Once we
have the count, increment the installedPackagePolicies by 1 to create a
unique integration name with the current package policy count.

<img width="1714" alt="Screen Shot 2023-04-24 at 7 50 44 PM"
src="https://user-images.githubusercontent.com/17135495/234168157-265670e9-5634-4af2-8cdf-d162e6374bf9.png">
<img width="1148" alt="Screen Shot 2023-04-24 at 7 51 03 PM"
src="https://user-images.githubusercontent.com/17135495/234168202-4675c6b4-23cd-4d55-b439-c4414f7541ca.png">
This commit is contained in:
Lola 2023-04-25 15:26:45 -04:00 committed by GitHub
parent b66df8774a
commit ccd9d1484b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 8 deletions

View file

@ -14,6 +14,8 @@ import userEvent from '@testing-library/user-event';
import { getPosturePolicy } from './utils';
import { CLOUDBEAT_AWS, CLOUDBEAT_EKS } from '../../../common/constants';
import { useParams } from 'react-router-dom';
import { createReactQueryResponse } from '../../test/fixtures/react_query';
import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api';
// mock useParams
jest.mock('react-router-dom', () => ({
@ -22,12 +24,19 @@ jest.mock('react-router-dom', () => ({
integration: undefined,
}),
}));
jest.mock('../../common/api/use_setup_status_api');
describe('<CspPolicyTemplateForm />', () => {
beforeEach(() => {
(useParams as jest.Mock).mockReturnValue({
integration: undefined,
});
(useCspSetupStatusApi as jest.Mock).mockImplementation(() =>
createReactQueryResponse({
status: 'success',
data: { status: 'indexed', installedPackageVersion: '1.2.13' },
})
);
});
const onChange = jest.fn();
@ -200,10 +209,18 @@ describe('<CspPolicyTemplateForm />', () => {
}));
policy.name = 'cloud_security_posture-1';
(useCspSetupStatusApi as jest.Mock).mockImplementation(() =>
createReactQueryResponse({
status: 'success',
data: {
kspm: { status: 'not-deployed', healthyAgents: 0, installedPackagePolicies: 1 },
},
})
);
(useParams as jest.Mock).mockReturnValue({
integration: 'kspm',
});
render(<WrappedComponent newPolicy={policy} />);
// 1st call happens on mount and selects the default policy template enabled input
@ -220,7 +237,7 @@ describe('<CspPolicyTemplateForm />', () => {
isValid: true,
updatedPolicy: {
...policy,
name: 'kspm-1',
name: 'kspm-2',
},
});
});
@ -237,6 +254,14 @@ describe('<CspPolicyTemplateForm />', () => {
(useParams as jest.Mock).mockReturnValue({
integration: 'cspm',
});
(useCspSetupStatusApi as jest.Mock).mockImplementation(() =>
createReactQueryResponse({
status: 'success',
data: {
cspm: { status: 'not-deployed', healthyAgents: 0, installedPackagePolicies: 1 },
},
})
);
render(<WrappedComponent newPolicy={policy} />);
@ -254,7 +279,49 @@ describe('<CspPolicyTemplateForm />', () => {
isValid: true,
updatedPolicy: {
...policy,
name: 'cspm-1',
name: 'cspm-2',
},
});
});
it('selects default VULN_MGMT input selector', () => {
const policy = getMockPolicyAWS();
// enable all inputs of a policy template, same as fleet does
policy.inputs = policy.inputs.map((input) => ({
...input,
enabled: input.policy_template === 'cspm',
}));
policy.name = 'cloud_security_posture-1';
(useParams as jest.Mock).mockReturnValue({
integration: 'vuln_mgmt',
});
(useCspSetupStatusApi as jest.Mock).mockImplementation(() =>
createReactQueryResponse({
status: 'success',
data: {
vuln_mgmt: { status: 'not-deployed', healthyAgents: 0, installedPackagePolicies: 1 },
},
})
);
render(<WrappedComponent newPolicy={policy} />);
// 1st call happens on mount and selects the default policy template enabled input
expect(onChange).toHaveBeenNthCalledWith(1, {
isValid: true,
updatedPolicy: {
...getMockPolicyAWS(),
name: 'cloud_security_posture-1',
},
});
// 2nd call happens to set integration name
expect(onChange).toHaveBeenNthCalledWith(2, {
isValid: true,
updatedPolicy: {
...policy,
name: 'vuln_mgmt-2',
},
});
});

View file

@ -43,6 +43,7 @@ import {
PolicyTemplateVarsForm,
} from './policy_template_selectors';
import { assert } from '../../../common/utils/helpers';
import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api';
const DEFAULT_INPUT_TYPE = {
kspm: CLOUDBEAT_VANILLA,
@ -96,7 +97,6 @@ export const CspPolicyTemplateForm = memo<PackagePolicyReplaceDefineStepExtensio
(updatedPolicy: NewPackagePolicy) => onChange({ isValid: true, updatedPolicy }),
[onChange]
);
/**
* - Updates policy inputs by user selection
* - Updates hidden policy vars
@ -140,7 +140,13 @@ export const CspPolicyTemplateForm = memo<PackagePolicyReplaceDefineStepExtensio
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoading, input.policy_template, isEditPage]);
usePolicyTemplateInitialName({ isEditPage, isLoading, integration, newPolicy, updatePolicy });
usePolicyTemplateInitialName({
isEditPage,
isLoading,
integration,
newPolicy,
updatePolicy,
});
useEnsureDefaultNamespace({ newPolicy, input, updatePolicy });
@ -180,7 +186,7 @@ export const CspPolicyTemplateForm = memo<PackagePolicyReplaceDefineStepExtensio
];
return (
<div>
<div data-test-subj={'test'}>
{isEditPage && <EditScreenStepTitle />}
{/* Defines the enabled policy template */}
{!integration && (
@ -235,12 +241,20 @@ const usePolicyTemplateInitialName = ({
newPolicy: NewPackagePolicy;
updatePolicy: (policy: NewPackagePolicy) => void;
}) => {
const getSetupStatus = useCspSetupStatusApi();
const installedPackagePolicyCount = Object.entries(getSetupStatus?.data ?? {})?.find(
([key, _value]) => key === integration
)?.[1]?.installedPackagePolicies;
const currentPackagePolicyCount =
typeof installedPackagePolicyCount === 'number' ? installedPackagePolicyCount + 1 : undefined;
useEffect(() => {
if (!integration) return;
if (isEditPage) return;
if (isLoading) return;
const sequenceNumber = newPolicy.name.replace(/\D/g, '');
const sequenceSuffix = sequenceNumber ? `-${sequenceNumber}` : '';
const sequenceSuffix = currentPackagePolicyCount ? `-${currentPackagePolicyCount}` : '';
const currentIntegrationName = `${integration}${sequenceSuffix}`;
if (newPolicy.name === currentIntegrationName) {
return;