Commit 835d06e9 authored by Simon Knox's avatar Simon Knox

Merge branch '338521-non-cilium-policy' into 'master'

Add support for non-cilium network policies

See merge request gitlab-org/gitlab!68497
parents 340e73c1 6810b91a
......@@ -28,7 +28,10 @@ export const POLICY_TYPE_COMPONENT_OPTIONS = {
text: s__('SecurityOrchestration|Network'),
urlParameter: 'container_policy',
value: 'container',
yamlIndicator: 'CiliumNetworkPolicy',
yamlIndicator: {
cilium: 'CiliumNetworkPolicy',
network: 'NetworkPolicy',
},
},
scanExecution: {
component: 'scan-execution-policy-editor',
......
......@@ -152,15 +152,19 @@ export default {
return Boolean(this.networkPolicies?.some((policy) => policy.fromAutoDevops));
},
editPolicyPath() {
return this.hasSelectedPolicy
? mergeUrlParams(
{
environment_id: this.currentEnvironmentId,
type: POLICY_TYPE_COMPONENT_OPTIONS[this.policyType]?.urlParameter,
},
this.newPolicyPath.replace('new', `${this.selectedPolicy.name}/edit`),
)
: '';
if (this.hasSelectedPolicy) {
const parameters = {
environment_id: this.currentEnvironmentId,
type: POLICY_TYPE_COMPONENT_OPTIONS[this.policyType]?.urlParameter,
...(this.selectedPolicy.kind && { kind: this.selectedPolicy.kind }),
};
return mergeUrlParams(
parameters,
this.newPolicyPath.replace('new', `${this.selectedPolicy.name}/edit`),
);
}
return '';
},
policyType() {
return this.selectedPolicy ? getPolicyType(this.selectedPolicy.yaml) : 'container';
......
......@@ -48,7 +48,7 @@ export default function toYaml(policy) {
const policySpec = {
apiVersion: 'cilium.io/v2',
kind: POLICY_TYPE_COMPONENT_OPTIONS.container.yamlIndicator,
kind: POLICY_TYPE_COMPONENT_OPTIONS.container.yamlIndicator.cilium,
};
if (description?.length > 0) {
......
import createGqClient from '~/lib/graphql';
import { POLICY_TYPE_COMPONENT_OPTIONS } from './components/constants';
/**
* Determines if the yaml passed in is of the type `container`
* @param {String} yaml the policy in yaml form
* @returns {Boolean}
*/
const isContainerPolicyYaml = (yaml) => {
const containerYamlIndicator = Object.values(
POLICY_TYPE_COMPONENT_OPTIONS.container.yamlIndicator,
);
return containerYamlIndicator.some((str) => yaml?.includes(str));
};
/**
* Get the height of the wrapper page element
* This height can be used to determine where the highest element goes in a page
......@@ -19,7 +31,7 @@ export const getContentWrapperHeight = (contentWrapperClass) => {
* @returns {String|null} policy type if available
*/
export const getPolicyType = (yaml = '') => {
if (yaml?.includes(POLICY_TYPE_COMPONENT_OPTIONS.container.yamlIndicator)) {
if (isContainerPolicyYaml(yaml)) {
return POLICY_TYPE_COMPONENT_OPTIONS.container.value;
}
if (yaml?.includes(POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.yamlIndicator)) {
......
......@@ -27,6 +27,10 @@ const environments = [
id: 2,
global_id: 'gid://gitlab/Environment/2',
},
{
id: 3,
global_id: 'gid://gitlab/Environment/3',
},
];
const scanExecutionPoliciesSpy = scanExecutionPolicies(mockScanExecutionPoliciesResponse);
const defaultRequestHandlers = {
......@@ -47,6 +51,7 @@ describe('PoliciesList component', () => {
...state,
});
store.state.threatMonitoring.environments = environments;
store.state.threatMonitoring.currentEnvironmentId = environments[0].id;
requestHandlers = {
...defaultRequestHandlers,
...handlers,
......@@ -125,6 +130,7 @@ describe('PoliciesList component', () => {
it('fetches policies', () => {
expect(requestHandlers.networkPolicies).toHaveBeenCalledWith({
environmentId: environments[0].global_id,
fullPath,
});
expect(requestHandlers.scanExecutionPolicies).toHaveBeenCalledWith({
......@@ -148,11 +154,11 @@ describe('PoliciesList component', () => {
it('fetches network policies on environment change', async () => {
store.dispatch.mockReset();
await store.commit('threatMonitoring/SET_CURRENT_ENVIRONMENT_ID', 2);
await store.commit('threatMonitoring/SET_CURRENT_ENVIRONMENT_ID', 3);
expect(requestHandlers.networkPolicies).toHaveBeenCalledTimes(2);
expect(requestHandlers.networkPolicies.mock.calls[1][0]).toEqual({
fullPath: 'project/path',
environmentId: environments[0].global_id,
environmentId: environments[1].global_id,
});
});
......@@ -259,10 +265,11 @@ describe('PoliciesList component', () => {
});
describe.each`
description | policy | policyType
${'container'} | ${mockNetworkPoliciesResponse[1]} | ${'container'}
${'scan execution'} | ${mockScanExecutionPoliciesResponse[0]} | ${'scanExecution'}
`('given there is a $description policy selected', ({ policy, policyType }) => {
description | policy | policyType | editPolicyPath
${'network'} | ${mockNetworkPoliciesResponse[0]} | ${'container'} | ${'path/to/policy?environment_id=2&type=container_policy&kind=NetworkPolicy'}
${'container'} | ${mockNetworkPoliciesResponse[1]} | ${'container'} | ${'path/to/policy?environment_id=2&type=container_policy&kind=CiliumNetworkPolicy'}
${'scan execution'} | ${mockScanExecutionPoliciesResponse[0]} | ${'scanExecution'} | ${'path/to/policy?environment_id=2&type=scan_execution_policy'}
`('given there is a $description policy selected', ({ policy, policyType, editPolicyPath }) => {
beforeEach(() => {
mountShallowWrapper();
findPoliciesTable().vm.$emit('row-selected', [policy]);
......@@ -272,6 +279,7 @@ describe('PoliciesList component', () => {
const editorDrawer = findPolicyDrawer();
expect(editorDrawer.exists()).toBe(true);
expect(editorDrawer.props()).toMatchObject({
editPolicyPath,
open: true,
policy,
policyType,
......
......@@ -115,9 +115,9 @@ describe('NetworkPolicyEditor component', () => {
findPolicyEditorLayout().vm.$emit('update-yaml', mockL3Manifest);
expect(wrapper.vm.policy).toMatchObject({
name: 'test-policy',
name: 'test-policy-02',
description: 'test description',
isEnabled: false,
isEnabled: true,
endpointMatchMode: EndpointMatchModeLabel,
endpointLabels: 'foo:bar',
rules: [
......
......@@ -15,27 +15,115 @@ export const mockEnvironmentsResponse = {
stopped_count: 5,
};
export const mockNetworkPoliciesResponse = [
{
name: 'policy',
kind: 'NetworkPolicy',
yaml: `---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
export const mockDastScanExecutionManifest = `type: scan_execution_policy
name: Test Dast
description: This policy enforces pipeline configuration to have a job with DAST scan
enabled: false
rules:
- type: pipeline
branches:
- main
actions:
- scan: dast
site_profile: required_site_profile
scanner_profile: required_scanner_profile
`;
export const mockDastScanExecutionObject = {
type: 'scan_execution_policy',
name: 'Test Dast',
description: 'This policy enforces pipeline configuration to have a job with DAST scan',
enabled: false,
rules: [{ type: 'pipeline', branches: ['main'] }],
actions: [
{
scan: 'dast',
site_profile: 'required_site_profile',
scanner_profile: 'required_scanner_profile',
},
],
};
export const mockNetworkManifest = `kind: CiliumNetworkPolicy
metadata:
name: example-name
namespace: example-namespace
name: test-policy-01
namespace: network-policy-demo-cluster-management-5000174-production
labels:
app.gitlab.com/proj: '5000174'
spec:
podSelector:
endpointSelector:
matchLabels:
role: db
policyTypes:
- Ingress
network-policy.gitlab.com/disabled_by: gitlab
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject`,
- fromCIDR:
- 192.168.2.3/5
description: this is the
`;
export const mockCiliumManifest = `apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: test-policy-03
namespace: network-policy-demo-cluster-management-5000174-production
labels:
app.gitlab.com/proj: '5000174'
resourceVersion: '655210'
spec:
endpointSelector:
matchLabels:
network-policy.gitlab.com/disabled_by: gitlab
ingress:
- fromCIDR:
- 10.101.12.14/5
description: 03-desc`;
export const mockL3Manifest = `apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
description: test description
metadata:
name: test-policy-02
labels:
app.gitlab.com/proj: '21'
spec:
endpointSelector:
matchLabels:
foo: bar
ingress:
- fromEndpoints:
- matchLabels:
foo: bar`;
export const mockL7Manifest = `apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: limit-inbound-ip
spec:
endpointSelector: {}
ingress:
- toPorts:
- ports:
- port: '80'
protocol: TCP
- port: '443'
protocol: TCP
rules:
http:
- headers:
- 'X-Forwarded-For: 192.168.1.1'
fromEntities:
- cluster`;
export const mockCiliumPolicy = {
name: 'test-policy-03',
updatedAt: new Date('2021-06-07T00:00:00.000Z'),
yaml: mockCiliumManifest,
};
export const mockNetworkPoliciesResponse = [
{
name: 'policy',
kind: 'NetworkPolicy',
yaml: mockNetworkManifest,
updatedAt: '2020-04-14T00:08:30Z',
enabled: true,
fromAutoDevops: false,
......@@ -44,23 +132,9 @@ spec:
},
},
{
name: 'test-policy-01',
name: 'test-policy-02',
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`,
yaml: mockL3Manifest,
enabled: true,
fromAutoDevops: false,
updatedAt: '2021-06-08T04:01:11Z',
......@@ -70,33 +144,10 @@ description: this is the first`,
},
];
export const mockCiliumPolicy = {
name: 'policy',
updatedAt: new Date('2021-06-07T00:00:00.000Z'),
yaml: `apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: policy
spec:
endpointSelector: {}`,
};
export const mockScanExecutionPolicy = {
name: 'Scheduled DAST scan',
updatedAt: new Date('2021-06-07T00:00:00.000Z'),
yaml: `---
name: Enforce DAST in every pipeline
description: This policy enforces pipeline configuration to have a job with DAST scan
enabled: true
rules:
- type: pipeline
branches:
- master
actions:
- scan: dast
scanner_profile: Scanner Profile
site_profile: Site Profile
`,
yaml: mockDastScanExecutionManifest,
enabled: true,
};
......@@ -219,69 +270,3 @@ export const mockAlertDetails = {
todos: { nodes: [{ id: 'gid://gitlab/Todo/5984130' }] },
notes: { nodes: [] },
};
export const mockDastScanExecutionManifest = `type: scan_execution_policy
name: Test Dast
description: This is a good test
enabled: false
rules:
- type: pipeline
branches:
- main
actions:
- scan: dast
site_profile: required_site_profile
scanner_profile: required_scanner_profile
`;
export const mockDastScanExecutionObject = {
type: 'scan_execution_policy',
name: 'Test Dast',
description: 'This is a good test',
enabled: false,
rules: [{ type: 'pipeline', branches: ['main'] }],
actions: [
{
scan: 'dast',
site_profile: 'required_site_profile',
scanner_profile: 'required_scanner_profile',
},
],
};
export const mockL7Manifest = `apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: limit-inbound-ip
spec:
endpointSelector: {}
ingress:
- toPorts:
- ports:
- port: '80'
protocol: TCP
- port: '443'
protocol: TCP
rules:
http:
- headers:
- 'X-Forwarded-For: 192.168.1.1'
fromEntities:
- cluster`;
export const mockL3Manifest = `apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
description: test description
metadata:
name: test-policy
labels:
app.gitlab.com/proj: '21'
spec:
endpointSelector:
matchLabels:
network-policy.gitlab.com/disabled_by: gitlab
foo: bar
ingress:
- fromEndpoints:
- matchLabels:
foo: bar`;
......@@ -5,7 +5,11 @@ import {
removeUnnecessaryDashes,
} from 'ee/threat_monitoring/utils';
import { setHTMLFixture } from 'helpers/fixtures';
import { mockL3Manifest, mockDastScanExecutionManifest } from './mocks/mock_data';
import {
mockDastScanExecutionManifest,
mockCiliumManifest,
mockNetworkManifest,
} from './mocks/mock_data';
describe('Threat Monitoring Utils', () => {
describe('getContentWrapperHeight', () => {
......@@ -34,8 +38,9 @@ describe('Threat Monitoring Utils', () => {
it.each`
input | output
${''} | ${null}
${'ciliumNetworkPolicy'} | ${null}
${mockL3Manifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.container.value}
${'random string'} | ${null}
${mockNetworkManifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.container.value}
${mockCiliumManifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.container.value}
${mockDastScanExecutionManifest} | ${POLICY_TYPE_COMPONENT_OPTIONS.scanExecution.value}
`('returns $output when used on $input', ({ input, output }) => {
expect(getPolicyType(input)).toBe(output);
......
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