Skip to content
Snippets Groups Projects
Commit 480dc210 authored by Mayra Cabrera's avatar Mayra Cabrera
Browse files

Integrates Kubernetes namespace on Clusters flow

- Modifies 'FinalizeCreationService' class to create KubernetesNamespace
  instance.
- Adds CreateServicesAccountService to ensure gitlab and namespaced
  services account are created.
- If cluster is using RBAC as authorization, also create a role binding
  and a cluster role binding account
parent ef5165ac
No related branches found
No related tags found
No related merge requests found
Showing
with 384 additions and 161 deletions
Loading
Loading
@@ -31,6 +31,11 @@ module Clusters
has_one :application_runner, class_name: 'Clusters::Applications::Runner'
has_one :application_jupyter, class_name: 'Clusters::Applications::Jupyter'
 
has_one :first_cluster_project, -> { order :created_at }, class_name: 'Clusters::Project'
has_many :kubernetes_namespaces, through: :first_cluster_project
alias_method :cluster_project, :first_cluster_project
accepts_nested_attributes_for :provider_gcp, update_only: true
accepts_nested_attributes_for :platform_kubernetes, update_only: true
 
Loading
Loading
@@ -47,6 +52,8 @@ module Clusters
delegate :available?, to: :application_ingress, prefix: true, allow_nil: true
delegate :available?, to: :application_prometheus, prefix: true, allow_nil: true
 
delegate :kubernetes_namespace, to: :cluster_project, allow_nil: true
enum platform_type: {
kubernetes: 1
}
Loading
Loading
Loading
Loading
@@ -8,15 +8,23 @@ module Clusters
has_one :cluster, through: :cluster_project
has_one :project, through: :cluster_project
 
delegate :platform_kubernetes, to: :cluster, allow_nil: true
delegate :rbac?, to: :platform_kubernetes, prefix: true, allow_nil: true
validates :namespace, presence: true
validates :namespace, uniqueness: { scope: :cluster_project_id }
before_validation :set_cluster_namespace_and_service_account
before_validation :ensure_namespace_uniqueness
 
attr_encrypted :encrypted_service_account_token,
attr_encrypted :service_account_token,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
algorithm: 'aes-256-cbc'
 
def token_name
"#{namespace}-token"
end
private
 
def set_cluster_namespace_and_service_account
Loading
Loading
@@ -25,19 +33,15 @@ module Clusters
end
 
def build_kubernetes_namespace
gcp_kubernetes_namespace.presence || default_namespace
platform_kubernetes_namespace.presence || default_namespace
end
 
def build_service_account_name
if cluster.platform_kubernetes_rbac?
"#{default_service_account_name}-#{namespace}"
else
default_service_account_name
end
"#{namespace}-service-account"
end
 
def gcp_kubernetes_namespace
@gcp_kubernetes_namespace ||= cluster&.platform_kubernetes&.namespace
def platform_kubernetes_namespace
@platform_kubernetes_namespace ||= platform_kubernetes&.namespace
end
 
def default_namespace
Loading
Loading
@@ -47,17 +51,5 @@ module Clusters
def project_slug
"#{project.path}-#{project.id}".downcase
end
def default_service_account_name
Clusters::Gcp::Kubernetes::SERVICE_ACCOUNT_NAME
end
def ensure_namespace_uniqueness
errors.add(:namespace, "Kubernetes namespace #{namespace} already exists on cluster") if kubernetes_namespace_exists?
end
def kubernetes_namespace_exists?
cluster_project.kubernetes_namespaces.where(namespace: namespace).exists?
end
end
end
Loading
Loading
@@ -35,12 +35,13 @@ module Clusters
message: Gitlab::Regex.kubernetes_namespace_regex_message
}
 
validates :namespace, exclusion: { in: RESERVED_NAMESPACES }
# We expect to be `active?` only when enabled and cluster is created (the api_url is assigned)
validates :api_url, url: true, presence: true
validates :token, presence: true
 
validate :prevent_modification, on: :update
validate :prevent_reserved_namespaces
 
after_save :clear_reactive_cache!
after_update :update_kubernetes_namespace
Loading
Loading
@@ -50,8 +51,7 @@ module Clusters
delegate :project, to: :cluster, allow_nil: true
delegate :enabled?, to: :cluster, allow_nil: true
delegate :managed?, to: :cluster, allow_nil: true
delegate :cluster_project, to: :project, allow_nil: true
delegate :cluster_project, to: :cluster
 
alias_method :active?, :enabled?
 
Loading
Loading
@@ -200,14 +200,6 @@ module Clusters
true
end
 
def prevent_reserved_namespaces
return if namespace.blank?
if RESERVED_NAMESPACES.include?(namespace)
errors.add(:namespace, 'Cannot used a GitLab reserved namespace')
end
end
def update_kubernetes_namespace
return unless namespace_changed?
 
Loading
Loading
Loading
Loading
@@ -2,18 +2,16 @@
 
module Clusters
class Project < ActiveRecord::Base
include Gitlab::Utils::StrongMemoize
self.table_name = 'cluster_projects'
 
belongs_to :cluster, class_name: 'Clusters::Cluster'
belongs_to :project, class_name: '::Project'
has_many :kubernetes_namespaces, class_name: 'Clusters::KubernetesNamespace', foreign_key: :cluster_project_id
 
def last_kubernetes_namespace
return @last_kubernetes_namespace if defined?(@last_kubernetes_namespace)
has_many :kubernetes_namespaces, class_name: 'Clusters::KubernetesNamespace', foreign_key: :cluster_project_id
has_one :last_kubernetes_namespace, -> { order created_at: :desc }, class_name: 'Clusters::KubernetesNamespace', foreign_key: :cluster_project_id
 
@first_kubernetes_namespace = kubernetes_namespaces.last
end
alias_method :kubernetes_namespace, :last_kubernetes_namespace
end
end
Loading
Loading
@@ -3,18 +3,21 @@
module Clusters
module Gcp
class FinalizeCreationService
include Gitlab::Utils::StrongMemoize
attr_reader :provider
 
def execute(provider)
@provider = provider
 
configure_provider
create_gitlab_service_account!
configure_kubernetes
create_kubernetes_namespace!
create_gitlab_service_account!
configure_kubernetes_tokens
 
cluster.save!
 
ClusterPlatformConfigureWorker.perform_async(cluster.id)
rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e
provider.make_errored!("Failed to request to CloudPlatform; #{e.message}")
rescue Kubeclient::HttpError => e
Loading
Loading
@@ -26,7 +29,7 @@ module Clusters
private
 
def create_gitlab_service_account!
Clusters::Gcp::Kubernetes::CreateServiceAccountService.new(kube_client, rbac: create_rbac_cluster?).execute
Clusters::Gcp::ServicesAccountService.new(kube_client, cluster).execute
end
 
def configure_provider
Loading
Loading
@@ -41,12 +44,23 @@ module Clusters
ca_cert: Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate),
username: gke_cluster.master_auth.username,
password: gke_cluster.master_auth.password,
authorization_type: authorization_type,
token: request_kubernetes_token)
authorization_type: authorization_type
)
end
def create_kubernetes_namespace!
cluster.cluster_project.kubernetes_namespaces.create!
end
 
def request_kubernetes_token
Clusters::Gcp::Kubernetes::FetchKubernetesTokenService.new(kube_client).execute
def configure_kubernetes_tokens
cluster.platform_kubernetes.token = fetch_kubernetes_token(Clusters::Gcp::Kubernetes::SERVICE_ACCOUNT_TOKEN_NAME, Clusters::Gcp::Kubernetes::SERVICE_ACCOUNT_NAMESPACE)
service_account_token = fetch_kubernetes_token(kubernetes_namespace.token_name, kubernetes_namespace.namespace)
kubernetes_namespace.update_attribute(:service_account_token, service_account_token)
end
def fetch_kubernetes_token(name, namespace)
Clusters::Gcp::Kubernetes::FetchKubernetesTokenService.new(kube_client, name, namespace).execute
end
 
def authorization_type
Loading
Loading
@@ -101,6 +115,12 @@ module Clusters
def cluster
@cluster ||= provider.cluster
end
def kubernetes_namespace
strong_memoize(:kubernetes_namespace) do
cluster.kubernetes_namespace
end
end
end
end
end
Loading
Loading
@@ -4,32 +4,57 @@ module Clusters
module Gcp
module Kubernetes
class CreateServiceAccountService
attr_reader :kubeclient, :rbac
attr_reader :kubeclient, :name, :namespace, :rbac
 
def initialize(kubeclient, rbac:)
def initialize(kubeclient, name:, namespace:, rbac:)
@kubeclient = kubeclient
@name = name
@namespace = namespace
@rbac = rbac
end
 
def execute
ensure_namespace_exists
kubeclient.create_service_account(service_account_resource)
kubeclient.create_secret(service_account_token_resource)
kubeclient.create_cluster_role_binding(cluster_role_binding_resource) if rbac
create_cluster_or_role_binding if rbac
end
 
private
 
def ensure_namespace_exists
Gitlab::Kubernetes::Namespace.new(namespace, kubeclient).ensure_exists!
end
def service_account_resource
Gitlab::Kubernetes::ServiceAccount.new(service_account_name, service_account_namespace).generate
Gitlab::Kubernetes::ServiceAccount.new(name, namespace).generate
end
 
def service_account_token_resource
Gitlab::Kubernetes::ServiceAccountToken.new(
SERVICE_ACCOUNT_TOKEN_NAME, service_account_name, service_account_namespace).generate
token_name, name, namespace).generate
end
def token_name
if default_namespace?
SERVICE_ACCOUNT_TOKEN_NAME
else
"#{namespace}-token"
end
end
def create_cluster_or_role_binding
if default_namespace?
kubeclient.create_cluster_role_binding(cluster_role_binding_resource)
else
kubeclient.create_role_binding(role_binding_resource)
end
end
 
def cluster_role_binding_resource
subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: service_account_namespace }]
subjects = [{ kind: 'ServiceAccount', name: name, namespace: namespace }]
 
Gitlab::Kubernetes::ClusterRoleBinding.new(
CLUSTER_ROLE_BINDING_NAME,
Loading
Loading
@@ -38,12 +63,16 @@ module Clusters
).generate
end
 
def service_account_name
SERVICE_ACCOUNT_NAME
def role_binding_resource
Gitlab::Kubernetes::RoleBinding.new(
role_name: 'edit',
namespace: namespace,
service_account_name: name
).generate
end
 
def service_account_namespace
SERVICE_ACCOUNT_NAMESPACE
def default_namespace?
namespace == SERVICE_ACCOUNT_NAMESPACE
end
end
end
Loading
Loading
Loading
Loading
@@ -4,10 +4,12 @@ module Clusters
module Gcp
module Kubernetes
class FetchKubernetesTokenService
attr_reader :kubeclient
attr_reader :kubeclient, :service_account_token_name, :namespace
 
def initialize(kubeclient)
def initialize(kubeclient, service_account_token_name, namespace)
@kubeclient = kubeclient
@service_account_token_name = service_account_token_name
@namespace = namespace
end
 
def execute
Loading
Loading
@@ -18,7 +20,7 @@ module Clusters
private
 
def get_secret
kubeclient.get_secret(SERVICE_ACCOUNT_TOKEN_NAME, SERVICE_ACCOUNT_NAMESPACE).as_json
kubeclient.get_secret(service_account_token_name, namespace).as_json
rescue Kubeclient::HttpError => err
raise err unless err.error_code == 404
 
Loading
Loading
# frozen_string_literal: true
module Clusters
module Gcp
class ServicesAccountService
include ::Gitlab::Utils::StrongMemoize
attr_reader :kube_client, :cluster
def initialize(kube_client, cluster)
@kube_client = kube_client
@cluster = cluster
end
def execute
create_gitlab_service_account
create_namespaced_service_account
end
private
def create_gitlab_service_account
create_service_account(
name: Clusters::Gcp::Kubernetes::SERVICE_ACCOUNT_NAME,
namespace: Clusters::Gcp::Kubernetes::SERVICE_ACCOUNT_NAMESPACE
)
end
def create_namespaced_service_account
create_service_account(
name: kubernetes_namespace.service_account_name,
namespace: kubernetes_namespace.namespace
)
end
def create_service_account(name:, namespace:)
Clusters::Gcp::Kubernetes::CreateServiceAccountService.new(
kube_client,
name: name,
namespace: namespace,
rbac: cluster.platform_kubernetes_rbac?
).execute
end
def kubernetes_namespace
strong_memoize(:kubernetes_namespace) do
cluster.kubernetes_namespace
end
end
end
end
end
Loading
Loading
@@ -5,30 +5,51 @@ module Clusters
class ConfigureService
include Gitlab::Utils::StrongMemoize
 
attr_reader :platform
attr_reader :platform, :cluster
 
def initialize(platform)
@platform = platform
def initialize(cluster)
@cluster = cluster
@platform = cluster.platform
end
 
def execute
return unless platform.cluster_project
return unless cluster_project
 
cluster_kubernetes_namespace.ensure_exists!
# To do: Create service account
create_kubernetes_namespace!
create_services_accounts!
configure_kubernetes_token
end
 
private
 
def cluster_kubernetes_namespace
strong_memoize(:cluster_kubernetes_namespace) do
Gitlab::Kubernetes::Namespace.new(namespace_name, platform.kubeclient)
def create_kubernetes_namespace!
cluster_project.kubernetes_namespaces.create!
end
def create_services_accounts!
Clusters::Gcp::ServicesAccountService.new(platform.kubeclient, cluster).execute
end
def configure_kubernetes_token
service_token_account = fetch_kubernetes_token(kubernetes_namespace.token_name, kubernetes_namespace.namespace)
kubernetes_namespace.update_attribute(:service_account_token, service_token_account)
end
def fetch_kubernetes_token(name, namespace)
Clusters::Gcp::Kubernetes::FetchKubernetesTokenService.new(platform.kubeclient, name, namespace).execute
end
def kubernetes_namespace
strong_memoize(:kubernetes_namespace) do
cluster.kubernetes_namespace
end
end
 
def namespace_name
platform.cluster_project.kubernetes_namespace.namespace
def cluster_project
strong_memoize(:cluster_project) do
cluster.cluster_project
end
end
end
end
Loading
Loading
Loading
Loading
@@ -6,9 +6,7 @@ class ClusterPlatformConfigureWorker
 
def perform(cluster_id)
Clusters::Cluster.find_by_id(cluster_id).try do |cluster|
cluster.platform_kubernetes.try do |platform|
Clusters::Kubernetes::ConfigureService.new(platform).execute
end
Clusters::Kubernetes::ConfigureService.new(cluster).execute
end
end
end
# frozen_string_literal: true
 
class CreateClustersKubernetesNamespaces < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'kubernetes_namespaces_cluster_project_and_namespace'
 
def change
create_table(:clusters_kubernetes_namespaces) do |t|
create_table :clusters_kubernetes_namespaces do |t|
t.references :cluster_project, null: false, index: true, foreign_key: { on_delete: :cascade }
 
t.timestamps_with_timezone null: false
 
t.text :encrypted_service_account_token
t.string :encrypted_service_account_token_iv
 
t.string :namespace, null: false
t.string :service_account_name
end
add_index :clusters_kubernetes_namespaces, [:cluster_project_id, :namespace],
unique: true,
name: INDEX_NAME
end
end
Loading
Loading
@@ -4,26 +4,27 @@ class PopulateClusterKubernetesNamespace < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
 
DOWNTIME = false
MIGRATION = 'PopulateClusterKubernetesNamespace'.freeze
 
disable_ddl_transaction!
 
class ClusterProject < ActiveRecord::Base
include EachBatch
self.table_name = 'cluster_projects'
end
include EachBatch
 
class ClusterKubernetesNamespace < ActiveRecord::Base
self.table_name = 'clusters_kubernetes_namespaces'
BATCH_SIZE = 500
def self.params_for_background_migration
yield all, MIGRATION, 5.minutes, BATCH_SIZE
end
end
 
def up
cluster_project_with_no_namespace = ClusterProject.where.not(id: ClusterKubernetesNamespace.select(:id))
cluster_project_with_no_namespace.tap do |relation|
ClusterProject.params_for_background_migration do |relation, class_name, delay_interval, batch_size|
queue_background_migration_jobs_by_range_at_intervals(relation,
'PopulateClusterKubernetesNamespace',
5.minutes,
batch_size: 500)
class_name,
delay_interval,
batch_size: batch_size)
end
end
 
Loading
Loading
Loading
Loading
@@ -696,10 +696,12 @@ ActiveRecord::Schema.define(version: 20181013005024) do
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
t.text "encrypted_service_account_token"
t.string "encrypted_service_account_token_iv"
t.string "namespace", null: false
t.string "service_account_name"
end
 
add_index "clusters_kubernetes_namespaces", ["cluster_project_id", "namespace"], name: "kubernetes_namespaces_cluster_project_and_namespace", unique: true, using: :btree
add_index "clusters_kubernetes_namespaces", ["cluster_project_id"], name: "index_clusters_kubernetes_namespaces_on_cluster_project_id", using: :btree
 
create_table "container_repositories", force: :cascade do |t|
Loading
Loading
# frozen_string_literal: true
#
# rubocop:disable Style/Documentation
 
module Gitlab
Loading
Loading
@@ -15,17 +16,17 @@ module Gitlab
belongs_to :project
belongs_to :cluster
 
def self.with_no_kubernetes_namespace
where.not(id: Migratable::ClusterKubernetesNamespace.select(:cluster_project_id))
end
def default_namespace
slug = "#{project.path}-#{project.id}".downcase
slug.gsub(/[^-a-z0-9]/, '-').gsub(/^-+/, '')
end
 
def default_service_account
if cluster.rbac?
"gitlab-#{default_namespace}"
else
"gitlab"
end
"#{default_namespace}-service-account"
end
end
 
Loading
Loading
@@ -59,7 +60,7 @@ module Gitlab
 
cluster_project_collection(start_id, stop_id).each do |cluster_project|
attributes = {
cluster_project_id: cluster_project.id,
cluster_project_id: cluster_project.id,
namespace: cluster_project.default_namespace,
service_account_name: cluster_project.default_service_account
}
Loading
Loading
@@ -73,9 +74,8 @@ module Gitlab
private
 
def cluster_project_collection(start_id, stop_id)
Migratable::ClusterProject.where(id: (start_id..stop_id))
Migratable::ClusterProject.where(id: (start_id..stop_id)).with_no_kubernetes_namespace
end
end
end
end
# frozen_string_literal: true
# rubocop:disable Style/Documentation
module Gitlab
module BackgroundMigration
class PopulateClusterProjectNamespace
module Migratable
class ClusterProject < ActiveRecord::Base
self.table_name = 'cluster_projects'
belongs_to :project
def default_namespace
slug = "#{project.path}-#{project.id}".downcase
slug.gsub(/[^-a-z0-9]/, '-').gsub(/^-+/, '')
end
end
class Project < ActiveRecord::Base
self.table_name = 'projects'
end
end
def perform(start_id, stop_id)
cluster_project_attributes = {}
cluster_project_collection(start_id, stop_id).each do |cluster_project|
cluster_project_attributes[cluster_project.id] = { namespace: cluster_project.default_namespace }
end
Migratable::ClusterProject.update(cluster_project_attributes.keys, cluster_project_attributes.values)
end
private
def cluster_project_collection(start_id, stop_id)
Migratable::ClusterProject.where(id: (start_id..stop_id))
end
end
end
end
Loading
Loading
@@ -45,6 +45,13 @@ module Gitlab
:update_cluster_role_binding,
to: :rbac_client
 
# RBAC methods delegates to the apis/rbac.authorization.k8s.io api
# group client
delegate :create_role_binding,
:get_role_binding,
:update_role_binding,
to: :rbac_client
# Deployments resource is currently on the apis/extensions api group
delegate :get_deployments,
to: :extensions_client
Loading
Loading
# frozen_string_literal: true
module Gitlab
module Kubernetes
class RoleBinding
attr_reader :role_name, :namespace, :service_account_name
def initialize(role_name:, namespace:, service_account_name:)
@role_name = role_name
@namespace = namespace
@service_account_name = service_account_name
end
def generate
::Kubeclient::Resource.new.tap do |resource|
resource.metadata = metadata
resource.roleRef = role_ref
resource.subjects = subjects
end
end
private
def metadata
{ name: "gitlab-#{namespace}", namespace: namespace }
end
def role_ref
{
apiGroup: 'rbac.authorization.k8s.io',
kind: 'Role',
name: role_name
}
end
def subjects
[
{
kind: 'ServiceAccount',
name: service_account_name,
namespace: namespace
}
]
end
end
end
end
Loading
Loading
@@ -308,6 +308,11 @@ describe Projects::ClustersController do
end
 
describe 'security' do
before do
allow(ClusterPlatformConfigureWorker).to receive(:perform_async)
stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace')
end
it { expect { go }.to be_allowed_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(project) }
it { expect { go }.to be_allowed_for(:maintainer).of(project) }
Loading
Loading
@@ -345,10 +350,6 @@ describe Projects::ClustersController do
end
 
describe 'security' do
before do
allow(ClusterProvisionWorker).to receive(:perform_async)
end
it { expect { go }.to be_allowed_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(project) }
it { expect { go }.to be_allowed_for(:maintainer).of(project) }
Loading
Loading
@@ -391,23 +392,7 @@ describe Projects::ClustersController do
end
 
describe 'PUT update' do
<<<<<<< HEAD
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
=======
before do
allow(ClusterPlatformConfigureWorker).to receive(:perform_async)
stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace')
end
context 'when cluster is provided by GCP' do
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let(:user) { create(:user) }
before do
project.add_maintainer(user)
sign_in(user)
end
>>>>>>> Extract actual_namespace logic to service
 
let(:params) do
{
Loading
Loading
@@ -429,6 +414,12 @@ describe Projects::ClustersController do
)
end
 
before do
allow(ClusterPlatformConfigureWorker).to receive(:perform_async)
stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace')
end
context 'when cluster is provided by GCP' do
it "updates and redirects back to show page" do
go
Loading
Loading
Loading
Loading
@@ -15,12 +15,67 @@ describe Gitlab::BackgroundMigration::PopulateClusterKubernetesNamespace, :migra
 
subject { migration.perform(cluster_projects.min, cluster_projects.max) }
 
it 'should populate namespace and service account information' do
subject
context 'when cluster projects dont have kubernetes namespace related' do
it 'should create kubernetes namespaces per cluster project' do
expect do
subject
end.to change(Clusters::KubernetesNamespace, :count).by(cluster_projects.count)
end
it 'should populate namespace and service account information' do
subject
cluster_projects.each do |cluster_project|
expect(cluster_project.kubernetes_namespace.namespace).not_to be_nil
expect(cluster_project.kubernetes_namespace.service_account_name).not_to be_nil
end
end
end
context 'when all cluster projects have kubernetes namespace related' do
before do
cluster_projects.each do |cluster_project|
create(:cluster_kubernetes_namespace, cluster_project: cluster_project)
end
end
it 'should not create any kubernetes namespace' do
expect do
subject
end.not_to change(Clusters::KubernetesNamespace, :count)
end
end
context 'when only some cluster projects have kubernetes namespace related' do
let(:with_kubernetes_namespace) { cluster_projects.first(6) }
let(:with_no_kubernetes_namespace) { cluster_projects.last(4) }
before do
with_kubernetes_namespace.each do |cluster_project|
create(:cluster_kubernetes_namespace, cluster_project: cluster_project)
end
end
it 'creates limited number of kubernetes namespace' do
expect do
subject
end.to change(Clusters::KubernetesNamespace, :count).by(with_no_kubernetes_namespace.count)
end
it 'should not modify clusters with kubernetes namespace' do
subject
with_kubernetes_namespace.each do |cluster_project|
expect(cluster_project.kubernetes_namespaces.count).to eq(1)
end
end
it 'should create kubernetes namespace for clusters that dont have one' do
subject
 
cluster_projects.each do |cluster_project|
expect(cluster_project.kubernetes_namespace.namespace).not_to be_nil
expect(cluster_project.kubernetes_namespace.service_account_name).not_to be_nil
with_no_kubernetes_namespace.each do |cluster_project|
expect(cluster_project.kubernetes_namespace).to be_present
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Kubernetes::RoleBinding, '#generate' do
let(:role_name) { 'edit' }
let(:namespace) { 'my-namespace' }
let(:service_account_name) { 'my-service-account' }
let(:subjects) do
[
{
kind: 'ServiceAccount',
name: service_account_name,
namespace: namespace
}
]
end
let(:role_ref) do
{
apiGroup: 'rbac.authorization.k8s.io',
kind: 'Role',
name: role_name
}
end
let(:resource) do
::Kubeclient::Resource.new(
metadata: { name: "gitlab-#{namespace}", namespace: namespace },
roleRef: role_ref,
subjects: subjects
)
end
subject do
described_class.new(
role_name: role_name,
namespace: namespace,
service_account_name: service_account_name
).generate
end
it 'should build a Kubeclient Resource' do
is_expected.to eq(resource)
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment