summaryrefslogtreecommitdiff
path: root/app/models/clusters/cluster.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/clusters/cluster.rb')
-rw-r--r--app/models/clusters/cluster.rb92
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: