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
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2017-11-23 17:28:08 +0300
committerShinya Maeda <shinya@gitlab.com>2017-11-23 19:56:35 +0300
commit7caa62e050049f774b3e282376b00cd438994e58 (patch)
treecf6d71d18ebcc21d4caa5668d09624dbf5ab204a
parent038f5a412d0085f2d9610c77cea37cec75572b27 (diff)
Follow up cluster_id recovery for Platform::Kubernetes
-rw-r--r--db/migrate/20171123104051_fix_cluster_platforms_kubernetes_association_mismatch.rb55
-rw-r--r--spec/migrations/fix_cluster_platforms_kubernetes_association_mismatch_spec.rb98
2 files changed, 153 insertions, 0 deletions
diff --git a/db/migrate/20171123104051_fix_cluster_platforms_kubernetes_association_mismatch.rb b/db/migrate/20171123104051_fix_cluster_platforms_kubernetes_association_mismatch.rb
new file mode 100644
index 00000000000..01bafaa4539
--- /dev/null
+++ b/db/migrate/20171123104051_fix_cluster_platforms_kubernetes_association_mismatch.rb
@@ -0,0 +1,55 @@
+class FixClusterPlatformsKubernetesAssociationMismatch < ActiveRecord::Migration
+ DOWNTIME = false
+
+ class GcpCluster < ActiveRecord::Base
+ self.table_name = 'gcp_clusters'
+
+ belongs_to :project, class_name: 'Project'
+ end
+
+ class Cluster < ActiveRecord::Base
+ self.table_name = 'clusters'
+
+ has_one :provider_gcp, class_name: 'ProvidersGcp'
+ has_one :platform_kubernetes, class_name: 'PlatformsKubernetes'
+ end
+
+ class ProvidersGcp < ActiveRecord::Base
+ self.table_name = 'cluster_providers_gcp'
+ end
+
+ class PlatformsKubernetes < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'cluster_platforms_kubernetes'
+ end
+
+ def up
+ PlatformsKubernetes.all.find_each(batch_size: 1) do |platforms_kubernetes|
+ # This is the culprit. See https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/15566
+ gcp_cluster = GcpCluster.find_by_id(platforms_kubernetes.cluster_id)
+
+ provider_gcp = ProvidersGcp.join(:clusters)
+ .where(gcp_project_id: gcp_cluster.gcp_project_id,
+ zone: gcp_cluster.gcp_cluster_zone,
+ num_nodes: gcp_cluster.gcp_cluster_size,
+ machine_type: gcp_cluster.gcp_machine_type,
+ endpoint: gcp_cluster.endpoint,
+ "clusters.name": gcp_cluster.gcp_cluster_name)
+
+ next unless provider_gcp.count == 1
+
+ correct_cluster_id = provider_gcp.first.cluster_id
+
+ unless correct_cluster_id == platforms_kubernetes.cluster_id
+ say 'Association mismatch detected'
+
+ platforms_kubernetes.update(cluster_id: correct_cluster_id)
+ end
+ end
+ end
+
+ def down
+ # noop
+ end
+end
diff --git a/spec/migrations/fix_cluster_platforms_kubernetes_association_mismatch_spec.rb b/spec/migrations/fix_cluster_platforms_kubernetes_association_mismatch_spec.rb
new file mode 100644
index 00000000000..15a9a8e2591
--- /dev/null
+++ b/spec/migrations/fix_cluster_platforms_kubernetes_association_mismatch_spec.rb
@@ -0,0 +1,98 @@
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20171123104051_fix_cluster_platforms_kubernetes_association_mismatch.rb')
+
+##
+# See more details at https://gitlab.com/gitlab-org/gitlab-ce/issues/40478
+#
+describe FixClusterPlatformsKubernetesAssociationMismatch, :migration do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ shared_examples 'expected behavior' do
+ it 'has correct association' do
+ migrate!
+
+ Cluster.all.each do |cluster|
+ expect(cluster.platform_kubernetes.api_url).to eq(api_url(cluster.provider_gcp.endpoint))
+ end
+ end
+ end
+
+ context 'when user did not create a cluster before post migration has done' do
+ before do
+ prepare
+ end
+
+ it_behaves_like 'expected behavior'
+ end
+
+ context 'when user created a cluster before post migration has done' do
+ before do
+ prepare
+ culprit
+ end
+
+ it_behaves_like 'expected behavior'
+ end
+
+ def prepare
+ create_test_data
+ migrate_gcp_clusters_to_new_clusters_architectures!
+ end
+
+ def migrate_gcp_clusters_to_new_clusters_architectures!
+ ActiveRecord::Migrator.up(migrations_paths) do |migration|
+ migration.name == 'MigrateGcpClustersToNewClustersArchitectures'
+ end
+ end
+
+ def create_test_data
+ (1..5).each do |i|
+ project = create(:project)
+ user = create(:user)
+ service = create(:kubernetes_service, project: project)
+
+ # Params
+ project_id = create(:project).id
+ user_id = create(:user).id
+ service_id = service.id
+ status = 3 # created
+ gcp_cluster_size = 1
+ created_at = "'2017-10-17 20:24:02'"
+ updated_at = "'2017-10-17 20:28:44'"
+ enabled = true
+ status_reason = "'NULL'"
+ project_namespace = "'sample-app-#{i}'"
+ endpoint = "'111.111.111.#{i}'"
+ ca_cert = "'ca_cert-#{i}'"
+ encrypted_kubernetes_token = "'NULL'"
+ encrypted_kubernetes_token_iv = "'NULL'"
+ username = "'username-#{i}'"
+ encrypted_password = "'encrypted_password-#{i}'"
+ encrypted_password_iv = "'encrypted_password_iv-#{i}'"
+ gcp_project_id = "'gcp_project_id-#{i}'"
+ gcp_cluster_zone = "'gcp_cluster_zone-#{i}'"
+ gcp_cluster_name = "'gcp_cluster_name-#{i}'"
+ gcp_machine_type = "'gcp_machine_type-#{i}'"
+ gcp_operation_id = "'gcp_operation_id-#{i}'"
+ encrypted_gcp_token = "'encrypted_gcp_token-#{i}'"
+ encrypted_gcp_token_iv = "'encrypted_gcp_token_iv-#{i}'"
+
+ ActiveRecord::Base.connection.execute <<-SQL
+ INSERT INTO gcp_clusters (project_id, user_id, service_id, status, gcp_cluster_size, created_at, updated_at, enabled, status_reason, project_namespace, endpoint, ca_cert, encrypted_kubernetes_token, encrypted_kubernetes_token_iv, username, encrypted_password, encrypted_password_iv, gcp_project_id, gcp_cluster_zone, gcp_cluster_name, gcp_machine_type, gcp_operation_id, encrypted_gcp_token, encrypted_gcp_token_iv)
+ VALUES (#{project_id}, #{user_id}, #{service_id}, #{status}, #{gcp_cluster_size}, #{created_at}, #{updated_at}, #{enabled}, #{status_reason}, #{project_namespace}, #{endpoint}, #{ca_cert}, #{encrypted_kubernetes_token}, #{encrypted_kubernetes_token_iv}, #{username}, #{encrypted_password}, #{encrypted_password_iv}, #{gcp_project_id}, #{gcp_cluster_zone}, #{gcp_cluster_name}, #{gcp_machine_type}, #{gcp_operation_id}, #{encrypted_gcp_token}, #{encrypted_gcp_token_iv});
+ SQL
+ end
+ end
+
+ def culprit
+ (1..5).each do |i|
+ cluster = Cluster.find_by_id(i)
+ cluster.platform_kubernetes.update!(cluster_id: (i % 5) + 1)
+ end
+ end
+
+ def api_url(endpoint)
+ endpoint ? 'https://' + endpoint : nil
+ end
+end