156 lines
3.8 KiB
Ruby
156 lines
3.8 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Clusters
|
||
|
module Applications
|
||
|
class PrometheusConfigService
|
||
|
def initialize(project, cluster, app)
|
||
|
@project = project
|
||
|
@cluster = cluster
|
||
|
@app = app
|
||
|
end
|
||
|
|
||
|
def execute(config = {})
|
||
|
if has_alerts?
|
||
|
generate_alert_manager(config)
|
||
|
else
|
||
|
reset_alert_manager(config)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
attr_reader :project, :cluster, :app
|
||
|
|
||
|
def reset_alert_manager(config)
|
||
|
config = set_alert_manager_enabled(config, false)
|
||
|
config.delete('alertmanagerFiles')
|
||
|
config['serverFiles'] ||= {}
|
||
|
config['serverFiles']['alerts'] = {}
|
||
|
|
||
|
config
|
||
|
end
|
||
|
|
||
|
def generate_alert_manager(config)
|
||
|
config = set_alert_manager_enabled(config, true)
|
||
|
config = set_alert_manager_files(config)
|
||
|
|
||
|
set_alert_manager_groups(config)
|
||
|
end
|
||
|
|
||
|
def set_alert_manager_enabled(config, enabled)
|
||
|
config['alertmanager'] ||= {}
|
||
|
config['alertmanager']['enabled'] = enabled
|
||
|
|
||
|
config
|
||
|
end
|
||
|
|
||
|
def set_alert_manager_files(config)
|
||
|
config['alertmanagerFiles'] = {
|
||
|
'alertmanager.yml' => {
|
||
|
'receivers' => alert_manager_receivers_params,
|
||
|
'route' => alert_manager_route_params
|
||
|
}
|
||
|
}
|
||
|
|
||
|
config
|
||
|
end
|
||
|
|
||
|
def set_alert_manager_groups(config)
|
||
|
config['serverFiles'] ||= {}
|
||
|
config['serverFiles']['alerts'] ||= {}
|
||
|
config['serverFiles']['alerts']['groups'] ||= []
|
||
|
|
||
|
environments_with_alerts.each do |env_name, alerts|
|
||
|
index = config['serverFiles']['alerts']['groups'].find_index do |group|
|
||
|
group['name'] == env_name
|
||
|
end
|
||
|
|
||
|
if index
|
||
|
config['serverFiles']['alerts']['groups'][index]['rules'] = alerts
|
||
|
else
|
||
|
config['serverFiles']['alerts']['groups'] << {
|
||
|
'name' => env_name,
|
||
|
'rules' => alerts
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
config
|
||
|
end
|
||
|
|
||
|
def alert_manager_receivers_params
|
||
|
[
|
||
|
{
|
||
|
'name' => 'gitlab',
|
||
|
'webhook_configs' => [
|
||
|
{
|
||
|
'url' => notify_url,
|
||
|
'send_resolved' => true,
|
||
|
'http_config' => {
|
||
|
'bearer_token' => alert_manager_token
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
end
|
||
|
|
||
|
def alert_manager_token
|
||
|
app.generate_alert_manager_token!
|
||
|
|
||
|
app.alert_manager_token
|
||
|
end
|
||
|
|
||
|
def alert_manager_route_params
|
||
|
{
|
||
|
'receiver' => 'gitlab',
|
||
|
'group_wait' => '30s',
|
||
|
'group_interval' => '5m',
|
||
|
'repeat_interval' => '4h'
|
||
|
}
|
||
|
end
|
||
|
|
||
|
def notify_url
|
||
|
::Gitlab::Routing.url_helpers
|
||
|
.notify_project_prometheus_alerts_url(project, format: :json)
|
||
|
end
|
||
|
|
||
|
def has_alerts?
|
||
|
environments_with_alerts.values.flatten(1).any?
|
||
|
end
|
||
|
|
||
|
def environments_with_alerts
|
||
|
@environments_with_alerts ||=
|
||
|
environments.each_with_object({}) do |environment, hash|
|
||
|
name = rule_name(environment)
|
||
|
hash[name] = alerts(environment)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def rule_name(environment)
|
||
|
"#{environment.name}.rules"
|
||
|
end
|
||
|
|
||
|
def alerts(environment)
|
||
|
variables = Gitlab::Prometheus::QueryVariables.call(environment)
|
||
|
alerts = Projects::Prometheus::AlertsFinder
|
||
|
.new(environment: environment)
|
||
|
.execute
|
||
|
|
||
|
alerts.map do |alert|
|
||
|
substitute_query_variables(alert.to_param, variables)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def substitute_query_variables(hash, variables)
|
||
|
hash['expr'] %= variables
|
||
|
hash
|
||
|
end
|
||
|
|
||
|
def environments
|
||
|
project.environments_for_scope(cluster.environment_scope)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|