Skip to content

Commit

Permalink
Merge branch 'main' into guided_onboarding/8.8/roles
Browse files Browse the repository at this point in the history
  • Loading branch information
yuliacech authored Apr 26, 2023
2 parents 17f68ed + 207c23e commit 98e2564
Show file tree
Hide file tree
Showing 60 changed files with 1,214 additions and 226 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const getMaxValue = (
if (isRespectRanges && paletteParams?.rangeMax) {
const metricValue = accessors?.metric ? getValueFromAccessor(accessors.metric, row) : undefined;
return !metricValue || metricValue < paletteParams?.rangeMax
? paletteParams?.rangeMax
? paletteParams.rangeMax
: metricValue;
}

Expand All @@ -93,16 +93,16 @@ export const getMinValue = (
accessors?: Accessors,
paletteParams?: CustomPaletteParams,
isRespectRanges?: boolean
) => {
): number => {
const currentValue = accessors?.min ? getValueFromAccessor(accessors.min, row) : undefined;
if (currentValue !== undefined && currentValue !== null) {
if (currentValue != null) {
return currentValue;
}

if (isRespectRanges && paletteParams?.rangeMin) {
const metricValue = accessors?.metric ? getValueFromAccessor(accessors.metric, row) : undefined;
return !metricValue || metricValue > paletteParams?.rangeMin
? paletteParams?.rangeMin
? paletteParams.rangeMin
: metricValue;
}

Expand All @@ -121,7 +121,7 @@ export const getMinValue = (

export const getGoalValue = (row?: DatatableRow, accessors?: Accessors) => {
const currentValue = accessors?.goal ? getValueFromAccessor(accessors.goal, row) : undefined;
if (currentValue !== undefined && currentValue !== null) {
if (currentValue != null) {
return currentValue;
}

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]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
import type {
NewPackagePolicy,
NewPackagePolicyInput,
PackageInfo,
PackagePolicyConfigRecordEntry,
RegistryPolicyTemplate,
RegistryVarsEntry,
} from '@kbn/fleet-plugin/common';
import merge from 'lodash/merge';
import {
Expand All @@ -21,6 +24,7 @@ import {
SUPPORTED_CLOUDBEAT_INPUTS,
CSPM_POLICY_TEMPLATE,
KSPM_POLICY_TEMPLATE,
VULN_MGMT_POLICY_TEMPLATE,
} from '../../../common/constants';
import { DEFAULT_AWS_VARS_GROUP } from './aws_credentials_form';
import type { PostureInput, CloudSecurityPolicyTemplate } from '../../../common/types';
Expand All @@ -34,7 +38,8 @@ type PosturePolicyInput =
| { type: typeof CLOUDBEAT_GCP; policy_template: typeof CSPM_POLICY_TEMPLATE }
| { type: typeof CLOUDBEAT_AWS; policy_template: typeof CSPM_POLICY_TEMPLATE }
| { type: typeof CLOUDBEAT_VANILLA; policy_template: typeof KSPM_POLICY_TEMPLATE }
| { type: typeof CLOUDBEAT_EKS; policy_template: typeof KSPM_POLICY_TEMPLATE };
| { type: typeof CLOUDBEAT_EKS; policy_template: typeof KSPM_POLICY_TEMPLATE }
| { type: typeof CLOUDBEAT_VULN_MGMT_AWS; policy_template: typeof VULN_MGMT_POLICY_TEMPLATE };

// Extend NewPackagePolicyInput with known string literals for input type and policy template
export type NewPackagePolicyPostureInput = NewPackagePolicyInput & PosturePolicyInput;
Expand Down Expand Up @@ -121,6 +126,40 @@ export const getPosturePolicy = (
}),
});

type RegistryPolicyTemplateWithInputs = RegistryPolicyTemplate & {
inputs: Array<{
vars?: RegistryVarsEntry[];
}>;
};
// type guard for checking inputs
export const hasPolicyTemplateInputs = (
policyTemplate: RegistryPolicyTemplate
): policyTemplate is RegistryPolicyTemplateWithInputs => {
return policyTemplate.hasOwnProperty('inputs');
};

export const getVulnMgmtCloudFormationDefaultValue = (packageInfo: PackageInfo): string => {
if (!packageInfo.policy_templates) return '';

const vulnMgmtPolicyTemplate = packageInfo.policy_templates.find(
(p) => p.name === VULN_MGMT_POLICY_TEMPLATE
);
if (!vulnMgmtPolicyTemplate) return '';

const vulnMgmtInputs =
hasPolicyTemplateInputs(vulnMgmtPolicyTemplate) && vulnMgmtPolicyTemplate.inputs;

if (!vulnMgmtInputs) return '';

const cloudFormationTemplate = vulnMgmtInputs.reduce((acc, input): string => {
if (!input.vars) return acc;
const template = input.vars.find((v) => v.name === 'cloud_formation_template')?.default;
return template ? String(template) : acc;
}, '');

return cloudFormationTemplate;
};

/**
* Input vars that are hidden from the user
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ function getArtifact(platform: PLATFORM_TYPE, kibanaVersion: string) {
kubernetes: {
downloadCommand: '',
},
cloudFormation: {
downloadCommand: '',
},
};

return artifactMap[platform];
Expand Down Expand Up @@ -115,6 +118,7 @@ export function getInstallCommandForPlatform(
deb: `${artifact.downloadCommand}\nsudo elastic-agent enroll ${commandArgumentsStr}\nsudo systemctl enable elastic-agent\nsudo systemctl start elastic-agent`,
rpm: `${artifact.downloadCommand}\nsudo elastic-agent enroll ${commandArgumentsStr}\nsudo systemctl enable elastic-agent\nsudo systemctl start elastic-agent`,
kubernetes: '',
cloudFormation: '',
};

return commands[platform];
Expand Down
Loading

0 comments on commit 98e2564

Please sign in to comment.