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

prometheus_config_service.rb « applications « clusters « services « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d39d63c874fe828a2d0f87f68e3c8e573dbeaeca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# 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.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)
        alerts = Projects::Prometheus::AlertsFinder
          .new(environment: environment)
          .execute

        alerts.map do |alert|
          hash = alert.to_param
          hash['expr'] = substitute_query_variables(hash['expr'], environment)
          hash
        end
      end

      def substitute_query_variables(query, environment)
        result = ::Prometheus::ProxyVariableSubstitutionService.new(environment, query: query).execute

        result[:params][:query]
      end

      def environments
        project.environments_for_scope(cluster.environment_scope)
      end
    end
  end
end