Commit f083739e authored by Shinya Maeda's avatar Shinya Maeda

Add logic to swtich environment_scope by the situation

parent 7eeada80
...@@ -51,36 +51,41 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati ...@@ -51,36 +51,41 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati
belongs_to :project, class_name: 'Project' belongs_to :project, class_name: 'Project'
# 10.1 ~ 10.2 scope :kubernetes_service, -> do
# 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
where("services.category = 'deployment'") where("services.category = 'deployment'")
.where("services.type = 'KubernetesService'") .where("services.type = 'KubernetesService'")
.where("services.template = FALSE") .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') .order('services.project_id')
end end
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 def up
Service.unmanaged_kubernetes_service Service.kubernetes_service.find_each(batch_size: 1) do |kubernetes_service|
.find_each(batch_size: 1) do |kubernetes_service| unless managed_by_clusters?(kubernetes_service)
Cluster.create( Cluster.create(
enabled: kubernetes_service.active, enabled: kubernetes_service.active,
user_id: nil, # KubernetesService doesn't have user_id: nil, # KubernetesService doesn't have
...@@ -88,7 +93,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati ...@@ -88,7 +93,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati
provider_type: Cluster.provider_types[:user], provider_type: Cluster.provider_types[:user],
platform_type: Cluster.platform_types[:kubernetes], platform_type: Cluster.platform_types[:kubernetes],
projects: [kubernetes_service.project], 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: { platform_kubernetes_attributes: {
api_url: kubernetes_service.api_url, api_url: kubernetes_service.api_url,
ca_cert: kubernetes_service.ca_pem, ca_cert: kubernetes_service.ca_pem,
...@@ -98,6 +103,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati ...@@ -98,6 +103,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati
encrypted_password_iv: nil, # KubernetesService doesn't have encrypted_password_iv: nil, # KubernetesService doesn't have
token: kubernetes_service.token # encrypted_token and encrypted_token_iv token: kubernetes_service.token # encrypted_token and encrypted_token_iv
} ) } )
end
# Disable the KubernetesService. Platforms::Kubernetes will be used from next time. # Disable the KubernetesService. Platforms::Kubernetes will be used from next time.
kubernetes_service.active = false kubernetes_service.active = false
......
...@@ -91,7 +91,7 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do ...@@ -91,7 +91,7 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
end end
end end
context 'when synced KubernetesService exists' do context 'when managed KubernetesService exists' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let!(:platform_kubernetes) { cluster.platform_kubernetes } let!(:platform_kubernetes) { cluster.platform_kubernetes }
...@@ -105,15 +105,16 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do ...@@ -105,15 +105,16 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
ca_pem: platform_kubernetes.ca_cert) ca_pem: platform_kubernetes.ca_cert)
end 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{ migrate! }.not_to change { Clusters::Cluster.count }
expect(kubernetes_service).to be_active kubernetes_service.reload
expect(kubernetes_service.properties['migrated']).to be_falsy expect(kubernetes_service).not_to be_active
expect(kubernetes_service.properties['migrated']).to be_truthy
end end
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(:project) { create(:project) }
let!(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: 'production/*', projects: [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) } let!(:kubernetes_service) { create(:kubernetes_service, api_url: 'https://debug.kube.com', active: true, project: project) }
...@@ -123,6 +124,7 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do ...@@ -123,6 +124,7 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
kubernetes_service.reload kubernetes_service.reload
project.clusters.last.tap do |cluster| 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.api_url).to eq(kubernetes_service.api_url)
expect(cluster.platform_kubernetes.ca_pem).to eq(kubernetes_service.ca_pem) expect(cluster.platform_kubernetes.ca_pem).to eq(kubernetes_service.ca_pem)
expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token) expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token)
...@@ -132,16 +134,44 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do ...@@ -132,16 +134,44 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do
end end
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(:project) { create(:project) }
let!(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: '*', projects: [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) } 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 it 'migrates the KubernetesService to Platform::Kubernetes with dedicated environment_scope' do # Because environment_scope is duplicated
expect{ migrate! }.not_to change { Clusters::Cluster.count } 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
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)
expect(kubernetes_service).to be_active kubernetes_service.reload
expect(kubernetes_service.properties['migrated']).to be_falsy 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
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