Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 12:55:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 12:55:51 +0300
commite8d2c2579383897a1dd7f9debd359abe8ae8373d (patch)
treec42be41678c2586d49a75cabce89322082698334 /app/models/integrations
parentfc845b37ec3a90aaa719975f607740c22ba6a113 (diff)
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'app/models/integrations')
-rw-r--r--app/models/integrations/bamboo.rb6
-rw-r--r--app/models/integrations/base_monitoring.rb23
-rw-r--r--app/models/integrations/base_slash_commands.rb2
-rw-r--r--app/models/integrations/buildkite.rb28
-rw-r--r--app/models/integrations/campfire.rb32
-rw-r--r--app/models/integrations/confluence.rb2
-rw-r--r--app/models/integrations/datadog.rb50
-rw-r--r--app/models/integrations/discord.rb2
-rw-r--r--app/models/integrations/drone_ci.rb36
-rw-r--r--app/models/integrations/ewm.rb2
-rw-r--r--app/models/integrations/jenkins.rb14
-rw-r--r--app/models/integrations/jira.rb15
-rw-r--r--app/models/integrations/mattermost_slash_commands.rb2
-rw-r--r--app/models/integrations/mock_ci.rb2
-rw-r--r--app/models/integrations/mock_monitoring.rb25
-rw-r--r--app/models/integrations/packagist.rb14
-rw-r--r--app/models/integrations/pipelines_email.rb2
-rw-r--r--app/models/integrations/pivotaltracker.rb17
-rw-r--r--app/models/integrations/prometheus.rb203
-rw-r--r--app/models/integrations/teamcity.rb15
20 files changed, 378 insertions, 114 deletions
diff --git a/app/models/integrations/bamboo.rb b/app/models/integrations/bamboo.rb
index fef2774c593..590be52151c 100644
--- a/app/models/integrations/bamboo.rb
+++ b/app/models/integrations/bamboo.rb
@@ -18,14 +18,8 @@ module Integrations
attr_accessor :response
- after_save :compose_service_hook, if: :activated?
before_update :reset_password
- def compose_service_hook
- hook = service_hook || build_service_hook
- hook.save
- end
-
def reset_password
if bamboo_url_changed? && !password_touched?
self.password = nil
diff --git a/app/models/integrations/base_monitoring.rb b/app/models/integrations/base_monitoring.rb
new file mode 100644
index 00000000000..280eeda7c6c
--- /dev/null
+++ b/app/models/integrations/base_monitoring.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+# Base class for monitoring services
+#
+# These services integrate with a deployment solution like Prometheus
+# to provide additional features for environments.
+module Integrations
+ class BaseMonitoring < Integration
+ default_value_for :category, 'monitoring'
+
+ def self.supported_events
+ %w()
+ end
+
+ def can_query?
+ raise NotImplementedError
+ end
+
+ def query(_, *_)
+ raise NotImplementedError
+ end
+ end
+end
diff --git a/app/models/integrations/base_slash_commands.rb b/app/models/integrations/base_slash_commands.rb
index eacf1184aae..1d271e75a91 100644
--- a/app/models/integrations/base_slash_commands.rb
+++ b/app/models/integrations/base_slash_commands.rb
@@ -20,7 +20,7 @@ module Integrations
%w()
end
- def can_test?
+ def testable?
false
end
diff --git a/app/models/integrations/buildkite.rb b/app/models/integrations/buildkite.rb
index 906a5d02f9c..94a37f0c4f2 100644
--- a/app/models/integrations/buildkite.rb
+++ b/app/models/integrations/buildkite.rb
@@ -4,7 +4,9 @@ require "addressable/uri"
module Integrations
class Buildkite < BaseCi
+ include HasWebHook
include ReactiveService
+ extend Gitlab::Utils::Override
ENDPOINT = "https://buildkite.com"
@@ -13,8 +15,6 @@ module Integrations
validates :project_url, presence: true, public_url: true, if: :activated?
validates :token, presence: true, if: :activated?
- after_save :compose_service_hook, if: :activated?
-
def self.supported_events
%w(push merge_request tag_push)
end
@@ -35,21 +35,15 @@ module Integrations
self.properties.delete('enable_ssl_verification') # Remove unused key
end
- def webhook_url
+ override :hook_url
+ def hook_url
"#{buildkite_endpoint('webhook')}/deliver/#{webhook_token}"
end
- def compose_service_hook
- hook = service_hook || build_service_hook
- hook.url = webhook_url
- hook.enable_ssl_verification = true
- hook.save
- end
-
def execute(data)
return unless supported_events.include?(data[:object_kind])
- service_hook.execute(data)
+ execute_web_hook!(data)
end
def commit_status(sha, ref)
@@ -76,18 +70,22 @@ module Integrations
'buildkite'
end
+ def help
+ s_('ProjectService|Run CI/CD pipelines with Buildkite.')
+ end
+
def fields
[
{ type: 'text',
name: 'token',
- title: 'Integration Token',
- help: 'This token will be provided when you create a Buildkite pipeline with a GitLab repository',
+ title: _('Token'),
+ help: s_('ProjectService|The token you get after you create a Buildkite pipeline with a GitLab repository.'),
required: true },
{ type: 'text',
name: 'project_url',
- title: 'Pipeline URL',
- placeholder: "#{ENDPOINT}/acme-inc/test-pipeline",
+ title: _('Pipeline URL'),
+ placeholder: "#{ENDPOINT}/example-org/test-pipeline",
required: true }
]
end
diff --git a/app/models/integrations/campfire.rb b/app/models/integrations/campfire.rb
index eede3d00307..c78fc6eff51 100644
--- a/app/models/integrations/campfire.rb
+++ b/app/models/integrations/campfire.rb
@@ -2,6 +2,8 @@
module Integrations
class Campfire < Integration
+ include ActionView::Helpers::UrlHelper
+
prop_accessor :token, :subdomain, :room
validates :token, presence: true, if: :activated?
@@ -13,15 +15,39 @@ module Integrations
'Send notifications about push events to Campfire chat rooms.'
end
+ def help
+ docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('api/services', anchor: 'campfire'), target: '_blank', rel: 'noopener noreferrer'
+ s_('CampfireService|Send notifications about push events to Campfire chat rooms. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
+ end
+
def self.to_param
'campfire'
end
def fields
[
- { type: 'text', name: 'token', placeholder: '', required: true },
- { type: 'text', name: 'subdomain', placeholder: '' },
- { type: 'text', name: 'room', placeholder: '' }
+ {
+ type: 'text',
+ name: 'token',
+ title: _('Campfire token'),
+ placeholder: '',
+ help: s_('CampfireService|API authentication token from Campfire.'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'subdomain',
+ title: _('Campfire subdomain (optional)'),
+ placeholder: '',
+ help: s_('CampfireService|The %{code_open}.campfirenow.com%{code_close} subdomain.') % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
+ },
+ {
+ type: 'text',
+ name: 'room',
+ title: _('Campfire room ID (optional)'),
+ placeholder: '123456',
+ help: s_('CampfireService|From the end of the room URL.')
+ }
]
end
diff --git a/app/models/integrations/confluence.rb b/app/models/integrations/confluence.rb
index 30f73496993..7f111f482dd 100644
--- a/app/models/integrations/confluence.rb
+++ b/app/models/integrations/confluence.rb
@@ -58,7 +58,7 @@ module Integrations
]
end
- def can_test?
+ def testable?
false
end
diff --git a/app/models/integrations/datadog.rb b/app/models/integrations/datadog.rb
index dd4b0664d52..27c2fcf266b 100644
--- a/app/models/integrations/datadog.rb
+++ b/app/models/integrations/datadog.rb
@@ -2,10 +2,13 @@
module Integrations
class Datadog < Integration
- DEFAULT_SITE = 'datadoghq.com'
- URL_TEMPLATE = 'https://webhooks-http-intake.logs.%{datadog_site}/v1/input/'
- URL_TEMPLATE_API_KEYS = 'https://app.%{datadog_site}/account/settings#api'
- URL_API_KEYS_DOCS = "https://docs.#{DEFAULT_SITE}/account_management/api-app-keys/"
+ include HasWebHook
+ extend Gitlab::Utils::Override
+
+ DEFAULT_DOMAIN = 'datadoghq.com'
+ URL_TEMPLATE = 'https://webhooks-http-intake.logs.%{datadog_domain}/api/v2/webhook'
+ URL_TEMPLATE_API_KEYS = 'https://app.%{datadog_domain}/account/settings#api'
+ URL_API_KEYS_DOCS = "https://docs.#{DEFAULT_DOMAIN}/account_management/api-app-keys/"
SUPPORTED_EVENTS = %w[
pipeline job
@@ -21,12 +24,10 @@ module Integrations
validates :api_url, presence: true, unless: -> (obj) { obj.datadog_site.present? }
end
- after_save :compose_service_hook, if: :activated?
-
def initialize_properties
super
- self.datadog_site ||= DEFAULT_SITE
+ self.datadog_site ||= DEFAULT_DOMAIN
end
def self.supported_events
@@ -62,7 +63,7 @@ module Integrations
{
type: 'text',
name: 'datadog_site',
- placeholder: DEFAULT_SITE,
+ placeholder: DEFAULT_DOMAIN,
help: 'Choose the Datadog site to send data to. Set to "datadoghq.eu" to send data to the EU site',
required: false
},
@@ -98,35 +99,31 @@ module Integrations
]
end
- def compose_service_hook
- hook = service_hook || build_service_hook
- hook.url = hook_url
- hook.save
- end
-
+ override :hook_url
def hook_url
- url = api_url.presence || sprintf(URL_TEMPLATE, datadog_site: datadog_site)
+ url = api_url.presence || sprintf(URL_TEMPLATE, datadog_domain: datadog_domain)
url = URI.parse(url)
- url.path = File.join(url.path || '/', api_key)
- query = { service: datadog_service.presence, env: datadog_env.presence }.compact
- url.query = query.to_query unless query.empty?
+ query = {
+ "dd-api-key" => api_key,
+ service: datadog_service.presence,
+ env: datadog_env.presence
+ }.compact
+ url.query = query.to_query
url.to_s
end
def api_keys_url
return URL_API_KEYS_DOCS unless datadog_site.presence
- sprintf(URL_TEMPLATE_API_KEYS, datadog_site: datadog_site)
+ sprintf(URL_TEMPLATE_API_KEYS, datadog_domain: datadog_domain)
end
def execute(data)
- return if project.disabled_services.include?(to_param)
-
object_kind = data[:object_kind]
object_kind = 'job' if object_kind == 'build'
return unless supported_events.include?(object_kind)
- service_hook.execute(data, "#{object_kind} hook")
+ execute_web_hook!(data, "#{object_kind} hook")
end
def test(data)
@@ -139,5 +136,14 @@ module Integrations
{ success: true, result: result[:message] }
end
+
+ private
+
+ def datadog_domain
+ # Transparently ignore "app" prefix from datadog_site as the official docs table in
+ # https://docs.datadoghq.com/getting_started/site/ is confusing for internal URLs.
+ # US3 needs to keep a prefix but other datacenters cannot have the listed "app" prefix
+ datadog_site.delete_prefix("app.")
+ end
end
end
diff --git a/app/models/integrations/discord.rb b/app/models/integrations/discord.rb
index ef6d46fd3d3..76160a61bc3 100644
--- a/app/models/integrations/discord.rb
+++ b/app/models/integrations/discord.rb
@@ -54,6 +54,8 @@ module Integrations
builder.add_embed do |embed|
embed.author = Discordrb::Webhooks::EmbedAuthor.new(name: message.user_name, icon_url: message.user_avatar)
embed.description = (message.pretext + "\n" + Array.wrap(message.attachments).join("\n")).gsub(ATTACHMENT_REGEX, " \\k<entry> - \\k<name>\n")
+ embed.colour = 16543014 # The hex "fc6d26" as an Integer
+ embed.timestamp = Time.now.utc
end
end
rescue RestClient::Exception => error
diff --git a/app/models/integrations/drone_ci.rb b/app/models/integrations/drone_ci.rb
index 0f021356815..c93ae432fe9 100644
--- a/app/models/integrations/drone_ci.rb
+++ b/app/models/integrations/drone_ci.rb
@@ -2,8 +2,10 @@
module Integrations
class DroneCi < BaseCi
+ include HasWebHook
include ReactiveService
include ServicePushDataValidations
+ extend Gitlab::Utils::Override
prop_accessor :drone_url, :token
boolean_accessor :enable_ssl_verification
@@ -11,24 +13,16 @@ module Integrations
validates :drone_url, presence: true, public_url: true, if: :activated?
validates :token, presence: true, if: :activated?
- after_save :compose_service_hook, if: :activated?
-
- def compose_service_hook
- hook = service_hook || build_service_hook
- # If using a service template, project may not be available
- hook.url = [drone_url, "/api/hook", "?owner=#{project.namespace.full_path}", "&name=#{project.path}", "&access_token=#{token}"].join if project
- hook.enable_ssl_verification = !!enable_ssl_verification
- hook.save
- end
-
def execute(data)
+ return unless project
+
case data[:object_kind]
when 'push'
- service_hook.execute(data) if push_valid?(data)
+ execute_web_hook!(data) if push_valid?(data)
when 'merge_request'
- service_hook.execute(data) if merge_request_valid?(data)
+ execute_web_hook!(data) if merge_request_valid?(data)
when 'tag_push'
- service_hook.execute(data) if tag_push_valid?(data)
+ execute_web_hook!(data) if tag_push_valid?(data)
end
end
@@ -105,5 +99,21 @@ module Integrations
{ type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
]
end
+
+ override :hook_url
+ def hook_url
+ [drone_url, "/hook", "?owner=#{project.namespace.full_path}", "&name=#{project.path}", "&access_token=#{token}"].join
+ end
+
+ override :hook_ssl_verification
+ def hook_ssl_verification
+ !!enable_ssl_verification
+ end
+
+ override :update_web_hook!
+ def update_web_hook!
+ # If using a service template, project may not be available
+ super if project
+ end
end
end
diff --git a/app/models/integrations/ewm.rb b/app/models/integrations/ewm.rb
index 0a4e8d92ed7..24d343b7cb4 100644
--- a/app/models/integrations/ewm.rb
+++ b/app/models/integrations/ewm.rb
@@ -27,7 +27,7 @@ module Integrations
'ewm'
end
- def can_test?
+ def testable?
false
end
diff --git a/app/models/integrations/jenkins.rb b/app/models/integrations/jenkins.rb
index 815e86bcaa1..55fc60990f3 100644
--- a/app/models/integrations/jenkins.rb
+++ b/app/models/integrations/jenkins.rb
@@ -2,7 +2,9 @@
module Integrations
class Jenkins < BaseCi
+ include HasWebHook
include ActionView::Helpers::UrlHelper
+ extend Gitlab::Utils::Override
prop_accessor :jenkins_url, :project_name, :username, :password
@@ -16,8 +18,6 @@ module Integrations
default_value_for :merge_requests_events, false
default_value_for :tag_push_events, false
- after_save :compose_service_hook, if: :activated?
-
def reset_password
# don't reset the password if a new one is provided
if (jenkins_url_changed? || username.blank?) && !password_touched?
@@ -25,16 +25,10 @@ module Integrations
end
end
- def compose_service_hook
- hook = service_hook || build_service_hook
- hook.url = hook_url
- hook.save
- end
-
def execute(data)
return unless supported_events.include?(data[:object_kind])
- service_hook.execute(data, "#{data[:object_kind]}_hook")
+ execute_web_hook!(data, "#{data[:object_kind]}_hook")
end
def test(data)
@@ -48,6 +42,7 @@ module Integrations
{ success: true, result: result[:message] }
end
+ override :hook_url
def hook_url
url = URI.parse(jenkins_url)
url.path = File.join(url.path || '/', "project/#{project_name}")
@@ -97,7 +92,6 @@ module Integrations
{
type: 'text',
name: 'username',
- required: true,
help: s_('The username for the Jenkins server.')
},
{
diff --git a/app/models/integrations/jira.rb b/app/models/integrations/jira.rb
index a5aee35bada..1dc5c0db9e3 100644
--- a/app/models/integrations/jira.rb
+++ b/app/models/integrations/jira.rb
@@ -272,6 +272,10 @@ module Integrations
test(nil)[:success]
end
+ def configured?
+ active? && valid_connection?
+ end
+
def test(_)
result = server_info
success = result.present?
@@ -533,7 +537,7 @@ module Integrations
def update_deployment_type?
(api_url_changed? || url_changed? || username_changed? || password_changed?) &&
- can_test?
+ testable?
end
def update_deployment_type
@@ -573,15 +577,6 @@ module Integrations
data_fields.deployment_server!
end
end
-
- def self.event_description(event)
- case event
- when "merge_request", "merge_request_events"
- s_("JiraService|Jira comments are created when an issue is referenced in a merge request.")
- when "commit", "commit_events"
- s_("JiraService|Jira comments are created when an issue is referenced in a commit.")
- end
- end
end
end
diff --git a/app/models/integrations/mattermost_slash_commands.rb b/app/models/integrations/mattermost_slash_commands.rb
index 6cd664da9e7..30a8ba973c1 100644
--- a/app/models/integrations/mattermost_slash_commands.rb
+++ b/app/models/integrations/mattermost_slash_commands.rb
@@ -6,7 +6,7 @@ module Integrations
prop_accessor :token
- def can_test?
+ def testable?
false
end
diff --git a/app/models/integrations/mock_ci.rb b/app/models/integrations/mock_ci.rb
index a0eae9e4abf..7359be83d4f 100644
--- a/app/models/integrations/mock_ci.rb
+++ b/app/models/integrations/mock_ci.rb
@@ -83,7 +83,7 @@ module Integrations
end
end
- def can_test?
+ def testable?
false
end
end
diff --git a/app/models/integrations/mock_monitoring.rb b/app/models/integrations/mock_monitoring.rb
new file mode 100644
index 00000000000..72bb292edaa
--- /dev/null
+++ b/app/models/integrations/mock_monitoring.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Integrations
+ class MockMonitoring < BaseMonitoring
+ def title
+ 'Mock monitoring'
+ end
+
+ def description
+ 'Mock monitoring service'
+ end
+
+ def self.to_param
+ 'mock_monitoring'
+ end
+
+ def metrics(environment)
+ Gitlab::Json.parse(File.read(Rails.root + 'spec/fixtures/metrics.json'))
+ end
+
+ def testable?
+ false
+ end
+ end
+end
diff --git a/app/models/integrations/packagist.rb b/app/models/integrations/packagist.rb
index b597bd11175..fb0917db02b 100644
--- a/app/models/integrations/packagist.rb
+++ b/app/models/integrations/packagist.rb
@@ -2,6 +2,9 @@
module Integrations
class Packagist < Integration
+ include HasWebHook
+ extend Gitlab::Utils::Override
+
prop_accessor :username, :token, :server
validates :username, presence: true, if: :activated?
@@ -10,8 +13,6 @@ module Integrations
default_value_for :push_events, true
default_value_for :tag_push_events, true
- after_save :compose_service_hook, if: :activated?
-
def title
'Packagist'
end
@@ -39,7 +40,7 @@ module Integrations
def execute(data)
return unless supported_events.include?(data[:object_kind])
- service_hook.execute(data)
+ execute_web_hook!(data)
end
def test(data)
@@ -53,12 +54,7 @@ module Integrations
{ success: true, result: result[:message] }
end
- def compose_service_hook
- hook = service_hook || build_service_hook
- hook.url = hook_url
- hook.save
- end
-
+ override :hook_url
def hook_url
base_url = server.presence || 'https://packagist.org'
"#{base_url}/api/update-package?username=#{username}&apiToken=#{token}"
diff --git a/app/models/integrations/pipelines_email.rb b/app/models/integrations/pipelines_email.rb
index 585bc14242a..efba35cc2a8 100644
--- a/app/models/integrations/pipelines_email.rb
+++ b/app/models/integrations/pipelines_email.rb
@@ -57,7 +57,7 @@ module Integrations
PipelineNotificationWorker.new.perform(pipeline_id, recipients: all_recipients)
end
- def can_test?
+ def testable?
project&.ci_pipelines&.any?
end
diff --git a/app/models/integrations/pivotaltracker.rb b/app/models/integrations/pivotaltracker.rb
index 46f97cc3c6b..24cfd51eb55 100644
--- a/app/models/integrations/pivotaltracker.rb
+++ b/app/models/integrations/pivotaltracker.rb
@@ -2,17 +2,23 @@
module Integrations
class Pivotaltracker < Integration
+ include ActionView::Helpers::UrlHelper
API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits'
prop_accessor :token, :restrict_to_branch
validates :token, presence: true, if: :activated?
def title
- 'PivotalTracker'
+ 'Pivotal Tracker'
end
def description
- s_('PivotalTrackerService|Add commit messages as comments to PivotalTracker stories.')
+ s_('PivotalTrackerService|Add commit messages as comments to Pivotal Tracker stories.')
+ end
+
+ def help
+ docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/pivotal_tracker'), target: '_blank', rel: 'noopener noreferrer'
+ s_('Add commit messages as comments to Pivotal Tracker stories. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
def self.to_param
@@ -24,14 +30,15 @@ module Integrations
{
type: 'text',
name: 'token',
- placeholder: s_('PivotalTrackerService|Pivotal Tracker API token.'),
+ help: s_('PivotalTrackerService|Pivotal Tracker API token. User must have access to the story. All comments are attributed to this user.'),
required: true
},
{
type: 'text',
name: 'restrict_to_branch',
- placeholder: s_('PivotalTrackerService|Comma-separated list of branches which will be ' \
- 'automatically inspected. Leave blank to include all branches.')
+ title: 'Restrict to branch (optional)',
+ help: s_('PivotalTrackerService|Comma-separated list of branches to ' \
+ 'automatically inspect. Leave blank to include all branches.')
}
]
end
diff --git a/app/models/integrations/prometheus.rb b/app/models/integrations/prometheus.rb
new file mode 100644
index 00000000000..54cb823d606
--- /dev/null
+++ b/app/models/integrations/prometheus.rb
@@ -0,0 +1,203 @@
+# frozen_string_literal: true
+
+module Integrations
+ class Prometheus < BaseMonitoring
+ include PrometheusAdapter
+
+ # Access to prometheus is directly through the API
+ prop_accessor :api_url
+ prop_accessor :google_iap_service_account_json
+ prop_accessor :google_iap_audience_client_id
+ boolean_accessor :manual_configuration
+
+ # We need to allow the self-monitoring project to connect to the internal
+ # Prometheus instance.
+ # Since the internal Prometheus instance is usually a localhost URL, we need
+ # to allow localhost URLs when the following conditions are true:
+ # 1. project is the self-monitoring project.
+ # 2. api_url is the internal Prometheus URL.
+ with_options presence: true do
+ validates :api_url, public_url: true, if: ->(object) { object.manual_configuration? && !object.allow_local_api_url? }
+ validates :api_url, url: true, if: ->(object) { object.manual_configuration? && object.allow_local_api_url? }
+ end
+
+ before_save :synchronize_service_state
+
+ after_save :clear_reactive_cache!
+
+ after_commit :track_events
+
+ after_create_commit :create_default_alerts
+
+ scope :preload_project, -> { preload(:project) }
+ scope :with_clusters_with_cilium, -> { joins(project: [:clusters]).merge(Clusters::Cluster.with_available_cilium) }
+
+ def initialize_properties
+ if properties.nil?
+ self.properties = {}
+ end
+ end
+
+ def show_active_box?
+ false
+ end
+
+ def title
+ 'Prometheus'
+ end
+
+ def description
+ s_('PrometheusService|Monitor application health with Prometheus metrics and dashboards')
+ end
+
+ def self.to_param
+ 'prometheus'
+ end
+
+ def fields
+ [
+ {
+ type: 'checkbox',
+ name: 'manual_configuration',
+ title: s_('PrometheusService|Active'),
+ help: s_('PrometheusService|Select this checkbox to override the auto configuration settings with your own settings.'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'api_url',
+ title: 'API URL',
+ placeholder: s_('PrometheusService|https://prometheus.example.com/'),
+ help: s_('PrometheusService|The Prometheus API base URL.'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'google_iap_audience_client_id',
+ title: 'Google IAP Audience Client ID',
+ placeholder: s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com'),
+ help: s_('PrometheusService|PrometheusService|The ID of the IAP-secured resource.'),
+ autocomplete: 'off',
+ required: false
+ },
+ {
+ type: 'textarea',
+ name: 'google_iap_service_account_json',
+ title: 'Google IAP Service Account JSON',
+ placeholder: s_('PrometheusService|{ "type": "service_account", "project_id": ... }'),
+ help: s_('PrometheusService|The contents of the credentials.json file of your service account.'),
+ required: false
+ }
+ ]
+ end
+
+ # Check we can connect to the Prometheus API
+ def test(*args)
+ prometheus_client.ping
+ { success: true, result: 'Checked API endpoint' }
+ rescue Gitlab::PrometheusClient::Error => err
+ { success: false, result: err }
+ end
+
+ def prometheus_client
+ return unless should_return_client?
+
+ options = prometheus_client_default_options.merge(
+ allow_local_requests: allow_local_api_url?
+ )
+
+ if behind_iap?
+ # Adds the Authorization header
+ options[:headers] = iap_client.apply({})
+ end
+
+ Gitlab::PrometheusClient.new(api_url, options)
+ end
+
+ def prometheus_available?
+ return false if template?
+ return false unless project
+
+ project.all_clusters.enabled.eager_load(:integration_prometheus).any? do |cluster|
+ cluster.integration_prometheus_available?
+ end
+ end
+
+ def allow_local_api_url?
+ allow_local_requests_from_web_hooks_and_services? ||
+ (self_monitoring_project? && internal_prometheus_url?)
+ end
+
+ def configured?
+ should_return_client?
+ end
+
+ private
+
+ delegate :allow_local_requests_from_web_hooks_and_services?, to: :current_settings, private: true
+
+ def self_monitoring_project?
+ project && project.id == current_settings.self_monitoring_project_id
+ end
+
+ def internal_prometheus_url?
+ api_url.present? && api_url == ::Gitlab::Prometheus::Internal.uri
+ end
+
+ def should_return_client?
+ api_url.present? && manual_configuration? && active? && valid?
+ end
+
+ def current_settings
+ Gitlab::CurrentSettings.current_application_settings
+ end
+
+ def synchronize_service_state
+ self.active = prometheus_available? || manual_configuration?
+
+ true
+ end
+
+ def track_events
+ if enabled_manual_prometheus?
+ Gitlab::Tracking.event('cluster:services:prometheus', 'enabled_manual_prometheus')
+ elsif disabled_manual_prometheus?
+ Gitlab::Tracking.event('cluster:services:prometheus', 'disabled_manual_prometheus')
+ end
+
+ true
+ end
+
+ def enabled_manual_prometheus?
+ manual_configuration_changed? && manual_configuration?
+ end
+
+ def disabled_manual_prometheus?
+ manual_configuration_changed? && !manual_configuration?
+ end
+
+ def create_default_alerts
+ return unless project_id
+
+ ::Prometheus::CreateDefaultAlertsWorker.perform_async(project_id)
+ end
+
+ def behind_iap?
+ manual_configuration? && google_iap_audience_client_id.present? && google_iap_service_account_json.present?
+ end
+
+ def clean_google_iap_service_account
+ return unless google_iap_service_account_json
+
+ google_iap_service_account_json
+ .then { |json| Gitlab::Json.parse(json) }
+ .except('token_credential_uri')
+ end
+
+ def iap_client
+ @iap_client ||= Google::Auth::Credentials
+ .new(clean_google_iap_service_account, target_audience: google_iap_audience_client_id)
+ .client
+ end
+ end
+end
diff --git a/app/models/integrations/teamcity.rb b/app/models/integrations/teamcity.rb
index 3f14c5d82b3..135c304b57e 100644
--- a/app/models/integrations/teamcity.rb
+++ b/app/models/integrations/teamcity.rb
@@ -18,7 +18,6 @@ module Integrations
attr_accessor :response
- after_save :compose_service_hook, if: :activated?
before_update :reset_password
class << self
@@ -29,20 +28,6 @@ module Integrations
def supported_events
%w(push merge_request)
end
-
- def event_description(event)
- case event
- when 'push', 'push_events'
- 'TeamCity CI will be triggered after every push to the repository except branch delete'
- when 'merge_request', 'merge_request_events'
- 'TeamCity CI will be triggered after a merge request has been created or updated'
- end
- end
- end
-
- def compose_service_hook
- hook = service_hook || build_service_hook
- hook.save
end
def reset_password