Commit ce05c01d authored by Peter Leitzen's avatar Peter Leitzen

Handle severity for generic alert payloads more gracefully

Allow values being case-insensitive and use `critical` as fallback
for unmapped values.
parent df39fe86
---
title: Handle severity for generic payloads more gracefully
merge_request: 53999
author:
type: fixed
......@@ -53,7 +53,7 @@ RSpec.describe Gitlab::AlertManagement::Payload::Generic do
describe '#severity' do
subject { parsed_payload.severity }
it { is_expected.to eq('low') }
it { is_expected.to eq(:low) }
end
describe '#environment_name' do
......@@ -178,7 +178,7 @@ RSpec.describe Gitlab::AlertManagement::Payload::Generic do
describe '#severity' do
subject { parsed_payload.severity }
it { is_expected.to eq('high') }
it { is_expected.to eq(:high) }
end
describe '#environment_name' do
......
......@@ -44,11 +44,25 @@ module Gitlab
:title
].freeze
private_constant :EXPECTED_PAYLOAD_ATTRIBUTES
# Define expected API for a payload
EXPECTED_PAYLOAD_ATTRIBUTES.each do |key|
define_method(key) {}
end
SEVERITY_MAPPING = {
'critical' => :critical,
'high' => :high,
'medium' => :medium,
'low' => :low,
'info' => :info
}.freeze
# Handle an unmapped severity value the same way we treat missing values
# so we can fallback to alert's default severity `critical`.
UNMAPPED_SEVERITY = nil
# Defines a method which allows access to a given
# value within an alert payload
#
......@@ -131,9 +145,21 @@ module Gitlab
true
end
def severity
severity_mapping.fetch(severity_raw.to_s.downcase, UNMAPPED_SEVERITY)
end
private
def plain_gitlab_fingerprint; end
def plain_gitlab_fingerprint
end
def severity_raw
end
def severity_mapping
SEVERITY_MAPPING
end
def truncate_hosts(hosts)
return hosts if hosts.join.length <= ::AlertManagement::Alert::HOSTS_MAX_LENGTH
......
......@@ -6,7 +6,6 @@ module Gitlab
module Payload
class Generic < Base
DEFAULT_TITLE = 'New: Incident'
DEFAULT_SEVERITY = 'critical'
attribute :description, paths: 'description'
attribute :ends_at, paths: 'end_time', type: :time
......@@ -15,10 +14,12 @@ module Gitlab
attribute :monitoring_tool, paths: 'monitoring_tool'
attribute :runbook, paths: 'runbook'
attribute :service, paths: 'service'
attribute :severity, paths: 'severity', fallback: -> { DEFAULT_SEVERITY }
attribute :starts_at, paths: 'start_time', type: :time, fallback: -> { Time.current.utc }
attribute :title, paths: 'title', fallback: -> { DEFAULT_TITLE }
attribute :severity_raw, paths: 'severity'
private :severity_raw
attribute :plain_gitlab_fingerprint, paths: 'fingerprint'
private :plain_gitlab_fingerprint
end
......
......@@ -5,6 +5,8 @@ module Gitlab
module Payload
# Attribute mapping for alerts via prometheus alerting integration.
class Prometheus < Base
extend Gitlab::Utils::Override
attribute :alert_markdown, paths: %w(annotations gitlab_incident_markdown)
attribute :annotations, paths: 'annotations'
attribute :description, paths: %w(annotations description)
......@@ -35,12 +37,7 @@ module Gitlab
METRIC_TIME_WINDOW = 30.minutes
SEVERITY_MAP = {
'critical' => :critical,
'high' => :high,
'medium' => :medium,
'low' => :low,
'info' => :info,
ADDITIONAL_SEVERITY_MAPPING = {
's1' => :critical,
's2' => :high,
's3' => :medium,
......@@ -65,10 +62,6 @@ module Gitlab
'page' => :high
}.freeze
# Handle an unmapped severity value the same way we treat missing values
# so we can fallback to alert's default severity `critical`.
UNMAPPED_SEVERITY = nil
def monitoring_tool
Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus]
end
......@@ -101,14 +94,13 @@ module Gitlab
project && title && starts_at_raw
end
def severity
return unless severity_raw
private
SEVERITY_MAP.fetch(severity_raw.to_s.downcase, UNMAPPED_SEVERITY)
override :severity_mapping
def severity_mapping
super.merge(ADDITIONAL_SEVERITY_MAPPING)
end
private
def plain_gitlab_fingerprint
[starts_at_raw, title, full_query].join('/')
end
......
......@@ -19,7 +19,34 @@ RSpec.describe Gitlab::AlertManagement::Payload::Generic do
describe '#severity' do
subject { parsed_payload.severity }
it_behaves_like 'parsable alert payload field with fallback', 'critical', 'severity'
context 'when set' do
using RSpec::Parameterized::TableSyntax
let(:raw_payload) { { 'severity' => payload_severity } }
where(:payload_severity, :expected_severity) do
'critical' | :critical
'high' | :high
'medium' | :medium
'low' | :low
'info' | :info
'CRITICAL' | :critical
'cRiTiCaL' | :critical
'unmapped' | nil
1 | nil
nil | nil
end
with_them do
it { is_expected.to eq(expected_severity) }
end
end
context 'without key' do
it { is_expected.to be_nil }
end
end
describe '#monitoring_tool' do
......
......@@ -239,13 +239,13 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do
end
describe '#severity' do
using RSpec::Parameterized::TableSyntax
let(:raw_payload) { { 'labels' => { 'severity' => payload_severity } } }
subject { parsed_payload.severity }
context 'when set' do
using RSpec::Parameterized::TableSyntax
let(:raw_payload) { { 'labels' => { 'severity' => payload_severity } } }
where(:payload_severity, :expected_severity) do
'critical' | :critical
'high' | :high
......@@ -293,8 +293,6 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do
end
context 'without key' do
let(:raw_payload) { {} }
it { is_expected.to be_nil }
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment