Commit b36023cb authored by ap4y's avatar ap4y

Add predefined network policies to the policy list

This commit adds a predefined policies to the network policies
list. This allows users to quickly try out network policies against
deployment platform.
parent c00c10ed
...@@ -99,6 +99,11 @@ deployment platform. Changes performed outside of this tab are ...@@ -99,6 +99,11 @@ deployment platform. Changes performed outside of this tab are
reflected upon refresh. Enforcement status changes are deployed reflected upon refresh. Enforcement status changes are deployed
directly to a deployment namespace of the selected environment. directly to a deployment namespace of the selected environment.
By default, the network policy list contains predefined policies in a
disabled state. Once enabled,a predefined policy deploys to the
selected environment's deployment platform and you can manage it like
the regular policies.
NOTE: **Note:** NOTE: **Note:**
If you're using [Auto DevOps](../../../topics/autodevops/index.md) and If you're using [Auto DevOps](../../../topics/autodevops/index.md) and
change a policy in this section, your `auto-deploy-values.yaml` file change a policy in this section, your `auto-deploy-values.yaml` file
......
<script> <script>
import { mapState, mapActions } from 'vuex'; import { mapState, mapActions, mapGetters } from 'vuex';
import { import {
GlTable, GlTable,
GlEmptyState, GlEmptyState,
...@@ -41,6 +41,7 @@ export default { ...@@ -41,6 +41,7 @@ export default {
computed: { computed: {
...mapState('networkPolicies', ['policies', 'isLoadingPolicies', 'isUpdatingPolicy']), ...mapState('networkPolicies', ['policies', 'isLoadingPolicies', 'isUpdatingPolicy']),
...mapState('threatMonitoring', ['currentEnvironmentId']), ...mapState('threatMonitoring', ['currentEnvironmentId']),
...mapGetters('networkPolicies', ['policiesWithDefaults']),
documentationFullPath() { documentationFullPath() {
return setUrlFragment(this.documentationPath, 'container-network-policy'); return setUrlFragment(this.documentationPath, 'container-network-policy');
}, },
...@@ -50,7 +51,7 @@ export default { ...@@ -50,7 +51,7 @@ export default {
selectedPolicy() { selectedPolicy() {
if (!this.hasSelectedPolicy) return null; if (!this.hasSelectedPolicy) return null;
return this.policies.find(policy => policy.name === this.selectedPolicyName); return this.policiesWithDefaults.find(policy => policy.name === this.selectedPolicyName);
}, },
hasPolicyChanges() { hasPolicyChanges() {
if (!this.hasSelectedPolicy) return false; if (!this.hasSelectedPolicy) return false;
...@@ -61,12 +62,13 @@ export default { ...@@ -61,12 +62,13 @@ export default {
); );
}, },
hasAutoDevopsPolicy() { hasAutoDevopsPolicy() {
return this.policies.some(policy => policy.isAutodevops); return this.policiesWithDefaults.some(policy => policy.isAutodevops);
}, },
}, },
methods: { methods: {
...mapActions('networkPolicies', ['updatePolicy']), ...mapActions('networkPolicies', ['createPolicy', 'updatePolicy']),
getTimeAgoString(creationTimestamp) { getTimeAgoString(creationTimestamp) {
if (!creationTimestamp) return '';
return getTimeago().format(creationTimestamp); return getTimeago().format(creationTimestamp);
}, },
presentPolicyDrawer(rows) { presentPolicyDrawer(rows) {
...@@ -84,12 +86,18 @@ export default { ...@@ -84,12 +86,18 @@ export default {
bTable.clearSelected(); bTable.clearSelected();
}, },
savePolicy() { savePolicy() {
return this.updatePolicy({ const promise = this.selectedPolicy.creationTimestamp ? this.updatePolicy : this.createPolicy;
return promise({
environmentId: this.currentEnvironmentId, environmentId: this.currentEnvironmentId,
policy: this.selectedPolicy, policy: this.selectedPolicy,
}).then(() => { })
.then(() => {
this.initialManifest = this.selectedPolicy.manifest; this.initialManifest = this.selectedPolicy.manifest;
this.initialEnforcementStatus = this.selectedPolicy.isEnabled; this.initialEnforcementStatus = this.selectedPolicy.isEnabled;
})
.catch(() => {
this.selectedPolicy.manifest = this.initialManifest;
this.selectedPolicy.isEnabled = this.initialEnforcementStatus;
}); });
}, },
}, },
...@@ -149,7 +157,7 @@ export default { ...@@ -149,7 +157,7 @@ export default {
<gl-table <gl-table
ref="policiesTable" ref="policiesTable"
:busy="isLoadingPolicies" :busy="isLoadingPolicies"
:items="policies" :items="policiesWithDefaults"
:fields="$options.fields" :fields="$options.fields"
head-variant="white" head-variant="white"
stacked="md" stacked="md"
......
/* eslint-disable import/prefer-default-export */
export const INVALID_CURRENT_ENVIRONMENT_NAME = ''; export const INVALID_CURRENT_ENVIRONMENT_NAME = '';
export const PREDEFINED_NETWORK_POLICIES = [
{
name: 'drop-outbound',
isEnabled: false,
manifest: `---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: drop-outbound
spec:
podSelector: {}
policyTypes:
- Egress`,
},
{
name: 'allow-inbound-http',
isEnabled: false,
manifest: `---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-inbound-http
spec:
podSelector: {}
ingress:
- ports:
- port: 80
- port: 443`,
},
];
/* eslint-disable import/prefer-default-export */
import { PREDEFINED_NETWORK_POLICIES } from 'ee/threat_monitoring/constants';
export const policiesWithDefaults = ({ policies }) => {
// Predefined policies that were enabled by users will be present in
// the list of policies we received from the backend. We want to
// filter out enabled predefined policies and only append the ones
// that are not present in a cluster.
const predefined = PREDEFINED_NETWORK_POLICIES.filter(
({ name }) => !policies.some(policy => name === policy.name),
);
return [...policies, ...predefined];
};
import * as actions from './actions'; import * as actions from './actions';
import * as getters from './getters';
import mutations from './mutations'; import mutations from './mutations';
import state from './state'; import state from './state';
export default () => ({ export default () => ({
namespaced: true, namespaced: true,
actions, actions,
getters,
mutations, mutations,
state, state,
}); });
---
title: Add predefined network policies to the network policy list
merge_request: 36257
author:
type: added
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NetworkPolicyList component given there is a default environment with no data to display shows the table empty state 1`] = ` exports[`NetworkPolicyList component given there is a default environment with no data to display shows the table empty state 1`] = `undefined`;
<section
class="row empty-state text-center"
>
<div
class="col-12"
>
<!---->
</div>
<div
class="col-12"
>
<div
class="text-content gl-mx-auto gl-my-0 gl-p-5"
>
<h1
class="h4"
>
No policies detected
</h1>
<p>
Policies are a specification of how groups of pods are allowed to communicate with each other's network endpoints.
</p>
<div>
<a
class="btn btn-success btn-md gl-button"
href="documentation_path#container-network-policy"
>
<!---->
<!---->
<span
class="gl-button-text"
>
Learn more
</span>
</a>
<!---->
</div>
</div>
</div>
</section>
`;
exports[`NetworkPolicyList component renders policies table 1`] = ` exports[`NetworkPolicyList component renders policies table 1`] = `
<table <table
aria-busy="false" aria-busy="false"
aria-colcount="3" aria-colcount="3"
aria-describedby="__BVID__41__caption_" aria-describedby="__BVID__45__caption_"
aria-multiselectable="false" aria-multiselectable="false"
class="table b-table gl-table table-hover b-table-stacked-md b-table-selectable b-table-select-single" class="table b-table gl-table table-hover b-table-stacked-md b-table-selectable b-table-select-single"
id="__BVID__41" id="__BVID__45"
role="table" role="table"
> >
<!----> <!---->
...@@ -139,7 +90,89 @@ exports[`NetworkPolicyList component renders policies table 1`] = ` ...@@ -139,7 +90,89 @@ exports[`NetworkPolicyList component renders policies table 1`] = `
> >
<div> <div>
just now 3 months ago
</div>
</td>
</tr>
<tr
aria-selected="false"
class=""
role="row"
tabindex="0"
>
<td
aria-colindex="1"
class=""
data-label="Name"
role="cell"
>
<div>
drop-outbound
</div>
</td>
<td
aria-colindex="2"
class=""
data-label="Status"
role="cell"
>
<div>
Disabled
</div>
</td>
<td
aria-colindex="3"
class=""
data-label="Last modified"
role="cell"
>
<div>
</div>
</td>
</tr>
<tr
aria-selected="false"
class=""
role="row"
tabindex="0"
>
<td
aria-colindex="1"
class=""
data-label="Name"
role="cell"
>
<div>
allow-inbound-http
</div>
</td>
<td
aria-colindex="2"
class=""
data-label="Status"
role="cell"
>
<div>
Disabled
</div>
</td>
<td
aria-colindex="3"
class=""
data-label="Last modified"
role="cell"
>
<div>
</div> </div>
</td> </td>
......
...@@ -5,6 +5,7 @@ import { GlTable } from '@gitlab/ui'; ...@@ -5,6 +5,7 @@ import { GlTable } from '@gitlab/ui';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { mockPoliciesResponse } from '../mock_data'; import { mockPoliciesResponse } from '../mock_data';
import { PREDEFINED_NETWORK_POLICIES } from 'ee/threat_monitoring/constants';
const mockData = mockPoliciesResponse.map(policy => convertObjectPropsToCamelCase(policy)); const mockData = mockPoliciesResponse.map(policy => convertObjectPropsToCamelCase(policy));
...@@ -147,6 +148,43 @@ describe('NetworkPolicyList component', () => { ...@@ -147,6 +148,43 @@ describe('NetworkPolicyList component', () => {
policy: mockData[0], policy: mockData[0],
}); });
}); });
describe('given there is an updatePolicy error', () => {
beforeEach(() => {
jest.spyOn(store, 'dispatch').mockRejectedValue();
});
it('reverts isEnabled change', () => {
const initial = mockData[0].isEnabled;
findApplyButton().vm.$emit('click');
const policyToggle = findPolicyToggle();
expect(policyToggle.exists()).toBe(true);
expect(policyToggle.props('value')).toBe(initial);
});
});
describe('given theres is a predefined policy change', () => {
beforeEach(() => {
factory({
data: () => ({
selectedPolicyName: 'drop-outbound',
initialManifest: mockData[0].manifest,
initialEnforcementStatus: mockData[0].isEnabled,
}),
});
});
it('dispatches createPolicy action on apply button click', () => {
findApplyButton().vm.$emit('click');
expect(store.dispatch).toHaveBeenCalledWith('networkPolicies/createPolicy', {
environmentId: -1,
policy: PREDEFINED_NETWORK_POLICIES[0],
});
});
});
}); });
describe('given there is a policy enforcement status change', () => { describe('given there is a policy enforcement status change', () => {
......
...@@ -36,7 +36,7 @@ spec: ...@@ -36,7 +36,7 @@ spec:
- namespaceSelector: - namespaceSelector:
matchLabels: matchLabels:
project: myproject`, project: myproject`,
created_timestamp: '2020-04-14T00:08:30Z', creation_timestamp: '2020-04-14T00:08:30Z',
is_enabled: true, is_enabled: true,
}, },
]; ];
......
import createState from 'ee/threat_monitoring/store/modules/network_policies/state';
import * as getters from 'ee/threat_monitoring/store/modules/network_policies/getters';
describe('networkPolicies module getters', () => {
let state;
beforeEach(() => {
state = createState();
});
describe('policiesWithDefaults', () => {
describe('without policies in the state', () => {
it('returns predefined policies', () => {
expect(getters.policiesWithDefaults(state).map(({ name }) => name)).toEqual([
'drop-outbound',
'allow-inbound-http',
]);
});
});
describe('with policies in the state', () => {
beforeEach(() => {
state.policies = [{ name: 'user-policy' }];
});
it('returns user owned and predefined policies', () => {
expect(getters.policiesWithDefaults(state).map(({ name }) => name)).toEqual([
'user-policy',
'drop-outbound',
'allow-inbound-http',
]);
});
describe('with deployed predefined policy', () => {
beforeEach(() => {
state.policies = [{ name: 'user-policy' }, { name: 'drop-outbound' }];
});
it('returns user policies and a single predefined policy', () => {
expect(getters.policiesWithDefaults(state).map(({ name }) => name)).toEqual([
'user-policy',
'drop-outbound',
'allow-inbound-http',
]);
});
});
});
});
});
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