summaryrefslogtreecommitdiff
path: root/app/controllers/projects/prometheus/metrics_controller.rb
blob: c20c80ba334cd31c80d0b34e1b9e4eaa8dac8bd5 (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
# frozen_string_literal: true

module Projects
  module Prometheus
    class MetricsController < Projects::ApplicationController
      before_action :authorize_admin_project!
      before_action :require_prometheus_metrics!

      feature_category :metrics
      urgency :low

      def active_common
        respond_to do |format|
          format.json do
            matched_metrics = prometheus_adapter.query(:matched_metrics) || {}

            if matched_metrics.any?
              render json: matched_metrics
            else
              head :no_content
            end
          end
        end
      end

      def validate_query
        respond_to do |format|
          format.json do
            result = prometheus_adapter.query(:validate, params[:query])

            if result
              render json: result
            else
              head :accepted
            end
          end
        end
      end

      def new
        @metric = project.prometheus_metrics.new
      end

      def index
        respond_to do |format|
          format.json do
            metrics = ::PrometheusMetricsFinder.new(
              project: project,
              ordered: true
            ).execute.to_a

            response = {}
            if metrics.any?
              response[:metrics] = ::PrometheusMetricSerializer
                                     .new(project: project)
                                     .represent(metrics)
            end

            render json: response
          end
        end
      end

      def create
        @metric = project.prometheus_metrics.create(
          metrics_params.to_h.symbolize_keys
        )

        if @metric.persisted?
          redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus),
            notice: _('Metric was successfully added.')
        else
          render 'new'
        end
      end

      def update
        @metric = prometheus_metric

        if @metric.update(metrics_params)
          redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus),
            notice: _('Metric was successfully updated.')
        else
          render 'edit'
        end
      end

      def edit
        @metric = prometheus_metric
      end

      def destroy
        destroy_metrics_service(prometheus_metric).execute

        respond_to do |format|
          format.html do
            redirect_to edit_project_settings_integration_path(project, ::Integrations::Prometheus), status: :see_other
          end
          format.json do
            head :ok
          end
        end
      end

      private

      def prometheus_adapter
        @prometheus_adapter ||= ::Gitlab::Prometheus::Adapter.new(project, project.deployment_platform&.cluster).prometheus_adapter
      end

      def require_prometheus_metrics!
        render_404 unless prometheus_adapter&.can_query?
      end

      def prometheus_metric
        @prometheus_metric ||= ::PrometheusMetricsFinder.new(id: params[:id]).execute.first
      end

      def update_metrics_service(metric)
        ::Projects::Prometheus::Metrics::UpdateService.new(metric, metrics_params)
      end

      def destroy_metrics_service(metric)
        ::Projects::Prometheus::Metrics::DestroyService.new(metric)
      end

      def metrics_params
        params.require(:prometheus_metric).permit(:title, :query, :y_label, :unit, :legend, :group)
      end
    end
  end
end