diff options
Diffstat (limited to 'app/models/clusters/cluster.rb')
-rw-r--r-- | app/models/clusters/cluster.rb | 92 |
1 files changed, 66 insertions, 26 deletions
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 430a9b3c43e..83f558af1a1 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -26,6 +26,8 @@ module Clusters KUBE_INGRESS_BASE_DOMAIN = 'KUBE_INGRESS_BASE_DOMAIN' APPLICATIONS_ASSOCIATIONS = APPLICATIONS.values.map(&:association_name).freeze + self.reactive_cache_work_type = :external_dependency + belongs_to :user belongs_to :management_project, class_name: '::Project', optional: true @@ -33,6 +35,7 @@ module Clusters has_many :projects, through: :cluster_projects, class_name: '::Project' has_one :cluster_project, -> { order(id: :desc) }, class_name: 'Clusters::Project' has_many :deployment_clusters + has_many :deployments, inverse_of: :cluster has_many :cluster_groups, class_name: 'Clusters::Group' has_many :groups, through: :cluster_groups, class_name: '::Group' @@ -203,10 +206,16 @@ module Clusters end end + def nodes + with_reactive_cache do |data| + data[:nodes] + end + end + def calculate_reactive_cache return unless enabled? - { connection_status: retrieve_connection_status } + { connection_status: retrieve_connection_status, nodes: retrieve_nodes } end def persisted_applications @@ -214,11 +223,19 @@ module Clusters end def applications - APPLICATIONS_ASSOCIATIONS.map do |association_name| - public_send(association_name) || public_send("build_#{association_name}") # rubocop:disable GitlabSecurity/PublicSend + APPLICATIONS.each_value.map do |application_class| + find_or_build_application(application_class) end end + def find_or_build_application(application_class) + raise ArgumentError, "#{application_class} is not in APPLICATIONS" unless APPLICATIONS.value?(application_class) + + association_name = application_class.association_name + + public_send(association_name) || public_send("build_#{association_name}") # rubocop:disable GitlabSecurity/PublicSend + end + def provider if gcp? provider_gcp @@ -345,32 +362,55 @@ module Clusters end def retrieve_connection_status - kubeclient.core_client.discover - rescue *Gitlab::Kubernetes::Errors::CONNECTION - :unreachable - rescue *Gitlab::Kubernetes::Errors::AUTHENTICATION - :authentication_failure - rescue Kubeclient::HttpError => e - kubeclient_error_status(e.message) - rescue => e - Gitlab::ErrorTracking.track_exception(e, cluster_id: id) - - :unknown_failure - else - :connected - end - - # KubeClient uses the same error class - # For connection errors (eg. timeout) and - # for Kubernetes errors. - def kubeclient_error_status(message) - if message&.match?(/timed out|timeout/i) - :unreachable - else - :authentication_failure + result = ::Gitlab::Kubernetes::KubeClient.graceful_request(id) { kubeclient.core_client.discover } + result[:status] + end + + def retrieve_nodes + result = ::Gitlab::Kubernetes::KubeClient.graceful_request(id) { kubeclient.get_nodes } + cluster_nodes = result[:response].to_a + + result = ::Gitlab::Kubernetes::KubeClient.graceful_request(id) { kubeclient.metrics_client.get_nodes } + nodes_metrics = result[:response].to_a + + cluster_nodes.inject([]) do |memo, node| + sliced_node = filter_relevant_node_attributes(node) + + matched_node_metric = nodes_metrics.find { |node_metric| node_metric.metadata.name == node.metadata.name } + + sliced_node_metrics = matched_node_metric ? filter_relevant_node_metrics_attributes(matched_node_metric) : {} + + memo << sliced_node.merge(sliced_node_metrics) end end + def filter_relevant_node_attributes(node) + { + 'metadata' => { + 'name' => node.metadata.name + }, + 'status' => { + 'capacity' => { + 'cpu' => node.status.capacity.cpu, + 'memory' => node.status.capacity.memory + }, + 'allocatable' => { + 'cpu' => node.status.allocatable.cpu, + 'memory' => node.status.allocatable.memory + } + } + } + end + + def filter_relevant_node_metrics_attributes(node_metrics) + { + 'usage' => { + 'cpu' => node_metrics.usage.cpu, + 'memory' => node_metrics.usage.memory + } + } + end + # To keep backward compatibility with AUTO_DEVOPS_DOMAIN # environment variable, we need to ensure KUBE_INGRESS_BASE_DOMAIN # is set if AUTO_DEVOPS_DOMAIN is set on any of the following options: |