diff options
-rw-r--r-- | app/helpers/environments_helper.rb | 19 | ||||
-rw-r--r-- | app/models/clusters/applications/prometheus.rb | 8 | ||||
-rw-r--r-- | app/models/concerns/prometheus_adapter.rb | 15 | ||||
-rw-r--r-- | app/models/internal_id.rb | 2 | ||||
-rw-r--r-- | app/services/clusters/applications/check_installation_progress_service.rb | 6 | ||||
-rw-r--r-- | app/services/prometheus/adapter_service.rb | 2 | ||||
-rw-r--r-- | app/views/projects/environments/metrics.html.haml | 22 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/config_map.rb | 10 | ||||
-rw-r--r-- | lib/gitlab/kubernetes/helm/api.rb | 20 | ||||
-rw-r--r-- | lib/gitlab/prometheus/queries/additional_metrics_deployment_query.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/prometheus/queries/additional_metrics_environment_query.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/prometheus/queries/query_additional_metrics.rb | 2 | ||||
-rw-r--r-- | spec/lib/gitlab/kubernetes/config_map_spec.rb | 6 | ||||
-rw-r--r-- | spec/lib/gitlab/kubernetes/helm/api_spec.rb | 12 | ||||
-rw-r--r-- | spec/models/clusters/applications/prometheus_spec.rb | 57 | ||||
-rw-r--r-- | spec/support/prometheus/additional_metrics_shared_examples.rb | 7 |
16 files changed, 136 insertions, 54 deletions
diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb index 4ce89f89fa9..c005ecbb56b 100644 --- a/app/helpers/environments_helper.rb +++ b/app/helpers/environments_helper.rb @@ -4,4 +4,23 @@ module EnvironmentsHelper endpoint: project_environments_path(@project, format: :json) } end + + def metrics_data(project, environment) + { + "settings-path" => edit_project_service_path(project, 'prometheus'), + "clusters-path" => project_clusters_path(project), + "current-environment-name": environment.name, + "documentation-path" => help_page_path('administration/monitoring/prometheus/index.md'), + "empty-getting-started-svg-path" => image_path('illustrations/monitoring/getting_started.svg'), + "empty-loading-svg-path" => image_path('illustrations/monitoring/loading.svg'), + "empty-no-data-svg-path" => image_path('illustrations/monitoring/no_data.svg'), + "empty-unable-to-connect-svg-path" => image_path('illustrations/monitoring/unable_to_connect.svg'), + "metrics-endpoint" => additional_metrics_project_environment_path(project, environment, format: :json), + "deployment-endpoint" => project_environment_deployments_path(project, environment, format: :json), + "environments-endpoint": project_environments_path(project, format: :json), + "project-path" => project_path(project), + "tags-path" => project_tags_path(project), + "has-metrics" => "#{environment.has_metrics?}" + } + end end diff --git a/app/models/clusters/applications/prometheus.rb b/app/models/clusters/applications/prometheus.rb index 48137c2ed68..ea6ec4d6b03 100644 --- a/app/models/clusters/applications/prometheus.rb +++ b/app/models/clusters/applications/prometheus.rb @@ -21,6 +21,14 @@ module Clusters end end + def ready_status + [:installed] + end + + def ready? + ready_status.include?(status_name) + end + def chart 'stable/prometheus' end diff --git a/app/models/concerns/prometheus_adapter.rb b/app/models/concerns/prometheus_adapter.rb index 18cbbd871a1..9c36f633395 100644 --- a/app/models/concerns/prometheus_adapter.rb +++ b/app/models/concerns/prometheus_adapter.rb @@ -24,11 +24,10 @@ module PrometheusAdapter def query(query_name, *args) return unless can_query? - query_class = Gitlab::Prometheus::Queries.const_get("#{query_name.to_s.classify}Query") + query_class = query_klass_for(query_name) + query_args = build_query_args(*args) - args.map!(&:id) - - with_reactive_cache(query_class.name, *args, &query_class.method(:transform_reactive_result)) + with_reactive_cache(query_class.name, *query_args, &query_class.method(:transform_reactive_result)) end # Cache metrics for specific environment @@ -44,5 +43,13 @@ module PrometheusAdapter rescue Gitlab::PrometheusClient::Error => err { success: false, result: err.message } end + + def query_klass_for(query_name) + Gitlab::Prometheus::Queries.const_get("#{query_name.to_s.classify}Query") + end + + def build_query_args(*args) + args.map(&:id) + end end end diff --git a/app/models/internal_id.rb b/app/models/internal_id.rb index f50f28deffe..6a3e27625e9 100644 --- a/app/models/internal_id.rb +++ b/app/models/internal_id.rb @@ -14,7 +14,7 @@ class InternalId < ActiveRecord::Base belongs_to :project belongs_to :namespace - enum usage: { issues: 0, merge_requests: 1, deployments: 2, milestones: 3, epics: 4, ci_pipelines: 5 } + enum usage: { issues: 0, merge_requests: 1, deployments: 2, milestones: 3, epics: 4, ci_pipelines: 5, prometheus_alerts: 6 } validates :usage, presence: true diff --git a/app/services/clusters/applications/check_installation_progress_service.rb b/app/services/clusters/applications/check_installation_progress_service.rb index 4640c5a2d4b..a1165b0ab28 100644 --- a/app/services/clusters/applications/check_installation_progress_service.rb +++ b/app/services/clusters/applications/check_installation_progress_service.rb @@ -50,17 +50,17 @@ module Clusters end def remove_installation_pod - helm_api.delete_installation_pod!(install_command.pod_name) + helm_api.delete_pod!(install_command.pod_name) rescue # no-op end def installation_phase - helm_api.installation_status(install_command.pod_name) + helm_api.status(install_command.pod_name) end def installation_errors - helm_api.installation_log(install_command.pod_name) + helm_api.log(install_command.pod_name) end end end diff --git a/app/services/prometheus/adapter_service.rb b/app/services/prometheus/adapter_service.rb index cbba79690c5..a791845ba20 100644 --- a/app/services/prometheus/adapter_service.rb +++ b/app/services/prometheus/adapter_service.rb @@ -30,7 +30,7 @@ module Prometheus return unless deployment_platform.respond_to?(:cluster) cluster = deployment_platform.cluster - return unless cluster.application_prometheus&.installed? + return unless cluster.application_prometheus&.ready? cluster.application_prometheus end diff --git a/app/views/projects/environments/metrics.html.haml b/app/views/projects/environments/metrics.html.haml index 290970a1045..af86b8e8e67 100644 --- a/app/views/projects/environments/metrics.html.haml +++ b/app/views/projects/environments/metrics.html.haml @@ -2,17 +2,11 @@ - page_title "Metrics for environment", @environment.name .prometheus-container{ class: container_class } - #prometheus-graphs{ data: { "settings-path": edit_project_service_path(@project, 'prometheus'), - "clusters-path": project_clusters_path(@project), - "current-environment-name": @environment.name, - "documentation-path": help_page_path('administration/monitoring/prometheus/index.md'), - "empty-getting-started-svg-path": image_path('illustrations/monitoring/getting_started.svg'), - "empty-loading-svg-path": image_path('illustrations/monitoring/loading.svg'), - "empty-no-data-svg-path": image_path('illustrations/monitoring/no_data.svg'), - "empty-unable-to-connect-svg-path": image_path('illustrations/monitoring/unable_to_connect.svg'), - "metrics-endpoint": additional_metrics_project_environment_path(@project, @environment, format: :json), - "deployment-endpoint": project_environment_deployments_path(@project, @environment, format: :json), - "environments-endpoint": project_environments_path(@project, format: :json), - "project-path": project_path(@project), - "tags-path": project_tags_path(@project), - "has-metrics": "#{@environment.has_metrics?}" } } + .top-area + .row + .col-sm-6 + %h3 + Environment: + = link_to @environment.name, environment_path(@environment) + + #prometheus-graphs{ data: metrics_data(@project, @environment) } diff --git a/lib/gitlab/kubernetes/config_map.rb b/lib/gitlab/kubernetes/config_map.rb index 95e1054919d..8a8a59a9cd4 100644 --- a/lib/gitlab/kubernetes/config_map.rb +++ b/lib/gitlab/kubernetes/config_map.rb @@ -1,7 +1,7 @@ module Gitlab module Kubernetes class ConfigMap - def initialize(name, values) + def initialize(name, values = "") @name = name @values = values end @@ -13,6 +13,10 @@ module Gitlab resource end + def config_map_name + "values-content-configuration-#{name}" + end + private attr_reader :name, :values @@ -25,10 +29,6 @@ module Gitlab } end - def config_map_name - "values-content-configuration-#{name}" - end - def namespace Gitlab::Kubernetes::Helm::NAMESPACE end diff --git a/lib/gitlab/kubernetes/helm/api.rb b/lib/gitlab/kubernetes/helm/api.rb index 2edd34109ba..54332d0cc4e 100644 --- a/lib/gitlab/kubernetes/helm/api.rb +++ b/lib/gitlab/kubernetes/helm/api.rb @@ -2,15 +2,17 @@ module Gitlab module Kubernetes module Helm class Api + attr_reader :kubeclient, :namespace + def initialize(kubeclient) @kubeclient = kubeclient @namespace = Gitlab::Kubernetes::Namespace.new(Gitlab::Kubernetes::Helm::NAMESPACE, kubeclient) end def install(command) - @namespace.ensure_exists! + namespace.ensure_exists! create_config_map(command) if command.config_map? - @kubeclient.create_pod(command.pod_resource) + kubeclient.create_pod(command.pod_resource) end ## @@ -20,23 +22,23 @@ module Gitlab # # values: "Pending", "Running", "Succeeded", "Failed", "Unknown" # - def installation_status(pod_name) - @kubeclient.get_pod(pod_name, @namespace.name).status.phase + def status(pod_name) + kubeclient.get_pod(pod_name, namespace.name).status.phase end - def installation_log(pod_name) - @kubeclient.get_pod_log(pod_name, @namespace.name).body + def log(pod_name) + kubeclient.get_pod_log(pod_name, namespace.name).body end - def delete_installation_pod!(pod_name) - @kubeclient.delete_pod(pod_name, @namespace.name) + def delete_pod!(pod_name) + kubeclient.delete_pod(pod_name, namespace.name) end private def create_config_map(command) command.config_map_resource.tap do |config_map_resource| - @kubeclient.create_config_map(config_map_resource) + kubeclient.create_config_map(config_map_resource) end end end diff --git a/lib/gitlab/prometheus/queries/additional_metrics_deployment_query.rb b/lib/gitlab/prometheus/queries/additional_metrics_deployment_query.rb index e677ec84cd4..8534afcc849 100644 --- a/lib/gitlab/prometheus/queries/additional_metrics_deployment_query.rb +++ b/lib/gitlab/prometheus/queries/additional_metrics_deployment_query.rb @@ -8,6 +8,7 @@ module Gitlab Deployment.find_by(id: deployment_id).try do |deployment| query_metrics( deployment.project, + deployment.environment, common_query_context( deployment.environment, timeframe_start: (deployment.created_at - 30.minutes).to_f, diff --git a/lib/gitlab/prometheus/queries/additional_metrics_environment_query.rb b/lib/gitlab/prometheus/queries/additional_metrics_environment_query.rb index 9273e69e158..e3af217b202 100644 --- a/lib/gitlab/prometheus/queries/additional_metrics_environment_query.rb +++ b/lib/gitlab/prometheus/queries/additional_metrics_environment_query.rb @@ -8,6 +8,7 @@ module Gitlab ::Environment.find_by(id: environment_id).try do |environment| query_metrics( environment.project, + environment, common_query_context(environment, timeframe_start: 8.hours.ago.to_f, timeframe_end: Time.now.to_f) ) end diff --git a/lib/gitlab/prometheus/queries/query_additional_metrics.rb b/lib/gitlab/prometheus/queries/query_additional_metrics.rb index f5879de1e94..ddddc299240 100644 --- a/lib/gitlab/prometheus/queries/query_additional_metrics.rb +++ b/lib/gitlab/prometheus/queries/query_additional_metrics.rb @@ -2,7 +2,7 @@ module Gitlab module Prometheus module Queries module QueryAdditionalMetrics - def query_metrics(project, query_context) + def query_metrics(project, environment, query_context) matched_metrics(project).map(&query_group(query_context)) .select(&method(:group_with_any_metrics)) end diff --git a/spec/lib/gitlab/kubernetes/config_map_spec.rb b/spec/lib/gitlab/kubernetes/config_map_spec.rb index 33dfa461202..e253b291277 100644 --- a/spec/lib/gitlab/kubernetes/config_map_spec.rb +++ b/spec/lib/gitlab/kubernetes/config_map_spec.rb @@ -22,4 +22,10 @@ describe Gitlab::Kubernetes::ConfigMap do is_expected.to eq(resource) end end + + describe '#config_map_name' do + it 'returns the config_map name' do + expect(config_map.config_map_name).to eq("values-content-configuration-#{application.name}") + end + end end diff --git a/spec/lib/gitlab/kubernetes/helm/api_spec.rb b/spec/lib/gitlab/kubernetes/helm/api_spec.rb index aa7e43dfb16..6e9b4ca0869 100644 --- a/spec/lib/gitlab/kubernetes/helm/api_spec.rb +++ b/spec/lib/gitlab/kubernetes/helm/api_spec.rb @@ -49,33 +49,33 @@ describe Gitlab::Kubernetes::Helm::Api do end end - describe '#installation_status' do + describe '#status' do let(:phase) { Gitlab::Kubernetes::Pod::RUNNING } let(:pod) { Kubeclient::Resource.new(status: { phase: phase }) } # partial representation it 'fetches POD phase from kubernetes cluster' do expect(client).to receive(:get_pod).with(command.pod_name, gitlab_namespace).once.and_return(pod) - expect(subject.installation_status(command.pod_name)).to eq(phase) + expect(subject.status(command.pod_name)).to eq(phase) end end - describe '#installation_log' do + describe '#log' do let(:log) { 'some output' } let(:response) { RestClient::Response.new(log) } it 'fetches POD phase from kubernetes cluster' do expect(client).to receive(:get_pod_log).with(command.pod_name, gitlab_namespace).once.and_return(response) - expect(subject.installation_log(command.pod_name)).to eq(log) + expect(subject.log(command.pod_name)).to eq(log) end end - describe '#delete_installation_pod!' do + describe '#delete_pod!' do it 'deletes the POD from kubernetes cluster' do expect(client).to receive(:delete_pod).with(command.pod_name, gitlab_namespace).once - subject.delete_installation_pod!(command.pod_name) + subject.delete_pod!(command.pod_name) end end end diff --git a/spec/models/clusters/applications/prometheus_spec.rb b/spec/models/clusters/applications/prometheus_spec.rb index efd57040005..784b60fef8d 100644 --- a/spec/models/clusters/applications/prometheus_spec.rb +++ b/spec/models/clusters/applications/prometheus_spec.rb @@ -34,6 +34,47 @@ describe Clusters::Applications::Prometheus do end end + describe '#ready' do + let(:project) { create(:project) } + let(:cluster) { create(:cluster, projects: [project]) } + + it 'returns true when installed' do + application = build(:clusters_applications_prometheus, :installed, cluster: cluster) + + expect(application.ready?).to be true + end + + it 'returns false when not_installable' do + application = build(:clusters_applications_prometheus, :not_installable, cluster: cluster) + + expect(application.ready?).to be false + end + + it 'returns false when installable' do + application = build(:clusters_applications_prometheus, :installable, cluster: cluster) + + expect(application.ready?).to be false + end + + it 'returns false when scheduled' do + application = build(:clusters_applications_prometheus, :scheduled, cluster: cluster) + + expect(application.ready?).to be false + end + + it 'returns false when installing' do + application = build(:clusters_applications_prometheus, :installing, cluster: cluster) + + expect(application.ready?).to be false + end + + it 'returns false when errored' do + application = build(:clusters_applications_prometheus, :errored, cluster: cluster) + + expect(application.ready?).to be false + end + end + describe '#prometheus_client' do context 'cluster is nil' do it 'returns nil' do @@ -102,15 +143,17 @@ describe Clusters::Applications::Prometheus do let(:kubeclient) { double('kubernetes client') } let(:prometheus) { create(:clusters_applications_prometheus) } - subject { prometheus.install_command } - - it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) } + it 'returns an instance of Gitlab::Kubernetes::Helm::InstallCommand' do + expect(prometheus.install_command).to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) + end it 'should be initialized with 3 arguments' do - expect(subject.name).to eq('prometheus') - expect(subject.chart).to eq('stable/prometheus') - expect(subject.version).to eq('6.7.3') - expect(subject.values).to eq(prometheus.values) + command = prometheus.install_command + + expect(command.name).to eq('prometheus') + expect(command.chart).to eq('stable/prometheus') + expect(command.version).to eq('6.7.3') + expect(command.values).to eq(prometheus.values) end end diff --git a/spec/support/prometheus/additional_metrics_shared_examples.rb b/spec/support/prometheus/additional_metrics_shared_examples.rb index c7c3346d39e..0fd67531c3b 100644 --- a/spec/support/prometheus/additional_metrics_shared_examples.rb +++ b/spec/support/prometheus/additional_metrics_shared_examples.rb @@ -25,7 +25,7 @@ RSpec.shared_examples 'additional metrics query' do shared_examples 'query context containing environment slug and filter' do it 'contains ci_environment_slug' do - expect(subject).to receive(:query_metrics).with(project, hash_including(ci_environment_slug: environment.slug)) + expect(subject).to receive(:query_metrics).with(project, environment, hash_including(ci_environment_slug: environment.slug)) subject.query(*query_params) end @@ -33,6 +33,7 @@ RSpec.shared_examples 'additional metrics query' do it 'contains environment filter' do expect(subject).to receive(:query_metrics).with( project, + environment, hash_including( environment_filter: "container_name!=\"POD\",environment=\"#{environment.slug}\"" ) @@ -50,7 +51,7 @@ RSpec.shared_examples 'additional metrics query' do it_behaves_like 'query context containing environment slug and filter' it 'query context contains kube_namespace' do - expect(subject).to receive(:query_metrics).with(project, hash_including(kube_namespace: kube_namespace)) + expect(subject).to receive(:query_metrics).with(project, environment, hash_including(kube_namespace: kube_namespace)) subject.query(*query_params) end @@ -74,7 +75,7 @@ RSpec.shared_examples 'additional metrics query' do it_behaves_like 'query context containing environment slug and filter' it 'query context contains empty kube_namespace' do - expect(subject).to receive(:query_metrics).with(project, hash_including(kube_namespace: '')) + expect(subject).to receive(:query_metrics).with(project, environment, hash_including(kube_namespace: '')) subject.query(*query_params) end |