Commit dd5d5571 authored by Thong Kuah's avatar Thong Kuah

Merge branch 'namespace-labels' into 'master'

Assign labels to the GMA and project k8s namespaces

See merge request gitlab-org/gitlab!23027
parents fa86a635 375e1a52
......@@ -21,10 +21,15 @@ module Clusters
attr_reader :cluster, :kubernetes_namespace, :platform
def create_project_service_account
environment_slug = kubernetes_namespace.environment&.slug
namespace_labels = { 'app.gitlab.com/app' => kubernetes_namespace.project.full_path_slug }
namespace_labels['app.gitlab.com/env'] = environment_slug if environment_slug
Clusters::Kubernetes::CreateOrUpdateServiceAccountService.namespace_creator(
platform.kubeclient,
service_account_name: kubernetes_namespace.service_account_name,
service_account_namespace: kubernetes_namespace.namespace,
service_account_namespace_labels: namespace_labels,
rbac: platform.rbac?
).execute
end
......
......@@ -3,10 +3,11 @@
module Clusters
module Kubernetes
class CreateOrUpdateServiceAccountService
def initialize(kubeclient, service_account_name:, service_account_namespace:, token_name:, rbac:, namespace_creator: false, role_binding_name: nil)
def initialize(kubeclient, service_account_name:, service_account_namespace:, service_account_namespace_labels: nil, token_name:, rbac:, namespace_creator: false, role_binding_name: nil)
@kubeclient = kubeclient
@service_account_name = service_account_name
@service_account_namespace = service_account_namespace
@service_account_namespace_labels = service_account_namespace_labels
@token_name = token_name
@rbac = rbac
@namespace_creator = namespace_creator
......@@ -23,11 +24,12 @@ module Clusters
)
end
def self.namespace_creator(kubeclient, service_account_name:, service_account_namespace:, rbac:)
def self.namespace_creator(kubeclient, service_account_name:, service_account_namespace:, service_account_namespace_labels:, rbac:)
self.new(
kubeclient,
service_account_name: service_account_name,
service_account_namespace: service_account_namespace,
service_account_namespace_labels: service_account_namespace_labels,
token_name: "#{service_account_namespace}-token",
rbac: rbac,
namespace_creator: true,
......@@ -55,12 +57,13 @@ module Clusters
private
attr_reader :kubeclient, :service_account_name, :service_account_namespace, :token_name, :rbac, :namespace_creator, :role_binding_name
attr_reader :kubeclient, :service_account_name, :service_account_namespace, :service_account_namespace_labels, :token_name, :rbac, :namespace_creator, :role_binding_name
def ensure_project_namespace_exists
Gitlab::Kubernetes::Namespace.new(
service_account_namespace,
kubeclient
kubeclient,
labels: service_account_namespace_labels
).ensure_exists!
end
......
---
title: Assign labels to the GMA and project k8s namespaces
merge_request: 23027
author:
type: added
......@@ -6,6 +6,7 @@ module Gitlab
HELM_VERSION = '2.16.1'
KUBECTL_VERSION = '1.13.12'
NAMESPACE = 'gitlab-managed-apps'
NAMESPACE_LABELS = { 'app.gitlab.com/managed_by' => :gitlab }.freeze
SERVICE_ACCOUNT = 'tiller'
CLUSTER_ROLE_BINDING = 'tiller-admin'
CLUSTER_ROLE = 'cluster-admin'
......
......@@ -6,7 +6,11 @@ module Gitlab
class Api
def initialize(kubeclient)
@kubeclient = kubeclient
@namespace = Gitlab::Kubernetes::Namespace.new(Gitlab::Kubernetes::Helm::NAMESPACE, kubeclient)
@namespace = Gitlab::Kubernetes::Namespace.new(
Gitlab::Kubernetes::Helm::NAMESPACE,
kubeclient,
labels: Gitlab::Kubernetes::Helm::NAMESPACE_LABELS
)
end
def install(command)
......
......@@ -3,11 +3,12 @@
module Gitlab
module Kubernetes
class Namespace
attr_accessor :name
attr_accessor :name, :labels
def initialize(name, client)
def initialize(name, client, labels: nil)
@name = name
@client = client
@labels = labels
end
def exists?
......@@ -17,7 +18,7 @@ module Gitlab
end
def create!
resource = ::Kubeclient::Resource.new(metadata: { name: name })
resource = ::Kubeclient::Resource.new(metadata: { name: name, labels: labels })
log_event(:begin_create)
@client.create_namespace(resource)
......
......@@ -6,7 +6,8 @@ describe Gitlab::Kubernetes::Helm::Api do
let(:client) { double('kubernetes client') }
let(:helm) { described_class.new(client) }
let(:gitlab_namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
let(:namespace) { Gitlab::Kubernetes::Namespace.new(gitlab_namespace, client) }
let(:gitlab_namespace_labels) { Gitlab::Kubernetes::Helm::NAMESPACE_LABELS }
let(:namespace) { Gitlab::Kubernetes::Namespace.new(gitlab_namespace, client, labels: gitlab_namespace_labels) }
let(:application_name) { 'app-name' }
let(:rbac) { false }
let(:files) { {} }
......@@ -23,13 +24,17 @@ describe Gitlab::Kubernetes::Helm::Api do
subject { helm }
before do
allow(Gitlab::Kubernetes::Namespace).to receive(:new).with(gitlab_namespace, client).and_return(namespace)
allow(Gitlab::Kubernetes::Namespace).to(
receive(:new).with(gitlab_namespace, client, labels: gitlab_namespace_labels).and_return(namespace)
)
allow(client).to receive(:create_config_map)
end
describe '#initialize' do
it 'creates a namespace object' do
expect(Gitlab::Kubernetes::Namespace).to receive(:new).with(gitlab_namespace, client)
expect(Gitlab::Kubernetes::Namespace).to(
receive(:new).with(gitlab_namespace, client, labels: gitlab_namespace_labels)
)
subject
end
......
......@@ -5,8 +5,9 @@ require 'spec_helper'
describe Gitlab::Kubernetes::Namespace do
let(:name) { 'a_namespace' }
let(:client) { double('kubernetes client') }
let(:labels) { nil }
subject { described_class.new(name, client) }
subject { described_class.new(name, client, labels: labels) }
it { expect(subject.name).to eq(name) }
......@@ -49,6 +50,17 @@ describe Gitlab::Kubernetes::Namespace do
expect { subject.create! }.not_to raise_error
end
context 'with labels' do
let(:labels) { { foo: :bar } }
it 'creates a namespace with labels' do
matcher = have_attributes(metadata: have_attributes(name: name, labels: have_attributes(foo: :bar)))
expect(client).to receive(:create_namespace).with(matcher).once
expect { subject.create! }.not_to raise_error
end
end
end
describe '#ensure_exists!' do
......
......@@ -57,11 +57,21 @@ describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do
end.to change(Clusters::KubernetesNamespace, :count).by(1)
end
it 'creates project service account' do
expect_next_instance_of(Clusters::Kubernetes::CreateOrUpdateServiceAccountService) do |instance|
expect(instance).to receive(:execute).once
end
it 'creates project service account and namespace' do
account_service = double(Clusters::Kubernetes::CreateOrUpdateServiceAccountService)
expect(Clusters::Kubernetes::CreateOrUpdateServiceAccountService).to(
receive(:namespace_creator).with(
cluster.platform.kubeclient,
service_account_name: "#{namespace}-service-account",
service_account_namespace: namespace,
service_account_namespace_labels: {
'app.gitlab.com/app' => project.full_path_slug,
'app.gitlab.com/env' => environment.slug
},
rbac: true
).and_return(account_service)
)
expect(account_service).to receive(:execute).once
subject
end
......@@ -73,6 +83,29 @@ describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' do
expect(kubernetes_namespace.service_account_name).to eq("#{namespace}-service-account")
expect(kubernetes_namespace.encrypted_service_account_token).to be_present
end
context 'without environment' do
before do
kubernetes_namespace.environment = nil
end
it 'creates project service account and namespace' do
account_service = double(Clusters::Kubernetes::CreateOrUpdateServiceAccountService)
expect(Clusters::Kubernetes::CreateOrUpdateServiceAccountService).to(
receive(:namespace_creator).with(
cluster.platform.kubeclient,
service_account_name: "#{namespace}-service-account",
service_account_namespace: namespace,
service_account_namespace_labels: {
'app.gitlab.com/app' => project.full_path_slug
},
rbac: true
).and_return(account_service)
)
expect(account_service).to receive(:execute).once
subject
end
end
end
context 'group clusters' do
......
......@@ -116,6 +116,7 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do
describe '.namespace_creator' do
let(:namespace) { "#{project.path}-#{project.id}" }
let(:namespace_labels) { { app: project.full_path_slug, env: "staging" } }
let(:service_account_name) { "#{namespace}-service-account" }
let(:token_name) { "#{namespace}-token" }
......@@ -124,6 +125,7 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do
kubeclient,
service_account_name: service_account_name,
service_account_namespace: namespace,
service_account_namespace_labels: namespace_labels,
rbac: rbac
).execute
end
......@@ -149,6 +151,16 @@ describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do
stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME, namespace: namespace)
end
it 'creates a namespace object' do
kubernetes_namespace = double(Gitlab::Kubernetes::Namespace)
expect(Gitlab::Kubernetes::Namespace).to(
receive(:new).with(namespace, kubeclient, labels: namespace_labels).and_return(kubernetes_namespace)
)
expect(kubernetes_namespace).to receive(:ensure_exists!)
subject
end
it_behaves_like 'creates service account and token'
it 'creates a namespaced role binding with edit access' 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