Commit f26884a0 authored by James Fargher's avatar James Fargher

Migrate Kubernetes service integration templates to clusters

The migration uses active record model stubs so that field encryption
can be more easily used.
parent 82ccc8bc
---
title: Migrate Kubernetes service integration templates to clusters
merge_request: 28534
author:
type: added
# frozen_string_literal: true
class MigrateK8sServiceIntegration < ActiveRecord::Migration[5.1]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
class Cluster < ActiveRecord::Base
self.table_name = 'clusters'
has_one :platform_kubernetes, class_name: 'MigrateK8sServiceIntegration::PlatformsKubernetes'
accepts_nested_attributes_for :platform_kubernetes
enum cluster_type: {
instance_type: 1,
group_type: 2,
project_type: 3
}
enum platform_type: {
kubernetes: 1
}
enum provider_type: {
user: 0,
gcp: 1
}
end
class PlatformsKubernetes < ActiveRecord::Base
self.table_name = 'cluster_platforms_kubernetes'
belongs_to :cluster, class_name: 'MigrateK8sServiceIntegration::Cluster'
attr_encrypted :token,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc'
end
class Service < ActiveRecord::Base
include EachBatch
self.table_name = 'services'
self.inheritance_column = :_type_disabled # Disable STI, otherwise KubernetesModel will be looked up
belongs_to :project, class_name: 'MigrateK8sServiceIntegration::Project', foreign_key: :project_id
scope :kubernetes_service_templates, -> do
where(category: 'deployment', type: 'KubernetesService', template: true)
end
def api_url
parsed_properties['api_url'].presence
end
def ca_pem
parsed_properties['ca_pem']
end
def namespace
parsed_properties['namespace'].presence
end
def token
parsed_properties['token'].presence
end
private
def parsed_properties
@parsed_properties ||= JSON.parse(self.properties)
end
end
def up
MigrateK8sServiceIntegration::Service.kubernetes_service_templates.find_each do |service|
next unless service.api_url && service.token
MigrateK8sServiceIntegration::Cluster.create!(
enabled: service.active,
managed: false,
name: 'KubernetesService',
cluster_type: 'instance_type',
provider_type: 'user',
platform_type: 'kubernetes',
platform_kubernetes_attributes: {
api_url: service.api_url,
ca_cert: service.ca_pem,
namespace: service.namespace,
token: service.token
}
)
end
end
def down
# It is not possible to tell which instance-level clusters were created by
# this migration. The original data is intentionally left intact.
end
end
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20190517153211_migrate_k8s_service_integration.rb')
describe MigrateK8sServiceIntegration, :migration do
context 'template service' do
context 'with namespace' do
let!(:service) do
MigrateK8sServiceIntegration::Service.create!(
active: true,
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(:cluster) { MigrateK8sServiceIntegration::Cluster.instance_type.last! }
let(:platform) { cluster.platform_kubernetes }
it 'migrates the KubernetesService template to Platform::Kubernetes' do
expect { migrate! }.to change { MigrateK8sServiceIntegration::Cluster.count }.by(1)
expect(cluster).to be_enabled
expect(cluster).to be_user
expect(cluster).not_to be_managed
expect(cluster.environment_scope).to eq('*')
expect(platform.api_url).to eq('https://sample.kubernetes.com')
expect(platform.ca_cert).to eq('ca_pem-sample')
expect(platform.namespace).to eq('prod')
expect(platform.token).to eq('token-sample')
end
end
context 'without namespace' do
let!(:service) do
MigrateK8sServiceIntegration::Service.create!(
active: true,
template: true,
category: 'deployment',
type: 'KubernetesService',
properties: "{\"namespace\":\"\",\"api_url\":\"https://sample.kubernetes.com\",\"ca_pem\":\"ca_pem-sample\",\"token\":\"token-sample\"}"
)
end
let(:cluster) { MigrateK8sServiceIntegration::Cluster.instance_type.last! }
let(:platform) { cluster.platform_kubernetes }
it 'migrates the KubernetesService template to Platform::Kubernetes' do
expect { migrate! }.to change { MigrateK8sServiceIntegration::Cluster.count }.by(1)
expect(cluster).to be_enabled
expect(cluster).to be_user
expect(cluster).not_to be_managed
expect(cluster.environment_scope).to eq('*')
expect(platform.api_url).to eq('https://sample.kubernetes.com')
expect(platform.ca_cert).to eq('ca_pem-sample')
expect(platform.namespace).to be_nil
expect(platform.token).to eq('token-sample')
end
end
context 'with nullified parameters' do
let!(:service) do
MigrateK8sServiceIntegration::Service.create!(
active: true,
template: true,
category: 'deployment',
type: 'KubernetesService',
properties: "{}"
)
end
it 'does not migrate the KubernetesService' do
expect { migrate! }.not_to change { MigrateK8sServiceIntegration::Cluster.count }
end
end
context 'when disabled' do
let!(:service) do
MigrateK8sServiceIntegration::Service.create!(
active: false,
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(:cluster) { MigrateK8sServiceIntegration::Cluster.instance_type.last! }
let(:platform) { cluster.platform_kubernetes }
it 'migrates the KubernetesService template to Platform::Kubernetes' do
expect { migrate! }.to change { MigrateK8sServiceIntegration::Cluster.count }.by(1)
expect(cluster).not_to be_enabled
expect(cluster).to be_user
expect(cluster).not_to be_managed
expect(cluster.environment_scope).to eq('*')
expect(platform.api_url).to eq('https://sample.kubernetes.com')
expect(platform.ca_cert).to eq('ca_pem-sample')
expect(platform.namespace).to eq('prod')
expect(platform.token).to eq('token-sample')
end
end
end
context 'non-template service' do
let!(:service) do
MigrateK8sServiceIntegration::Service.create!(
active: true,
template: false,
category: 'deployment',
type: 'KubernetesService',
properties: "{\"namespace\":\"prod\",\"api_url\":\"https://sample.kubernetes.com\",\"ca_pem\":\"ca_pem-sample\",\"token\":\"token-sample\"}"
)
end
it 'does not migrate the KubernetesService' do
expect { migrate! }.not_to change { MigrateK8sServiceIntegration::Cluster.count }
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