summaryrefslogtreecommitdiff
path: root/app/controllers/projects/settings/operations_controller.rb
blob: d4126cbd708ab1e2214ee028b5a41c45c093d43c (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
156
157
158
# frozen_string_literal: true

module Projects
  module Settings
    class OperationsController < Projects::ApplicationController
      layout 'project_settings'
      before_action :authorize_admin_operations!
      before_action :authorize_read_prometheus_alerts!, only: [:reset_alerting_token]

      before_action do
        push_frontend_feature_flag(:integrated_error_tracking, project)
      end

      respond_to :json, only: [:reset_alerting_token, :reset_pagerduty_token]

      helper_method :error_tracking_setting
      helper_method :tracing_setting

      feature_category :incident_management
      urgency :low

      def update
        result = ::Projects::Operations::UpdateService.new(project, current_user, update_params).execute

        track_events(result)
        render_update_response(result)
      end

      def reset_alerting_token
        result = ::Projects::Operations::UpdateService
          .new(project, current_user, alerting_params)
          .execute

        if result[:status] == :success
          render json: { token: project.alerting_setting.token }
        else
          render json: {}, status: :unprocessable_entity
        end
      end

      def reset_pagerduty_token
        result = ::Projects::Operations::UpdateService
          .new(project, current_user, pagerduty_token_params)
          .execute

        if result[:status] == :success
          pagerduty_token = project.incident_management_setting&.pagerduty_token
          webhook_url = project_incidents_integrations_pagerduty_url(project, token: pagerduty_token)

          render json: { pagerduty_webhook_url: webhook_url, pagerduty_token: pagerduty_token }
        else
          render json: {}, status: :unprocessable_entity
        end
      end

      private

      def track_events(result)
        if result[:status] == :success
          ::Gitlab::Tracking::IncidentManagement.track_from_params(
            update_params[:incident_management_setting_attributes]
          )
          track_tracing_external_url
        end
      end

      def track_tracing_external_url
        external_url_previous_change = project&.tracing_setting&.external_url_previous_change

        return unless external_url_previous_change
        return unless external_url_previous_change[0].blank? && external_url_previous_change[1].present?

        ::Gitlab::Tracking.event('project:operations:tracing', 'external_url_populated', user: current_user, project: project, namespace: project.namespace)
      end

      def alerting_params
        { alerting_setting_attributes: { regenerate_token: true } }
      end

      def pagerduty_token_params
        { incident_management_setting_attributes: { regenerate_token: true } }
      end

      def render_update_response(result)
        respond_to do |format|
          format.html do
            render_update_html_response(result)
          end

          format.json do
            render_update_json_response(result)
          end
        end
      end

      def render_update_html_response(result)
        if result[:status] == :success
          flash[:notice] = _('Your changes have been saved')
          redirect_to project_settings_operations_path(@project)
        else
          render 'show'
        end
      end

      def render_update_json_response(result)
        if result[:status] == :success
          flash[:notice] = _('Your changes have been saved')
          render json: {
            status: result[:status]
          }
        else
          render(
            status: result[:http_status] || :bad_request,
            json: {
              status: result[:status],
              message: result[:message]
            }
          )
        end
      end

      def error_tracking_setting
        @error_tracking_setting ||= project.error_tracking_setting ||
          project.build_error_tracking_setting
      end

      def tracing_setting
        @tracing_setting ||= project.tracing_setting || project.build_tracing_setting
      end

      def update_params
        params.require(:project).permit(permitted_project_params)
      end

      # overridden in EE
      def permitted_project_params
        {
          incident_management_setting_attributes: ::Gitlab::Tracking::IncidentManagement.tracking_keys.keys,

          metrics_setting_attributes: [:external_dashboard_url, :dashboard_timezone],

          error_tracking_setting_attributes: [
            :enabled,
            :integrated,
            :api_host,
            :token,
            project: [:slug, :name, :organization_slug, :organization_name]
          ],

          grafana_integration_attributes: [:token, :grafana_url, :enabled],
          tracing_setting_attributes: [:external_url]
        }
      end
    end
  end
end

Projects::Settings::OperationsController.prepend_mod_with('Projects::Settings::OperationsController')