Commit a996f040 authored by ap4y's avatar ap4y

Implement policy removal in policy editor

parent 6ae64a37
...@@ -9,8 +9,10 @@ import { ...@@ -9,8 +9,10 @@ import {
GlSegmentedControl, GlSegmentedControl,
GlButton, GlButton,
GlAlert, GlAlert,
GlModal,
GlModalDirective,
} from '@gitlab/ui'; } from '@gitlab/ui';
import { s__ } from '~/locale'; import { s__, __, sprintf } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import EnvironmentPicker from '../environment_picker.vue'; import EnvironmentPicker from '../environment_picker.vue';
import NetworkPolicyEditor from '../network_policy_editor.vue'; import NetworkPolicyEditor from '../network_policy_editor.vue';
...@@ -38,12 +40,14 @@ export default { ...@@ -38,12 +40,14 @@ export default {
GlSegmentedControl, GlSegmentedControl,
GlButton, GlButton,
GlAlert, GlAlert,
GlModal,
EnvironmentPicker, EnvironmentPicker,
NetworkPolicyEditor, NetworkPolicyEditor,
PolicyRuleBuilder, PolicyRuleBuilder,
PolicyPreview, PolicyPreview,
PolicyActionPicker, PolicyActionPicker,
}, },
directives: { GlModal: GlModalDirective },
props: { props: {
threatMonitoringPath: { threatMonitoringPath: {
type: String, type: String,
...@@ -82,7 +86,12 @@ export default { ...@@ -82,7 +86,12 @@ export default {
return toYaml(this.policy); return toYaml(this.policy);
}, },
...mapState('threatMonitoring', ['currentEnvironmentId']), ...mapState('threatMonitoring', ['currentEnvironmentId']),
...mapState('networkPolicies', ['errorUpdatingPolicy']), ...mapState('networkPolicies', [
'isUpdatingPolicy',
'isRemovingPolicy',
'errorUpdatingPolicy',
'errorRemovingPolicy',
]),
shouldShowRuleEditor() { shouldShowRuleEditor() {
return this.editorMode === EditorModeRule; return this.editorMode === EditorModeRule;
}, },
...@@ -100,13 +109,16 @@ export default { ...@@ -100,13 +109,16 @@ export default {
? s__('NetworkPolicies|Save changes') ? s__('NetworkPolicies|Save changes')
: s__('NetworkPolicies|Create policy'); : s__('NetworkPolicies|Create policy');
}, },
deleteModalTitle() {
return sprintf(s__('NetworkPolicies|Delete policy: %{policy}'), { policy: this.policy.name });
},
}, },
created() { created() {
this.fetchEnvironments(); this.fetchEnvironments();
}, },
methods: { methods: {
...mapActions('threatMonitoring', ['fetchEnvironments']), ...mapActions('threatMonitoring', ['fetchEnvironments']),
...mapActions('networkPolicies', ['createPolicy', 'updatePolicy']), ...mapActions('networkPolicies', ['createPolicy', 'updatePolicy', 'deletePolicy']),
addRule() { addRule() {
this.policy.rules.push(buildRule(RuleTypeEndpoint)); this.policy.rules.push(buildRule(RuleTypeEndpoint));
}, },
...@@ -151,6 +163,13 @@ export default { ...@@ -151,6 +163,13 @@ export default {
if (!this.errorUpdatingPolicy) redirectTo(this.threatMonitoringPath); if (!this.errorUpdatingPolicy) redirectTo(this.threatMonitoringPath);
}); });
}, },
removePolicy() {
const policy = { name: this.existingPolicy.name, manifest: toYaml(this.policy) };
return this.deletePolicy({ environmentId: this.currentEnvironmentId, policy }).then(() => {
if (!this.errorRemovingPolicy) redirectTo(this.threatMonitoringPath);
});
},
}, },
policyTypes: [{ value: 'networkPolicy', text: s__('NetworkPolicies|Network Policy') }], policyTypes: [{ value: 'networkPolicy', text: s__('NetworkPolicies|Network Policy') }],
editorModes: [ editorModes: [
...@@ -160,6 +179,16 @@ export default { ...@@ -160,6 +179,16 @@ export default {
parsingErrorMessage: s__( parsingErrorMessage: s__(
'NetworkPolicies|Rule mode is unavailable for this policy. In some cases, we cannot parse the YAML file back into the rules editor.', 'NetworkPolicies|Rule mode is unavailable for this policy. In some cases, we cannot parse the YAML file back into the rules editor.',
), ),
deleteModal: {
id: 'delete-modal',
secondary: {
text: s__('NetworkPolicies|Delete policy'),
attributes: { variant: 'danger' },
},
cancel: {
text: __('Cancel'),
},
},
}; };
</script> </script>
...@@ -286,13 +315,36 @@ export default { ...@@ -286,13 +315,36 @@ export default {
category="primary" category="primary"
variant="success" variant="success"
data-testid="save-policy" data-testid="save-policy"
:loading="isUpdatingPolicy"
@click="savePolicy" @click="savePolicy"
>{{ saveButtonText }}</gl-button >{{ saveButtonText }}</gl-button
> >
<gl-button
v-if="isEditing"
v-gl-modal="'delete-modal'"
category="secondary"
variant="danger"
data-testid="delete-policy"
:loading="isRemovingPolicy"
>{{ s__('NetworkPolicies|Delete policy') }}</gl-button
>
<gl-button category="secondary" variant="default" :href="threatMonitoringPath">{{ <gl-button category="secondary" variant="default" :href="threatMonitoringPath">{{
__('Cancel') __('Cancel')
}}</gl-button> }}</gl-button>
</div> </div>
</div> </div>
<gl-modal
modal-id="delete-modal"
:title="deleteModalTitle"
:action-secondary="$options.deleteModal.secondary"
:action-cancel="$options.deleteModal.cancel"
@secondary="removePolicy"
>
{{
s__(
'NetworkPolicies|Are you sure you want to delete this policy? This action cannot be undone.',
)
}}
</gl-modal>
</section> </section>
</template> </template>
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlModal } from '@gitlab/ui';
import PolicyEditorApp from 'ee/threat_monitoring/components/policy_editor/policy_editor.vue'; import PolicyEditorApp from 'ee/threat_monitoring/components/policy_editor/policy_editor.vue';
import PolicyPreview from 'ee/threat_monitoring/components/policy_editor/policy_preview.vue'; import PolicyPreview from 'ee/threat_monitoring/components/policy_editor/policy_preview.vue';
import PolicyRuleBuilder from 'ee/threat_monitoring/components/policy_editor/policy_rule_builder.vue'; import PolicyRuleBuilder from 'ee/threat_monitoring/components/policy_editor/policy_rule_builder.vue';
...@@ -51,6 +52,7 @@ describe('PolicyEditorApp component', () => { ...@@ -51,6 +52,7 @@ describe('PolicyEditorApp component', () => {
const findNetworkPolicyEditor = () => wrapper.find(NetworkPolicyEditor); const findNetworkPolicyEditor = () => wrapper.find(NetworkPolicyEditor);
const findPolicyName = () => wrapper.find("[id='policyName']"); const findPolicyName = () => wrapper.find("[id='policyName']");
const findSavePolicy = () => wrapper.find("[data-testid='save-policy']"); const findSavePolicy = () => wrapper.find("[data-testid='save-policy']");
const findDeletePolicy = () => wrapper.find("[data-testid='delete-policy']");
beforeEach(() => { beforeEach(() => {
factory(); factory();
...@@ -72,6 +74,10 @@ describe('PolicyEditorApp component', () => { ...@@ -72,6 +74,10 @@ describe('PolicyEditorApp component', () => {
expect(findYAMLParsingAlert().exists()).toBe(false); expect(findYAMLParsingAlert().exists()).toBe(false);
}); });
it('does not render delete button', () => {
expect(findDeletePolicy().exists()).toBe(false);
});
describe('given .yaml editor mode is enabled', () => { describe('given .yaml editor mode is enabled', () => {
beforeEach(() => { beforeEach(() => {
factory({ factory({
...@@ -291,5 +297,27 @@ spec: ...@@ -291,5 +297,27 @@ spec:
expect(redirectTo).not.toHaveBeenCalledWith('/threat-monitoring'); expect(redirectTo).not.toHaveBeenCalledWith('/threat-monitoring');
}); });
}); });
it('renders delete button', () => {
expect(findDeletePolicy().exists()).toBe(true);
});
it('it does not trigger deletePolicy on delete button click', async () => {
findDeletePolicy().vm.$emit('click');
await wrapper.vm.$nextTick();
expect(store.dispatch).not.toHaveBeenCalledWith('networkPolicies/deletePolicy');
});
it('removes policy and redirects to a threat monitoring path on secondary modal button click', async () => {
wrapper.find(GlModal).vm.$emit('secondary');
await wrapper.vm.$nextTick();
expect(store.dispatch).toHaveBeenCalledWith('networkPolicies/deletePolicy', {
environmentId: -1,
policy: { name: 'policy', manifest: toYaml(wrapper.vm.policy) },
});
expect(redirectTo).toHaveBeenCalledWith('/threat-monitoring');
});
}); });
}); });
...@@ -16370,6 +16370,9 @@ msgstr "" ...@@ -16370,6 +16370,9 @@ msgstr ""
msgid "NetworkPolicies|Allow all outbound traffic from %{selector} to %{ruleSelector} on %{ports}" msgid "NetworkPolicies|Allow all outbound traffic from %{selector} to %{ruleSelector} on %{ports}"
msgstr "" msgstr ""
msgid "NetworkPolicies|Are you sure you want to delete this policy? This action cannot be undone."
msgstr ""
msgid "NetworkPolicies|Choose whether to enforce this policy." msgid "NetworkPolicies|Choose whether to enforce this policy."
msgstr "" msgstr ""
...@@ -16379,6 +16382,12 @@ msgstr "" ...@@ -16379,6 +16382,12 @@ 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|Delete policy"
msgstr ""
msgid "NetworkPolicies|Delete policy: %{policy}"
msgstr ""
msgid "NetworkPolicies|Deny all traffic" msgid "NetworkPolicies|Deny all traffic"
msgstr "" 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