From 93e9793ce38bb9b5d519f5ca86cb56201549ef19 Mon Sep 17 00:00:00 2001 From: Mayra Cabrera Date: Thu, 4 Jan 2018 22:35:41 +0000 Subject: [PATCH] Create Kubernetes based on Application Templates --- app/models/concerns/deployment_platform.rb | 47 ++++++++++++ app/models/project.rb | 7 +- app/models/service.rb | 5 ++ ...netes-integration-application-template.yml | 5 ++ .../import_export/export_file_spec.rb | 2 +- .../concerns/deployment_platform_spec.rb | 73 +++++++++++++++++++ spec/models/project_spec.rb | 19 ----- spec/models/service_spec.rb | 8 ++ 8 files changed, 140 insertions(+), 26 deletions(-) create mode 100644 app/models/concerns/deployment_platform.rb create mode 100644 changelogs/unreleased/41056-create-cluster-from-kubernetes-integration-application-template.yml create mode 100644 spec/models/concerns/deployment_platform_spec.rb diff --git a/app/models/concerns/deployment_platform.rb b/app/models/concerns/deployment_platform.rb new file mode 100644 index 00000000000..e1373455e98 --- /dev/null +++ b/app/models/concerns/deployment_platform.rb @@ -0,0 +1,47 @@ +module DeploymentPlatform + def deployment_platform + @deployment_platform ||= find_cluster_platform_kubernetes + @deployment_platform ||= find_kubernetes_service_integration + @deployment_platform ||= build_cluster_and_deployment_platform + end + + private + + def find_cluster_platform_kubernetes + clusters.find_by(enabled: true)&.platform_kubernetes + end + + def find_kubernetes_service_integration + services.deployment.reorder(nil).find_by(active: true) + end + + def build_cluster_and_deployment_platform + return unless kubernetes_service_template + + cluster = ::Clusters::Cluster.create(cluster_attributes_from_service_template) + cluster.platform_kubernetes if cluster.persisted? + end + + def kubernetes_service_template + @kubernetes_service_template ||= KubernetesService.active.find_by_template + end + + def cluster_attributes_from_service_template + { + name: 'kubernetes-template', + projects: [self], + provider_type: :user, + platform_type: :kubernetes, + platform_kubernetes_attributes: platform_kubernetes_attributes_from_service_template + } + end + + def platform_kubernetes_attributes_from_service_template + { + api_url: kubernetes_service_template.api_url, + ca_pem: kubernetes_service_template.ca_pem, + token: kubernetes_service_template.token, + namespace: kubernetes_service_template.namespace + } + end +end diff --git a/app/models/project.rb b/app/models/project.rb index 9c0bbf697e2..5d6c1b30587 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -19,6 +19,7 @@ class Project < ActiveRecord::Base include Routable include GroupDescendant include Gitlab::SQL::Pattern + include DeploymentPlatform extend Gitlab::ConfigHelper extend Gitlab::CurrentSettings @@ -904,12 +905,6 @@ class Project < ActiveRecord::Base @ci_service ||= ci_services.reorder(nil).find_by(active: true) end - # TODO: This will be extended for multiple enviroment clusters - def deployment_platform - @deployment_platform ||= clusters.find_by(enabled: true)&.platform_kubernetes - @deployment_platform ||= services.where(category: :deployment).reorder(nil).find_by(active: true) - end - def monitoring_services services.where(category: :monitoring) end diff --git a/app/models/service.rb b/app/models/service.rb index 176b472e724..24ba3039707 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -44,6 +44,7 @@ class Service < ActiveRecord::Base scope :pipeline_hooks, -> { where(pipeline_events: true, active: true) } scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) } scope :external_issue_trackers, -> { issue_trackers.active.without_defaults } + scope :deployment, -> { where(category: 'deployment') } default_value_for :category, 'common' @@ -271,6 +272,10 @@ class Service < ActiveRecord::Base nil end + def self.find_by_template + find_by(template: true) + end + private def cache_project_has_external_issue_tracker diff --git a/changelogs/unreleased/41056-create-cluster-from-kubernetes-integration-application-template.yml b/changelogs/unreleased/41056-create-cluster-from-kubernetes-integration-application-template.yml new file mode 100644 index 00000000000..2dd6fc5f1b5 --- /dev/null +++ b/changelogs/unreleased/41056-create-cluster-from-kubernetes-integration-application-template.yml @@ -0,0 +1,5 @@ +--- +title: Allow automatic creation of Kubernetes Integration from template +merge_request: 16104 +author: +type: added diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index 461aa39d0ad..6732cf61767 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' # Integration test that exports a file using the Import/Export feature # It looks up for any sensitive word inside the JSON, so if a sensitive word is found -# we''l have to either include it adding the model that includes it to the +safe_list+ +# we'll have to either include it adding the model that includes it to the +safe_list+ # or make sure the attribute is blacklisted in the +import_export.yml+ configuration feature 'Import/Export - project export integration test', :js do include Select2Helper diff --git a/spec/models/concerns/deployment_platform_spec.rb b/spec/models/concerns/deployment_platform_spec.rb new file mode 100644 index 00000000000..7bb89fe41dc --- /dev/null +++ b/spec/models/concerns/deployment_platform_spec.rb @@ -0,0 +1,73 @@ +require 'rails_helper' + +describe DeploymentPlatform do + let(:project) { create(:project) } + + describe '#deployment_platform' do + subject { project.deployment_platform } + + context 'with no Kubernetes configuration on CI/CD, no Kubernetes Service and a Kubernetes template configured' do + let!(:kubernetes_service) { create(:kubernetes_service, template: true) } + + it 'returns a platform kubernetes' do + expect(subject).to be_a_kind_of(Clusters::Platforms::Kubernetes) + end + + it 'creates a cluster and a platform kubernetes' do + expect { subject } + .to change { Clusters::Cluster.count }.by(1) + .and change { Clusters::Platforms::Kubernetes.count }.by(1) + end + + it 'includes appropriate attributes for Cluster' do + cluster = subject.cluster + expect(cluster.name).to eq('kubernetes-template') + expect(cluster.project).to eq(project) + expect(cluster.provider_type).to eq('user') + expect(cluster.platform_type).to eq('kubernetes') + end + + it 'creates a platform kubernetes' do + expect { subject }.to change { Clusters::Platforms::Kubernetes.count }.by(1) + end + + it 'copies attributes from Clusters::Platform::Kubernetes template into the new Cluster::Platforms::Kubernetes' do + expect(subject.api_url).to eq(kubernetes_service.api_url) + expect(subject.ca_pem).to eq(kubernetes_service.ca_pem) + expect(subject.token).to eq(kubernetes_service.token) + expect(subject.namespace).to eq(kubernetes_service.namespace) + end + end + + context 'with no Kubernetes configuration on CI/CD, no Kubernetes Service and no Kubernetes template configured' do + it { is_expected.to be_nil } + end + + context 'when user configured kubernetes from CI/CD > Clusters' do + let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } + let(:platform_kubernetes) { cluster.platform_kubernetes } + + it 'returns the Kubernetes platform' do + expect(subject).to eq(platform_kubernetes) + end + end + + context 'when user configured kubernetes integration from project services' do + let!(:kubernetes_service) { create(:kubernetes_service, project: project) } + + it 'returns the Kubernetes service' do + expect(subject).to eq(kubernetes_service) + end + end + + context 'when the cluster creation fails' do + let!(:kubernetes_service) { create(:kubernetes_service, template: true) } + + before do + allow_any_instance_of(Clusters::Cluster).to receive(:persisted?).and_return(false) + end + + it { is_expected.to be_nil } + end + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index cea22bbd184..3c2ed043b82 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -3137,25 +3137,6 @@ describe Project do end end - describe '#deployment_platform' do - subject { project.deployment_platform } - - let(:project) { create(:project) } - - context 'when user configured kubernetes from Integration > Kubernetes' do - let!(:kubernetes_service) { create(:kubernetes_service, project: project) } - - it { is_expected.to eq(kubernetes_service) } - end - - context 'when user configured kubernetes from CI/CD > Clusters' do - let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } - let(:platform_kubernetes) { cluster.platform_kubernetes } - - it { is_expected.to eq(platform_kubernetes) } - end - end - describe '#write_repository_config' do set(:project) { create(:project, :repository) } diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index 540615de117..ab6678cab38 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -272,4 +272,12 @@ describe Service do expect(service.deprecation_message).to be_nil end end + + describe '.find_by_template' do + let!(:kubernetes_service) { create(:kubernetes_service, template: true) } + + it 'returns service template' do + expect(KubernetesService.find_by_template).to eq(kubernetes_service) + end + end end