Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorJoão Cunha <j.a.cunha@gmail.com>2019-02-18 20:06:51 +0300
committerjerasmus <jerasmus@gitlab.com>2019-03-05 09:32:51 +0300
commitf8234d9a086a43a95698da13d2734fe62ddb9ad7 (patch)
tree14ac13feff76a5e622e26e58393863761a9eaa19 /app
parentcf1b85dd726c1947f9ff2af8d89aa240747f462d (diff)
Creates Clusterss::ApplciationsController update endpoint
- Creates new route - Creates new controller action - Creates call stack: Clusterss::ApplciationsController calls --> Clusters::Applications::UpdateService calls --> Clusters::Applications::ScheduleUpdateService calls --> ClusterUpdateAppWorker calls --> Clusters::Applications::PatchService --> ClusterWaitForAppInstallationWorker DRY req params Adds gcp_cluster:cluster_update_app queue Schedule_update_service is uneeded Extract common logic to a parent class (UpdateService will need it) Introduce new UpdateService Fix rescue class namespace Fix RuboCop offenses Adds BaseService for create and update services Remove request_handler code duplication Fixes update command Move update_command to ApplicationCore so all apps can use it Adds tests for Knative update_command Adds specs for PatchService Raise error if update receives an unistalled app Adds update_service spec Fix RuboCop offense Use subject in favor of go Adds update endpoint specs for project namespace Adds update endpoint specs for group namespace
Diffstat (limited to 'app')
-rw-r--r--app/controllers/clusters/applications_controller.rb29
-rw-r--r--app/models/clusters/concerns/application_core.rb6
-rw-r--r--app/services/clusters/applications/base_helm_service.rb4
-rw-r--r--app/services/clusters/applications/base_service.rb76
-rw-r--r--app/services/clusters/applications/create_service.rb57
-rw-r--r--app/services/clusters/applications/patch_service.rb26
-rw-r--r--app/services/clusters/applications/update_service.rb34
-rw-r--r--app/workers/all_queues.yml1
-rw-r--r--app/workers/cluster_update_app_worker.rb13
9 files changed, 185 insertions, 61 deletions
diff --git a/app/controllers/clusters/applications_controller.rb b/app/controllers/clusters/applications_controller.rb
index c4e7fc950f9..73c744efeba 100644
--- a/app/controllers/clusters/applications_controller.rb
+++ b/app/controllers/clusters/applications_controller.rb
@@ -3,26 +3,41 @@
class Clusters::ApplicationsController < Clusters::BaseController
before_action :cluster
before_action :authorize_create_cluster!, only: [:create]
+ before_action :authorize_update_cluster!, only: [:update]
def create
- Clusters::Applications::CreateService
- .new(@cluster, current_user, create_cluster_application_params)
- .execute(request)
+ request_handler do
+ Clusters::Applications::CreateService
+ .new(@cluster, current_user, cluster_application_params)
+ .execute(request)
+ end
+ end
+
+ def update
+ request_handler do
+ Clusters::Applications::UpdateService
+ .new(@cluster, current_user, cluster_application_params)
+ .execute(request)
+ end
+ end
+
+ private
+
+ def request_handler
+ yield
head :no_content
- rescue Clusters::Applications::CreateService::InvalidApplicationError
+ rescue Clusters::Applications::BaseService::InvalidApplicationError
render_404
rescue StandardError
head :bad_request
end
- private
-
def cluster
@cluster ||= clusterable.clusters.find(params[:id]) || render_404
end
- def create_cluster_application_params
+ def cluster_application_params
params.permit(:application, :hostname, :email)
end
end
diff --git a/app/models/clusters/concerns/application_core.rb b/app/models/clusters/concerns/application_core.rb
index 683b45331f6..cdb42117281 100644
--- a/app/models/clusters/concerns/application_core.rb
+++ b/app/models/clusters/concerns/application_core.rb
@@ -30,6 +30,12 @@ module Clusters
# Override if you need extra data synchronized
# from K8s after installation
end
+
+ def update_command
+ command = install_command
+ command.version = version
+ command
+ end
end
end
end
diff --git a/app/services/clusters/applications/base_helm_service.rb b/app/services/clusters/applications/base_helm_service.rb
index 8a71730d5ec..c38b2656260 100644
--- a/app/services/clusters/applications/base_helm_service.rb
+++ b/app/services/clusters/applications/base_helm_service.rb
@@ -46,6 +46,10 @@ module Clusters
@install_command ||= app.install_command
end
+ def update_command
+ @update_command ||= app.update_command
+ end
+
def upgrade_command(new_values = "")
app.upgrade_command(new_values)
end
diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb
new file mode 100644
index 00000000000..cbd1cf03ae1
--- /dev/null
+++ b/app/services/clusters/applications/base_service.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Applications
+ class BaseService
+ InvalidApplicationError = Class.new(StandardError)
+
+ attr_reader :cluster, :current_user, :params
+
+ def initialize(cluster, user, params = {})
+ @cluster = cluster
+ @current_user = user
+ @params = params.dup
+ end
+
+ def execute(request)
+ instantiate_application.tap do |application|
+ if application.has_attribute?(:hostname)
+ application.hostname = params[:hostname]
+ end
+
+ if application.has_attribute?(:email)
+ application.email = params[:email]
+ end
+
+ if application.respond_to?(:oauth_application)
+ application.oauth_application = create_oauth_application(application, request)
+ end
+
+ worker = worker_class(application)
+
+ application.make_scheduled!
+
+ worker.perform_async(application.name, application.id)
+ end
+ end
+
+ protected
+
+ def worker_class(application)
+ raise NotImplementedError
+ end
+
+ def builders
+ raise NotImplementedError
+ end
+
+ def project_builders
+ raise NotImplementedError
+ end
+
+ def instantiate_application
+ builder.call(@cluster) || raise(InvalidApplicationError, "invalid application: #{application_name}")
+ end
+
+ def builder
+ builders[application_name] || raise(InvalidApplicationError, "invalid application: #{application_name}")
+ end
+
+ def application_name
+ params[:application]
+ end
+
+ def create_oauth_application(application, request)
+ oauth_application_params = {
+ name: params[:application],
+ redirect_uri: application.callback_url,
+ scopes: 'api read_user openid',
+ owner: current_user
+ }
+
+ ::Applications::CreateService.new(current_user, oauth_application_params).execute(request)
+ end
+ end
+ end
+end
diff --git a/app/services/clusters/applications/create_service.rb b/app/services/clusters/applications/create_service.rb
index 12f8c849d41..bd7c31bb981 100644
--- a/app/services/clusters/applications/create_service.rb
+++ b/app/services/clusters/applications/create_service.rb
@@ -2,47 +2,11 @@
module Clusters
module Applications
- class CreateService
- InvalidApplicationError = Class.new(StandardError)
-
- attr_reader :cluster, :current_user, :params
-
- def initialize(cluster, user, params = {})
- @cluster = cluster
- @current_user = user
- @params = params.dup
- end
-
- def execute(request)
- create_application.tap do |application|
- if application.has_attribute?(:hostname)
- application.hostname = params[:hostname]
- end
-
- if application.has_attribute?(:email)
- application.email = params[:email]
- end
-
- if application.respond_to?(:oauth_application)
- application.oauth_application = create_oauth_application(application, request)
- end
-
- worker = application.updateable? ? ClusterUpgradeAppWorker : ClusterInstallAppWorker
-
- application.make_scheduled!
-
- worker.perform_async(application.name, application.id)
- end
- end
-
+ class CreateService < Clusters::Applications::BaseService
private
- def create_application
- builder.call(@cluster)
- end
-
- def builder
- builders[application_name] || raise(InvalidApplicationError, "invalid application: #{application_name}")
+ def worker_class(application)
+ application.updateable? ? ClusterUpgradeAppWorker : ClusterInstallAppWorker
end
def builders
@@ -65,21 +29,6 @@ module Clusters
"knative" => -> (cluster) { cluster.application_knative || cluster.build_application_knative }
}
end
-
- def application_name
- params[:application]
- end
-
- def create_oauth_application(application, request)
- oauth_application_params = {
- name: params[:application],
- redirect_uri: application.callback_url,
- scopes: 'api read_user openid',
- owner: current_user
- }
-
- ::Applications::CreateService.new(current_user, oauth_application_params).execute(request)
- end
end
end
end
diff --git a/app/services/clusters/applications/patch_service.rb b/app/services/clusters/applications/patch_service.rb
new file mode 100644
index 00000000000..67fc8fd9800
--- /dev/null
+++ b/app/services/clusters/applications/patch_service.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Applications
+ class PatchService < BaseHelmService
+ def execute
+ return unless app.scheduled?
+
+ begin
+ app.make_updating!
+
+ helm_api.update(update_command)
+
+ ClusterWaitForAppInstallationWorker.perform_in(
+ ClusterWaitForAppInstallationWorker::INTERVAL, app.name, app.id)
+ rescue Kubeclient::HttpError => e
+ log_error(e)
+ app.make_update_errored!("Kubernetes error: #{e.error_code}")
+ rescue StandardError => e
+ log_error(e)
+ app.make_update_errored!("Can't start update process.")
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/clusters/applications/update_service.rb b/app/services/clusters/applications/update_service.rb
new file mode 100644
index 00000000000..979d870cc94
--- /dev/null
+++ b/app/services/clusters/applications/update_service.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Applications
+ class UpdateService < Clusters::Applications::BaseService
+ private
+
+ def worker_class(application)
+ ClusterUpdateAppWorker
+ end
+
+ def builders
+ {
+ "helm" => -> (cluster) { cluster.application_helm },
+ "ingress" => -> (cluster) { cluster.application_ingress },
+ "cert_manager" => -> (cluster) { cluster.application_cert_manager }
+ }.tap do |hash|
+ hash.merge!(project_builders) if cluster.project_type?
+ end
+ end
+
+ # These applications will need extra configuration to enable them to work
+ # with groups of projects
+ def project_builders
+ {
+ "prometheus" => -> (cluster) { cluster.application_prometheus },
+ "runner" => -> (cluster) { cluster.application_runner },
+ "jupyter" => -> (cluster) { cluster.application_jupyter },
+ "knative" => -> (cluster) { cluster.application_knative }
+ }
+ end
+ end
+ end
+end
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index d86f654dd44..bc7db5669e1 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -23,6 +23,7 @@
- cronjob:prune_web_hook_logs
- gcp_cluster:cluster_install_app
+- gcp_cluster:cluster_update_app
- gcp_cluster:cluster_upgrade_app
- gcp_cluster:cluster_provision
- gcp_cluster:cluster_wait_for_app_installation
diff --git a/app/workers/cluster_update_app_worker.rb b/app/workers/cluster_update_app_worker.rb
new file mode 100644
index 00000000000..bec422c34a9
--- /dev/null
+++ b/app/workers/cluster_update_app_worker.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class ClusterUpdateAppWorker
+ include ApplicationWorker
+ include ClusterQueue
+ include ClusterApplications
+
+ def perform(app_name, app_id)
+ find_application(app_name, app_id) do |app|
+ Clusters::Applications::PatchService.new(app).execute
+ end
+ end
+end