Skip to content

Commit

Permalink
Merge branch 'main' into 155111-create-metrics-explorer-views
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyghiani authored Apr 26, 2023
2 parents 7709c92 + 1351760 commit 0ebb039
Show file tree
Hide file tree
Showing 54 changed files with 1,030 additions and 273 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import React, { useCallback, useMemo } from 'react';
import { EuiFormRow } from '@elastic/eui';
import { debounce } from 'lodash';
import { CodeEditor } from '@kbn/kibana-react-plugin/public';

import { EuiCodeEditor } from '../code_editor';
import { useJson, OnJsonEditorUpdateHandler } from './use_json';

interface Props<T extends object = { [key: string]: any }> {
Expand All @@ -19,7 +19,7 @@ interface Props<T extends object = { [key: string]: any }> {
helpText?: React.ReactNode;
value?: string;
defaultValue?: T;
euiCodeEditorProps?: { [key: string]: any };
codeEditorProps?: { [key: string]: any };
error?: string | null;
}

Expand All @@ -29,7 +29,7 @@ function JsonEditorComp<T extends object = { [key: string]: any }>({
onUpdate,
value,
defaultValue,
euiCodeEditorProps,
codeEditorProps,
error: propsError,
}: Props<T>) {
const {
Expand Down Expand Up @@ -83,23 +83,17 @@ function JsonEditorComp<T extends object = { [key: string]: any }>({
error={error}
fullWidth
>
<EuiCodeEditor
mode="json"
theme="textmate"
width="100%"
height="500px"
setOptions={{
showLineNumbers: false,
<CodeEditor
languageId="json"
height={500}
options={{
lineNumbers: 'off',
tabSize: 2,
automaticLayout: true,
}}
editorProps={{
$blockScrolling: Infinity,
}}
showGutter={false}
minLines={6}
value={isControlled ? value : content}
value={isControlled ? value! : content}
onChange={onEuiCodeEditorChange}
{...euiCodeEditorProps}
{...codeEditorProps}
/>
</EuiFormRow>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,50 @@
* 2.0.
*/
import type { NewPackagePolicy } from '@kbn/fleet-plugin/public';
import type { PackageInfo } from '@kbn/fleet-plugin/common';
import { createNewPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks';
import {
CLOUDBEAT_GCP,
CLOUDBEAT_AZURE,
CLOUDBEAT_EKS,
CLOUDBEAT_VANILLA,
CLOUDBEAT_AWS,
CLOUDBEAT_VULN_MGMT_AWS,
} from '../../../common/constants';
import type { PostureInput } from '../../../common/types';

export const getMockPolicyAWS = () => getPolicyMock(CLOUDBEAT_AWS, 'cspm', 'aws');
export const getMockPolicyK8s = () => getPolicyMock(CLOUDBEAT_VANILLA, 'kspm', 'self_managed');
export const getMockPolicyEKS = () => getPolicyMock(CLOUDBEAT_EKS, 'kspm', 'eks');
export const getMockPolicyVulnMgmtAWS = () =>
getPolicyMock(CLOUDBEAT_VULN_MGMT_AWS, 'vuln_mgmt', 'aws');

export const getMockPackageInfoVulnMgmtAWS = () => {
return {
policy_templates: [
{
title: '',
description: '',
name: 'vuln_mgmt',
inputs: [
{
type: 'cloudbeat/vuln_mgmt_aws',
title: '',
description: '',
vars: [
{
type: 'text',
name: 'cloud_formation_template',
default: 's3_url',
show_user: false,
},
],
},
],
},
],
} as PackageInfo;
};

const getPolicyMock = (
type: PostureInput,
Expand Down Expand Up @@ -84,6 +115,12 @@ const getPolicyMock = (
enabled: false,
streams: [{ enabled: false, data_stream: dataStream }],
},
{
type: CLOUDBEAT_VULN_MGMT_AWS,
policy_template: 'vuln_mgmt',
enabled: type === CLOUDBEAT_VULN_MGMT_AWS,
streams: [{ enabled: false, data_stream: dataStream }],
},
],
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,19 @@ import React from 'react';
import { render } from '@testing-library/react';
import { CspPolicyTemplateForm } from './policy_template_form';
import { TestProvider } from '../../test/test_provider';
import { getMockPolicyAWS, getMockPolicyEKS, getMockPolicyK8s } from './mocks';
import type { NewPackagePolicy, PackageInfo, PackagePolicy } from '@kbn/fleet-plugin/common';
import {
getMockPackageInfoVulnMgmtAWS,
getMockPolicyAWS,
getMockPolicyEKS,
getMockPolicyK8s,
getMockPolicyVulnMgmtAWS,
} from './mocks';
import type {
AgentPolicy,
NewPackagePolicy,
PackageInfo,
PackagePolicy,
} from '@kbn/fleet-plugin/common';
import userEvent from '@testing-library/user-event';
import { getPosturePolicy } from './utils';
import { CLOUDBEAT_AWS, CLOUDBEAT_EKS } from '../../../common/constants';
Expand All @@ -26,11 +37,14 @@ jest.mock('react-router-dom', () => ({
}));
jest.mock('../../common/api/use_setup_status_api');

const onChange = jest.fn();

describe('<CspPolicyTemplateForm />', () => {
beforeEach(() => {
(useParams as jest.Mock).mockReturnValue({
integration: undefined,
});
onChange.mockClear();
(useCspSetupStatusApi as jest.Mock).mockImplementation(() =>
createReactQueryResponse({
status: 'success',
Expand All @@ -39,40 +53,40 @@ describe('<CspPolicyTemplateForm />', () => {
);
});

const onChange = jest.fn();

const WrappedComponent = ({
newPolicy,
edit = false,
agentPolicy,
packageInfo = {} as PackageInfo,
}: {
edit?: boolean;
newPolicy: NewPackagePolicy;
agentPolicy?: AgentPolicy;
packageInfo?: PackageInfo;
}) => (
<TestProvider>
{edit && (
<CspPolicyTemplateForm
policy={newPolicy as PackagePolicy}
newPolicy={newPolicy}
onChange={onChange}
packageInfo={{} as PackageInfo}
packageInfo={packageInfo}
isEditPage={true}
agentPolicy={agentPolicy}
/>
)}
{!edit && (
<CspPolicyTemplateForm
newPolicy={newPolicy}
onChange={onChange}
packageInfo={{} as PackageInfo}
packageInfo={packageInfo}
isEditPage={false}
agentPolicy={agentPolicy}
/>
)}
</TestProvider>
);

beforeEach(() => {
onChange.mockClear();
});

it('updates package policy namespace to default when it changes', () => {
const policy = getMockPolicyK8s();
const { rerender } = render(<WrappedComponent newPolicy={policy} />);
Expand Down Expand Up @@ -505,4 +519,31 @@ describe('<CspPolicyTemplateForm />', () => {
});
});
}

describe('Vuln Mgmt', () => {
it('Update Agent Policy CloudFormation template from vars', () => {
const policy = getMockPolicyVulnMgmtAWS();

const packageInfo = getMockPackageInfoVulnMgmtAWS();
render(<WrappedComponent newPolicy={policy} packageInfo={packageInfo} />);

const expectedUpdatedPolicy = {
...policy,
inputs: policy.inputs.map((input) => {
if (input.type === 'cloudbeat/vuln_mgmt_aws') {
return {
...input,
config: { cloud_formation_template_url: { value: 's3_url' } },
};
}
return input;
}),
};

expect(onChange).toHaveBeenNthCalledWith(2, {
isValid: true,
updatedPolicy: expectedUpdatedPolicy,
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
NewPackagePolicyInput,
PackagePolicyReplaceDefineStepExtensionComponentProps,
} from '@kbn/fleet-plugin/public/types';
import type { PackageInfo } from '@kbn/fleet-plugin/common';
import { useParams } from 'react-router-dom';
import type { PostureInput, CloudSecurityPolicyTemplate } from '../../../common/types';
import {
Expand All @@ -32,6 +33,7 @@ import {
import {
getPosturePolicy,
getPostureInputHiddenVars,
getVulnMgmtCloudFormationDefaultValue,
POSTURE_NAMESPACE,
type NewPackagePolicyPostureInput,
isPostureInput,
Expand Down Expand Up @@ -86,11 +88,12 @@ const IntegrationSettings = ({ onChange, fields }: IntegrationInfoFieldsProps) =
);

export const CspPolicyTemplateForm = memo<PackagePolicyReplaceDefineStepExtensionComponentProps>(
({ newPolicy, onChange, validationResults, isEditPage }) => {
({ newPolicy, onChange, validationResults, isEditPage, packageInfo }) => {
const integrationParam = useParams<{ integration: CloudSecurityPolicyTemplate }>().integration;
const integration = SUPPORTED_POLICY_TEMPLATES.includes(integrationParam)
? integrationParam
: undefined;

const input = getSelectedOption(newPolicy.inputs, integration);

const updatePolicy = useCallback(
Expand Down Expand Up @@ -150,6 +153,12 @@ export const CspPolicyTemplateForm = memo<PackagePolicyReplaceDefineStepExtensio

useEnsureDefaultNamespace({ newPolicy, input, updatePolicy });

useCloudFormationTemplate({
packageInfo,
updatePolicy,
newPolicy,
});

if (isLoading) {
return (
<EuiFlexGroup justifyContent="spaceAround">
Expand Down Expand Up @@ -301,3 +310,45 @@ const getSelectedOption = (

return selectedOption;
};

/**
* Update CloudFormation template and stack name in the Agent Policy
* based on the selected policy template
*/
const useCloudFormationTemplate = ({
packageInfo,
newPolicy,
updatePolicy,
}: {
packageInfo: PackageInfo;
newPolicy: NewPackagePolicy;
updatePolicy: (policy: NewPackagePolicy) => void;
}) => {
useEffect(() => {
const templateUrl = getVulnMgmtCloudFormationDefaultValue(packageInfo);

// If the template is not available, do not update the policy
if (templateUrl === '') return;

const checkCurrentTemplate = newPolicy?.inputs?.find(
(i: any) => i.type === CLOUDBEAT_VULN_MGMT_AWS
)?.config?.cloud_formation_template_url?.value;

// If the template is already set, do not update the policy
if (checkCurrentTemplate === templateUrl) return;

updatePolicy?.({
...newPolicy,
inputs: newPolicy.inputs.map((input) => {
if (input.type === CLOUDBEAT_VULN_MGMT_AWS) {
return {
...input,
config: { cloud_formation_template_url: { value: templateUrl } },
};
}
return input;
}),
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [newPolicy?.vars?.cloud_formation_template_url, newPolicy, packageInfo]);
};
Loading

0 comments on commit 0ebb039

Please sign in to comment.