Commit 11810cb2 authored by Thong Kuah's avatar Thong Kuah

Merge branch '63079-exclude-k8s-namespaces-with-no-service-account-token' into 'master'

Don't use Kubernetes namespaces with no token

See merge request gitlab-org/gitlab-ce!29643
parents bd228617 ddd271b6
...@@ -193,15 +193,34 @@ module Clusters ...@@ -193,15 +193,34 @@ module Clusters
platform_kubernetes.kubeclient if kubernetes? platform_kubernetes.kubeclient if kubernetes?
end end
##
# This is subtly different to #find_or_initialize_kubernetes_namespace_for_project
# below because it will ignore any namespaces that have not got a service account
# token. This provides a guarantee that any namespace selected here can be used
# for cluster operations - a namespace needs to have a service account configured
# before it it can be used.
#
# This is used for selecting a namespace to use when querying a cluster, or
# generating variables to pass to CI.
def kubernetes_namespace_for(project) def kubernetes_namespace_for(project)
find_or_initialize_kubernetes_namespace_for_project(project).namespace find_or_initialize_kubernetes_namespace_for_project(
project, scope: kubernetes_namespaces.has_service_account_token
).namespace
end end
def find_or_initialize_kubernetes_namespace_for_project(project) ##
# This is subtly different to #kubernetes_namespace_for because it will include
# namespaces that have yet to receive a service account token. This allows
# the namespace configuration process to be repeatable - if a namespace has
# already been created without a token we don't need to create another
# record entirely, just set the token on the pre-existing namespace.
#
# This is used for configuring cluster namespaces.
def find_or_initialize_kubernetes_namespace_for_project(project, scope: kubernetes_namespaces)
attributes = { project: project } attributes = { project: project }
attributes[:cluster_project] = cluster_project if project_type? attributes[:cluster_project] = cluster_project if project_type?
kubernetes_namespaces.find_or_initialize_by(attributes).tap do |namespace| scope.find_or_initialize_by(attributes).tap do |namespace|
namespace.set_defaults namespace.set_defaults
end end
end end
......
---
title: Ensure a Kubernetes namespace is not used for deployments if there is no service
account token associated with it
merge_request: 29643
author:
type: fixed
...@@ -555,6 +555,63 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do ...@@ -555,6 +555,63 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end end
end end
describe '#find_or_initialize_kubernetes_namespace_for_project' do
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.projects.first }
subject { cluster.find_or_initialize_kubernetes_namespace_for_project(project) }
context 'kubernetes namespace exists' do
context 'with no service account token' do
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, project: project, cluster: cluster) }
it { is_expected.to eq kubernetes_namespace }
end
context 'with a service account token' do
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, :with_token, project: project, cluster: cluster) }
it { is_expected.to eq kubernetes_namespace }
end
end
context 'kubernetes namespace does not exist' do
it 'initializes a new namespace and sets default values' do
expect(subject).to be_new_record
expect(subject.project).to eq project
expect(subject.cluster).to eq cluster
expect(subject.namespace).to be_present
expect(subject.service_account_name).to be_present
end
end
context 'a custom scope is provided' do
let(:scope) { cluster.kubernetes_namespaces.has_service_account_token }
subject { cluster.find_or_initialize_kubernetes_namespace_for_project(project, scope: scope) }
context 'kubernetes namespace exists' do
context 'with no service account token' do
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, project: project, cluster: cluster) }
it 'initializes a new namespace and sets default values' do
expect(subject).to be_new_record
expect(subject.project).to eq project
expect(subject.cluster).to eq cluster
expect(subject.namespace).to be_present
expect(subject.service_account_name).to be_present
end
end
context 'with a service account token' do
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, :with_token, project: project, cluster: cluster) }
it { is_expected.to eq kubernetes_namespace }
end
end
end
end
describe '#predefined_variables' do describe '#predefined_variables' do
subject { cluster.predefined_variables } subject { cluster.predefined_variables }
......
...@@ -223,19 +223,33 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching ...@@ -223,19 +223,33 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
let(:namespace) { 'namespace-123' } let(:namespace) { 'namespace-123' }
it { is_expected.to eq(namespace) } it { is_expected.to eq(namespace) }
context 'kubernetes namespace is present but has no service account token' do
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, cluster: cluster) }
it { is_expected.to eq(namespace) }
end
end end
context 'with no namespace assigned' do context 'with no namespace assigned' do
let(:namespace) { nil } let(:namespace) { nil }
context 'when kubernetes namespace is present' do context 'when kubernetes namespace is present' do
let(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, cluster: cluster) } let(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, :with_token, cluster: cluster) }
before do before do
kubernetes_namespace kubernetes_namespace
end end
it { is_expected.to eq(kubernetes_namespace.namespace) } it { is_expected.to eq(kubernetes_namespace.namespace) }
context 'kubernetes namespace has no service account token' do
before do
kubernetes_namespace.update!(namespace: 'old-namespace', service_account_token: nil)
end
it { is_expected.to eq("#{project.path}-#{project.id}") }
end
end end
context 'when kubernetes namespace is not present' do context 'when kubernetes namespace is not present' do
......
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