DELETE clusters/:id/:application endpoint
Add endpoint to delete/uninstall a cluster application
This commit is contained in:
parent
43c284b711
commit
abb530a619
8 changed files with 240 additions and 0 deletions
|
@ -4,6 +4,7 @@ class Clusters::ApplicationsController < Clusters::BaseController
|
|||
before_action :cluster
|
||||
before_action :authorize_create_cluster!, only: [:create]
|
||||
before_action :authorize_update_cluster!, only: [:update]
|
||||
before_action :authorize_admin_cluster!, only: [:destroy]
|
||||
|
||||
def create
|
||||
request_handler do
|
||||
|
@ -21,6 +22,14 @@ class Clusters::ApplicationsController < Clusters::BaseController
|
|||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
request_handler do
|
||||
Clusters::Applications::DestroyService
|
||||
.new(@cluster, current_user, cluster_application_destroy_params)
|
||||
.execute(request)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def request_handler
|
||||
|
@ -40,4 +49,8 @@ class Clusters::ApplicationsController < Clusters::BaseController
|
|||
def cluster_application_params
|
||||
params.permit(:application, :hostname, :email)
|
||||
end
|
||||
|
||||
def cluster_application_destroy_params
|
||||
params.permit(:application)
|
||||
end
|
||||
end
|
||||
|
|
23
app/services/clusters/applications/destroy_service.rb
Normal file
23
app/services/clusters/applications/destroy_service.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Clusters
|
||||
module Applications
|
||||
class DestroyService < ::Clusters::Applications::BaseService
|
||||
def execute(_request)
|
||||
instantiate_application.tap do |application|
|
||||
break unless application.can_uninstall?
|
||||
|
||||
application.make_scheduled!
|
||||
|
||||
Clusters::Applications::UninstallWorker.perform_async(application.name, application.id)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def builder
|
||||
cluster.method("application_#{application_name}").call
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -33,6 +33,7 @@
|
|||
- gcp_cluster:cluster_configure
|
||||
- gcp_cluster:cluster_project_configure
|
||||
- gcp_cluster:clusters_applications_wait_for_uninstall_app
|
||||
- gcp_cluster:clusters_applications_uninstall
|
||||
|
||||
- github_import_advance_stage
|
||||
- github_importer:github_import_import_diff_note
|
||||
|
|
17
app/workers/clusters/applications/uninstall_worker.rb
Normal file
17
app/workers/clusters/applications/uninstall_worker.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Clusters
|
||||
module Applications
|
||||
class UninstallWorker
|
||||
include ApplicationWorker
|
||||
include ClusterQueue
|
||||
include ClusterApplications
|
||||
|
||||
def perform(app_name, app_id)
|
||||
find_application(app_name, app_id) do |app|
|
||||
Clusters::Applications::UninstallService.new(app).execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -103,6 +103,7 @@ Rails.application.routes.draw do
|
|||
scope :applications do
|
||||
post '/:application', to: 'clusters/applications#create', as: :install_applications
|
||||
patch '/:application', to: 'clusters/applications#update', as: :update_applications
|
||||
delete '/:application', to: 'clusters/applications#destroy', as: :uninstall_applications
|
||||
end
|
||||
|
||||
get :cluster_status, format: :json
|
||||
|
|
|
@ -144,4 +144,64 @@ describe Groups::Clusters::ApplicationsController do
|
|||
it_behaves_like 'a secure endpoint'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE destroy' do
|
||||
subject do
|
||||
delete :destroy, params: params.merge(group_id: group)
|
||||
end
|
||||
|
||||
let!(:application) { create(:clusters_applications_cert_managers, :installed, cluster: cluster) }
|
||||
let(:application_name) { application.name }
|
||||
let(:params) { { application: application_name, id: cluster.id } }
|
||||
let(:worker_class) { Clusters::Applications::UninstallWorker }
|
||||
|
||||
describe 'functionality' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
group.add_maintainer(user)
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
context "when cluster and app exists" do
|
||||
xit "schedules an application update" do
|
||||
expect(worker_class).to receive(:perform_async).with(application.name, application.id).once
|
||||
|
||||
is_expected.to have_http_status(:no_content)
|
||||
|
||||
expect(cluster.application_cert_manager).to be_scheduled
|
||||
end
|
||||
end
|
||||
|
||||
context 'when cluster do not exists' do
|
||||
before do
|
||||
cluster.destroy!
|
||||
end
|
||||
|
||||
it { is_expected.to have_http_status(:not_found) }
|
||||
end
|
||||
|
||||
context 'when application is unknown' do
|
||||
let(:application_name) { 'unkwnown-app' }
|
||||
|
||||
it { is_expected.to have_http_status(:not_found) }
|
||||
end
|
||||
|
||||
context 'when application is already scheduled' do
|
||||
before do
|
||||
application.make_scheduled!
|
||||
end
|
||||
|
||||
xit { is_expected.to have_http_status(:bad_request) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'security' do
|
||||
before do
|
||||
allow(worker_class).to receive(:perform_async)
|
||||
end
|
||||
|
||||
it_behaves_like 'a secure endpoint'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -145,4 +145,66 @@ describe Projects::Clusters::ApplicationsController do
|
|||
it_behaves_like 'a secure endpoint'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE destroy' do
|
||||
subject do
|
||||
delete :destroy, params: params.merge(namespace_id: project.namespace, project_id: project)
|
||||
end
|
||||
|
||||
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
|
||||
let(:project) { cluster.project }
|
||||
let!(:application) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
|
||||
let(:application_name) { application.name }
|
||||
let(:params) { { application: application_name, id: cluster.id } }
|
||||
let(:worker_class) { Clusters::Applications::UninstallWorker }
|
||||
|
||||
describe 'functionality' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
context "when cluster and app exists" do
|
||||
it "schedules an application update" do
|
||||
expect(worker_class).to receive(:perform_async).with(application.name, application.id).once
|
||||
|
||||
is_expected.to have_http_status(:no_content)
|
||||
|
||||
expect(cluster.application_prometheus).to be_scheduled
|
||||
end
|
||||
end
|
||||
|
||||
context 'when cluster do not exists' do
|
||||
before do
|
||||
cluster.destroy!
|
||||
end
|
||||
|
||||
it { is_expected.to have_http_status(:not_found) }
|
||||
end
|
||||
|
||||
context 'when application is unknown' do
|
||||
let(:application_name) { 'unkwnown-app' }
|
||||
|
||||
it { is_expected.to have_http_status(:not_found) }
|
||||
end
|
||||
|
||||
context 'when application is already scheduled' do
|
||||
before do
|
||||
application.make_scheduled!
|
||||
end
|
||||
|
||||
it { is_expected.to have_http_status(:bad_request) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'security' do
|
||||
before do
|
||||
allow(worker_class).to receive(:perform_async)
|
||||
end
|
||||
|
||||
it_behaves_like 'a secure endpoint'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
63
spec/services/clusters/applications/destroy_service_spec.rb
Normal file
63
spec/services/clusters/applications/destroy_service_spec.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Clusters::Applications::DestroyService, '#execute' do
|
||||
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
|
||||
let(:user) { create(:user) }
|
||||
let(:params) { { application: 'prometheus' } }
|
||||
let(:service) { described_class.new(cluster, user, params) }
|
||||
let(:test_request) { double }
|
||||
let(:worker_class) { Clusters::Applications::UninstallWorker }
|
||||
|
||||
subject { service.execute(test_request) }
|
||||
|
||||
before do
|
||||
allow(worker_class).to receive(:perform_async)
|
||||
end
|
||||
|
||||
context 'application is not installed' do
|
||||
it 'raises Clusters::Applications::BaseService::InvalidApplicationError' do
|
||||
expect(worker_class).not_to receive(:perform_async)
|
||||
|
||||
expect { subject }
|
||||
.to raise_exception { Clusters::Applications::BaseService::InvalidApplicationError }
|
||||
.and not_change { Clusters::Applications::Prometheus.count }
|
||||
.and not_change { Clusters::Applications::Prometheus.with_status(:scheduled).count }
|
||||
end
|
||||
end
|
||||
|
||||
context 'application is installed' do
|
||||
context 'application is schedulable' do
|
||||
let!(:application) do
|
||||
create(:clusters_applications_prometheus, :installed, cluster: cluster)
|
||||
end
|
||||
|
||||
it 'makes application scheduled!' do
|
||||
subject
|
||||
|
||||
expect(application.reload).to be_scheduled
|
||||
end
|
||||
|
||||
it 'schedules UninstallWorker' do
|
||||
expect(worker_class).to receive(:perform_async).with(application.name, application.id)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
context 'application is not schedulable' do
|
||||
let!(:application) do
|
||||
create(:clusters_applications_prometheus, :updating, cluster: cluster)
|
||||
end
|
||||
|
||||
it 'raises StateMachines::InvalidTransition' do
|
||||
expect(worker_class).not_to receive(:perform_async)
|
||||
|
||||
expect { subject }
|
||||
.to raise_exception { StateMachines::InvalidTransition }
|
||||
.and not_change { Clusters::Applications::Prometheus.with_status(:scheduled).count }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue