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
|
# frozen_string_literal: true
module Projects
module Operations
class UpdateService < BaseService
def execute
Projects::UpdateService
.new(project, current_user, project_update_params)
.execute
end
private
def project_update_params
error_tracking_params
.merge(alerting_setting_params)
.merge(metrics_setting_params)
.merge(grafana_integration_params)
.merge(prometheus_integration_params)
.merge(incident_management_setting_params)
end
def alerting_setting_params
return {} unless can?(current_user, :read_prometheus_alerts, project)
attr = params[:alerting_setting_attributes]
return {} unless attr
regenerate_token = attr.delete(:regenerate_token)
if regenerate_token
attr[:token] = nil
else
attr = attr.except(:token)
end
{ alerting_setting_attributes: attr }
end
def metrics_setting_params
attribs = params[:metrics_setting_attributes]
return {} unless attribs
attribs[:external_dashboard_url] = attribs[:external_dashboard_url].presence
{ metrics_setting_attributes: attribs }
end
def error_tracking_params
settings = params[:error_tracking_setting_attributes]
return {} if settings.blank?
if error_tracking_params_partial_updates?(settings)
error_tracking_params_for_partial_update(settings)
else
error_tracking_params_for_update(settings)
end
end
def error_tracking_params_partial_updates?(settings)
# Help from @splattael :bow:
# Make sure we're converting to symbols because
# * ActionController::Parameters#keys returns a list of strings
# * in specs we're using hashes with symbols as keys
update_keys = settings.keys.map(&:to_sym)
# Integrated error tracking works without Sentry integration,
# so we don't need to update all those values from error_tracking_params_for_update method.
# Instead we turn it on/off with partial update together with "enabled" attribute.
# But since its optional, we exclude it from the condition below.
update_keys.delete(:integrated)
update_keys == %i[enabled]
end
def error_tracking_params_for_partial_update(settings)
{ error_tracking_setting_attributes: settings }
end
def error_tracking_params_for_update(settings)
api_url = ::ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from(
api_host: settings[:api_host],
project_slug: settings.dig(:project, :slug),
organization_slug: settings.dig(:project, :organization_slug)
)
params = {
error_tracking_setting_attributes: {
api_url: api_url,
enabled: settings[:enabled],
project_name: settings.dig(:project, :name),
organization_name: settings.dig(:project, :organization_name),
sentry_project_id: settings.dig(:project, :sentry_project_id)
}
}
params[:error_tracking_setting_attributes][:token] = settings[:token] unless ::ErrorTracking::SentryClient::Token.masked_token?(settings[:token]) # Don't update token if we receive masked value
params[:error_tracking_setting_attributes][:integrated] = settings[:integrated] unless settings[:integrated].nil?
params
end
def grafana_integration_params
return {} unless attrs = params[:grafana_integration_attributes]
destroy = attrs[:grafana_url].blank? && attrs[:token].blank?
{ grafana_integration_attributes: attrs.merge(_destroy: destroy) }
end
def prometheus_integration_params
return {} unless attrs = params[:prometheus_integration_attributes]
integration = project.find_or_initialize_integration(::Integrations::Prometheus.to_param)
integration.assign_attributes(attrs)
attrs = integration.to_database_hash
{ prometheus_integration_attributes: attrs }
end
def incident_management_setting_params
attrs = params[:incident_management_setting_attributes]
return {} unless attrs
regenerate_token = attrs.delete(:regenerate_token)
if regenerate_token
attrs[:pagerduty_token] = nil
else
attrs = attrs.except(:pagerduty_token)
end
{ incident_management_setting_attributes: attrs }
end
end
end
end
Projects::Operations::UpdateService.prepend_mod_with('Projects::Operations::UpdateService')
|