Commit 89b0bc04 authored by Tiger's avatar Tiger

Create one Kubernetes namespace for a deployment

Instead of creating a Kubernetes namespace on every
cluster related to a project, only create one on the
cluster the project is about to be deployed to.
parent 759dab5b
...@@ -78,6 +78,10 @@ class Deployment < ActiveRecord::Base ...@@ -78,6 +78,10 @@ class Deployment < ActiveRecord::Base
Commit.truncate_sha(sha) Commit.truncate_sha(sha)
end end
def cluster
project.deployment_platform(environment: environment.name)&.cluster
end
def last? def last?
self == environment.last_deployment self == environment.last_deployment
end end
......
...@@ -5,8 +5,6 @@ module Gitlab ...@@ -5,8 +5,6 @@ module Gitlab
module Build module Build
module Prerequisite module Prerequisite
class Base class Base
include Utils::StrongMemoize
attr_reader :build attr_reader :build
def initialize(build) def initialize(build)
......
...@@ -10,37 +10,29 @@ module Gitlab ...@@ -10,37 +10,29 @@ module Gitlab
# so we must always ensure the namespace is up to date. # so we must always ensure the namespace is up to date.
# #
def unmet? def unmet?
build.has_deployment? && clusters_missing_namespaces.present? deployment_cluster.present?
end end
def complete! def complete!
return unless unmet? return unless unmet?
clusters_missing_namespaces.each do |cluster| create_or_update_namespace
create_or_update_namespace(cluster)
end
end end
private private
def project def deployment_cluster
build.project build.deployment&.cluster
end end
def create_or_update_namespace(cluster) def create_or_update_namespace
kubernetes_namespace = cluster.find_or_initialize_kubernetes_namespace_for_project(project) kubernetes_namespace = deployment_cluster.find_or_initialize_kubernetes_namespace_for_project(build.project)
Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new( Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new(
cluster: cluster, cluster: deployment_cluster,
kubernetes_namespace: kubernetes_namespace kubernetes_namespace: kubernetes_namespace
).execute ).execute
end end
def clusters_missing_namespaces
strong_memoize(:clusters_missing_namespaces) do
project.all_clusters.missing_kubernetes_namespace(project.kubernetes_namespaces).to_a
end
end
end end
end end
end end
......
...@@ -16,34 +16,41 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do ...@@ -16,34 +16,41 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
context 'build has a deployment, and no existing kubernetes namespace' do context 'build has a deployment' do
let!(:deployment) { create(:deployment, deployable: build) } let!(:deployment) { create(:deployment, deployable: build) }
let!(:cluster) { create(:cluster, projects: [build.project]) }
context 'and a cluster to deploy to' do
let(:cluster) { create(:cluster, projects: [build.project]) }
before do before do
expect(build.project.kubernetes_namespaces).to be_empty allow(build.deployment).to receive(:cluster).and_return(cluster)
end end
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
end end
context 'build has a deployment and kubernetes namespaces' do context 'and no cluster to deploy to' do
let!(:deployment) { create(:deployment, deployable: build) } before do
let!(:cluster) { create(:cluster, projects: [build.project]) } expect(deployment.cluster).to be_nil
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, cluster: cluster) } end
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
end end
end
describe '#complete!' do describe '#complete!' do
let(:cluster) { create(:cluster, projects: [build.project]) } let!(:deployment) { create(:deployment, deployable: build) }
let(:service) { double(execute: true) } let(:service) { double(execute: true) }
subject { described_class.new(build).complete! } subject { described_class.new(build).complete! }
context 'completion is required' do context 'completion is required' do
let!(:deployment) { create(:deployment, deployable: build) } let(:cluster) { create(:cluster, projects: [build.project]) }
before do
allow(build.deployment).to receive(:cluster).and_return(cluster)
end
it 'creates a kubernetes namespace' do it 'creates a kubernetes namespace' do
expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService) expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService)
...@@ -59,7 +66,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do ...@@ -59,7 +66,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
context 'completion is not required' do context 'completion is not required' do
before do before do
expect(build.deployment).to be_nil expect(deployment.cluster).to be_nil
end end
it 'does not create a namespace' do it 'does not create a namespace' do
......
...@@ -356,4 +356,32 @@ describe Deployment do ...@@ -356,4 +356,32 @@ describe Deployment do
end end
end end
end end
describe '#cluster' do
let(:deployment) { create(:deployment) }
let(:project) { deployment.project }
let(:environment) { deployment.environment }
subject { deployment.cluster }
before do
expect(project).to receive(:deployment_platform)
.with(environment: environment.name).and_call_original
end
context 'project has no deployment platform' do
before do
expect(project.clusters).to be_empty
end
it { is_expected.to be_nil }
end
context 'project has a deployment platform' do
let!(:cluster) { create(:cluster, projects: [project]) }
let!(:platform) { create(:cluster_platform_kubernetes, cluster: cluster) }
it { is_expected.to eq cluster }
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