summaryrefslogtreecommitdiff
path: root/app/services/projects/prometheus/alerts/notify_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/projects/prometheus/alerts/notify_service.rb')
-rw-r--r--app/services/projects/prometheus/alerts/notify_service.rb35
1 files changed, 29 insertions, 6 deletions
diff --git a/app/services/projects/prometheus/alerts/notify_service.rb b/app/services/projects/prometheus/alerts/notify_service.rb
index 2583a6cae9f..877a4f99a94 100644
--- a/app/services/projects/prometheus/alerts/notify_service.rb
+++ b/app/services/projects/prometheus/alerts/notify_service.rb
@@ -7,9 +7,19 @@ module Projects
include Gitlab::Utils::StrongMemoize
include IncidentManagement::Settings
+ # This set of keys identifies a payload as a valid Prometheus
+ # payload and thus processable by this service. See also
+ # https://prometheus.io/docs/alerting/configuration/#webhook_config
+ REQUIRED_PAYLOAD_KEYS = %w[
+ version groupKey status receiver groupLabels commonLabels
+ commonAnnotations externalURL alerts
+ ].to_set.freeze
+
+ SUPPORTED_VERSION = '4'
+
def execute(token)
return bad_request unless valid_payload_size?
- return unprocessable_entity unless valid_version?
+ return unprocessable_entity unless self.class.processable?(params)
return unauthorized unless valid_alert_manager_token?(token)
process_prometheus_alerts
@@ -20,6 +30,14 @@ module Projects
ServiceResponse.success
end
+ def self.processable?(params)
+ # Workaround for https://gitlab.com/gitlab-org/gitlab/-/issues/220496
+ return false unless params
+
+ REQUIRED_PAYLOAD_KEYS.subset?(params.keys.to_set) &&
+ params['version'] == SUPPORTED_VERSION
+ end
+
private
def valid_payload_size?
@@ -42,12 +60,10 @@ module Projects
params['alerts']
end
- def valid_version?
- params['version'] == '4'
- end
-
def valid_alert_manager_token?(token)
- valid_for_manual?(token) || valid_for_managed?(token)
+ valid_for_manual?(token) ||
+ valid_for_alerts_endpoint?(token) ||
+ valid_for_managed?(token)
end
def valid_for_manual?(token)
@@ -61,6 +77,13 @@ module Projects
end
end
+ def valid_for_alerts_endpoint?(token)
+ return false unless project.alerts_service_activated?
+
+ # Here we are enforcing the existence of the token
+ compare_token(token, project.alerts_service.token)
+ end
+
def valid_for_managed?(token)
prometheus_application = available_prometheus_application(project)
return false unless prometheus_application