Commit 9bf5a622 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '321884-add-new-and-edit-page' into 'master'

Add new and edit pages for policies

See merge request gitlab-org/gitlab!67900
parents f56db5fa c778a018
import initPolicyEditorApp from 'ee/threat_monitoring/policy_editor';
initPolicyEditorApp();
import initPolicyEditorApp from 'ee/threat_monitoring/policy_editor';
initPolicyEditorApp();
......@@ -21,23 +21,36 @@ export const COLORS = {
// See https://gitlab.com/gitlab-org/gitlab-ui/issues/554.
export { dateFormats as DATE_FORMATS } from '~/analytics/shared/constants';
export const POLICY_KINDS = {
ciliumNetwork: 'CiliumNetworkPolicy',
scanExecution: 'scanner_profile',
export const POLICY_TYPE_COMPONENT_OPTIONS = {
container: {
component: 'network-policy-editor',
shouldShowEnvironmentPicker: true,
text: s__('SecurityOrchestration|Network'),
urlParameter: 'container_policy',
value: 'container',
yamlIndicator: 'CiliumNetworkPolicy',
},
scanExecution: {
component: 'scan-execution-policy-editor',
text: s__('SecurityOrchestration|Scan Execution'),
urlParameter: 'scan_execution_policy',
value: 'scanExecution',
yamlIndicator: 'scanner_profile',
},
};
export const POLICY_TYPE_OPTIONS = {
POLICY_TYPE_NETWORK: {
value: 'POLICY_TYPE_NETWORK',
text: s__('SecurityPolicies|Network'),
text: s__('SecurityOrchestration|Network'),
},
POLICY_TYPE_SCAN_EXECUTION: {
value: 'POLICY_TYPE_SCAN_EXECUTION',
text: s__('SecurityPolicies|Scan execution'),
text: s__('SecurityOrchestration|Scan execution'),
},
ALL: {
value: '',
text: s__('SecurityPolicies|All policies'),
text: s__('SecurityOrchestration|All policies'),
},
};
......
......@@ -16,7 +16,8 @@ import { setUrlFragment, mergeUrlParams } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
import networkPoliciesQuery from '../../graphql/queries/network_policies.query.graphql';
import scanExecutionPoliciesQuery from '../../graphql/queries/scan_execution_policies.query.graphql';
import { POLICY_TYPE_OPTIONS } from '../constants';
import { getPolicyType } from '../../utils';
import { POLICY_TYPE_COMPONENT_OPTIONS, POLICY_TYPE_OPTIONS } from '../constants';
import EnvironmentPicker from '../environment_picker.vue';
import PolicyDrawer from '../policy_drawer/policy_drawer.vue';
import PolicyEnvironments from '../policy_environments.vue';
......@@ -146,13 +147,17 @@ export default {
editPolicyPath() {
return this.hasSelectedPolicy
? mergeUrlParams(
!this.selectedPolicy.kind
? { environment_id: this.currentEnvironmentId }
: { environment_id: this.currentEnvironmentId, kind: this.selectedPolicy.kind },
{
environment_id: this.currentEnvironmentId,
type: POLICY_TYPE_COMPONENT_OPTIONS[this.policyType]?.urlParameter,
},
this.newPolicyPath.replace('new', `${this.selectedPolicy.name}/edit`),
)
: '';
},
policyType() {
return this.selectedPolicy ? getPolicyType(this.selectedPolicy.yaml) : 'container';
},
fields() {
const environments = {
key: 'environments',
......@@ -308,6 +313,7 @@ export default {
<policy-drawer
:open="hasSelectedPolicy"
:policy="selectedPolicy"
:policy-type="policyType"
:edit-policy-path="editPolicyPath"
data-testid="policyDrawer"
@close="deselectPolicy"
......
<script>
import { GlButton, GlDrawer } from '@gitlab/ui';
import { getContentWrapperHeight, getPolicyKind } from '../../utils';
import { POLICIES_LIST_CONTAINER_CLASS, POLICY_KINDS } from '../constants';
import { getContentWrapperHeight } from '../../utils';
import { POLICIES_LIST_CONTAINER_CLASS, POLICY_TYPE_COMPONENT_OPTIONS } from '../constants';
import CiliumNetworkPolicy from './cilium_network_policy.vue';
import ScanExecutionPolicy from './scan_execution_policy.vue';
const policyComponent = {
[POLICY_KINDS.ciliumNetwork]: CiliumNetworkPolicy,
[POLICY_KINDS.scanExecution]: ScanExecutionPolicy,
[POLICY_TYPE_COMPONENT_OPTIONS.container.value]: CiliumNetworkPolicy,
[POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value]: ScanExecutionPolicy,
};
export default {
......@@ -30,6 +30,11 @@ export default {
required: false,
default: null,
},
policyType: {
type: String,
required: false,
default: '',
},
editPolicyPath: {
type: String,
required: false,
......@@ -37,11 +42,8 @@ export default {
},
},
computed: {
policyKind() {
return getPolicyKind(this.policy?.yaml);
},
policyComponent() {
return policyComponent[this.policyKind] || null;
return policyComponent[this.policyType] || null;
},
},
methods: {
......
......@@ -12,20 +12,6 @@ export const EDITOR_MODES = [
{ value: EDITOR_MODE_YAML, text: s__('NetworkPolicies|.yaml mode') },
];
export const POLICY_KIND_OPTIONS = {
network: {
value: 'network',
text: s__('NetworkPolicies|Network'),
component: 'network-policy-editor',
shouldShowEnvironmentPicker: true,
},
scanExecution: {
value: 'scanExecution',
text: s__('NetworkPolicies|Scan Execution'),
component: 'scan-execution-policy-editor',
},
};
export const DELETE_MODAL_CONFIG = {
id: 'delete-modal',
secondary: {
......
import { safeDump } from 'js-yaml';
import { POLICY_KINDS } from 'ee/threat_monitoring/components/constants';
import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/threat_monitoring/components/constants';
import { EndpointMatchModeAny, DisabledByLabel } from './constants';
import { ruleSpec } from './rules';
import { labelSelector } from './utils';
......@@ -48,7 +48,7 @@ export default function toYaml(policy) {
const policySpec = {
apiVersion: 'cilium.io/v2',
kind: POLICY_KINDS.ciliumNetwork,
kind: POLICY_TYPE_COMPONENT_OPTIONS.container.yamlIndicator,
};
if (description?.length > 0) {
......
......@@ -2,8 +2,8 @@
import { GlAlert, GlFormGroup, GlFormSelect } from '@gitlab/ui';
import { mapActions } from 'vuex';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { POLICY_TYPE_COMPONENT_OPTIONS } from '../constants';
import EnvironmentPicker from '../environment_picker.vue';
import { POLICY_KIND_OPTIONS } from './constants';
import NetworkPolicyEditor from './network_policy/network_policy_editor.vue';
import ScanExecutionPolicyEditor from './scan_execution_policy/scan_execution_policy_editor.vue';
......@@ -31,18 +31,18 @@ export default {
data() {
return {
error: '',
policyType: POLICY_KIND_OPTIONS.network.value,
policyType: POLICY_TYPE_COMPONENT_OPTIONS.container.value,
};
},
computed: {
policyComponent() {
return POLICY_KIND_OPTIONS[this.policyType].component;
return POLICY_TYPE_COMPONENT_OPTIONS[this.policyType].component;
},
shouldAllowPolicyTypeSelection() {
return !this.existingPolicy && this.glFeatures.securityOrchestrationPoliciesConfiguration;
},
shouldShowEnvironmentPicker() {
return POLICY_KIND_OPTIONS[this.policyType].shouldShowEnvironmentPicker;
return POLICY_TYPE_COMPONENT_OPTIONS[this.policyType].shouldShowEnvironmentPicker;
},
},
created() {
......@@ -57,7 +57,7 @@ export default {
this.policyType = type;
},
},
policyTypes: Object.values(POLICY_KIND_OPTIONS),
policyTypes: Object.values(POLICY_TYPE_COMPONENT_OPTIONS),
};
</script>
......
......@@ -18,6 +18,7 @@ import { setUrlFragment, mergeUrlParams } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
import networkPoliciesQuery from '../graphql/queries/network_policies.query.graphql';
import scanExecutionPoliciesQuery from '../graphql/queries/scan_execution_policies.query.graphql';
import { getPolicyType } from '../utils';
import { POLICY_TYPE_OPTIONS } from './constants';
import EnvironmentPicker from './environment_picker.vue';
import PolicyDrawer from './policy_drawer/policy_drawer.vue';
......@@ -166,6 +167,9 @@ export default {
)
: '';
},
policyType() {
return this.selectedPolicy ? getPolicyType(this.selectedPolicy.yaml) : '';
},
fields() {
const environments = {
key: 'environments',
......@@ -329,6 +333,7 @@ export default {
:open="hasSelectedPolicy"
container-class=".js-threat-monitoring-container-wrapper"
:policy="selectedPolicy"
:policy-type="policyType"
:edit-policy-path="editPolicyPath"
data-testid="policyDrawer"
@close="deselectPolicy"
......
import createGqClient from '~/lib/graphql';
import { POLICY_KINDS } from './components/constants';
import { POLICY_TYPE_COMPONENT_OPTIONS } from './components/constants';
/**
* Get the height of the wrapper page element
......@@ -18,12 +18,12 @@ export const getContentWrapperHeight = (contentWrapperClass) => {
* @param {String} yaml policy's YAML manifest
* @returns {String|null} policy type if available
*/
export const getPolicyKind = (yaml = '') => {
if (yaml?.includes(POLICY_KINDS.ciliumNetwork)) {
return POLICY_KINDS.ciliumNetwork;
export const getPolicyType = (yaml = '') => {
if (yaml?.includes(POLICY_TYPE_COMPONENT_OPTIONS.container.yamlIndicator)) {
return POLICY_TYPE_COMPONENT_OPTIONS.container.value;
}
if (yaml?.includes(POLICY_KINDS.scanExecution)) {
return POLICY_KINDS.scanExecution;
if (yaml?.includes(POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.yamlIndicator)) {
return POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value;
}
return null;
};
......
......@@ -169,9 +169,9 @@ describe('PoliciesList component', () => {
describe.each`
rowIndex | expectedPolicyName | expectedPolicyType
${1} | ${mockScanExecutionPoliciesResponse[0].name} | ${'Scan execution'}
${2} | ${mockNetworkPoliciesResponse[0].name} | ${'Network'}
${3} | ${'drop-outbound'} | ${'Network'}
${4} | ${'allow-inbound-http'} | ${'Network'}
${3} | ${mockNetworkPoliciesResponse[0].name} | ${'Network'}
${4} | ${'drop-outbound'} | ${'Network'}
${5} | ${'allow-inbound-http'} | ${'Network'}
`('policy in row #$rowIndex', ({ rowIndex, expectedPolicyName, expectedPolicyType }) => {
let row;
......@@ -219,7 +219,7 @@ describe('PoliciesList component', () => {
});
it('renders a "Disabled" label for screen readers for disabled policies', () => {
const span = findPolicyStatusCells().at(2).find('span');
const span = findPolicyStatusCells().at(3).find('span');
expect(span.exists()).toBe(true);
expect(span.attributes('class')).toBe('gl-sr-only');
......@@ -240,10 +240,10 @@ describe('PoliciesList component', () => {
});
describe.each`
description | policy
${'network'} | ${mockNetworkPoliciesResponse[0]}
${'scan execution'} | ${mockScanExecutionPoliciesResponse[0]}
`('given there is a $description policy selected', ({ policy }) => {
description | policy | policyType
${'container'} | ${mockNetworkPoliciesResponse[1]} | ${'container'}
${'scan execution'} | ${mockScanExecutionPoliciesResponse[0]} | ${'scanExecution'}
`('given there is a $description policy selected', ({ policy, policyType }) => {
beforeEach(() => {
mountShallowWrapper();
findPoliciesTable().vm.$emit('row-selected', [policy]);
......@@ -255,6 +255,7 @@ describe('PoliciesList component', () => {
expect(editorDrawer.props()).toMatchObject({
open: true,
policy,
policyType,
});
});
});
......@@ -262,7 +263,7 @@ describe('PoliciesList component', () => {
describe('given an autodevops policy', () => {
beforeEach(() => {
const autoDevOpsPolicy = {
...mockNetworkPoliciesResponse[0],
...mockNetworkPoliciesResponse[1],
name: 'auto-devops',
fromAutoDevops: true,
};
......
import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/threat_monitoring/components/constants';
import CiliumNetworkPolicy from 'ee/threat_monitoring/components/policy_drawer/cilium_network_policy.vue';
import PolicyDrawer from 'ee/threat_monitoring/components/policy_drawer/policy_drawer.vue';
import ScanExecutionPolicy from 'ee/threat_monitoring/components/policy_drawer/scan_execution_policy.vue';
......@@ -73,19 +74,20 @@ describe('PolicyDrawer component', () => {
});
describe.each`
policyKind | mock | finder
${'cilium'} | ${mockCiliumPolicy} | ${findCiliumNetworkPolicy}
${'scan execution'} | ${mockScanExecutionPolicy} | ${findScanExecutionPolicy}
`('given a $policyKind policy', ({ policyKind, mock, finder }) => {
policyType | mock | finder
${POLICY_TYPE_COMPONENT_OPTIONS.container.value} | ${mockCiliumPolicy} | ${findCiliumNetworkPolicy}
${POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value} | ${mockScanExecutionPolicy} | ${findScanExecutionPolicy}
`('given a $policyType policy', ({ policyType, mock, finder }) => {
beforeEach(() => {
factory({
propsData: {
policy: mock,
policyType,
},
});
});
it(`renders the ${policyKind} component`, () => {
it(`renders the ${policyType} component`, () => {
expect(finder().exists()).toBe(true);
});
......
import { GlAlert, GlFormSelect } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/threat_monitoring/components/constants';
import EnvironmentPicker from 'ee/threat_monitoring/components/environment_picker.vue';
import { POLICY_KIND_OPTIONS } from 'ee/threat_monitoring/components/policy_editor/constants';
import NetworkPolicyEditor from 'ee/threat_monitoring/components/policy_editor/network_policy/network_policy_editor.vue';
import PolicyEditor from 'ee/threat_monitoring/components/policy_editor/policy_editor.vue';
import { DEFAULT_ASSIGNED_POLICY_PROJECT } from 'ee/threat_monitoring/constants';
......@@ -52,7 +52,7 @@ describe('PolicyEditor component', () => {
it('renders the disabled form select', () => {
const formSelect = findFormSelect();
expect(formSelect.exists()).toBe(true);
expect(formSelect.attributes('value')).toBe(POLICY_KIND_OPTIONS.network.value);
expect(formSelect.attributes('value')).toBe(POLICY_TYPE_COMPONENT_OPTIONS.container.value);
expect(formSelect.attributes('disabled')).toBe('true');
});
......@@ -74,7 +74,7 @@ describe('PolicyEditor component', () => {
it('renders the disabled form select', () => {
const formSelect = findFormSelect();
expect(formSelect.exists()).toBe(true);
expect(formSelect.attributes('value')).toBe(POLICY_KIND_OPTIONS.network.value);
expect(formSelect.attributes('value')).toBe(POLICY_TYPE_COMPONENT_OPTIONS.container.value);
expect(formSelect.attributes('disabled')).toBe('true');
});
});
......
......@@ -169,9 +169,9 @@ describe('PolicyList component', () => {
describe.each`
rowIndex | expectedPolicyName | expectedPolicyType
${1} | ${mockScanExecutionPoliciesResponse[0].name} | ${'Scan execution'}
${2} | ${mockNetworkPoliciesResponse[0].name} | ${'Network'}
${3} | ${'drop-outbound'} | ${'Network'}
${4} | ${'allow-inbound-http'} | ${'Network'}
${3} | ${mockNetworkPoliciesResponse[0].name} | ${'Network'}
${4} | ${'drop-outbound'} | ${'Network'}
${5} | ${'allow-inbound-http'} | ${'Network'}
`('policy in row #$rowIndex', ({ rowIndex, expectedPolicyName, expectedPolicyType }) => {
let row;
......@@ -217,7 +217,7 @@ describe('PolicyList component', () => {
});
it('renders a "Disabled" label for screen readers for disabled policies', () => {
const span = findPolicyStatusCells().at(2).find('span');
const span = findPolicyStatusCells().at(3).find('span');
expect(span.exists()).toBe(true);
expect(span.attributes('class')).toBe('gl-sr-only');
......
......@@ -43,6 +43,31 @@ spec:
nodes: [],
},
},
{
name: 'test-policy-01',
kind: 'CiliumNetworkPolicy',
yaml: `---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: test-policy-01
namespace: network-policy-demo-cluster-management-5000174-production
labels:
app.gitlab.com/proj: '5000174'
resourceVersion: '630685'
spec:
endpointSelector: {}
ingress:
- fromCIDR:
- 192.168.2.3/5
description: this is the first`,
enabled: true,
fromAutoDevops: false,
updatedAt: '2021-06-08T04:01:11Z',
environments: {
nodes: [{ name: 'production', __typename: 'Environment' }],
},
},
];
export const mockCiliumPolicy = {
......
import { POLICY_KINDS } from 'ee/threat_monitoring/components/constants';
import { POLICY_TYPE_COMPONENT_OPTIONS } from 'ee/threat_monitoring/components/constants';
import {
getContentWrapperHeight,
getPolicyKind,
getPolicyType,
removeUnnecessaryDashes,
} from 'ee/threat_monitoring/utils';
import { setHTMLFixture } from 'helpers/fixtures';
......@@ -30,15 +30,15 @@ describe('Threat Monitoring Utils', () => {
});
});
describe('getPolicyKind', () => {
describe('getPolicyType', () => {
it.each`
input | output
${''} | ${null}
${'ciliumNetworkPolicy'} | ${null}
${mockL3Manifest} | ${POLICY_KINDS.ciliumNetwork}
${mockDastScanExecutionManifest} | ${POLICY_KINDS.scanExecution}
${mockL3Manifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.container.value}
${mockDastScanExecutionManifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value}
`('returns $output when used on $input', ({ input, output }) => {
expect(getPolicyKind(input)).toBe(output);
expect(getPolicyType(input)).toBe(output);
});
});
......
......@@ -22179,9 +22179,6 @@ msgstr ""
msgid "NetworkPolicies|Save changes"
msgstr ""
msgid "NetworkPolicies|Scan Execution"
msgstr ""
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
......@@ -29556,6 +29553,9 @@ msgstr ""
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
msgid "SecurityOrchestration|All policies"
msgstr ""
msgid "SecurityOrchestration|An error occurred assigning your security policy project"
msgstr ""
......@@ -29568,6 +29568,9 @@ msgstr ""
msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|Network"
msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
......@@ -29580,6 +29583,12 @@ msgstr ""
msgid "SecurityOrchestration|Policy editor"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
msgstr ""
msgid "SecurityOrchestration|Scan execution"
msgstr ""
msgid "SecurityOrchestration|Security policy project was linked successfully"
msgstr ""
......@@ -29598,9 +29607,6 @@ msgstr ""
msgid "SecurityPolicies|+%{count} more"
msgstr ""
msgid "SecurityPolicies|All policies"
msgstr ""
msgid "SecurityPolicies|Description"
msgstr ""
......@@ -29613,9 +29619,6 @@ msgstr ""
msgid "SecurityPolicies|Latest scan"
msgstr ""
msgid "SecurityPolicies|Network"
msgstr ""
msgid "SecurityPolicies|Policy type"
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment