Commit 71e9829d authored by Dylan Griffith's avatar Dylan Griffith

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

Network policy toggle

See merge request gitlab-org/gitlab!33003
parents 05953ab1 e7662467
...@@ -50,6 +50,10 @@ module Projects ...@@ -50,6 +50,10 @@ module Projects
def update def update
policy = Gitlab::Kubernetes::NetworkPolicy.from_yaml(params[:manifest]) policy = Gitlab::Kubernetes::NetworkPolicy.from_yaml(params[:manifest])
unless params[:enabled].nil?
params[:enabled] ? policy.enable : policy.disable
end
response = NetworkPolicies::DeployResourceService.new( response = NetworkPolicies::DeployResourceService.new(
resource_name: params[:id], resource_name: params[:id],
policy: policy, policy: policy,
......
...@@ -9,7 +9,7 @@ describe Projects::Security::NetworkPoliciesController do ...@@ -9,7 +9,7 @@ describe Projects::Security::NetworkPoliciesController do
let_it_be(:project) { create(:project, :public, :repository, group: group) } let_it_be(:project) { create(:project, :public, :repository, group: group) }
let_it_be(:environment) { create(:environment, :with_review_app, project: project) } let_it_be(:environment) { create(:environment, :with_review_app, project: project) }
let_it_be(:action_params) { { project_id: project, namespace_id: project.namespace, environment_id: environment } } let_it_be(:action_params) { { project_id: project, namespace_id: project.namespace, environment_id: environment.id } }
shared_examples 'CRUD service errors' do shared_examples 'CRUD service errors' do
context 'with a error service response' do context 'with a error service response' do
...@@ -239,8 +239,9 @@ describe Projects::Security::NetworkPoliciesController do ...@@ -239,8 +239,9 @@ describe Projects::Security::NetworkPoliciesController do
end end
describe 'PUT #update' do describe 'PUT #update' do
subject { put :update, params: action_params.merge(id: 'example-policy', manifest: manifest), format: :json } subject { put :update, params: action_params.merge(id: 'example-policy', manifest: manifest, enabled: enabled), as: :json }
let(:enabled) { nil }
let(:service) { instance_double('NetworkPolicies::DeployResourceService', execute: ServiceResponse.success(payload: policy)) } let(:service) { instance_double('NetworkPolicies::DeployResourceService', execute: ServiceResponse.success(payload: policy)) }
let(:policy) do let(:policy) do
Gitlab::Kubernetes::NetworkPolicy.new( Gitlab::Kubernetes::NetworkPolicy.new(
...@@ -289,6 +290,34 @@ describe Projects::Security::NetworkPoliciesController do ...@@ -289,6 +290,34 @@ describe Projects::Security::NetworkPoliciesController do
end end
include_examples 'CRUD service errors' include_examples 'CRUD service errors'
context 'with enabled param' do
let(:enabled) { true }
before do
allow(Gitlab::Kubernetes::NetworkPolicy).to receive(:new) { policy }
end
it 'enables policy and responds with success' do
expect(policy).to receive(:enable)
subject
expect(response).to have_gitlab_http_status(:success)
end
context 'with enabled=false' do
let(:enabled) { false }
it 'disables policy and responds with success' do
expect(policy).to receive(:disable)
subject
expect(response).to have_gitlab_http_status(:success)
end
end
end
end end
context 'with unauthorized user' do context 'with unauthorized user' do
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
module Gitlab module Gitlab
module Kubernetes module Kubernetes
class NetworkPolicy class NetworkPolicy
DISABLED_BY_LABEL = :'network-policy.gitlab.com/disabled_by'
def initialize(name:, namespace:, pod_selector:, ingress:, labels: nil, creation_timestamp: nil, policy_types: ["Ingress"], egress: nil) def initialize(name:, namespace:, pod_selector:, ingress:, labels: nil, creation_timestamp: nil, policy_types: ["Ingress"], egress: nil)
@name = name @name = name
@namespace = namespace @namespace = namespace
...@@ -66,7 +68,8 @@ module Gitlab ...@@ -66,7 +68,8 @@ module Gitlab
namespace: namespace, namespace: namespace,
creation_timestamp: creation_timestamp, creation_timestamp: creation_timestamp,
manifest: manifest, manifest: manifest,
is_autodevops: autodevops? is_autodevops: autodevops?,
is_enabled: enabled?
} }
end end
...@@ -76,6 +79,28 @@ module Gitlab ...@@ -76,6 +79,28 @@ module Gitlab
!labels[:chart].nil? && labels[:chart].start_with?('auto-deploy-app-') !labels[:chart].nil? && labels[:chart].start_with?('auto-deploy-app-')
end end
# podSelector selects pods that should be targeted by this
# policy. We can narrow selection by requiring this policy to
# match our custom labels. Since DISABLED_BY label will not be
# on any pod a policy will be effectively disabled.
def enabled?
return true unless pod_selector&.key?(:matchLabels)
!pod_selector[:matchLabels]&.key?(DISABLED_BY_LABEL)
end
def enable
return if enabled?
pod_selector[:matchLabels].delete(DISABLED_BY_LABEL)
end
def disable
@pod_selector ||= {}
pod_selector[:matchLabels] ||= {}
pod_selector[:matchLabels].merge!(DISABLED_BY_LABEL => 'gitlab')
end
private private
attr_reader :name, :namespace, :labels, :creation_timestamp, :pod_selector, :policy_types, :ingress, :egress attr_reader :name, :namespace, :labels, :creation_timestamp, :pod_selector, :policy_types, :ingress, :egress
......
...@@ -219,7 +219,8 @@ describe Gitlab::Kubernetes::NetworkPolicy do ...@@ -219,7 +219,8 @@ describe Gitlab::Kubernetes::NetworkPolicy do
spec: { podSelector: pod_selector, policyTypes: %w(Ingress Egress), ingress: ingress, egress: egress } spec: { podSelector: pod_selector, policyTypes: %w(Ingress Egress), ingress: ingress, egress: egress }
}.deep_stringify_keys }.deep_stringify_keys
), ),
is_autodevops: false is_autodevops: false,
is_enabled: true
} }
end end
...@@ -256,4 +257,138 @@ describe Gitlab::Kubernetes::NetworkPolicy do ...@@ -256,4 +257,138 @@ describe Gitlab::Kubernetes::NetworkPolicy do
it { is_expected.to be true } it { is_expected.to be true }
end end
end end
describe '#enabled?' do
subject { policy.enabled? }
let(:pod_selector) { nil }
let(:policy) do
described_class.new(
name: name,
namespace: namespace,
pod_selector: pod_selector,
ingress: ingress
)
end
it { is_expected.to be true }
context 'with empty pod_selector' do
let(:pod_selector) { {} }
it { is_expected.to be true }
end
context 'with nil matchLabels in pod_selector' do
let(:pod_selector) { { matchLabels: nil } }
it { is_expected.to be true }
end
context 'with empty matchLabels in pod_selector' do
let(:pod_selector) { { matchLabels: {} } }
it { is_expected.to be true }
end
context 'with disabled_by label in matchLabels in pod_selector' do
let(:pod_selector) do
{ matchLabels: { Gitlab::Kubernetes::NetworkPolicy::DISABLED_BY_LABEL => 'gitlab' } }
end
it { is_expected.to be false }
end
end
describe '#enable' do
subject { policy.enabled? }
let(:pod_selector) { nil }
let(:policy) do
described_class.new(
name: name,
namespace: namespace,
pod_selector: pod_selector,
ingress: ingress
)
end
before do
policy.enable
end
it { is_expected.to be true }
context 'with empty pod_selector' do
let(:pod_selector) { {} }
it { is_expected.to be true }
end
context 'with nil matchLabels in pod_selector' do
let(:pod_selector) { { matchLabels: nil } }
it { is_expected.to be true }
end
context 'with empty matchLabels in pod_selector' do
let(:pod_selector) { { matchLabels: {} } }
it { is_expected.to be true }
end
context 'with disabled_by label in matchLabels in pod_selector' do
let(:pod_selector) do
{ matchLabels: { Gitlab::Kubernetes::NetworkPolicy::DISABLED_BY_LABEL => 'gitlab' } }
end
it { is_expected.to be true }
end
end
describe '#disable' do
subject { policy.enabled? }
let(:pod_selector) { nil }
let(:policy) do
described_class.new(
name: name,
namespace: namespace,
pod_selector: pod_selector,
ingress: ingress
)
end
before do
policy.disable
end
it { is_expected.to be false }
context 'with empty pod_selector' do
let(:pod_selector) { {} }
it { is_expected.to be false }
end
context 'with nil matchLabels in pod_selector' do
let(:pod_selector) { { matchLabels: nil } }
it { is_expected.to be false }
end
context 'with empty matchLabels in pod_selector' do
let(:pod_selector) { { matchLabels: {} } }
it { is_expected.to be false }
end
context 'with disabled_by label in matchLabels in pod_selector' do
let(:pod_selector) do
{ matchLabels: { Gitlab::Kubernetes::NetworkPolicy::DISABLED_BY_LABEL => 'gitlab' } }
end
it { is_expected.to be false }
end
end
end end
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