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