diff options
author | Shinya Maeda <shinya@gitlab.com> | 2018-01-08 16:17:35 +0900 |
---|---|---|
committer | Shinya Maeda <shinya@gitlab.com> | 2018-01-08 16:22:18 +0900 |
commit | df658c7b1337afc71d9f3d66d3e8ad55db26b523 (patch) | |
tree | ade962d930f55372f83f0edb95ea7fe94cd4d282 | |
parent | 58d074e0013fb6123a084275edd14bb52955c21e (diff) | |
download | gitlab-ce-df658c7b1337afc71d9f3d66d3e8ad55db26b523.tar.gz |
Disable STI of ActiveRecord. Refactoring specs.
-rw-r--r-- | db/post_migrate/20171124104327_migrate_kubernetes_service_to_new_clusters_architectures.rb | 22 | ||||
-rw-r--r-- | spec/migrations/migrate_kubernetes_service_to_new_clusters_architectures_spec.rb | 228 |
2 files changed, 184 insertions, 66 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 0445044cc3c..3fe0a4941d5 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 @@ -12,6 +12,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati has_many :cluster_projects, class_name: 'MigrateKubernetesServiceToNewClustersArchitectures::ClustersProject' has_many :clusters, through: :cluster_projects, class_name: 'MigrateKubernetesServiceToNewClustersArchitectures::Cluster' has_many :services, class_name: 'MigrateKubernetesServiceToNewClustersArchitectures::Service' + has_one :kubernetes_service, -> { where(category: 'deployment', type: 'KubernetesService') }, class_name: 'MigrateKubernetesServiceToNewClustersArchitectures::Service', inverse_of: :project, foreign_key: :project_id end class Cluster < ActiveRecord::Base @@ -55,8 +56,9 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati include EachBatch self.table_name = 'services' + self.inheritance_column = :_type_disabled # Disable STI, otherwise KubernetesModel will be looked up - belongs_to :project, class_name: 'MigrateKubernetesServiceToNewClustersArchitectures::Project' + belongs_to :project, class_name: 'MigrateKubernetesServiceToNewClustersArchitectures::Project', foreign_key: :project_id scope :unmanaged_kubernetes_service, -> do joins('LEFT JOIN projects ON projects.id = services.project_id') @@ -72,6 +74,22 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati scope :kubernetes_service_without_template, -> do where(category: 'deployment', type: 'KubernetesService', template: false) end + + def api_url + JSON.parse(self.properties)['api_url'] + end + + def ca_pem + JSON.parse(self.properties)['ca_pem'] + end + + def namespace + JSON.parse(self.properties)['namespace'] + end + + def token + JSON.parse(self.properties)['token'] + end end def find_dedicated_environement_scope(project) @@ -101,7 +119,7 @@ class MigrateKubernetesServiceToNewClustersArchitectures < ActiveRecord::Migrati name: DEFAULT_KUBERNETES_SERVICE_CLUSTER_NAME, provider_type: MigrateKubernetesServiceToNewClustersArchitectures::Cluster.provider_types[:user], platform_type: MigrateKubernetesServiceToNewClustersArchitectures::Cluster.platform_types[:kubernetes], - projects: [kubernetes_service.project.becomes(MigrateKubernetesServiceToNewClustersArchitectures::Project)], + projects: [kubernetes_service.project], environment_scope: find_dedicated_environement_scope(kubernetes_service.project), platform_kubernetes_attributes: { api_url: kubernetes_service.api_url, 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 85ed1328211..54ae4c97d4e 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 @@ -5,27 +5,32 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do context 'when unique KubernetesService exists' do shared_examples 'KubernetesService migration' do let(:sample_num) { 2 } - let(:projects) { create_list(:project, sample_num) } + + let(:projects) do + (1..sample_num).each_with_object([]) do |n, array| + array << MigrateKubernetesServiceToNewClustersArchitectures::Project.create! + end + end let!(:kubernetes_services) do projects.map do |project| - create(:kubernetes_service, - project: project, - active: active, - api_url: "https://kubernetes#{project.id}.com", - token: defined?(token) ? token : "token#{project.id}", - ca_pem: "ca_pem#{project.id}") + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + project: project, + active: active, + category: 'deployment', + type: 'KubernetesService', + properties: "{\"namespace\":\"prod\",\"api_url\":\"https://kubernetes#{project.id}.com\",\"ca_pem\":\"ca_pem#{project.id}\",\"token\":\"token#{project.id}\"}") end end it 'migrates the KubernetesService to Platform::Kubernetes' do - expect { migrate! }.to change { Clusters::Cluster.count }.by(sample_num) + expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(sample_num) projects.each do |project| project.clusters.last.tap do |cluster| expect(cluster.enabled).to eq(active) expect(cluster.platform_kubernetes.api_url).to eq(project.kubernetes_service.api_url) - expect(cluster.platform_kubernetes.ca_pem).to eq(project.kubernetes_service.ca_pem) + expect(cluster.platform_kubernetes.ca_cert).to eq(project.kubernetes_service.ca_pem) expect(cluster.platform_kubernetes.token).to eq(project.kubernetes_service.token) expect(project.kubernetes_service).not_to be_active end @@ -42,34 +47,38 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do context 'when unique KubernetesService spawned from Service Template' do let(:sample_num) { 2 } - let(:projects) { create_list(:project, sample_num) } + + let(:projects) do + (1..sample_num).each_with_object([]) do |n, array| + array << MigrateKubernetesServiceToNewClustersArchitectures::Project.create! + end + end let!(:kubernetes_service_template) do - create(:kubernetes_service, - project: nil, - template: true, - api_url: "https://sample.kubernetes.com", - token: "token-sample", - ca_pem: "ca_pem-sample") + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + template: true, + category: 'deployment', + type: 'KubernetesService', + properties: "{\"namespace\":\"prod\",\"api_url\":\"https://sample.kubernetes.com\",\"ca_pem\":\"ca_pem-sample\",\"token\":\"token-sample\"}") end let!(:kubernetes_services) do projects.map do |project| - create(:kubernetes_service, - project: project, - api_url: kubernetes_service_template.api_url, - token: kubernetes_service_template.token, - ca_pem: kubernetes_service_template.ca_pem) + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + project: project, + category: 'deployment', + type: 'KubernetesService', + properties: "{\"namespace\":\"prod\",\"api_url\":\"#{kubernetes_service_template.api_url}\",\"ca_pem\":\"#{kubernetes_service_template.ca_pem}\",\"token\":\"#{kubernetes_service_template.token}\"}") end end it 'migrates the KubernetesService to Platform::Kubernetes without template' do - expect { migrate! }.to change { Clusters::Cluster.count }.by(sample_num) + expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(sample_num) projects.each do |project| project.clusters.last.tap do |cluster| expect(cluster.platform_kubernetes.api_url).to eq(project.kubernetes_service.api_url) - expect(cluster.platform_kubernetes.ca_pem).to eq(project.kubernetes_service.ca_pem) + expect(cluster.platform_kubernetes.ca_cert).to eq(project.kubernetes_service.ca_pem) expect(cluster.platform_kubernetes.token).to eq(project.kubernetes_service.token) expect(project.kubernetes_service).not_to be_active end @@ -78,21 +87,32 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do end 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 } + let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! } + + let(:cluster) do + MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!( + projects: [project], + name: 'sample-cluster', + platform_type: :kubernetes, + provider_type: :user, + platform_kubernetes_attributes: { + api_url: 'https://sample.kubernetes.com', + ca_cert: 'ca_pem-sample', + token: 'token-sample' + } ) + end let!(:kubernetes_service) do - create(:kubernetes_service, - project: project, - active: cluster.enabled, - api_url: platform_kubernetes.api_url, - token: platform_kubernetes.token, - ca_pem: platform_kubernetes.ca_cert) + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + project: project, + active: cluster.enabled, + category: 'deployment', + type: 'KubernetesService', + properties: "{\"api_url\":\"#{cluster.platform_kubernetes.api_url}\"}") end 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 { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count } kubernetes_service.reload expect(kubernetes_service).not_to be_active @@ -100,18 +120,39 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do end 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) } + let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! } + + let(:cluster) do + MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!( + projects: [project], + name: 'sample-cluster', + platform_type: :kubernetes, + provider_type: :user, + environment_scope: 'production/*', + platform_kubernetes_attributes: { + api_url: 'https://sample.kubernetes.com', + ca_cert: 'ca_pem-sample', + token: 'token-sample' + } ) + end + + let!(:kubernetes_service) do + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + project: project, + active: true, + category: 'deployment', + type: 'KubernetesService', + properties: "{\"api_url\":\"https://debug.kube.com\"}") + end it 'migrates the KubernetesService to Platform::Kubernetes' do - expect { migrate! }.to change { Clusters::Cluster.count }.by(1) + expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(1) 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.ca_cert).to eq(kubernetes_service.ca_pem) expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token) expect(kubernetes_service).not_to be_active end @@ -119,18 +160,39 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do end 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) } + let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! } + + let!(:cluster) do + MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!( + projects: [project], + name: 'sample-cluster', + platform_type: :kubernetes, + provider_type: :user, + environment_scope: '*', + platform_kubernetes_attributes: { + api_url: 'https://sample.kubernetes.com', + ca_cert: 'ca_pem-sample', + token: 'token-sample' + } ) + end + + let!(:kubernetes_service) do + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + project: project, + active: true, + category: 'deployment', + type: 'KubernetesService', + properties: "{\"api_url\":\"https://debug.kube.com\"}") + end 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 { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::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.ca_cert).to eq(kubernetes_service.ca_pem) expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token) expect(kubernetes_service).not_to be_active end @@ -138,19 +200,53 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do 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) } + let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! } + + let!(:cluster) do + MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!( + projects: [project], + name: 'sample-cluster', + platform_type: :kubernetes, + provider_type: :user, + environment_scope: '*', + platform_kubernetes_attributes: { + api_url: 'https://sample.kubernetes.com', + ca_cert: 'ca_pem-sample', + token: 'token-sample' + } ) + end + + let!(:migrated_cluster) do + MigrateKubernetesServiceToNewClustersArchitectures::Cluster.create!( + projects: [project], + name: 'sample-cluster', + platform_type: :kubernetes, + provider_type: :user, + environment_scope: 'migrated/*', + platform_kubernetes_attributes: { + api_url: 'https://sample.kubernetes.com', + ca_cert: 'ca_pem-sample', + token: 'token-sample' + } ) + end + + let!(:kubernetes_service) do + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + project: project, + active: true, + category: 'deployment', + type: 'KubernetesService', + properties: "{\"api_url\":\"https://debug.kube.com\"}") + end 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 { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::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.ca_cert).to eq(kubernetes_service.ca_pem) expect(cluster.platform_kubernetes.token).to eq(kubernetes_service.token) expect(kubernetes_service).not_to be_active end @@ -158,17 +254,19 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do end context 'when KubernetesService has nullified parameters' do - let(:project) { create(:project) } + let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! } before do - ActiveRecord::Base.connection.execute <<~SQL - INSERT INTO services (project_id, active, category, type, properties) - VALUES (#{project.id}, false, 'deployment', 'KubernetesService', '{}'); - SQL + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + project: project, + active: false, + category: 'deployment', + type: 'KubernetesService', + properties: "{}") end it 'does not migrate the KubernetesService and disables the kubernetes_service' do - expect { migrate! }.not_to change { Clusters::Cluster.count } + expect { migrate! }.not_to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count } expect(project.kubernetes_service).not_to be_active end @@ -179,23 +277,25 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do # However, in this migration file, there are no validations because of the re-defined model class # therefore, we should safely add this raw to Platform::Kubernetes context 'when KubernetesService has empty token' do - let(:project) { create(:project) } + let(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! } before do - ActiveRecord::Base.connection.execute <<~SQL - INSERT INTO services (project_id, active, category, type, properties) - VALUES (#{project.id}, false, 'deployment', 'KubernetesService', '{"namespace":"prod","api_url":"http://111.111.111.111","ca_pem":"a","token":""}'); - SQL + MigrateKubernetesServiceToNewClustersArchitectures::Service.create!( + project: project, + active: false, + category: 'deployment', + type: 'KubernetesService', + properties: "{\"namespace\":\"prod\",\"api_url\":\"http://111.111.111.111\",\"ca_pem\":\"a\",\"token\":\"\"}") end it 'does not migrate the KubernetesService and disables the kubernetes_service' do - expect { migrate! }.to change { Clusters::Cluster.count }.by(1) + expect { migrate! }.to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count }.by(1) project.clusters.last.tap do |cluster| expect(cluster.environment_scope).to eq('*') expect(cluster.platform_kubernetes.namespace).to eq('prod') expect(cluster.platform_kubernetes.api_url).to eq('http://111.111.111.111') - expect(cluster.platform_kubernetes.ca_pem).to eq('a') + expect(cluster.platform_kubernetes.ca_cert).to eq('a') expect(cluster.platform_kubernetes.token).to be_empty expect(project.kubernetes_service).not_to be_active end @@ -203,10 +303,10 @@ describe MigrateKubernetesServiceToNewClustersArchitectures, :migration do end context 'when KubernetesService does not exist' do - let!(:project) { create(:project) } + let!(:project) { MigrateKubernetesServiceToNewClustersArchitectures::Project.create! } it 'does not migrate the KubernetesService' do - expect { migrate! }.not_to change { Clusters::Cluster.count } + expect { migrate! }.not_to change { MigrateKubernetesServiceToNewClustersArchitectures::Cluster.count } end end end |