Commit ec560eae authored by ap4y's avatar ap4y

Remove networkPolicyEditor feature flag

This MR make a new policy editor available to all EE users.
parent 433a839a
......@@ -88,8 +88,9 @@ investigate it for potential threats by
The **Threat Monitoring** page's **Policy** tab displays deployed
network policies for all available environments. You can check a
network policy's `yaml` manifest and toggle the policy's enforcement
status. This section has the following prerequisites:
network policy's `yaml` manifest, toggle the policy's enforcement
status, and create and edit deployed policies. This section has the
following prerequisites:
- Your project contains at least one [environment](../../../ci/environments/index.md)
- You've [installed Cilium](../../clusters/applications.md#install-cilium-using-gitlab-cicd)
......@@ -124,3 +125,47 @@ Disabled network policies have the
`podSelector` block. This narrows the scope of such a policy and as a
result it doesn't affect any pods. The policy itself is still deployed
to the corresponding deployment namespace.
### Container Network Policy editor
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3403) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.4.
The policy editor allows you to create, edit, and delete policies. To
create a new policy click the **New policy** button located in the
**Policy** tab's header. To edit an existing policy, click**Edit
policy** in the selected policy drawer.
NOTE: **Note:**
The policy editor only supports the
[CiliumNetworkPolicy](https://docs.cilium.io/en/v1.8/policy/)specification. Regular
Kubernetes
[NetworkPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#networkpolicy-v1-networking-k8s-io)
resources aren't supported.
The policy editor has two modes:
- The visual _Rule_ mode allows you to construct and preview policy
rules using rule blocks and related controls.
- YAML mode allows you to enter a policy definition in `.yaml` format
and is aimed at expert users and cases that the Rule mode doesn't
support.
You can use both modes interchangeably and switch between them at any
time. If a YAML resource is incorrect, Rule mode is automatically
disabled. You must use YAML mode to fix your policy before Rule mode
is available again.
Rule mode supports the following rule types:
- [Labels](https://docs.cilium.io/en/v1.8/policy/language/#labels-based).
- [Entities](https://docs.cilium.io/en/v1.8/policy/language/#entities-based).
- [IP/CIDR](https://docs.cilium.io/en/v1.8/policy/language/#ip-cidr-based). Only
the `toCIDR` block without `except` is supported.
- [DNS](https://docs.cilium.io/en/v1.8/policy/language/#dns-based).
- [Level 4](https://docs.cilium.io/en/v1.8/policy/language/#layer-4-examples)
can be added to all other rules.
Once your policy is complete, save it by pressing the **Save policy**
button at the bottom of the editor. Existing policies can also be
removed from the editor interface by clicking the **Delete policy**
button at the bottom of the editor.
......@@ -18,8 +18,6 @@ import NetworkPolicyEditor from './network_policy_editor.vue';
import PolicyDrawer from './policy_editor/policy_drawer.vue';
import { CiliumNetworkPolicyKind } from './policy_editor/constants';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
components: {
GlTable,
......@@ -34,7 +32,6 @@ export default {
NetworkPolicyEditor,
PolicyDrawer,
},
mixins: [glFeatureFlagsMixin()],
props: {
documentationPath: {
type: String,
......@@ -80,14 +77,10 @@ export default {
: false;
},
shouldShowCiliumDrawer() {
return this.glFeatures.networkPolicyEditor && this.hasCiliumSelectedPolicy;
return this.hasCiliumSelectedPolicy;
},
shouldShowEditButton() {
return (
this.glFeatures.networkPolicyEditor &&
this.hasCiliumSelectedPolicy &&
Boolean(this.selectedPolicy.creationTimestamp)
);
return this.hasCiliumSelectedPolicy && Boolean(this.selectedPolicy.creationTimestamp);
},
editPolicyPath() {
return this.hasSelectedPolicy
......@@ -184,7 +177,7 @@ export default {
<div class="pt-3 px-3 bg-gray-light">
<div class="row justify-content-between align-items-center">
<environment-picker ref="environmentsPicker" />
<div v-if="glFeatures.networkPolicyEditor" class="col-sm-auto">
<div class="col-sm-auto">
<gl-button
category="secondary"
variant="info"
......
......@@ -3,10 +3,6 @@
module Projects
class ThreatMonitoringController < Projects::ApplicationController
before_action :authorize_read_threat_monitoring!
before_action :verify_network_policy_editor_flag!, only: [:new, :edit]
before_action do
push_frontend_feature_flag(:network_policy_editor, project)
end
def edit
environment = project.environments.find(params[:environment_id])
......@@ -23,11 +19,5 @@ module Projects
render_404
end
end
private
def verify_network_policy_editor_flag!
render_404 unless Feature.enabled?(:network_policy_editor, project, default_enabled: false)
end
end
end
---
title: Add policy editor to the Threat Monitoring page
merge_request: 41949
author:
type: added
......@@ -83,29 +83,11 @@ RSpec.describe Projects::ThreatMonitoringController do
stub_licensed_features(threat_monitoring: true)
end
context 'and feature flag is disabled' do
before do
stub_feature_flags(network_policy_editor: false)
end
it 'returns 404' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'and feature flag is enabled' do
before do
stub_feature_flags(network_policy_editor: true)
end
it 'renders the new template' do
subject
it 'renders the new template' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:new)
end
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:new)
end
end
......@@ -165,14 +147,35 @@ RSpec.describe Projects::ThreatMonitoringController do
end
context 'when feature is available' do
let(:service) { instance_double('NetworkPolicies::FindResourceService', execute: ServiceResponse.success(payload: policy)) }
let(:policy) do
Gitlab::Kubernetes::CiliumNetworkPolicy.new(
name: 'policy',
namespace: 'another',
selector: { matchLabels: { role: 'db' } },
ingress: [{ from: [{ namespaceSelector: { matchLabels: { project: 'myproject' } } }] }]
)
end
before do
stub_licensed_features(threat_monitoring: true)
allow(NetworkPolicies::FindResourceService).to(
receive(:new)
.with(resource_name: 'policy', environment: environment, kind: Gitlab::Kubernetes::CiliumNetworkPolicy::KIND)
.and_return(service)
)
end
context 'and feature flag is disabled' do
before do
stub_feature_flags(network_policy_editor: false)
end
it 'renders the new template' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:edit)
end
context 'when environment is missing' do
let(:environment_id) { 'missing' }
it 'returns 404' do
subject
......@@ -181,51 +184,13 @@ RSpec.describe Projects::ThreatMonitoringController do
end
end
context 'and feature flag is enabled' do
let(:service) { instance_double('NetworkPolicies::FindResourceService', execute: ServiceResponse.success(payload: policy)) }
let(:policy) do
Gitlab::Kubernetes::CiliumNetworkPolicy.new(
name: 'policy',
namespace: 'another',
selector: { matchLabels: { role: 'db' } },
ingress: [{ from: [{ namespaceSelector: { matchLabels: { project: 'myproject' } } }] }]
)
end
before do
stub_feature_flags(network_policy_editor: true)
allow(NetworkPolicies::FindResourceService).to(
receive(:new)
.with(resource_name: 'policy', environment: environment, kind: Gitlab::Kubernetes::CiliumNetworkPolicy::KIND)
.and_return(service)
)
end
context 'when service failed' do
let(:service) { instance_double('NetworkPolicies::FindResourceService', execute: ServiceResponse.error(message: 'error')) }
it 'renders the new template' do
it 'returns 404' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:edit)
end
context 'when environment is missing' do
let(:environment_id) { 'missing' }
it 'returns 404' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when service failed' do
let(:service) { instance_double('NetworkPolicies::FindResourceService', execute: ServiceResponse.error(message: 'error')) }
it 'returns 404' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
......
......@@ -6,10 +6,10 @@ exports[`NetworkPolicyList component renders policies table 1`] = `
<table
aria-busy="false"
aria-colcount="3"
aria-describedby="__BVID__529__caption_"
aria-describedby="__BVID__341__caption_"
aria-multiselectable="false"
class="table b-table gl-table table-hover b-table-stacked-md b-table-selectable b-table-select-single"
id="__BVID__529"
id="__BVID__341"
role="table"
>
<!---->
......
......@@ -61,85 +61,50 @@ describe('NetworkPolicyList component', () => {
expect(findEnvironmentsPicker().exists()).toBe(true);
});
it('does not render the new policy button', () => {
it('renders the new policy button', () => {
const button = wrapper.find('[data-testid="new-policy"]');
expect(button.exists()).toBe(false);
expect(button.exists()).toBe(true);
});
describe('given the networkPolicyEditor feature flag is enabled', () => {
beforeEach(() => {
factory({
provide: {
glFeatures: {
networkPolicyEditor: true,
},
},
});
});
it('renders the new policy button', () => {
const button = wrapper.find('[data-testid="new-policy"]');
expect(button.exists()).toBe(true);
});
it('does not render the new policy drawer', () => {
expect(wrapper.find(PolicyDrawer).exists()).toBe(false);
});
it('does not render edit button', () => {
expect(wrapper.find('[data-testid="edit-button"]').exists()).toBe(false);
});
it('does not render the new policy drawer', () => {
expect(wrapper.find(PolicyDrawer).exists()).toBe(false);
});
describe('given there is a selected policy', () => {
beforeEach(() => {
factory({
provide: {
glFeatures: {
networkPolicyEditor: true,
},
},
data: () => ({ selectedPolicyName: 'policy' }),
});
});
});
it('does not render edit button', () => {
expect(wrapper.find('[data-testid="edit-button"]').exists()).toBe(false);
});
describe('given selected policy is a cilium policy', () => {
const manifest = `apiVersion: cilium.io/v2
describe('given selected policy is a cilium policy', () => {
const manifest = `apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: policy
spec:
endpointSelector: {}`;
beforeEach(() => {
factory({
provide: {
glFeatures: {
networkPolicyEditor: true,
beforeEach(() => {
factory({
data: () => ({ selectedPolicyName: 'policy' }),
state: {
policies: [
{
name: 'policy',
creationTimestamp: new Date(),
manifest,
},
},
data: () => ({ selectedPolicyName: 'policy' }),
state: {
policies: [
{
name: 'policy',
creationTimestamp: new Date(),
manifest,
},
],
},
});
],
},
});
});
it('renders the new policy drawer', () => {
expect(wrapper.find(PolicyDrawer).exists()).toBe(true);
});
it('renders the new policy drawer', () => {
expect(wrapper.find(PolicyDrawer).exists()).toBe(true);
});
it('renders edit button', () => {
const button = wrapper.find('[data-testid="edit-button"]');
expect(button.exists()).toBe(true);
expect(button.attributes().href).toBe('/policies/policy/edit?environment_id=-1');
});
it('renders edit button', () => {
const button = wrapper.find('[data-testid="edit-button"]');
expect(button.exists()).toBe(true);
expect(button.attributes().href).toBe('/policies/policy/edit?environment_id=-1');
});
});
......
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