From e3ca493876ab71ed29817a0af436fc563f564bbe Mon Sep 17 00:00:00 2001 From: Mayra Cabrera Date: Tue, 16 Oct 2018 15:03:59 -0500 Subject: Add Clusters::KubernetesNamespace model This model will be used to persist into database Kubernetes properties, such as namespace, service account name and service account token. --- app/models/clusters/cluster.rb | 3 ++ app/models/clusters/kubernetes_namespace.rb | 49 +++++++++++++++++++++++++++++ app/models/clusters/platforms/kubernetes.rb | 16 +++++++++- app/models/clusters/project.rb | 3 ++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 app/models/clusters/kubernetes_namespace.rb (limited to 'app') diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 20d53b8e620..95efecfc41d 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -31,6 +31,9 @@ module Clusters has_one :application_runner, class_name: 'Clusters::Applications::Runner' has_one :application_jupyter, class_name: 'Clusters::Applications::Jupyter' + has_many :kubernetes_namespaces + has_one :kubernetes_namespace, -> { order(id: :desc) }, class_name: 'Clusters::KubernetesNamespace' + accepts_nested_attributes_for :provider_gcp, update_only: true accepts_nested_attributes_for :platform_kubernetes, update_only: true diff --git a/app/models/clusters/kubernetes_namespace.rb b/app/models/clusters/kubernetes_namespace.rb new file mode 100644 index 00000000000..fb5f6b65d9d --- /dev/null +++ b/app/models/clusters/kubernetes_namespace.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Clusters + class KubernetesNamespace < ActiveRecord::Base + self.table_name = 'clusters_kubernetes_namespaces' + + belongs_to :cluster_project, class_name: 'Clusters::Project' + belongs_to :cluster, class_name: 'Clusters::Cluster' + belongs_to :project, class_name: '::Project' + has_one :platform_kubernetes, through: :cluster + + validates :namespace, presence: true + validates :namespace, uniqueness: { scope: :cluster_id } + + before_validation :set_namespace_and_service_account_to_default, on: :create + + 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_namespace_and_service_account_to_default + self.namespace ||= default_namespace + self.service_account_name ||= default_service_account_name + end + + def default_namespace + platform_kubernetes&.namespace.presence || project_namespace + end + + def default_service_account_name + "#{namespace}-service-account" + end + + def project_namespace + Gitlab::NamespaceSanitizer.sanitize(project_slug) + end + + def project_slug + "#{project.path}-#{project.id}".downcase + end + end +end diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb index 3a335909101..e8e943872de 100644 --- a/app/models/clusters/platforms/kubernetes.rb +++ b/app/models/clusters/platforms/kubernetes.rb @@ -7,6 +7,8 @@ module Clusters include ReactiveCaching include EnumWithNil + RESERVED_NAMESPACES = %w(gitlab-managed-apps).freeze + self.table_name = 'cluster_platforms_kubernetes' self.reactive_cache_key = ->(kubernetes) { [kubernetes.class.model_name.singular, kubernetes.id] } @@ -32,6 +34,8 @@ 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 @@ -45,6 +49,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 :kubernetes_namespace, to: :cluster alias_method :active?, :enabled? @@ -116,10 +121,19 @@ module Clusters end def default_namespace + kubernetes_namespace&.namespace.presence || fallback_default_namespace + end + + # DEPRECATED + # + # On 11.4 Clusters::KubernetesNamespace was introduced, this model will allow to + # have multiple namespaces per project. This method will be removed after migration + # has been completed. + def fallback_default_namespace return unless project slug = "#{project.path}-#{project.id}".downcase - slug.gsub(/[^-a-z0-9]/, '-').gsub(/^-+/, '') + Gitlab::NamespaceSanitizer.sanitize(slug) end def build_kube_client!(api_groups: ['api'], api_version: 'v1') diff --git a/app/models/clusters/project.rb b/app/models/clusters/project.rb index 839ce796081..15092b1c9d2 100644 --- a/app/models/clusters/project.rb +++ b/app/models/clusters/project.rb @@ -6,5 +6,8 @@ module Clusters 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 + has_one :kubernetes_namespace, -> { order(id: :desc) }, class_name: 'Clusters::KubernetesNamespace', foreign_key: :cluster_project_id end end -- cgit v1.2.1