Commit e308bb0c authored by Pawel Chojnacki's avatar Pawel Chojnacki

Cleanup implementation and add cluster finding tests

parent 9c0b10da
......@@ -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
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment