summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Chojnacki <pawel@chojnacki.ws>2018-01-04 13:56:07 +0100
committerPawel Chojnacki <pawel@chojnacki.ws>2018-01-04 13:56:07 +0100
commite308bb0cd2226297093ffb488a4d97e3c02c4883 (patch)
treedd3087cc2561ae4a186076dca816eaf28af822ae
parent9c0b10da4147470050c1ae144fc75c2963eeb4ba (diff)
downloadgitlab-ce-e308bb0cd2226297093ffb488a4d97e3c02c4883.tar.gz
Cleanup implementation and add cluster finding tests
-rw-r--r--app/models/clusters/cluster.rb3
-rw-r--r--app/models/environment.rb12
-rw-r--r--app/models/project_services/prometheus_service.rb22
-rw-r--r--lib/gitlab/prometheus_client.rb2
-rw-r--r--spec/models/project_services/prometheus_service_spec.rb127
5 files changed, 147 insertions, 19 deletions
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index 5ecbd4cbceb..8678f70f78c 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -49,6 +49,9 @@ module Clusters
scope :enabled, -> { where(enabled: true) }
scope :disabled, -> { where(enabled: false) }
+ scope :for_environment, -> (env) { where(environment_scope: ['*', '', env.slug]) }
+ scope :for_all_environments, -> { where(environment_scope: ['*', '']) }
+
def status_name
if provider
provider.status_name
diff --git a/app/models/environment.rb b/app/models/environment.rb
index d895550784d..bf69b4c50f0 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -163,18 +163,6 @@ class Environment < ActiveRecord::Base
end
end
- def enabled_clusters
- slug = self.slug
- result = project.clusters.enabled.select do |cluster|
- scope = cluster.environment_scope || '*'
- File.fnmatch(scope, slug)
- end
-
- # sort results by descending order based on environment_scope being longer
- # thus more closely matching environment slug
- result.sort_by { |cluster| cluster.environment_scope.length }.reverse!
- end
-
def slug
super.presence || generate_slug
end
diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb
index 2fb94c1facb..580e2c01aaa 100644
--- a/app/models/project_services/prometheus_service.rb
+++ b/app/models/project_services/prometheus_service.rb
@@ -116,31 +116,41 @@ class PrometheusService < MonitoringService
{ success: false, result: err.message }
end
- def client(environment_id)
+ def client(environment_id = nil)
if manual_configuration?
Gitlab::PrometheusClient.new(RestClient::Resource.new(api_url))
else
cluster = cluster_with_prometheus(environment_id)
raise Gitlab::PrometheusError, "couldn't find cluster with Prometheus installed" unless cluster
+ rest_client = client_from_cluster(cluster)
- Gitlab::PrometheusClient.new(cluster.application_prometheus.proxy_client)
+ raise Gitlab::PrometheusError, "couldn't create proxy Prometheus client" unless rest_client
+ Gitlab::PrometheusClient.new(rest_client)
end
end
def prometheus_installed?
- cluster_with_prometheus.present?
+ project.clusters.enabled.any? { |cluster| cluster.application_prometheus&.installed? }
end
private
def cluster_with_prometheus(environment_id = nil)
clusters = if environment_id
- ::Environment.find_by(id: environment_id).try(:enabled_clusters) || []
+ ::Environment.find_by(id: environment_id).try do |env|
+ # sort results by descending order based on environment_scope being longer
+ # thus more closely matching environment slug
+ project.clusters.enabled.for_environment(env).sort_by { |c| c.environment_scope&.length }.reverse!
+ end
else
- project.clusters.enabled.select { |c| c.environment_scope == '*' || c.environment_scope == '' }
+ project.clusters.enabled.for_all_environments
end
- clusters.detect { |cluster| cluster.application_prometheus&.installed? }
+ clusters&.detect { |cluster| cluster.application_prometheus&.installed? }
+ end
+
+ def client_from_cluster(cluster)
+ cluster.application_prometheus.proxy_client
end
def rename_data_to_metrics(metrics)
diff --git a/lib/gitlab/prometheus_client.rb b/lib/gitlab/prometheus_client.rb
index 79f66b42c21..8264501b1ae 100644
--- a/lib/gitlab/prometheus_client.rb
+++ b/lib/gitlab/prometheus_client.rb
@@ -6,7 +6,7 @@ module Gitlab
attr_reader :rest_client, :headers
def initialize(rest_client)
- @rest_client = rest_client || RestClient::Resource.new(api_url)
+ @rest_client = rest_client
end
def ping
diff --git a/spec/models/project_services/prometheus_service_spec.rb b/spec/models/project_services/prometheus_service_spec.rb
index bf39e8d7a39..3cbd0bb75f7 100644
--- a/spec/models/project_services/prometheus_service_spec.rb
+++ b/spec/models/project_services/prometheus_service_spec.rb
@@ -8,6 +8,8 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
let(:service) { project.prometheus_service }
let(:environment_query) { Gitlab::Prometheus::Queries::EnvironmentQuery }
+ subject { project.prometheus_service }
+
describe "Associations" do
it { is_expected.to belong_to :project }
end
@@ -132,4 +134,129 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
end
end
end
+
+ describe '#client' do
+ context 'manual configuration is enabled' do
+ let(:api_url) { 'http://some_url' }
+ before do
+ subject.manual_configuration = true
+ subject.api_url = api_url
+ end
+
+ it 'returns simple rest client from api_url' do
+ expect(subject.client).to be_instance_of(Gitlab::PrometheusClient)
+ expect(subject.client.rest_client.url).to eq(api_url)
+ end
+ end
+
+ context 'manual configuration is disabled' do
+ let!(:cluster_for_all) { create(:cluster, environment_scope: '*', projects: [project]) }
+ let!(:cluster_for_dev) { create(:cluster, environment_scope: 'dev', projects: [project]) }
+
+ let!(:prometheus_for_dev) { create(:clusters_applications_prometheus, :installed, cluster: cluster_for_dev) }
+ let(:proxy_client) { double('proxy_client') }
+
+ before do
+ subject.manual_configuration = false
+ end
+
+ context 'with cluster for all environments with prometheus installed' do
+ let!(:prometheus_for_all) { create(:clusters_applications_prometheus, :installed, cluster: cluster_for_all) }
+
+ context 'without environment supplied' do
+ it 'returns client handling all environments' do
+ expect(subject).to receive(:client_from_cluster).with(cluster_for_all).and_return(proxy_client).twice
+
+ expect(subject.client).to be_instance_of(Gitlab::PrometheusClient)
+ expect(subject.client.rest_client).to eq(proxy_client)
+ end
+ end
+
+ context 'with dev environment supplied' do
+ let!(:environment) { create(:environment, project: project, name: 'dev') }
+
+ it 'returns dev cluster client' do
+ expect(subject).to receive(:client_from_cluster).with(cluster_for_dev).and_return(proxy_client).twice
+
+ expect(subject.client(environment.id)).to be_instance_of(Gitlab::PrometheusClient)
+ expect(subject.client(environment.id).rest_client).to eq(proxy_client)
+ end
+ end
+
+ context 'with prod environment supplied' do
+ let!(:environment) { create(:environment, project: project, name: 'prod') }
+
+ it 'returns dev cluster client' do
+ expect(subject).to receive(:client_from_cluster).with(cluster_for_all).and_return(proxy_client).twice
+
+ expect(subject.client(environment.id)).to be_instance_of(Gitlab::PrometheusClient)
+ expect(subject.client(environment.id).rest_client).to eq(proxy_client)
+ end
+ end
+ end
+
+ context 'with cluster for all environments without prometheus installed' do
+ context 'without environment supplied' do
+ it 'raises PrometheusError because cluster was not found' do
+ expect{subject.client}.to raise_error(Gitlab::PrometheusError, /couldn't find cluster with Prometheus installed/)
+ end
+ end
+
+ context 'with dev environment supplied' do
+ let!(:environment) { create(:environment, project: project, name: 'dev') }
+
+ it 'returns dev cluster client' do
+ expect(subject).to receive(:client_from_cluster).with(cluster_for_dev).and_return(proxy_client).twice
+
+ expect(subject.client(environment.id)).to be_instance_of(Gitlab::PrometheusClient)
+ expect(subject.client(environment.id).rest_client).to eq(proxy_client)
+ end
+ end
+
+ context 'with prod environment supplied' do
+ let!(:environment) { create(:environment, project: project, name: 'prod') }
+
+ it 'raises PrometheusError because cluster was not found' do
+ expect{subject.client}.to raise_error(Gitlab::PrometheusError, /couldn't find cluster with Prometheus installed/)
+ end
+ end
+ end
+ end
+ end
+
+ describe '#prometheus_installed?' do
+ subject { project.prometheus_service }
+
+ context 'clusters with installed prometheus' do
+ let!(:cluster) { create(:cluster, projects: [project]) }
+ let!(:prometheus) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
+
+ it 'returns true' do
+ expect(subject.prometheus_installed?).to be(true)
+ end
+ end
+
+ context 'clusters without prometheus installed' do
+ let(:cluster) { create(:cluster, projects: [project]) }
+ let!(:prometheus) { create(:clusters_applications_prometheus, cluster: cluster) }
+
+ it 'returns false' do
+ expect(subject.prometheus_installed?).to be(false)
+ end
+ end
+
+ context 'clusters without prometheus' do
+ let(:cluster) { create(:cluster, projects: [project]) }
+
+ it 'returns false' do
+ expect(subject.prometheus_installed?).to be(false)
+ end
+ end
+
+ context 'no clusters' do
+ it 'returns false' do
+ expect(subject.prometheus_installed?).to be(false)
+ end
+ end
+ end
end