Commit 1184a332 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch '218250-build-service-from-integration' into 'master'

Find or initialize services with instance-level integrations

See merge request gitlab-org/gitlab!32654
parents f2302f60 f0832955
...@@ -1267,16 +1267,7 @@ class Project < ApplicationRecord ...@@ -1267,16 +1267,7 @@ class Project < ApplicationRecord
def find_or_initialize_service(name) def find_or_initialize_service(name)
return if disabled_services.include?(name) return if disabled_services.include?(name)
service = find_service(services, name) find_service(services, name) || build_from_instance_or_template(name) || public_send("build_#{name}_service") # rubocop:disable GitlabSecurity/PublicSend
return service if service
template = find_service(services_templates, name)
if template
Service.build_from_integration(id, template)
else
public_send("build_#{name}_service") # rubocop:disable GitlabSecurity/PublicSend
end
end end
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
...@@ -2444,6 +2435,22 @@ class Project < ApplicationRecord ...@@ -2444,6 +2435,22 @@ class Project < ApplicationRecord
services.find { |service| service.to_param == name } services.find { |service| service.to_param == name }
end end
def build_from_instance_or_template(name)
instance = find_service(services_instances, name)
return Service.build_from_integration(id, instance) if instance
template = find_service(services_templates, name)
return Service.build_from_integration(id, template) if template
end
def services_templates
@services_templates ||= Service.templates
end
def services_instances
@services_instances ||= Service.instances
end
def closest_namespace_setting(name) def closest_namespace_setting(name)
namespace.closest_setting(name) namespace.closest_setting(name)
end end
...@@ -2572,10 +2579,6 @@ class Project < ApplicationRecord ...@@ -2572,10 +2579,6 @@ class Project < ApplicationRecord
end end
end end
def services_templates
@services_templates ||= Service.where(template: true)
end
def ensure_pages_metadatum def ensure_pages_metadatum
pages_metadatum || create_pages_metadatum! pages_metadatum || create_pages_metadatum!
rescue ActiveRecord::RecordNotUnique rescue ActiveRecord::RecordNotUnique
......
...@@ -5241,12 +5241,10 @@ describe Project do ...@@ -5241,12 +5241,10 @@ describe Project do
end end
end end
describe "#find_or_initialize_services" do describe '#find_or_initialize_services' do
subject { build(:project) }
it 'returns only enabled services' do it 'returns only enabled services' do
allow(Service).to receive(:available_services_names).and_return(%w(prometheus pushover)) allow(Service).to receive(:available_services_names).and_return(%w[prometheus pushover])
allow(subject).to receive(:disabled_services).and_return(%w(prometheus)) allow(subject).to receive(:disabled_services).and_return(%w[prometheus])
services = subject.find_or_initialize_services services = subject.find_or_initialize_services
...@@ -5255,11 +5253,9 @@ describe Project do ...@@ -5255,11 +5253,9 @@ describe Project do
end end
end end
describe "#find_or_initialize_service" do describe '#find_or_initialize_service' do
subject { build(:project) }
it 'avoids N+1 database queries' do it 'avoids N+1 database queries' do
allow(Service).to receive(:available_services_names).and_return(%w(prometheus pushover)) allow(Service).to receive(:available_services_names).and_return(%w[prometheus pushover])
control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_service('prometheus') }.count control_count = ActiveRecord::QueryRecorder.new { subject.find_or_initialize_service('prometheus') }.count
...@@ -5268,11 +5264,51 @@ describe Project do ...@@ -5268,11 +5264,51 @@ describe Project do
expect { subject.find_or_initialize_service('prometheus') }.not_to exceed_query_limit(control_count) expect { subject.find_or_initialize_service('prometheus') }.not_to exceed_query_limit(control_count)
end end
it 'returns nil if service is disabled' do it 'returns nil if integration is disabled' do
allow(subject).to receive(:disabled_services).and_return(%w(prometheus)) allow(subject).to receive(:disabled_services).and_return(%w[prometheus])
expect(subject.find_or_initialize_service('prometheus')).to be_nil expect(subject.find_or_initialize_service('prometheus')).to be_nil
end end
context 'with an existing integration' do
subject { create(:project) }
before do
create(:prometheus_service, project: subject, api_url: 'https://prometheus.project.com/')
end
it 'retrieves the integration' do
expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.project.com/')
end
end
context 'with an instance-level and template integrations' do
before do
create(:prometheus_service, :instance, api_url: 'https://prometheus.instance.com/')
create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/')
end
it 'builds the service from the instance if exists' do
expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.instance.com/')
end
end
context 'with an instance-level and template integrations' do
before do
create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/')
end
it 'builds the service from the template if instance does not exists' do
expect(subject.find_or_initialize_service('prometheus').api_url).to eq('https://prometheus.template.com/')
end
end
context 'without an exisiting integration, nor instance-level or template' do
it 'builds the service if instance or template does not exists' do
expect(subject.find_or_initialize_service('prometheus')).to be_a(PrometheusService)
expect(subject.find_or_initialize_service('prometheus').api_url).to be_nil
end
end
end end
describe '.for_group' do describe '.for_group' do
......
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