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
path: root/spec/lib
diff options
context:
space:
mode:
authorTiger Watson <twatson@gitlab.com>2019-08-07 07:40:29 +0300
committerThong Kuah <tkuah@gitlab.com>2019-08-07 07:40:29 +0300
commit36a01a88ce4c35f3d2b455c7943eeb9649b51163 (patch)
treee568be9b9b80626b60f8e0e445ea95ee570e9523 /spec/lib
parent54377159730c676bd40b64e66acfb57faf90eabf (diff)
Use separate Kubernetes namespaces per environment
Kubernetes deployments on new clusters will now have a separate namespace per project environment, instead of sharing a single namespace for the project. Behaviour of existing clusters is unchanged. All new functionality is controlled by the :kubernetes_namespace_per_environment feature flag, which is safe to enable/disable at any time.
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb81
-rw-r--r--spec/lib/gitlab/kubernetes/default_namespace_spec.rb85
-rw-r--r--spec/lib/gitlab/prometheus/query_variables_spec.rb6
3 files changed, 153 insertions, 19 deletions
diff --git a/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb b/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb
index d88a2097ba2..775550f2acc 100644
--- a/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb
+++ b/spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
- let(:build) { create(:ci_build) }
-
describe '#unmet?' do
+ let(:build) { create(:ci_build) }
+
subject { described_class.new(build).unmet? }
context 'build has no deployment' do
@@ -18,7 +18,6 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
context 'build has a deployment' do
let!(:deployment) { create(:deployment, deployable: build, cluster: cluster) }
- let(:cluster) { nil }
context 'and a cluster to deploy to' do
let(:cluster) { create(:cluster, :group) }
@@ -32,12 +31,17 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
end
context 'and a namespace is already created for this project' do
- let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, :with_token, cluster: cluster, project: build.project) }
+ let(:kubernetes_namespace) { instance_double(Clusters::KubernetesNamespace, service_account_token: 'token') }
+
+ before do
+ allow(Clusters::KubernetesNamespaceFinder).to receive(:new)
+ .and_return(double(execute: kubernetes_namespace))
+ end
it { is_expected.to be_falsey }
context 'and the service_account_token is blank' do
- let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, :without_token, cluster: cluster, project: build.project) }
+ let(:kubernetes_namespace) { instance_double(Clusters::KubernetesNamespace, service_account_token: nil) }
it { is_expected.to be_truthy }
end
@@ -45,34 +49,79 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
end
context 'and no cluster to deploy to' do
+ let(:cluster) { nil }
+
it { is_expected.to be_falsey }
end
end
end
describe '#complete!' do
- let!(:deployment) { create(:deployment, deployable: build, cluster: cluster) }
- let(:service) { double(execute: true) }
- let(:cluster) { nil }
+ let(:build) { create(:ci_build) }
+ let(:prerequisite) { described_class.new(build) }
- subject { described_class.new(build).complete! }
+ subject { prerequisite.complete! }
context 'completion is required' do
let(:cluster) { create(:cluster, :group) }
+ let(:deployment) { create(:deployment, cluster: cluster) }
+ let(:service) { double(execute: true) }
+ let(:kubernetes_namespace) { double }
+
+ before do
+ allow(prerequisite).to receive(:unmet?).and_return(true)
+ allow(build).to receive(:deployment).and_return(deployment)
+ end
+
+ context 'kubernetes namespace does not exist' do
+ let(:namespace_builder) { double(execute: kubernetes_namespace)}
- it 'creates a kubernetes namespace' do
- expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService)
- .to receive(:new)
- .with(cluster: cluster, kubernetes_namespace: instance_of(Clusters::KubernetesNamespace))
- .and_return(service)
+ before do
+ allow(Clusters::KubernetesNamespaceFinder).to receive(:new)
+ .and_return(double(execute: nil))
+ end
- expect(service).to receive(:execute).once
+ it 'creates a namespace using a new record' do
+ expect(Clusters::BuildKubernetesNamespaceService)
+ .to receive(:new)
+ .with(cluster, environment: deployment.environment)
+ .and_return(namespace_builder)
- subject
+ expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService)
+ .to receive(:new)
+ .with(cluster: cluster, kubernetes_namespace: kubernetes_namespace)
+ .and_return(service)
+
+ expect(service).to receive(:execute).once
+
+ subject
+ end
+ end
+
+ context 'kubernetes namespace exists (but has no service_account_token)' do
+ before do
+ allow(Clusters::KubernetesNamespaceFinder).to receive(:new)
+ .and_return(double(execute: kubernetes_namespace))
+ end
+
+ it 'creates a namespace using the tokenless record' do
+ expect(Clusters::BuildKubernetesNamespaceService).not_to receive(:new)
+
+ expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService)
+ .to receive(:new)
+ .with(cluster: cluster, kubernetes_namespace: kubernetes_namespace)
+ .and_return(service)
+
+ subject
+ end
end
end
context 'completion is not required' do
+ before do
+ allow(prerequisite).to receive(:unmet?).and_return(false)
+ end
+
it 'does not create a namespace' do
expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).not_to receive(:new)
diff --git a/spec/lib/gitlab/kubernetes/default_namespace_spec.rb b/spec/lib/gitlab/kubernetes/default_namespace_spec.rb
new file mode 100644
index 00000000000..1fda547f35c
--- /dev/null
+++ b/spec/lib/gitlab/kubernetes/default_namespace_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Kubernetes::DefaultNamespace do
+ let(:generator) { described_class.new(cluster, project: environment.project) }
+
+ describe '#from_environment_name' do
+ let(:cluster) { create(:cluster) }
+ let(:environment) { create(:environment) }
+
+ subject { generator.from_environment_name(environment.name) }
+
+ it 'generates a slug and passes it to #from_environment_slug' do
+ expect(Gitlab::Slug::Environment).to receive(:new)
+ .with(environment.name)
+ .and_return(double(generate: environment.slug))
+
+ expect(generator).to receive(:from_environment_slug)
+ .with(environment.slug)
+ .and_return(:mock_namespace)
+
+ expect(subject).to eq :mock_namespace
+ end
+ end
+
+ describe '#from_environment_slug' do
+ let(:platform) { create(:cluster_platform_kubernetes, namespace: platform_namespace) }
+ let(:cluster) { create(:cluster, platform_kubernetes: platform) }
+ let(:project) { create(:project, path: "Path-With-Capitals") }
+ let(:environment) { create(:environment, project: project) }
+
+ subject { generator.from_environment_slug(environment.slug) }
+
+ context 'namespace per environment is enabled' do
+ context 'platform namespace is specified' do
+ let(:platform_namespace) { 'platform-namespace' }
+
+ it { is_expected.to eq "#{platform_namespace}-#{environment.slug}" }
+
+ context 'cluster is unmanaged' do
+ let(:cluster) { create(:cluster, :not_managed, platform_kubernetes: platform) }
+
+ it { is_expected.to eq platform_namespace }
+ end
+ end
+
+ context 'platform namespace is blank' do
+ let(:platform_namespace) { nil }
+ let(:mock_namespace) { 'mock-namespace' }
+
+ it 'constructs a namespace from the project and environment' do
+ expect(Gitlab::NamespaceSanitizer).to receive(:sanitize)
+ .with("#{project.path}-#{project.id}-#{environment.slug}".downcase)
+ .and_return(mock_namespace)
+
+ expect(subject).to eq mock_namespace
+ end
+ end
+ end
+
+ context 'namespace per environment is disabled' do
+ let(:cluster) { create(:cluster, :namespace_per_environment_disabled, platform_kubernetes: platform) }
+
+ context 'platform namespace is specified' do
+ let(:platform_namespace) { 'platform-namespace' }
+
+ it { is_expected.to eq platform_namespace }
+ end
+
+ context 'platform namespace is blank' do
+ let(:platform_namespace) { nil }
+ let(:mock_namespace) { 'mock-namespace' }
+
+ it 'constructs a namespace from the project and environment' do
+ expect(Gitlab::NamespaceSanitizer).to receive(:sanitize)
+ .with("#{project.path}-#{project.id}".downcase)
+ .and_return(mock_namespace)
+
+ expect(subject).to eq mock_namespace
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/prometheus/query_variables_spec.rb b/spec/lib/gitlab/prometheus/query_variables_spec.rb
index 6dc99ef26ec..3f9b245a3fb 100644
--- a/spec/lib/gitlab/prometheus/query_variables_spec.rb
+++ b/spec/lib/gitlab/prometheus/query_variables_spec.rb
@@ -23,7 +23,7 @@ describe Gitlab::Prometheus::QueryVariables do
context 'with deployment platform' do
context 'with project cluster' do
- let(:kube_namespace) { environment.deployment_platform.cluster.kubernetes_namespace_for(project) }
+ let(:kube_namespace) { environment.deployment_namespace }
before do
create(:cluster, :project, :provided_by_user, projects: [project])
@@ -38,8 +38,8 @@ describe Gitlab::Prometheus::QueryVariables do
let(:project2) { create(:project) }
let(:kube_namespace) { k8s_ns.namespace }
- let!(:k8s_ns) { create(:cluster_kubernetes_namespace, cluster: cluster, project: project) }
- let!(:k8s_ns2) { create(:cluster_kubernetes_namespace, cluster: cluster, project: project2) }
+ let!(:k8s_ns) { create(:cluster_kubernetes_namespace, cluster: cluster, project: project, environment: environment) }
+ let!(:k8s_ns2) { create(:cluster_kubernetes_namespace, cluster: cluster, project: project2, environment: environment) }
before do
group.projects << project