Commit 125daf21 authored by Markus Koller's avatar Markus Koller

Merge branch '201855-rename-project_services_to_integrations-9' into 'master'

Move monitoring integrations to `Integrations::` [RUN ALL RSPEC] [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!62645
parents 85c4edfc b86b6f90
......@@ -1640,9 +1640,6 @@ Gitlab/NamespacedClass:
- 'app/models/project_pages_metadatum.rb'
- 'app/models/project_repository.rb'
- 'app/models/project_repository_storage_move.rb'
- 'app/models/project_services/mock_monitoring_service.rb'
- 'app/models/project_services/monitoring_service.rb'
- 'app/models/project_services/prometheus_service.rb'
- 'app/models/project_setting.rb'
- 'app/models/project_snippet.rb'
- 'app/models/project_statistics.rb'
......
......@@ -31,7 +31,7 @@ class ChaosController < ActionController::Base
gc_stat = Gitlab::Chaos.run_gc
render json: {
worker_id: Prometheus::PidProvider.worker_id,
worker_id: ::Prometheus::PidProvider.worker_id,
gc_stat: gc_stat
}
end
......
......@@ -16,7 +16,7 @@ module Metrics::Dashboard::PrometheusApiProxy
return error_response(variable_substitution_result)
end
prometheus_result = Prometheus::ProxyService.new(
prometheus_result = ::Prometheus::ProxyService.new(
proxyable,
proxy_method,
proxy_path,
......
......@@ -30,7 +30,7 @@ class MetricsController < ActionController::Base
def system_metrics
Gitlab::Metrics::System.summary.merge(
worker_id: Prometheus::PidProvider.worker_id
worker_id: ::Prometheus::PidProvider.worker_id
)
end
end
......@@ -14,6 +14,6 @@ class Projects::Environments::PrometheusApiController < Projects::ApplicationCon
end
def proxy_variable_substitution_service
Prometheus::ProxyVariableSubstitutionService
::Prometheus::ProxyVariableSubstitutionService
end
end
......@@ -66,7 +66,7 @@ module Projects
)
if @metric.persisted?
redirect_to edit_project_service_path(project, ::PrometheusService),
redirect_to edit_project_service_path(project, ::Integrations::Prometheus),
notice: _('Metric was successfully added.')
else
render 'new'
......@@ -77,7 +77,7 @@ module Projects
@metric = update_metrics_service(prometheus_metric).execute
if @metric.persisted?
redirect_to edit_project_service_path(project, ::PrometheusService),
redirect_to edit_project_service_path(project, ::Integrations::Prometheus),
notice: _('Metric was successfully updated.')
else
render 'edit'
......@@ -93,7 +93,7 @@ module Projects
respond_to do |format|
format.html do
redirect_to edit_project_service_path(project, ::PrometheusService), status: :see_other
redirect_to edit_project_service_path(project, ::Integrations::Prometheus), status: :see_other
end
format.json do
head :ok
......
......@@ -105,11 +105,11 @@ class Projects::ServicesController < Projects::ApplicationController
end
def redirect_deprecated_prometheus_service
redirect_to edit_project_service_path(project, integration) if integration.is_a?(::PrometheusService) && Feature.enabled?(:settings_operations_prometheus_service, project)
redirect_to edit_project_service_path(project, integration) if integration.is_a?(::Integrations::Prometheus) && Feature.enabled?(:settings_operations_prometheus_service, project)
end
def set_deprecation_notice_for_prometheus_service
return if !integration.is_a?(::PrometheusService) || !Feature.enabled?(:settings_operations_prometheus_service, project)
return if !integration.is_a?(::Integrations::Prometheus) || !Feature.enabled?(:settings_operations_prometheus_service, project)
operations_link_start = "<a href=\"#{project_settings_operations_path(project)}\">"
message = s_('PrometheusService|You can now manage your Prometheus settings on the %{operations_link_start}Operations%{operations_link_end} page. Fields on this page has been deprecated.') % { operations_link_start: operations_link_start, operations_link_end: "</a>" }
......
......@@ -14,7 +14,7 @@ module Mutations
private
def find_object(id:)
GitlabSchema.object_from_id(id, expected_class: ::PrometheusService)
GitlabSchema.object_from_id(id, expected_class: ::Integrations::Prometheus)
end
def response(integration, result)
......
......@@ -6,7 +6,7 @@ module Mutations
class ResetToken < PrometheusIntegrationBase
graphql_name 'PrometheusIntegrationResetToken'
argument :id, Types::GlobalIDType[::PrometheusService],
argument :id, Types::GlobalIDType[::Integrations::Prometheus],
required: true,
description: "The ID of the integration to mutate."
......
......@@ -6,7 +6,7 @@ module Mutations
class Update < PrometheusIntegrationBase
graphql_name 'PrometheusIntegrationUpdate'
argument :id, Types::GlobalIDType[::PrometheusService],
argument :id, Types::GlobalIDType[::Integrations::Prometheus],
required: true,
description: "The ID of the integration to mutate."
......
......@@ -54,7 +54,7 @@ module Resolvers
def expected_integration_types
[].tap do |types|
types << ::AlertManagement::HttpIntegration if http_integrations_allowed?
types << ::PrometheusService if prometheus_integrations_allowed?
types << ::Integrations::Prometheus if prometheus_integrations_allowed?
end
end
end
......
......@@ -43,7 +43,7 @@ module Types
definition_methods do
def resolve_type(object, context)
if object.is_a?(::PrometheusService)
if object.is_a?(::Integrations::Prometheus)
Types::AlertManagement::PrometheusIntegrationType
else
Types::AlertManagement::HttpIntegrationType
......
......@@ -5,7 +5,7 @@ module CustomMetricsHelper
{
'custom-metrics-path' => url_for([project, metric]),
'metric-persisted' => metric.persisted?.to_s,
'edit-project-service-path' => edit_project_service_path(project, PrometheusService),
'edit-project-service-path' => edit_project_service_path(project, ::Integrations::Prometheus),
'validate-query-path' => validate_query_project_prometheus_metrics_path(project),
'title' => metric.title.to_s,
'query' => metric.query.to_s,
......
......@@ -5,7 +5,7 @@ module OperationsHelper
def prometheus_service
strong_memoize(:prometheus_service) do
@project.find_or_initialize_service(::PrometheusService.to_param)
@project.find_or_initialize_service(::Integrations::Prometheus.to_param)
end
end
......
......@@ -47,12 +47,12 @@ module Clusters
def activate_project_services
::Clusters::Applications::ActivateServiceWorker
.perform_async(cluster_id, ::PrometheusService.to_param) # rubocop:disable CodeReuse/ServiceClass
.perform_async(cluster_id, ::Integrations::Prometheus.to_param)
end
def deactivate_project_services
::Clusters::Applications::DeactivateServiceWorker
.perform_async(cluster_id, ::PrometheusService.to_param) # rubocop:disable CodeReuse/ServiceClass
.perform_async(cluster_id, ::Integrations::Prometheus.to_param)
end
end
end
......
......@@ -4,18 +4,20 @@
#
# These services integrate with a deployment solution like Prometheus
# to provide additional features for environments.
class MonitoringService < Integration
default_value_for :category, 'monitoring'
module Integrations
class BaseMonitoring < Integration
default_value_for :category, 'monitoring'
def self.supported_events
%w()
end
def self.supported_events
%w()
end
def can_query?
raise NotImplementedError
end
def can_query?
raise NotImplementedError
end
def query(_, *_)
raise NotImplementedError
def query(_, *_)
raise NotImplementedError
end
end
end
# 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 can_test?
false
end
end
end
# 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
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 allow_local_requests_from_web_hooks_and_services?
current_settings.allow_local_requests_from_web_hooks_and_services?
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
......@@ -178,10 +178,11 @@ class Project < ApplicationRecord
has_one :mattermost_slash_commands_integration, class_name: 'Integrations::MattermostSlashCommands'
has_one :microsoft_teams_integration, class_name: 'Integrations::MicrosoftTeams'
has_one :mock_ci_integration, class_name: 'Integrations::MockCi'
has_one :mock_monitoring_integration, class_name: 'MockMonitoringService'
has_one :mock_monitoring_integration, class_name: 'Integrations::MockMonitoring'
has_one :packagist_integration, class_name: 'Integrations::Packagist'
has_one :pipelines_email_integration, class_name: 'Integrations::PipelinesEmail'
has_one :pivotaltracker_integration, class_name: 'Integrations::Pivotaltracker'
has_one :prometheus_service, class_name: 'Integrations::Prometheus', inverse_of: :project
has_one :pushover_integration, class_name: 'Integrations::Pushover'
has_one :redmine_service, class_name: 'Integrations::Redmine'
has_one :slack_service, class_name: 'Integrations::Slack'
......@@ -190,7 +191,6 @@ class Project < ApplicationRecord
has_one :unify_circuit_service, class_name: 'Integrations::UnifyCircuit'
has_one :webex_teams_service, class_name: 'Integrations::WebexTeams'
has_one :youtrack_service, class_name: 'Integrations::Youtrack'
has_one :prometheus_service, inverse_of: :project
has_one :root_of_fork_network,
foreign_key: 'root_project_id',
......
# frozen_string_literal: true
class MockMonitoringService < MonitoringService
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 can_test?
false
end
end
# frozen_string_literal: true
class PrometheusService < MonitoringService
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
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 allow_local_requests_from_web_hooks_and_services?
current_settings.allow_local_requests_from_web_hooks_and_services?
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
......@@ -4,7 +4,7 @@ require 'prometheus/client/formats/text'
class MetricsService
def prometheus_metrics_text
Prometheus::Client::Formats::Text.marshal_multiprocess(multiprocess_metrics_path)
::Prometheus::Client::Formats::Text.marshal_multiprocess(multiprocess_metrics_path)
end
def metrics_text
......
......@@ -193,7 +193,7 @@ module Projects
# Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/326665
def create_prometheus_service
service = @project.find_or_initialize_service(::PrometheusService.to_param)
service = @project.find_or_initialize_service(::Integrations::Prometheus.to_param)
# If the service has already been inserted in the database, that
# means it came from a template, and there's nothing more to do.
......
......@@ -102,7 +102,7 @@ module Projects
def prometheus_integration_params
return {} unless attrs = params[:prometheus_integration_attributes]
service = project.find_or_initialize_service(::PrometheusService.to_param)
service = project.find_or_initialize_service(::Integrations::Prometheus.to_param)
service.assign_attributes(attrs)
{ prometheus_service_attributes: service.attributes.except(*%w(id project_id created_at updated_at)) }
......
- add_to_breadcrumbs _("Settings"), edit_project_path(@project)
- add_to_breadcrumbs _("Integrations"), project_settings_integrations_path(@project)
- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, PrometheusService)
- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, ::Integrations::Prometheus)
- breadcrumb_title s_('Metrics|Edit metric')
- page_title @metric.title, s_('Metrics|Edit metric')
= render 'form', project: @project, metric: @metric
- add_to_breadcrumbs _("Settings"), edit_project_path(@project)
- add_to_breadcrumbs _("Integrations"), project_settings_integrations_path(@project)
- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, PrometheusService)
- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, ::Integrations::Prometheus)
- breadcrumb_title s_('Metrics|New metric')
- page_title s_('Metrics|New metric')
= render 'form', project: @project, metric: @metric
......@@ -21,7 +21,7 @@ module Projects
private
def create_prometheus_service(project)
service = project.find_or_initialize_service(::PrometheusService.to_param)
service = project.find_or_initialize_service(::Integrations::Prometheus.to_param)
# If the service has already been inserted in the database, that
# means it came from a template, and there's nothing more to do.
......
......@@ -15,7 +15,7 @@ module Prometheus
return unless project
result = Prometheus::CreateDefaultAlertsService.new(project: project).execute
result = ::Prometheus::CreateDefaultAlertsService.new(project: project).execute
log_info(result.message) if result.error?
end
......
......@@ -15,14 +15,14 @@ def prometheus_default_multiproc_dir
end
end
Prometheus::Client.configure do |config|
::Prometheus::Client.configure do |config|
config.logger = Gitlab::AppLogger
config.initial_mmap_file_size = 4 * 1024
config.multiprocess_files_dir = ENV['prometheus_multiproc_dir'] || prometheus_default_multiproc_dir
config.pid_provider = Prometheus::PidProvider.method(:worker_id)
config.pid_provider = ::Prometheus::PidProvider.method(:worker_id)
end
Gitlab::Application.configure do |config|
......@@ -43,7 +43,7 @@ if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled?
# Thus, we order these events to run `reinitialize_on_pid_change` with `force: true` first.
Gitlab::Cluster::LifecycleEvents.on_master_start do
# Ensure that stale Prometheus metrics don't accumulate over time
Prometheus::CleanupMultiprocDirService.new.execute
::Prometheus::CleanupMultiprocDirService.new.execute
::Prometheus::Client.reinitialize_on_pid_change(force: true)
......@@ -64,7 +64,7 @@ if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled?
end
Gitlab::Cluster::LifecycleEvents.on_worker_start do
defined?(::Prometheus::Client.reinitialize_on_pid_change) && Prometheus::Client.reinitialize_on_pid_change
defined?(::Prometheus::Client.reinitialize_on_pid_change) && ::Prometheus::Client.reinitialize_on_pid_change
Gitlab::Metrics::Samplers::RubySampler.initialize_instance.start
Gitlab::Metrics::Samplers::DatabaseSampler.initialize_instance.start
......
......@@ -3273,7 +3273,7 @@ Input type: `PrometheusIntegrationResetTokenInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationprometheusintegrationresettokenclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationprometheusintegrationresettokenid"></a>`id` | [`PrometheusServiceID!`](#prometheusserviceid) | The ID of the integration to mutate. |
| <a id="mutationprometheusintegrationresettokenid"></a>`id` | [`IntegrationsPrometheusID!`](#integrationsprometheusid) | The ID of the integration to mutate. |
#### Fields
......@@ -3294,7 +3294,7 @@ Input type: `PrometheusIntegrationUpdateInput`
| <a id="mutationprometheusintegrationupdateactive"></a>`active` | [`Boolean`](#boolean) | Whether the integration is receiving alerts. |
| <a id="mutationprometheusintegrationupdateapiurl"></a>`apiUrl` | [`String`](#string) | Endpoint at which Prometheus can be queried. |
| <a id="mutationprometheusintegrationupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationprometheusintegrationupdateid"></a>`id` | [`PrometheusServiceID!`](#prometheusserviceid) | The ID of the integration to mutate. |
| <a id="mutationprometheusintegrationupdateid"></a>`id` | [`IntegrationsPrometheusID!`](#integrationsprometheusid) | The ID of the integration to mutate. |
#### Fields
......@@ -15365,6 +15365,13 @@ An example `IncidentManagementOncallRotationID` is: `"gid://gitlab/IncidentManag
Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
### `IntegrationsPrometheusID`
A `IntegrationsPrometheusID` is a global ID. It is encoded as a string.
An example `IntegrationsPrometheusID` is: `"gid://gitlab/Integrations::Prometheus/1"`.
The older format `"gid://gitlab/PrometheusService/1"` was deprecated in 14.1.
### `IssuableID`
A `IssuableID` is a global ID. It is encoded as a string.
......@@ -15510,12 +15517,6 @@ A `ProjectID` is a global ID. It is encoded as a string.
An example `ProjectID` is: `"gid://gitlab/Project/1"`.
### `PrometheusServiceID`
A `PrometheusServiceID` is a global ID. It is encoded as a string.
An example `PrometheusServiceID` is: `"gid://gitlab/PrometheusService/1"`.
### `ReleasesLinkID`
A `ReleasesLinkID` is a global ID. It is encoded as a string.
......
......@@ -152,7 +152,7 @@ module EE
scope :with_security_reports_stored, -> { where('EXISTS (?)', ::Vulnerabilities::Finding.scoped_project.select(1)) }
scope :with_security_reports, -> { where('EXISTS (?)', ::Ci::JobArtifact.security_reports.scoped_project.select(1)) }
scope :with_github_service_pipeline_events, -> { joins(:github_service).merge(::Integrations::Github.pipeline_hooks) }
scope :with_active_prometheus_service, -> { joins(:prometheus_service).merge(PrometheusService.active) }
scope :with_active_prometheus_service, -> { joins(:prometheus_service).merge(::Integrations::Prometheus.active) }
scope :with_enabled_incident_sla, -> { joins(:incident_management_setting).where(project_incident_management_settings: { sla_timer: true }) }
scope :mirrored_with_enabled_pipelines, -> do
joins(:project_feature).mirror.where(mirror_trigger_builds: true,
......
......@@ -12,7 +12,7 @@ class NetworkPolicyMetricsWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :container_network_security
def perform
services = PrometheusService
services = ::Integrations::Prometheus
.preload_project
.with_clusters_with_cilium
service_metrics = count_adapter_metrics(services)
......
......@@ -799,20 +799,20 @@ module API
::Integrations::Packagist,
::Integrations::PipelinesEmail,
::Integrations::Pivotaltracker,
::Integrations::Prometheus,
::Integrations::Pushover,
::Integrations::Redmine,
::Integrations::Slack,
::Integrations::SlackSlashCommands,
::Integrations::Teamcity,
::Integrations::Youtrack,
::PrometheusService
::Integrations::Youtrack
]
end
def self.development_service_classes
[
::Integrations::MockCi,
::MockMonitoringService
::Integrations::MockMonitoring
]
end
end
......
......@@ -75,13 +75,13 @@ module Gitlab
if response
# In the add_prometheus_manual_configuration method, the Prometheus
# server_address config is saved as an api_url in the PrometheusService
# model. There are validates hooks in the PrometheusService model that
# check if the project associated with the PrometheusService is the
# server_address config is saved as an api_url in the Integrations::Prometheus
# model. There are validates hooks in the Integrations::Prometheus model that
# check if the project associated with the Integrations::Prometheus is the
# self_monitoring project. It checks
# Gitlab::CurrentSettings.self_monitoring_project_id, which is why the
# Gitlab::CurrentSettings cache needs to be expired here, so that
# PrometheusService sees the latest self_monitoring_project_id.
# Integrations::Prometheus sees the latest self_monitoring_project_id.
Gitlab::CurrentSettings.expire_current_application_settings
success(result)
else
......
......@@ -9,11 +9,12 @@ module Gitlab
# Example:
#
# DEPRECATIONS = [
# Deprecation.new(old_model_name: 'PrometheusService', new_model_name: 'Integrations::Prometheus', milestone: '14.0')
# Deprecation.new(old_model_name: 'PrometheusService', new_model_name: 'Integrations::Prometheus', milestone: '14.1')
# ].freeze
DEPRECATIONS = [
# This works around an accidentally released argument named as `"EEIterationID"` in 7000489db.
Deprecation.new(old_model_name: 'EEIteration', new_model_name: 'Iteration', milestone: '13.3')
Deprecation.new(old_model_name: 'EEIteration', new_model_name: 'Iteration', milestone: '13.3'),
Deprecation.new(old_model_name: 'PrometheusService', new_model_name: 'Integrations::Prometheus', milestone: '14.1')
].freeze
# Maps of the DEPRECATIONS Hash for quick access.
......
......@@ -5,9 +5,9 @@ module Gitlab
class StiType < ActiveRecord::Type::String
NAMESPACED_INTEGRATIONS = Set.new(%w(
Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog
Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker
Jenkins Jira Mattermost MattermostSlashCommands MicrosoftTeams MockCi Packagist PipelinesEmail Pivotaltracker
Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit Youtrack WebexTeams
Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker Jenkins Jira Mattermost
MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker
Prometheus Pushover Redmine Slack SlackSlashCommands Teamcity UnifyCircuit Youtrack WebexTeams
)).freeze
def cast(value)
......
......@@ -141,7 +141,7 @@ RSpec.describe Projects::Prometheus::MetricsController do
expect(flash[:notice]).to include('Metric was successfully added.')
expect(response).to redirect_to(edit_project_service_path(project, PrometheusService))
expect(response).to redirect_to(edit_project_service_path(project, ::Integrations::Prometheus))
end
end
......@@ -164,7 +164,7 @@ RSpec.describe Projects::Prometheus::MetricsController do
it 'destroys the metric' do
delete :destroy, params: project_params(id: metric.id)
expect(response).to redirect_to(edit_project_service_path(project, PrometheusService))
expect(response).to redirect_to(edit_project_service_path(project, ::Integrations::Prometheus))
expect(PrometheusMetric.find_by(id: metric.id)).to be_nil
end
end
......
......@@ -27,7 +27,7 @@ FactoryBot.define do
end
end
factory :prometheus_service do
factory :prometheus_service, class: 'Integrations::Prometheus' do
project
active { true }
properties do
......
......@@ -32,7 +32,7 @@ RSpec.describe Mutations::AlertManagement::PrometheusIntegration::Create do
context 'when UpdateService responds with success' do
it 'returns the integration with no errors' do
expect(resolve).to eq(
integration: ::PrometheusService.last!,
integration: ::Integrations::Prometheus.last!,
errors: []
)
end
......
......@@ -21,7 +21,7 @@ RSpec.describe OperationsHelper do
end
context 'initial service configuration' do
let_it_be(:prometheus_service) { PrometheusService.new(project: project) }
let_it_be(:prometheus_service) { ::Integrations::Prometheus.new(project: project) }
before do
allow(project).to receive(:find_or_initialize_service).and_call_original
......
......@@ -140,7 +140,7 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
integrations = result[:project].reload.integrations
expect(integrations.count).to eq(1)
# Ensures PrometheusService#self_monitoring_project? is true
# Ensures Integrations::Prometheus#self_monitoring_project? is true
expect(integrations.first.allow_local_api_url?).to be_truthy
end
......
......@@ -20,7 +20,7 @@ RSpec.describe DeploymentMetrics do
end
context 'with a Prometheus Service' do
let(:prometheus_service) { instance_double(PrometheusService, can_query?: true, configured?: true) }
let(:prometheus_service) { instance_double(::Integrations::Prometheus, can_query?: true, configured?: true) }
before do
allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_service
......@@ -30,7 +30,7 @@ RSpec.describe DeploymentMetrics do
end
context 'with a Prometheus Service that cannot query' do
let(:prometheus_service) { instance_double(PrometheusService, configured?: true, can_query?: false) }
let(:prometheus_service) { instance_double(::Integrations::Prometheus, configured?: true, can_query?: false) }
before do
allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_service
......@@ -40,7 +40,7 @@ RSpec.describe DeploymentMetrics do
end
context 'with a Prometheus Service that is not configured' do
let(:prometheus_service) { instance_double(PrometheusService, configured?: false, can_query?: false) }
let(:prometheus_service) { instance_double(::Integrations::Prometheus, configured?: false, can_query?: false) }
before do
allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_service
......@@ -64,7 +64,7 @@ RSpec.describe DeploymentMetrics do
describe '#metrics' do
let(:deployment) { create(:deployment, :success) }
let(:prometheus_adapter) { instance_double(PrometheusService, can_query?: true, configured?: true) }
let(:prometheus_adapter) { instance_double(::Integrations::Prometheus, can_query?: true, configured?: true) }
let(:deployment_metrics) { described_class.new(deployment.project, deployment) }
subject { deployment_metrics.metrics }
......
......@@ -669,11 +669,8 @@ RSpec.describe Integration do
end
describe '.integration_name_to_model' do
it 'returns the model for the given service name', :aggregate_failures do
it 'returns the model for the given service name' do
expect(described_class.integration_name_to_model('asana')).to eq(Integrations::Asana)
# TODO We can remove this test when all models have been namespaced:
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60968#note_570994955
expect(described_class.integration_name_to_model('prometheus')).to eq(PrometheusService)
end
it 'raises an error if service name is invalid' do
......
......@@ -4,7 +4,7 @@ require 'spec_helper'
require 'googleauth'
RSpec.describe PrometheusService, :use_clean_rails_memory_store_caching, :snowplow do
RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching, :snowplow do
include PrometheusHelpers
include ReactiveCachingHelpers
......
......@@ -5942,7 +5942,7 @@ RSpec.describe Project, factory_default: :keep do
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')).to be_a(::Integrations::Prometheus)
expect(subject.find_or_initialize_service('prometheus').api_url).to be_nil
end
end
......
......@@ -42,7 +42,7 @@ RSpec.describe 'Creating a new Prometheus Integration' do
it 'creates a new integration' do
post_graphql_mutation(mutation, current_user: current_user)
new_integration = ::PrometheusService.last!
new_integration = ::Integrations::Prometheus.last!
integration_response = mutation_response['integration']
expect(response).to have_gitlab_http_status(:success)
......
......@@ -121,9 +121,9 @@ RSpec.describe API::Services do
end
def deactive_service!
return initialized_service.update!(active: false) unless initialized_service.is_a?(PrometheusService)
return initialized_service.update!(active: false) unless initialized_service.is_a?(::Integrations::Prometheus)
# PrometheusService sets `#active` itself within a `before_save`:
# Integrations::Prometheus sets `#active` itself within a `before_save`:
initialized_service.manual_configuration = false
initialized_service.save!
end
......
......@@ -703,7 +703,7 @@ RSpec.describe Projects::CreateService, '#execute' do
create(:clusters_integrations_prometheus, cluster: cluster)
end
it 'creates PrometheusService record', :aggregate_failures do
it 'creates Integrations::Prometheus record', :aggregate_failures do
project = create_project(user, opts.merge!(namespace_id: group.id))
service = project.prometheus_service
......@@ -720,7 +720,7 @@ RSpec.describe Projects::CreateService, '#execute' do
create(:clusters_integrations_prometheus, cluster: cluster)
end
it 'creates PrometheusService record', :aggregate_failures do
it 'creates Integrations::Prometheus record', :aggregate_failures do
project = create_project(user, opts)
service = project.prometheus_service
......@@ -731,7 +731,7 @@ RSpec.describe Projects::CreateService, '#execute' do
it 'cleans invalid record and logs warning', :aggregate_failures do
invalid_service_record = build(:prometheus_service, properties: { api_url: nil, manual_configuration: true }.to_json)
allow(PrometheusService).to receive(:new).and_return(invalid_service_record)
allow(::Integrations::Prometheus).to receive(:new).and_return(invalid_service_record)
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(an_instance_of(ActiveRecord::RecordInvalid), include(extra: { project_id: a_kind_of(Integer) }))
project = create_project(user, opts)
......@@ -741,7 +741,7 @@ RSpec.describe Projects::CreateService, '#execute' do
end
context 'shared Prometheus integration is not available' do
it 'does not persist PrometheusService record', :aggregate_failures do
it 'does not persist Integrations::Prometheus record' do
project = create_project(user, opts)
expect(project.prometheus_service).to be_nil
......
......@@ -503,7 +503,7 @@ RSpec.describe Projects::UpdateService do
it 'creates new record' do
expect { update_project(project, user, prometheus_service_attributes: prometheus_service_attributes) }
.to change { ::PrometheusService.where(project: project).count }
.to change { ::Integrations::Prometheus.where(project: project).count }
.from(0)
.to(1)
end
......@@ -519,7 +519,7 @@ RSpec.describe Projects::UpdateService do
it 'does not create new record' do
expect { update_project(project, user, prometheus_service_attributes: prometheus_service_attributes) }
.not_to change { ::PrometheusService.where(project: project).count }
.not_to change { ::Integrations::Prometheus.where(project: project).count }
end
end
end
......
......@@ -65,7 +65,7 @@ RSpec.describe Prometheus::ProxyService do
end
describe '#execute' do
let(:prometheus_adapter) { instance_double(PrometheusService) }
let(:prometheus_adapter) { instance_double(::Integrations::Prometheus) }
let(:params) { ActionController::Parameters.new(query: '1').permit! }
subject { described_class.new(environment, 'GET', 'query', params) }
......
......@@ -36,7 +36,7 @@ RSpec.describe Projects::PostCreationWorker do
create(:clusters_integrations_prometheus, cluster: cluster)
end
it 'creates PrometheusService record', :aggregate_failures do
it 'creates an Integrations::Prometheus record', :aggregate_failures do
subject
service = project.prometheus_service
......@@ -53,7 +53,7 @@ RSpec.describe Projects::PostCreationWorker do
create(:clusters_integrations_prometheus, cluster: cluster)
end
it 'creates PrometheusService record', :aggregate_failures do
it 'creates an Integrations::Prometheus record', :aggregate_failures do
subject
service = project.prometheus_service
......@@ -64,7 +64,7 @@ RSpec.describe Projects::PostCreationWorker do
it 'cleans invalid record and logs warning', :aggregate_failures do
invalid_service_record = build(:prometheus_service, properties: { api_url: nil, manual_configuration: true }.to_json)
allow(PrometheusService).to receive(:new).and_return(invalid_service_record)
allow(::Integrations::Prometheus).to receive(:new).and_return(invalid_service_record)
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(an_instance_of(ActiveRecord::RecordInvalid), include(extra: { project_id: a_kind_of(Integer) })).twice
subject
......@@ -74,7 +74,7 @@ RSpec.describe Projects::PostCreationWorker do
end
context 'shared Prometheus application is not available' do
it 'does not persist PrometheusService record', :aggregate_failures do
it 'does not persist an Integrations::Prometheus record' do
subject
expect(project.prometheus_service).to be_nil
......
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