mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
(cherry picked from commit ce090a508a
)
Co-authored-by: Or Ouziel <or.ouziel@elastic.co>
This commit is contained in:
parent
7a26538af2
commit
cf43c0ac11
9 changed files with 647 additions and 0 deletions
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiComboBox,
|
||||
EuiToolTip,
|
||||
EuiFormRow,
|
||||
EuiIcon,
|
||||
type EuiComboBoxOptionOption,
|
||||
EuiDescribedFormGroup,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CIS_INTEGRATION_INPUTS_MAP } from '../../../common/constants';
|
||||
|
||||
export type InputType = keyof typeof CIS_INTEGRATION_INPUTS_MAP;
|
||||
|
||||
interface Props {
|
||||
type: InputType;
|
||||
onChange?: (type: InputType) => void;
|
||||
isDisabled?: boolean;
|
||||
}
|
||||
|
||||
const kubeDeployOptions: Array<EuiComboBoxOptionOption<InputType>> = [
|
||||
{
|
||||
value: 'cloudbeat/vanilla',
|
||||
label: i18n.translate(
|
||||
'xpack.csp.createPackagePolicy.stepConfigure.integrationSettingsSection.vanillaKubernetesDeploymentOption',
|
||||
{ defaultMessage: 'Unmanaged Kubernetes' }
|
||||
),
|
||||
},
|
||||
{
|
||||
value: 'cloudbeat/eks',
|
||||
label: i18n.translate(
|
||||
'xpack.csp.createPackagePolicy.stepConfigure.integrationSettingsSection.eksKubernetesDeploymentOption',
|
||||
{ defaultMessage: 'EKS (Elastic Kubernetes Service)' }
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const KubernetesDeploymentFieldLabel = () => (
|
||||
<EuiToolTip
|
||||
content={
|
||||
<FormattedMessage
|
||||
id="xpack.csp.createPackagePolicy.stepConfigure.integrationSettingsSection.kubernetesDeploymentLabelTooltip"
|
||||
defaultMessage="Select your Kubernetes deployment type"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiFlexGroup gutterSize="none" alignItems="center" responsive={false}>
|
||||
<EuiFlexItem grow style={{ flexDirection: 'row' }}>
|
||||
<FormattedMessage
|
||||
id="xpack.csp.createPackagePolicy.stepConfigure.integrationSettingsSection.kubernetesDeploymentLabel"
|
||||
defaultMessage="Kubernetes Deployment"
|
||||
/>
|
||||
|
||||
<EuiIcon size="m" color="subdued" type="questionInCircle" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiToolTip>
|
||||
);
|
||||
|
||||
export const DeploymentTypeSelect = ({ type, isDisabled, onChange }: Props) => (
|
||||
<EuiDescribedFormGroup title={<div />}>
|
||||
<EuiFormRow label={<KubernetesDeploymentFieldLabel />}>
|
||||
<EuiComboBox
|
||||
singleSelection={{ asPlainText: true }}
|
||||
options={kubeDeployOptions}
|
||||
selectedOptions={kubeDeployOptions.filter((o) => o.value === type)}
|
||||
isDisabled={isDisabled}
|
||||
onChange={(options) => !isDisabled && onChange?.(options[0].value!)}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiDescribedFormGroup>
|
||||
);
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { EuiFormRow, EuiFieldText, EuiDescribedFormGroup, EuiText, EuiSpacer } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { NewPackagePolicyInput } from '@kbn/fleet-plugin/common';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isEksInput } from './utils';
|
||||
|
||||
export const eksVars = [
|
||||
{
|
||||
id: 'access_key_id',
|
||||
label: i18n.translate(
|
||||
'xpack.csp.createPackagePolicy.eksIntegrationSettingsSection.accessKeyIdFieldLabel',
|
||||
{ defaultMessage: 'Access key ID' }
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'secret_access_key',
|
||||
label: i18n.translate(
|
||||
'xpack.csp.createPackagePolicy.eksIntegrationSettingsSection.secretAccessKeyFieldLabel',
|
||||
{ defaultMessage: 'Secret access key' }
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'session_token',
|
||||
label: i18n.translate(
|
||||
'xpack.csp.createPackagePolicy.eksIntegrationSettingsSection.sessionTokenFieldLabel',
|
||||
{ defaultMessage: 'Session token' }
|
||||
),
|
||||
},
|
||||
] as const;
|
||||
|
||||
type EksVars = typeof eksVars;
|
||||
type EksVarId = EksVars[number]['id'];
|
||||
type EksFormVars = { [K in EksVarId]: string };
|
||||
|
||||
interface Props {
|
||||
onChange(key: EksVarId, value: string): void;
|
||||
inputs: NewPackagePolicyInput[];
|
||||
}
|
||||
|
||||
const getEksVars = (input?: NewPackagePolicyInput): EksFormVars => {
|
||||
const vars = input?.streams?.[0]?.vars;
|
||||
return {
|
||||
access_key_id: vars?.access_key_id.value || '',
|
||||
secret_access_key: vars?.secret_access_key.value || '',
|
||||
session_token: vars?.session_token.value || '',
|
||||
};
|
||||
};
|
||||
|
||||
export const EksFormWrapper = ({ onChange, inputs }: Props) => (
|
||||
<>
|
||||
<EuiSpacer size="m" />
|
||||
<EksForm inputs={inputs} onChange={onChange} />
|
||||
</>
|
||||
);
|
||||
|
||||
const EksForm = ({ onChange, inputs }: Props) => {
|
||||
const values = getEksVars(inputs.find(isEksInput));
|
||||
|
||||
const eksFormTitle = (
|
||||
<h4>
|
||||
<FormattedMessage
|
||||
id="xpack.csp.createPackagePolicy.eksIntegrationSettingsSection.awsCredentialsTitle"
|
||||
defaultMessage="AWS Credentials"
|
||||
/>
|
||||
</h4>
|
||||
);
|
||||
|
||||
const eksFormDescription = (
|
||||
<>
|
||||
<FormattedMessage
|
||||
id="xpack.csp.createPackagePolicy.eksIntegrationSettingsSection.awsCredentialsNote"
|
||||
defaultMessage="If you choose not to provide credentials, only a subset of the benchmark rules will be evaluated against your cluster(s)."
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiDescribedFormGroup title={eksFormTitle} description={eksFormDescription}>
|
||||
{eksVars.map((field) => (
|
||||
<EuiFormRow
|
||||
key={field.id}
|
||||
label={field.label}
|
||||
labelAppend={
|
||||
<EuiText size="xs" color="subdued">
|
||||
<FormattedMessage
|
||||
id="xpack.csp.createPackagePolicy.eksIntegrationSettingsSection.optionalField"
|
||||
defaultMessage="Optional"
|
||||
/>
|
||||
</EuiText>
|
||||
}
|
||||
>
|
||||
<EuiFieldText
|
||||
value={values[field.id]}
|
||||
onChange={(event) => onChange(field.id, event.target.value)}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
))}
|
||||
</EuiDescribedFormGroup>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import type { NewPackagePolicy } from '@kbn/fleet-plugin/public';
|
||||
import type { PackagePolicy } from '@kbn/fleet-plugin/common';
|
||||
import { BenchmarkId } from '../../../common/types';
|
||||
|
||||
export const getCspNewPolicyMock = (type: BenchmarkId = 'cis_k8s'): NewPackagePolicy => ({
|
||||
name: 'some-cloud_security_posture-policy',
|
||||
description: '',
|
||||
namespace: 'default',
|
||||
policy_id: '',
|
||||
enabled: true,
|
||||
output_id: '',
|
||||
inputs: [
|
||||
{
|
||||
type: 'cloudbeat/vanilla',
|
||||
policy_template: 'kspm',
|
||||
enabled: type === 'cis_k8s',
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
type: 'logs',
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'cloudbeat/eks',
|
||||
policy_template: 'kspm',
|
||||
enabled: type === 'cis_eks',
|
||||
streams: [
|
||||
{
|
||||
enabled: false,
|
||||
data_stream: {
|
||||
type: 'logs',
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
vars: {
|
||||
access_key_id: {
|
||||
type: 'text',
|
||||
},
|
||||
secret_access_key: {
|
||||
type: 'text',
|
||||
},
|
||||
session_token: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
package: {
|
||||
name: 'cloud_security_posture',
|
||||
title: 'Kubernetes Security Posture Management',
|
||||
version: '0.0.21',
|
||||
},
|
||||
vars: {
|
||||
dataYaml: {
|
||||
type: 'yaml',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const getCspPolicyMock = (type: BenchmarkId = 'cis_k8s'): PackagePolicy => ({
|
||||
...getCspNewPolicyMock(type),
|
||||
id: 'c6d16e42-c32d-4dce-8a88-113cfe276ad1',
|
||||
version: 'abcd',
|
||||
revision: 1,
|
||||
updated_at: '2020-06-25T16:03:38.159292',
|
||||
updated_by: 'kibana',
|
||||
created_at: '2020-06-25T16:03:38.159292',
|
||||
created_by: 'kibana',
|
||||
inputs: [
|
||||
{
|
||||
policy_template: 'kspm',
|
||||
streams: [
|
||||
{
|
||||
compiled_stream: {
|
||||
data_yaml: {
|
||||
activated_rules: {
|
||||
cis_k8s: [],
|
||||
cis_eks: ['cis_3_1_4'],
|
||||
},
|
||||
},
|
||||
name: 'Findings',
|
||||
processors: [{ add_cluster_id: null }],
|
||||
},
|
||||
data_stream: {
|
||||
type: 'logs',
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
id: 'cloudbeat/vanilla-cloud_security_posture.findings-de97ed6f-5024-46af-a4f9-9acd7bd012d8',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
type: 'cloudbeat/vanilla',
|
||||
enabled: type === 'cis_k8s',
|
||||
},
|
||||
{
|
||||
policy_template: 'kspm',
|
||||
streams: [
|
||||
{
|
||||
data_stream: {
|
||||
type: 'logs',
|
||||
dataset: 'cloud_security_posture.findings',
|
||||
},
|
||||
vars: {
|
||||
access_key_id: {
|
||||
type: 'text',
|
||||
},
|
||||
session_token: {
|
||||
type: 'text',
|
||||
},
|
||||
secret_access_key: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
id: 'cloudbeat/eks-cloud_security_posture.findings-de97ed6f-5024-46af-a4f9-9acd7bd012d8',
|
||||
enabled: false,
|
||||
},
|
||||
],
|
||||
type: 'cloudbeat/eks',
|
||||
enabled: type === 'cis_eks',
|
||||
},
|
||||
],
|
||||
vars: {
|
||||
dataYaml: {
|
||||
type: 'yaml',
|
||||
value: 'data_yaml:\n activated_rules:\n cis_k8s: []\n cis_eks:\n - cis_3_1_4\n ',
|
||||
},
|
||||
},
|
||||
});
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import CspCreatePolicyExtension from './policy_extension_create';
|
||||
import { eksVars } from './eks_form';
|
||||
import Chance from 'chance';
|
||||
import { TestProvider } from '../../test/test_provider';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { getCspNewPolicyMock } from './mocks';
|
||||
|
||||
// ensures that fields appropriately match to their label
|
||||
jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
||||
...jest.requireActual('@elastic/eui/lib/services/accessibility/html_id_generator'),
|
||||
htmlIdGenerator: () => () => `id-${Math.random()}`,
|
||||
}));
|
||||
|
||||
// ensures that fields appropriately match to their label
|
||||
jest.mock('@elastic/eui/lib/services/accessibility', () => ({
|
||||
...jest.requireActual('@elastic/eui/lib/services/accessibility'),
|
||||
useGeneratedHtmlId: () => `id-${Math.random()}`,
|
||||
}));
|
||||
|
||||
const chance = new Chance();
|
||||
|
||||
describe('<CspCreatePolicyExtension />', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
const WrappedComponent = ({ newPolicy = getCspNewPolicyMock() }) => (
|
||||
<TestProvider>
|
||||
<CspCreatePolicyExtension newPolicy={newPolicy} onChange={onChange} />
|
||||
</TestProvider>
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
onChange.mockClear();
|
||||
});
|
||||
|
||||
it('renders non-disabled <DeploymentTypeSelect/>', () => {
|
||||
const { getByLabelText } = render(<WrappedComponent />);
|
||||
const input = getByLabelText('Kubernetes Deployment') as HTMLInputElement;
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(input).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('renders non-disabled <EksForm/>', () => {
|
||||
const { getByLabelText } = render(
|
||||
<WrappedComponent newPolicy={getCspNewPolicyMock('cis_eks')} />
|
||||
);
|
||||
|
||||
eksVars.forEach((eksVar) => {
|
||||
expect(getByLabelText(eksVar.label)).toBeInTheDocument();
|
||||
expect(getByLabelText(eksVar.label)).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
it('handles updating deployment type', () => {
|
||||
const { getByLabelText } = render(<WrappedComponent />);
|
||||
const input = getByLabelText('Kubernetes Deployment') as HTMLInputElement;
|
||||
|
||||
userEvent.type(input, 'EKS (Elastic Kubernetes Service){enter}');
|
||||
|
||||
expect(onChange).toBeCalledWith({
|
||||
isValid: true,
|
||||
updatedPolicy: getCspNewPolicyMock('cis_eks'),
|
||||
});
|
||||
});
|
||||
|
||||
it('handles updating EKS vars', () => {
|
||||
const { getByLabelText } = render(
|
||||
<WrappedComponent newPolicy={getCspNewPolicyMock('cis_eks')} />
|
||||
);
|
||||
|
||||
const randomValues = chance.unique(chance.string, eksVars.length);
|
||||
|
||||
eksVars.forEach((eksVar, i) => {
|
||||
const eksVarInput = getByLabelText(eksVar.label) as HTMLInputElement;
|
||||
fireEvent.change(eksVarInput, { target: { value: randomValues[i] } });
|
||||
|
||||
const policy = getCspNewPolicyMock('cis_eks');
|
||||
policy.inputs[1].streams[0].vars![eksVar.id].value = randomValues[i];
|
||||
|
||||
expect(onChange).toBeCalledWith({
|
||||
isValid: true,
|
||||
updatedPolicy: policy,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React, { memo } from 'react';
|
||||
import { EuiForm } from '@elastic/eui';
|
||||
import type { PackagePolicyCreateExtensionComponentProps } from '@kbn/fleet-plugin/public';
|
||||
import { CLOUDBEAT_EKS } from '../../../common/constants';
|
||||
import { DeploymentTypeSelect, InputType } from './deployment_type_select';
|
||||
import { EksFormWrapper } from './eks_form';
|
||||
import { getEnabledInputType, getUpdatedDeploymentType, getUpdatedEksVar } from './utils';
|
||||
|
||||
export const CspCreatePolicyExtension = memo<PackagePolicyCreateExtensionComponentProps>(
|
||||
({ newPolicy, onChange }) => {
|
||||
const selectedDeploymentType = getEnabledInputType(newPolicy.inputs);
|
||||
|
||||
const updateDeploymentType = (inputType: InputType) =>
|
||||
onChange(getUpdatedDeploymentType(newPolicy, inputType));
|
||||
|
||||
const updateEksVar = (key: string, value: string) =>
|
||||
onChange(getUpdatedEksVar(newPolicy, key, value));
|
||||
|
||||
return (
|
||||
<EuiForm>
|
||||
<DeploymentTypeSelect type={selectedDeploymentType} onChange={updateDeploymentType} />
|
||||
{selectedDeploymentType === CLOUDBEAT_EKS && (
|
||||
<EksFormWrapper inputs={newPolicy.inputs} onChange={updateEksVar} />
|
||||
)}
|
||||
</EuiForm>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
CspCreatePolicyExtension.displayName = 'CspCreatePolicyExtension';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export { CspCreatePolicyExtension as default };
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import CspEditPolicyExtension from './policy_extension_edit';
|
||||
import { TestProvider } from '../../test/test_provider';
|
||||
import { getCspNewPolicyMock, getCspPolicyMock } from './mocks';
|
||||
import Chance from 'chance';
|
||||
import { eksVars } from './eks_form';
|
||||
|
||||
const chance = new Chance();
|
||||
|
||||
// ensures that fields appropriately match to their label
|
||||
jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
||||
...jest.requireActual('@elastic/eui/lib/services/accessibility/html_id_generator'),
|
||||
htmlIdGenerator: () => () => `id-${Math.random()}`,
|
||||
}));
|
||||
|
||||
// ensures that fields appropriately match to their label
|
||||
jest.mock('@elastic/eui/lib/services/accessibility', () => ({
|
||||
...jest.requireActual('@elastic/eui/lib/services/accessibility'),
|
||||
useGeneratedHtmlId: () => `id-${Math.random()}`,
|
||||
}));
|
||||
|
||||
describe('<CspEditPolicyExtension />', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
const WrappedComponent = ({ policy = getCspPolicyMock(), newPolicy = getCspNewPolicyMock() }) => (
|
||||
<TestProvider>
|
||||
<CspEditPolicyExtension policy={policy} newPolicy={newPolicy} onChange={onChange} />
|
||||
</TestProvider>
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
onChange.mockClear();
|
||||
});
|
||||
|
||||
it('renders disabled <DeploymentTypeSelect/>', () => {
|
||||
const { getByLabelText } = render(<WrappedComponent />);
|
||||
const input = getByLabelText('Kubernetes Deployment') as HTMLInputElement;
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(input).toBeDisabled();
|
||||
});
|
||||
|
||||
it('renders non-disabled <EksForm/>', () => {
|
||||
const { getByLabelText } = render(
|
||||
<WrappedComponent newPolicy={getCspNewPolicyMock('cis_eks')} />
|
||||
);
|
||||
|
||||
eksVars.forEach((eksVar) => {
|
||||
expect(getByLabelText(eksVar.label)).toBeInTheDocument();
|
||||
expect(getByLabelText(eksVar.label)).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
it('handles updating EKS vars', () => {
|
||||
const { getByLabelText } = render(
|
||||
<WrappedComponent newPolicy={getCspNewPolicyMock('cis_eks')} />
|
||||
);
|
||||
|
||||
const randomValues = chance.unique(chance.string, eksVars.length);
|
||||
|
||||
eksVars.forEach((eksVar, i) => {
|
||||
const eksVarInput = getByLabelText(eksVar.label) as HTMLInputElement;
|
||||
fireEvent.change(eksVarInput, { target: { value: randomValues[i] } });
|
||||
|
||||
const policy = getCspNewPolicyMock('cis_eks');
|
||||
policy.inputs[1].streams[0].vars![eksVar.id].value = randomValues[i];
|
||||
|
||||
expect(onChange).toBeCalledWith({
|
||||
isValid: true,
|
||||
updatedPolicy: policy,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import React, { memo } from 'react';
|
||||
import { EuiForm } from '@elastic/eui';
|
||||
import type { PackagePolicyEditExtensionComponentProps } from '@kbn/fleet-plugin/public';
|
||||
import { CLOUDBEAT_EKS } from '../../../common/constants';
|
||||
import { DeploymentTypeSelect } from './deployment_type_select';
|
||||
import { EksFormWrapper } from './eks_form';
|
||||
import { getEnabledInputType, getUpdatedEksVar } from './utils';
|
||||
|
||||
export const CspEditPolicyExtension = memo<PackagePolicyEditExtensionComponentProps>(
|
||||
({ newPolicy, onChange }) => {
|
||||
const selectedDeploymentType = getEnabledInputType(newPolicy.inputs);
|
||||
|
||||
const updateEksVar = (key: string, value: string) =>
|
||||
onChange(getUpdatedEksVar(newPolicy, key, value));
|
||||
|
||||
return (
|
||||
<EuiForm>
|
||||
<DeploymentTypeSelect type={selectedDeploymentType} isDisabled />
|
||||
{selectedDeploymentType === CLOUDBEAT_EKS && (
|
||||
<EksFormWrapper inputs={newPolicy.inputs} onChange={updateEksVar} />
|
||||
)}
|
||||
</EuiForm>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
CspEditPolicyExtension.displayName = 'CspEditPolicyExtension';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export { CspEditPolicyExtension as default };
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import type { NewPackagePolicy, NewPackagePolicyInput } from '@kbn/fleet-plugin/common';
|
||||
import { CLOUDBEAT_EKS, CLOUDBEAT_VANILLA } from '../../../common/constants';
|
||||
import type { InputType } from './deployment_type_select';
|
||||
|
||||
export const isEksInput = (input: NewPackagePolicyInput) => input.type === CLOUDBEAT_EKS;
|
||||
|
||||
export const getEnabledInputType = (inputs: NewPackagePolicy['inputs']): InputType =>
|
||||
(inputs.find((input) => input.enabled)?.type as InputType) || CLOUDBEAT_VANILLA;
|
||||
|
||||
export const getUpdatedDeploymentType = (newPolicy: NewPackagePolicy, inputType: InputType) => ({
|
||||
isValid: true, // TODO: add validations
|
||||
updatedPolicy: {
|
||||
...newPolicy,
|
||||
inputs: newPolicy.inputs.map((item) => ({
|
||||
...item,
|
||||
enabled: item.type === inputType,
|
||||
})),
|
||||
},
|
||||
});
|
||||
|
||||
export const getUpdatedEksVar = (newPolicy: NewPackagePolicy, key: string, value: string) => ({
|
||||
isValid: true, // TODO: add validations
|
||||
updatedPolicy: {
|
||||
...newPolicy,
|
||||
inputs: newPolicy.inputs.map((item) =>
|
||||
isEksInput(item) ? getUpdatedStreamVars(item, key, value) : item
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: remove access to first stream
|
||||
const getUpdatedStreamVars = (item: NewPackagePolicyInput, key: string, value: string) => {
|
||||
if (!item.streams[0]) return item;
|
||||
|
||||
return {
|
||||
...item,
|
||||
streams: [
|
||||
{
|
||||
...item.streams[0],
|
||||
vars: {
|
||||
...item.streams[0]?.vars,
|
||||
[key]: {
|
||||
...item.streams[0]?.vars?.[key],
|
||||
value,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
|
@ -18,6 +18,10 @@ import type {
|
|||
} from './types';
|
||||
import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../common/constants';
|
||||
|
||||
const LazyCspEditPolicy = lazy(() => import('./components/fleet_extensions/policy_extension_edit'));
|
||||
const LazyCspCreatePolicy = lazy(
|
||||
() => import('./components/fleet_extensions/policy_extension_create')
|
||||
);
|
||||
const LazyCspCustomAssets = lazy(
|
||||
() => import('./components/fleet_extensions/custom_assets_extension')
|
||||
);
|
||||
|
@ -47,6 +51,18 @@ export class CspPlugin
|
|||
}
|
||||
|
||||
public start(core: CoreStart, plugins: CspClientPluginStartDeps): CspClientPluginStart {
|
||||
plugins.fleet.registerExtension({
|
||||
package: CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
|
||||
view: 'package-policy-create',
|
||||
Component: LazyCspCreatePolicy,
|
||||
});
|
||||
|
||||
plugins.fleet.registerExtension({
|
||||
package: CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
|
||||
view: 'package-policy-edit',
|
||||
Component: LazyCspEditPolicy,
|
||||
});
|
||||
|
||||
plugins.fleet.registerExtension({
|
||||
package: CLOUD_SECURITY_POSTURE_PACKAGE_NAME,
|
||||
view: 'package-detail-assets',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue