summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2018-01-03 20:58:54 +0900
committerShinya Maeda <shinya@gitlab.com>2018-01-08 16:22:17 +0900
commitf083739e9935f774984f4c8ba2ce4663c29c7564 (patch)
treedfb4cea93cd55da57f1364c32949e7cf74b145ba
parent7eeada80d5c03025c8c37bc1c1567f2500acc8d1 (diff)
downloadgitlab-ce-f083739e9935f774984f4c8ba2ce4663c29c7564.tar.gz
Add logic to swtich environment_scope by the situation
-rw-r--r--db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb52
-rw-r--r--spec/migrations/migrate_kubernetes_service_to_new_clusters_architectures_spec.rb50
2 files changed, 69 insertions, 33 deletions
diff --git a/db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb b/db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb
index 5dee8cb8c5f..46b40ea7a44 100644
--- a/db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb
+++ b/db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb
@@ -51,36 +51,41 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati
belongs_to :project, class_name: 'Project'
- # 10.1 ~ 10.2
- # When users created a cluster, KubernetesService was automatically configured
- # by Platforms::Kubernetes parameters.
- # Because Platforms::Kubernetes delegated some logic to KubernetesService.
- #
- # 10.3
- # When users create a cluster, KubernetesService is no longer synchronized.
- # Because we copied delegated logic in Platforms::Kubernetes.
- #
- # NOTE:
- # - "unmanaged" means "unmanaged by Platforms::Kubernetes(New archetecture)"
- # - We only want to migrate records which are not synchronized with Platforms::Kubernetes.
- scope :unmanaged_kubernetes_service, -> do
+ scope :kubernetes_service, -> do
where("services.category = 'deployment'")
.where("services.type = 'KubernetesService'")
.where("services.template = FALSE")
- .where("NOT EXISTS (?)",
- PlatformsKubernetes
- .joins('INNER JOIN projects ON projects.id = services.project_id')
- .joins('INNER JOIN cluster_projects ON cluster_projects.project_id = projects.id')
- .where('cluster_projects.cluster_id = cluster_platforms_kubernetes.cluster_id')
- .where("services.properties LIKE CONCAT('%', cluster_platforms_kubernetes.api_url, '%')")
- .select('1') )
.order('services.project_id')
end
end
+ def find_dedicated_environement_scope(project)
+ environment_scopes = project.clusters.map(&:environment_scope)
+
+ return '*' if environment_scopes.exclude?('*') # KubernetesService should be added as a default cluster (environment_scope: '*') at first place
+ return 'migrated/*' if environment_scopes.exclude?('migrated/*') # If it's conflicted, the KubernetesService added as a migrated cluster
+
+ unique_iid = 0
+
+ # If it's still conflicted, finding an unique environment scope incrementaly
+ while true
+ candidate = "migrated#{unique_iid}/*"
+ return candidate if environment_scopes.exclude?(candidate)
+ unique_iid += 1
+ end
+ end
+
+ # KubernetesService might be already managed by clusters
+ def managed_by_clusters?(kubernetes_service)
+ kubernetes_service.project.clusters
+ .joins('INNER JOIN cluster_platforms_kubernetes ON clusters.id = cluster_platforms_kubernetes.cluster_id')
+ .where('cluster_platforms_kubernetes.api_url = ?', kubernetes_service.api_url)
+ .exists?
+ end
+
def up
- Service.unmanaged_kubernetes_service
- .find_each(batch_size: 1) do |kubernetes_service|
+ Service.kubernetes_service.find_each(batch_size: 1) do |kubernetes_service|
+ unless managed_by_clusters?(kubernetes_service)
Cluster.create(
enabled: kubernetes_service.active,
user_id: nil, # KubernetesService doesn't have
@@ -88,7 +93,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati
provider_type: Cluster.provider_types[:user],
platform_type: Cluster.platform_types[:kubernetes],
projects: [kubernetes_service.project],
- environment_scope: '*', # KubernetesService is considered as a default cluster
+ environment_scope: find_dedicated_environement_scope(kubernetes_service.project),
platform_kubernetes_attributes: {
api_url: kubernetes_service.api_url,
ca_cert: kubernetes_service.ca_pem,
@@ -98,6 +103,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati
encrypted_password_iv: nil, # KubernetesService doesn't have
token: kubernetes_service.token # encrypted_token and encrypted_token_iv
} )
+ end
# Disable the KubernetesService. Platforms::Kubernetes will be used from next time.
kubernetes_service.active = false
diff --git a/spec/migrations/migrate_kubernetes_service_to_new_clusters_architectures_spec.rb b/spec/migrations/migrate_kubernetes_service_to_new_clusters_architectures_spec.rb
index bf41b2df359..5ce1c43d92a 100644
--- a/spec/migrations/migrate_kubernetes_service_to_new_clusters_architectures_spec.rb
+++ b/spec/migrations/migrate_kubernetes_service_to_new_clusters_architectures_spec.rb
@@ -91,7 +91,7 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
end
end
- context 'when synced KubernetesService exists' do
+ context 'when managed KubernetesService exists' do
let(:project) { create(:project) }
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let!(:platform_kubernetes) { cluster.platform_kubernetes }
@@ -105,15 +105,16 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
ca_pem: platform_kubernetes.ca_cert)
end
- it 'does not migrate the KubernetesService' do # Because the corresponding Platform::Kubernetes already exists
+ it 'does not migrate the KubernetesService and disables the kubernetes_service' do # Because the corresponding Platform::Kubernetes already exists
expect{ migrate! }.not_to change { Clusters::Cluster.count }
- expect(kubernetes_service).to be_active
- expect(kubernetes_service.properties['migrated']).to be_falsy
+ kubernetes_service.reload
+ expect(kubernetes_service).not_to be_active
+ expect(kubernetes_service.properties['migrated']).to be_truthy
end
end
- context 'when production cluster has already been existsed' do
+ context 'when production cluster has already been existed' do # i.e. There are no environment_scope conflicts
let(:project) { create(:project) }
let!(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: 'production/*', projects: [project]) }
let!(:kubernetes_service) { create(:kubernetes_service, api_url: 'https://debug.kube.com', active: true, project: project) }
@@ -123,6 +124,7 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
kubernetes_service.reload
project.clusters.last.tap do |cluster|
+ expect(cluster.environment_scope).to eq('*')
expect(cluster.platform_kubernetes.api_url).to eq(kubernetes_service.api_url)
expect(cluster.platform_kubernetes.ca_pem).to eq(kubernetes_service.ca_pem)
expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token)
@@ -132,16 +134,44 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
end
end
- context 'when default cluster has already been existsed' do
+ context 'when default cluster has already been existed' do
let(:project) { create(:project) }
let!(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: '*', projects: [project]) }
let!(:kubernetes_service) { create(:kubernetes_service, api_url: 'https://debug.kube.com', active: true, project: project) }
- it 'does not migrate the KubernetesService' do # Because environment_scope is duplicated
- expect{ migrate! }.not_to change { Clusters::Cluster.count }
+ it 'migrates the KubernetesService to Platform::Kubernetes with dedicated environment_scope' do # Because environment_scope is duplicated
+ expect{ migrate! }.to change { Clusters::Cluster.count }.by(1)
+
+ kubernetes_service.reload
+ project.clusters.last.tap do |cluster|
+ expect(cluster.environment_scope).to eq('migrated/*')
+ expect(cluster.platform_kubernetes.api_url).to eq(kubernetes_service.api_url)
+ expect(cluster.platform_kubernetes.ca_pem).to eq(kubernetes_service.ca_pem)
+ expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token)
+ expect(kubernetes_service).not_to be_active
+ expect(kubernetes_service.properties['migrated']).to be_truthy
+ end
+ end
+ end
- expect(kubernetes_service).to be_active
- expect(kubernetes_service.properties['migrated']).to be_falsy
+ context 'when default cluster and migrated cluster has already been existed' do
+ let(:project) { create(:project) }
+ let!(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: '*', projects: [project]) }
+ let!(:migrated_cluster) { create(:cluster, :provided_by_gcp, environment_scope: 'migrated/*', projects: [project]) }
+ let!(:kubernetes_service) { create(:kubernetes_service, api_url: 'https://debug.kube.com', active: true, project: project) }
+
+ it 'migrates the KubernetesService to Platform::Kubernetes with dedicated environment_scope' do # Because environment_scope is duplicated
+ expect{ migrate! }.to change { Clusters::Cluster.count }.by(1)
+
+ kubernetes_service.reload
+ project.clusters.last.tap do |cluster|
+ expect(cluster.environment_scope).to eq('migrated0/*')
+ expect(cluster.platform_kubernetes.api_url).to eq(kubernetes_service.api_url)
+ expect(cluster.platform_kubernetes.ca_pem).to eq(kubernetes_service.ca_pem)
+ expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token)
+ expect(kubernetes_service).not_to be_active
+ expect(kubernetes_service.properties['migrated']).to be_truthy
+ end
end
end