Commit cd600060 authored by ap4y's avatar ap4y

Implement CRUD controller actions for network policy management

This patch adds CRUD operations for the new network policy management
page.
parent d08f439f
...@@ -5,7 +5,7 @@ module Projects ...@@ -5,7 +5,7 @@ module Projects
class NetworkPoliciesController < Projects::ApplicationController class NetworkPoliciesController < Projects::ApplicationController
POLLING_INTERVAL = 5_000 POLLING_INTERVAL = 5_000
before_action :authorize_read_network_policies! before_action :authorize_read_threat_monitoring!
before_action :set_polling_interval, only: [:summary] before_action :set_polling_interval, only: [:summary]
def summary def summary
...@@ -33,6 +33,41 @@ module Projects ...@@ -33,6 +33,41 @@ module Projects
end end
end end
def index
response = NetworkPolicies::ResourcesService.new(environment: environment).execute
respond_with_service_response(response)
end
def create
policy = Gitlab::Kubernetes::NetworkPolicy.from_yaml(params[:manifest])
response = NetworkPolicies::DeployResourceService.new(
policy: policy,
environment: environment
).execute
respond_with_service_response(response)
end
def update
policy = Gitlab::Kubernetes::NetworkPolicy.from_yaml(params[:manifest])
response = NetworkPolicies::DeployResourceService.new(
resource_name: params[:id],
policy: policy,
environment: environment
).execute
respond_with_service_response(response)
end
def destroy
response = NetworkPolicies::DeleteResourceService.new(
resource_name: params[:id],
environment: environment
).execute
respond_with_service_response(response)
end
private private
def environment def environment
...@@ -43,9 +78,18 @@ module Projects ...@@ -43,9 +78,18 @@ module Projects
Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL) Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL)
end end
def authorize_read_network_policies! def authorize_read_threat_monitoring!
render_403 unless can?(current_user, :read_threat_monitoring, project) render_403 unless can?(current_user, :read_threat_monitoring, project)
end end
def respond_with_service_response(response)
payload = response.success? ? response.payload : { error: response.message }
respond_to do |format|
format.json do
render status: response.http_status, json: payload
end
end
end
end end
end end
end end
...@@ -64,7 +64,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do ...@@ -64,7 +64,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get :summary, on: :collection get :summary, on: :collection
end end
resource :network_policies, only: [] do resources :network_policies, only: [:index, :create, :update, :destroy] do
get :summary, on: :collection get :summary, on: :collection
end end
......
...@@ -11,17 +11,32 @@ describe Projects::Security::NetworkPoliciesController do ...@@ -11,17 +11,32 @@ describe Projects::Security::NetworkPoliciesController do
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 } }
shared_examples 'CRUD service errors' do
context 'with a error service response' do
before do
allow(service).to receive(:execute) { ServiceResponse.error(http_status: :bad_request, message: 'error') }
end
it 'responds with bad_request' do
subject
expect(response).to have_gitlab_http_status(:bad_request)
expect(response.body).to eq('{"error":"error"}')
end
end
end
before do
stub_licensed_features(threat_monitoring: true)
sign_in(user)
end
describe 'GET #summary' do describe 'GET #summary' do
subject { get :summary, params: action_params, format: :json } subject { get :summary, params: action_params, format: :json }
let_it_be(:kubernetes_namespace) { environment.deployment_namespace } let_it_be(:kubernetes_namespace) { environment.deployment_namespace }
before do
stub_licensed_features(threat_monitoring: true)
sign_in(user)
end
context 'with authorized user' do context 'with authorized user' do
before do before do
group.add_developer(user) group.add_developer(user)
...@@ -122,4 +137,199 @@ describe Projects::Security::NetworkPoliciesController do ...@@ -122,4 +137,199 @@ describe Projects::Security::NetworkPoliciesController do
end end
end end
end end
describe 'GET #index' do
subject { get :index, params: action_params, format: :json }
context 'with authorized user' do
let(:service) { instance_double('NetworkPolicies::ResourcesService', execute: ServiceResponse.success(payload: [policy])) }
let(:policy) do
Gitlab::Kubernetes::NetworkPolicy.new(
name: 'policy',
namespace: 'another',
pod_selector: { matchLabels: { role: 'db' } },
ingress: [{ from: [{ namespaceSelector: { matchLabels: { project: 'myproject' } } }] }]
)
end
before do
group.add_developer(user)
allow(NetworkPolicies::ResourcesService).to receive(:new).with(environment: environment) { service }
end
it 'responds with policies' do
subject
expect(response).to have_gitlab_http_status(:success)
expect(response.body).to eq([policy].to_json)
end
include_examples 'CRUD service errors'
end
context 'with unauthorized user' do
it 'returns unauthorized' do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
describe 'POST #create' do
subject { post :create, params: action_params.merge(manifest: manifest), format: :json }
let(:service) { instance_double('NetworkPolicies::DeployResourceService', execute: ServiceResponse.success(payload: policy)) }
let(:policy) do
Gitlab::Kubernetes::NetworkPolicy.new(
name: 'policy',
namespace: 'another',
pod_selector: { matchLabels: { role: 'db' } },
ingress: [{ from: [{ namespaceSelector: { matchLabels: { project: 'myproject' } } }] }]
)
end
let(:manifest) do
<<~POLICY
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-name
namespace: example-namespace
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject
POLICY
end
context 'with authorized user' do
before do
group.add_developer(user)
allow(NetworkPolicies::DeployResourceService).to(
receive(:new)
.with(policy: kind_of(Gitlab::Kubernetes::NetworkPolicy), environment: environment)
.and_return(service)
)
end
it 'responds with success' do
subject
expect(response).to have_gitlab_http_status(:success)
expect(response.body).to eq(policy.to_json)
end
include_examples 'CRUD service errors'
end
context 'with unauthorized user' do
it 'returns unauthorized' do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
describe 'PUT #update' do
subject { put :update, params: action_params.merge(id: 'example-policy', manifest: manifest), format: :json }
let(:service) { instance_double('NetworkPolicies::DeployResourceService', execute: ServiceResponse.success(payload: policy)) }
let(:policy) do
Gitlab::Kubernetes::NetworkPolicy.new(
name: 'policy',
namespace: 'another',
pod_selector: { matchLabels: { role: 'db' } },
ingress: [{ from: [{ namespaceSelector: { matchLabels: { project: 'myproject' } } }] }]
)
end
let(:manifest) do
<<~POLICY
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-name
namespace: example-namespace
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject
POLICY
end
context 'with authorized user' do
before do
group.add_developer(user)
allow(NetworkPolicies::DeployResourceService).to(
receive(:new)
.with(policy: kind_of(Gitlab::Kubernetes::NetworkPolicy), environment: environment, resource_name: 'example-policy')
.and_return(service)
)
end
it 'responds with success' do
subject
expect(response).to have_gitlab_http_status(:success)
expect(response.body).to eq(policy.to_json)
end
include_examples 'CRUD service errors'
end
context 'with unauthorized user' do
it 'returns unauthorized' do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
describe 'DELETE #destroy' do
subject { delete :destroy, params: action_params.merge(id: 'example-policy'), format: :json }
let(:service) { instance_double('NetworkPolicies::DeleteResourceService', execute: ServiceResponse.success) }
context 'with authorized user' do
before do
group.add_developer(user)
allow(NetworkPolicies::DeleteResourceService).to(
receive(:new)
.with(environment: environment, resource_name: 'example-policy')
.and_return(service)
)
end
it 'responds with success' do
subject
expect(response).to have_gitlab_http_status(:success)
end
include_examples 'CRUD service errors'
end
context 'with unauthorized user' do
it 'returns unauthorized' do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
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