summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorThong Kuah <tkuah@gitlab.com>2018-11-15 22:17:41 +1300
committerThong Kuah <tkuah@gitlab.com>2018-12-05 10:16:44 +1300
commitd54791e0942ae774876db22675cde1b54f35109d (patch)
tree0921f14ff534d058b321d008c2ff570d043d4cfc /app
parent8419b7dd2b85fbe9216a31ce84d5ecb234a8b90a (diff)
downloadgitlab-ce-d54791e0942ae774876db22675cde1b54f35109d.tar.gz
Create k8s namespace for project in group clusters
AFAIK the only relevant place is Projects::CreateService, this gets called when user creates a new project, forks a new project and does those things via the api. Also create k8s namespace for new group hierarchy when transferring project between groups Uses new Refresh service to create k8s namespaces - Ensure we use Cluster#cluster_project If a project has multiple clusters (EE), using Project#cluster_project is not guaranteed to return the cluster_project for this cluster. So switch to using Cluster#cluster_project - at this stage a cluster can only have 1 cluster_project. Also, remove rescue so that sidekiq can retry
Diffstat (limited to 'app')
-rw-r--r--app/models/clusters/cluster.rb22
-rw-r--r--app/models/project.rb6
-rw-r--r--app/services/clusters/refresh_service.rb33
-rw-r--r--app/services/projects/create_service.rb6
-rw-r--r--app/services/projects/transfer_service.rb5
-rw-r--r--app/workers/all_queues.yml1
-rw-r--r--app/workers/cluster_platform_configure_worker.rb12
-rw-r--r--app/workers/cluster_project_configure_worker.rb12
8 files changed, 81 insertions, 16 deletions
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index 54314f69c3d..73cae8d3b25 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -87,6 +87,12 @@ module Clusters
scope :default_environment, -> { where(environment_scope: DEFAULT_ENVIRONMENT) }
+ scope :missing_kubernetes_namespace, -> (kubernetes_namespaces) do
+ subquery = kubernetes_namespaces.select('1').where('clusters_kubernetes_namespaces.cluster_id = clusters.id')
+
+ where('NOT EXISTS (?)', subquery)
+ end
+
# Returns an ordered list of group clusters order from clusters of closest
# group up to furthest ancestor group
def self.ordered_group_clusters_for_project(project_id)
@@ -161,11 +167,17 @@ module Clusters
platform_kubernetes.kubeclient if kubernetes?
end
- def find_or_initialize_kubernetes_namespace(cluster_project)
- kubernetes_namespaces.find_or_initialize_by(
- project: cluster_project.project,
- cluster_project: cluster_project
- )
+ def find_or_initialize_kubernetes_namespace_for_project(project)
+ if project_type?
+ kubernetes_namespaces.find_or_initialize_by(
+ project: project,
+ cluster_project: cluster_project
+ )
+ else
+ kubernetes_namespaces.find_or_initialize_by(
+ project: project
+ )
+ end
end
def allow_user_defined_namespace?
diff --git a/app/models/project.rb b/app/models/project.rb
index 8f41629e5e5..a3580961d42 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -383,6 +383,12 @@ class Project < ActiveRecord::Base
.where(project_ci_cd_settings: { group_runners_enabled: true })
end
+ scope :missing_kubernetes_namespace, -> (kubernetes_namespaces) do
+ subquery = kubernetes_namespaces.select('1').where('clusters_kubernetes_namespaces.project_id = projects.id')
+
+ where('NOT EXISTS (?)', subquery)
+ end
+
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
chronic_duration_attr :build_timeout_human_readable, :build_timeout, default: 3600
diff --git a/app/services/clusters/refresh_service.rb b/app/services/clusters/refresh_service.rb
new file mode 100644
index 00000000000..51859a002c0
--- /dev/null
+++ b/app/services/clusters/refresh_service.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Clusters
+ class RefreshService
+ def create_or_update_namespaces_for_cluster(cluster)
+ cluster_namespaces = cluster.kubernetes_namespaces
+
+ # Create all namespaces that are missing for each project
+ cluster.all_projects.missing_kubernetes_namespace(cluster_namespaces).each do |project|
+ kubernetes_namespace = cluster.find_or_initialize_kubernetes_namespace_for_project(project)
+
+ ::Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new(
+ cluster: cluster,
+ kubernetes_namespace: kubernetes_namespace
+ ).execute
+ end
+ end
+
+ def create_or_update_namespaces_for_project(project)
+ project_namespaces = project.kubernetes_namespaces
+
+ # Create all namespaces that are missing for each cluster
+ project.all_clusters.missing_kubernetes_namespace(project_namespaces).each do |cluster|
+ kubernetes_namespace = cluster.find_or_initialize_kubernetes_namespace_for_project(project)
+
+ ::Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new(
+ cluster: cluster,
+ kubernetes_namespace: kubernetes_namespace
+ ).execute
+ end
+ end
+ end
+end
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 9e77a3237e3..d03137b63b2 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -96,6 +96,8 @@ module Projects
current_user.invalidate_personal_projects_count
create_readme if @initialize_with_readme
+
+ configure_group_clusters_for_project
end
# Refresh the current user's authorizations inline (so they can access the
@@ -121,6 +123,10 @@ module Projects
Files::CreateService.new(@project, current_user, commit_attrs).execute
end
+ def configure_group_clusters_for_project
+ ClusterProjectConfigureWorker.perform_async(@project.id)
+ end
+
def skip_wiki?
!@project.feature_available?(:wiki, current_user) || @skip_wiki
end
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index 9d40ab166ff..9db3fd9cf17 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -54,6 +54,7 @@ module Projects
end
attempt_transfer_transaction
+ configure_group_clusters_for_project
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -162,5 +163,9 @@ module Projects
@new_namespace.full_path
)
end
+
+ def configure_group_clusters_for_project
+ ClusterProjectConfigureWorker.perform_async(project.id)
+ end
end
end
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index c0b410472eb..e51da79c6b5 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -29,6 +29,7 @@
- gcp_cluster:wait_for_cluster_creation
- gcp_cluster:cluster_wait_for_ingress_ip_address
- gcp_cluster:cluster_platform_configure
+- gcp_cluster:cluster_project_configure
- github_import_advance_stage
- github_importer:github_import_import_diff_note
diff --git a/app/workers/cluster_platform_configure_worker.rb b/app/workers/cluster_platform_configure_worker.rb
index 8f3689f0166..7f14f8efa2f 100644
--- a/app/workers/cluster_platform_configure_worker.rb
+++ b/app/workers/cluster_platform_configure_worker.rb
@@ -6,17 +6,7 @@ class ClusterPlatformConfigureWorker
def perform(cluster_id)
Clusters::Cluster.find_by_id(cluster_id).try do |cluster|
- next unless cluster.cluster_project
-
- kubernetes_namespace = cluster.find_or_initialize_kubernetes_namespace(cluster.cluster_project)
-
- Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new(
- cluster: cluster,
- kubernetes_namespace: kubernetes_namespace
- ).execute
+ Clusters::RefreshService.new.create_or_update_namespaces_for_cluster(cluster)
end
-
- rescue ::Kubeclient::HttpError => err
- Rails.logger.error "Failed to create/update Kubernetes namespace for cluster_id: #{cluster_id} with error: #{err.message}"
end
end
diff --git a/app/workers/cluster_project_configure_worker.rb b/app/workers/cluster_project_configure_worker.rb
new file mode 100644
index 00000000000..1271b26e945
--- /dev/null
+++ b/app/workers/cluster_project_configure_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class ClusterProjectConfigureWorker
+ include ApplicationWorker
+ include ClusterQueue
+
+ def perform(project_id)
+ project = Project.find(project_id)
+
+ ::Clusters::RefreshService.new.create_or_update_namespaces_for_project(project)
+ end
+end