Commit cb30e948 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'network-policy-management-toggle' into 'master'

Network policy management toggle

See merge request gitlab-org/gitlab!33234
parents 806f682f a09c3090
<script>
import { mapState, mapActions } from 'vuex';
import { GlTable, GlEmptyState, GlDrawer, GlButton, GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
import {
GlTable,
GlEmptyState,
GlDrawer,
GlButton,
GlAlert,
GlSprintf,
GlLink,
GlToggle,
} from '@gitlab/ui';
import { s__ } from '~/locale';
import { getTimeago } from '~/lib/utils/datetime_utility';
import { setUrlFragment } from '~/lib/utils/url_utility';
......@@ -16,6 +25,7 @@ export default {
GlAlert,
GlSprintf,
GlLink,
GlToggle,
EnvironmentPicker,
NetworkPolicyEditor,
},
......@@ -26,7 +36,7 @@ export default {
},
},
data() {
return { selectedPolicyName: null, initialManifest: null };
return { selectedPolicyName: null, initialManifest: null, initialEnforcementStatus: null };
},
computed: {
...mapState('networkPolicies', ['policies', 'isLoadingPolicies', 'isUpdatingPolicy']),
......@@ -43,7 +53,12 @@ export default {
return this.policies.find(policy => policy.name === this.selectedPolicyName);
},
hasPolicyChanges() {
return this.hasSelectedPolicy && this.selectedPolicy.manifest !== this.initialManifest;
if (!this.hasSelectedPolicy) return false;
return (
this.selectedPolicy.manifest !== this.initialManifest ||
this.selectedPolicy.isEnabled !== this.initialEnforcementStatus
);
},
hasAutoDevopsPolicy() {
return this.policies.some(policy => policy.isAutodevops);
......@@ -60,6 +75,7 @@ export default {
const [selectedPolicy] = rows;
this.selectedPolicyName = selectedPolicy?.name;
this.initialManifest = selectedPolicy?.manifest;
this.initialEnforcementStatus = selectedPolicy?.isEnabled;
},
deselectPolicy() {
this.selectedPolicyName = null;
......@@ -73,6 +89,7 @@ export default {
policy: this.selectedPolicy,
}).then(() => {
this.initialManifest = this.selectedPolicy.manifest;
this.initialEnforcementStatus = this.selectedPolicy.isEnabled;
});
},
},
......@@ -145,8 +162,8 @@ export default {
selected-variant="primary"
@row-selected="presentPolicyDrawer"
>
<template #cell(status)>
{{ s__('NetworkPolicies|Enabled') }}
<template #cell(status)="value">
{{ value.item.isEnabled ? __('Enabled') : __('Disabled') }}
</template>
<template #cell(creationTimestamp)="value">
......@@ -195,6 +212,16 @@ export default {
<h5>{{ s__('NetworkPolicies|Policy definition') }}</h5>
<p>{{ s__("NetworkPolicies|Define this policy's location, conditions and actions.") }}</p>
<network-policy-editor ref="policyEditor" v-model="selectedPolicy.manifest" />
<h5 class="mt-4">{{ s__('NetworkPolicies|Enforcement status') }}</h5>
<p>{{ s__('NetworkPolicies|Choose whether to enforce this policy.') }}</p>
<gl-toggle
v-model="selectedPolicy.isEnabled"
:label-on="__('Enabled')"
:label-off="__('Disabled')"
label-position="right"
data-testid="policyToggle"
/>
</div>
</template>
</gl-drawer>
......
......@@ -44,6 +44,7 @@ export const updatePolicy = ({ state, commit }, { environmentId, policy }) => {
.put(joinPaths(state.policiesEndpoint, policy.name), {
environment_id: environmentId,
manifest: policy.manifest,
enabled: policy.isEnabled,
})
.then(({ data }) => {
commit(types.RECEIVE_UPDATE_POLICY_SUCCESS, {
......
......@@ -2,9 +2,12 @@ import { mount } from '@vue/test-utils';
import createStore from 'ee/threat_monitoring/store';
import NetworkPolicyList from 'ee/threat_monitoring/components/network_policy_list.vue';
import { GlTable } from '@gitlab/ui';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { mockPoliciesResponse } from '../mock_data';
const mockData = mockPoliciesResponse.map(policy => convertObjectPropsToCamelCase(policy));
describe('NetworkPolicyList component', () => {
let store;
let wrapper;
......@@ -13,7 +16,7 @@ describe('NetworkPolicyList component', () => {
store = createStore();
Object.assign(store.state.networkPolicies, {
isLoadingPolicies: false,
policies: mockPoliciesResponse,
policies: mockData,
...state,
});
......@@ -34,6 +37,7 @@ describe('NetworkPolicyList component', () => {
const findTableEmptyState = () => wrapper.find({ ref: 'tableEmptyState' });
const findEditorDrawer = () => wrapper.find({ ref: 'editorDrawer' });
const findPolicyEditor = () => wrapper.find({ ref: 'policyEditor' });
const findPolicyToggle = () => wrapper.find('[data-testid="policyToggle"]');
const findApplyButton = () => wrapper.find({ ref: 'applyButton' });
const findCancelButton = () => wrapper.find({ ref: 'cancelButton' });
const findAutodevopsAlert = () => wrapper.find('[data-testid="autodevopsAlert"]');
......@@ -82,7 +86,8 @@ describe('NetworkPolicyList component', () => {
factory({
data: () => ({
selectedPolicyName: 'policy',
initialManifest: mockPoliciesResponse[0].manifest,
initialManifest: mockData[0].manifest,
initialEnforcementStatus: mockData[0].isEnabled,
}),
});
});
......@@ -96,7 +101,13 @@ describe('NetworkPolicyList component', () => {
it('renders network policy editor with manifest', () => {
const policyEditor = findPolicyEditor();
expect(policyEditor.exists()).toBe(true);
expect(policyEditor.props('value')).toBe(mockPoliciesResponse[0].manifest);
expect(policyEditor.props('value')).toBe(mockData[0].manifest);
});
it('renders network policy toggle', () => {
const policyToggle = findPolicyToggle();
expect(policyToggle.exists()).toBe(true);
expect(policyToggle.props('value')).toBe(mockData[0].isEnabled);
});
it('renders disabled apply button', () => {
......@@ -133,10 +144,22 @@ describe('NetworkPolicyList component', () => {
expect(store.dispatch).toHaveBeenCalledWith('networkPolicies/updatePolicy', {
environmentId: -1,
policy: mockPoliciesResponse[0],
policy: mockData[0],
});
});
});
describe('given there is a policy enforcement status change', () => {
beforeEach(() => {
findPolicyToggle().vm.$emit('change', false);
});
it('renders enabled apply button', () => {
const applyButton = findApplyButton();
expect(applyButton.exists()).toBe(true);
expect(applyButton.props('disabled')).toBe(false);
});
});
});
describe('given there is a default environment with no data to display', () => {
......
......@@ -37,6 +37,7 @@ spec:
matchLabels:
project: myproject`,
created_timestamp: '2020-04-14T00:08:30Z',
is_enabled: true,
},
];
......
......@@ -141,8 +141,8 @@ describe('Network Policy actions', () => {
describe('updatePolicy', () => {
let mock;
const environmentId = 3;
const policy = { name: 'policy', manifest: 'foo' };
const updatedPolicy = { name: 'policy', manifest: 'bar' };
const policy = { name: 'policy', manifest: 'foo', isEnabled: true };
const updatedPolicy = { name: 'policy', manifest: 'bar', isEnabled: true };
beforeEach(() => {
state.policiesEndpoint = networkPoliciesEndpoint;
......@@ -159,6 +159,7 @@ describe('Network Policy actions', () => {
.onPut(joinPaths(networkPoliciesEndpoint, policy.name), {
environment_id: environmentId,
manifest: policy.manifest,
enabled: policy.isEnabled,
})
.replyOnce(httpStatus.OK, updatedPolicy);
});
......@@ -187,6 +188,7 @@ describe('Network Policy actions', () => {
.onPut(joinPaths(networkPoliciesEndpoint, policy.name), {
environment_id: environmentId,
manifest: policy.manifest,
enabled: policy.isEnabled,
})
.replyOnce(500, error);
});
......
......@@ -14351,10 +14351,13 @@ msgstr ""
msgid "Network"
msgstr ""
msgid "NetworkPolicies|Choose whether to enforce this policy."
msgstr ""
msgid "NetworkPolicies|Define this policy's location, conditions and actions."
msgstr ""
msgid "NetworkPolicies|Enabled"
msgid "NetworkPolicies|Enforcement status"
msgstr ""
msgid "NetworkPolicies|Environment does not have deployment platform"
......
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