Commit fa33a3df authored by Sarah Yasonik's avatar Sarah Yasonik Committed by Vitali Tatarintev

Condense alert presenters into single presenter

This transitions the alert presenter away from using
Gitlab::Alerting::Alert for parsing content, prefering
to use the new payload parsing classes.
parent 7b7a6515
...@@ -6,6 +6,8 @@ module Types ...@@ -6,6 +6,8 @@ module Types
graphql_name 'AlertManagementAlert' graphql_name 'AlertManagementAlert'
description "Describes an alert from the project's Alert Management" description "Describes an alert from the project's Alert Management"
present_using ::AlertManagement::AlertPresenter
implements(Types::Notes::NoteableType) implements(Types::Notes::NoteableType)
authorize :read_alert_management_alert authorize :read_alert_management_alert
...@@ -120,10 +122,6 @@ module Types ...@@ -120,10 +122,6 @@ module Types
def notes def notes
object.ordered_notes object.ordered_notes
end end
def runbook
object.parsed_payload.runbook
end
end end
end end
end end
...@@ -117,7 +117,7 @@ module AlertManagement ...@@ -117,7 +117,7 @@ module AlertManagement
end end
delegate :iid, to: :issue, prefix: true, allow_nil: true delegate :iid, to: :issue, prefix: true, allow_nil: true
delegate :metrics_dashboard_url, :details_url, :details, to: :present delegate :details_url, to: :present
scope :for_iid, -> (iid) { where(iid: iid) } scope :for_iid, -> (iid) { where(iid: iid) }
scope :for_status, -> (status) { where(status: status) } scope :for_status, -> (status) { where(status: status) }
...@@ -198,12 +198,6 @@ module AlertManagement ...@@ -198,12 +198,6 @@ module AlertManagement
end end
end end
def present
return super(presenter_class: AlertManagement::PrometheusAlertPresenter) if prometheus?
super
end
private private
def hook_data def hook_data
......
...@@ -6,7 +6,10 @@ module AlertManagement ...@@ -6,7 +6,10 @@ module AlertManagement
include IncidentManagement::Settings include IncidentManagement::Settings
include ActionView::Helpers::UrlHelper include ActionView::Helpers::UrlHelper
MARKDOWN_LINE_BREAK = " \n".freeze MARKDOWN_LINE_BREAK = " \n"
HORIZONTAL_LINE = "\n\n---\n\n"
delegate :metrics_dashboard_url, :runbook, to: :parsed_payload
def initialize(alert, _attributes = {}) def initialize(alert, _attributes = {})
super super
...@@ -16,28 +19,17 @@ module AlertManagement ...@@ -16,28 +19,17 @@ module AlertManagement
end end
def issue_description def issue_description
horizontal_line = "\n\n---\n\n"
[ [
issue_summary_markdown, issue_summary_markdown,
alert_markdown, alert_markdown,
incident_management_setting.issue_template_content incident_management_setting.issue_template_content
].compact.join(horizontal_line) ].compact.join(HORIZONTAL_LINE)
end end
def start_time def start_time
started_at&.strftime('%d %B %Y, %-l:%M%p (%Z)') started_at&.strftime('%d %B %Y, %-l:%M%p (%Z)')
end end
def issue_summary_markdown
<<~MARKDOWN.chomp
#{metadata_list}
#{alert_details}#{metric_embed_for_alert}
MARKDOWN
end
def metrics_dashboard_url; end
def details_url def details_url
details_project_alert_management_url(project, alert.iid) details_project_alert_management_url(project, alert.iid)
end end
...@@ -49,15 +41,15 @@ module AlertManagement ...@@ -49,15 +41,15 @@ module AlertManagement
private private
attr_reader :alert, :project attr_reader :alert, :project
delegate :alert_markdown, :full_query, to: :parsed_payload
def alerting_alert def issue_summary_markdown
strong_memoize(:alerting_alert) do <<~MARKDOWN.chomp
Gitlab::Alerting::Alert.new(project: project, payload: alert.payload).present #{metadata_list}
end #{alert_details}#{metric_embed_for_alert}
MARKDOWN
end end
def alert_markdown; end
def metadata_list def metadata_list
metadata = [] metadata = []
...@@ -90,9 +82,9 @@ module AlertManagement ...@@ -90,9 +82,9 @@ module AlertManagement
.join(MARKDOWN_LINE_BREAK) .join(MARKDOWN_LINE_BREAK)
end end
def metric_embed_for_alert; end def metric_embed_for_alert
"\n[](#{metrics_dashboard_url})" if metrics_dashboard_url
def full_query; end end
def list_item(key, value) def list_item(key, value)
"**#{key}:** #{value}".strip "**#{key}:** #{value}".strip
......
# frozen_string_literal: true
module AlertManagement
class PrometheusAlertPresenter < AlertManagement::AlertPresenter
def metrics_dashboard_url
alerting_alert.metrics_dashboard_url
end
private
def alert_markdown
alerting_alert.alert_markdown
end
def metric_embed_for_alert
alerting_alert.metric_embed_for_alert
end
def full_query
alerting_alert.full_query
end
end
end
...@@ -422,22 +422,4 @@ RSpec.describe AlertManagement::Alert do ...@@ -422,22 +422,4 @@ RSpec.describe AlertManagement::Alert do
expect { subject }.to change { alert.events }.by(1) expect { subject }.to change { alert.events }.by(1)
end end
end end
describe '#present' do
context 'when alert is generic' do
let(:alert) { triggered_alert }
it 'uses generic alert presenter' do
expect(alert.present).to be_kind_of(AlertManagement::AlertPresenter)
end
end
context 'when alert is Prometheus specific' do
let(:alert) { build(:alert_management_alert, :prometheus, project: project) }
it 'uses Prometheus Alert presenter' do
expect(alert.present).to be_kind_of(AlertManagement::PrometheusAlertPresenter)
end
end
end
end end
...@@ -4,8 +4,7 @@ require 'spec_helper' ...@@ -4,8 +4,7 @@ require 'spec_helper'
RSpec.describe AlertManagement::AlertPresenter do RSpec.describe AlertManagement::AlertPresenter do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let_it_be(:payload) do
let_it_be(:generic_payload) do
{ {
'title' => 'Alert title', 'title' => 'Alert title',
'start_time' => '2020-04-27T10:10:22.265949279Z', 'start_time' => '2020-04-27T10:10:22.265949279Z',
...@@ -20,42 +19,108 @@ RSpec.describe AlertManagement::AlertPresenter do ...@@ -20,42 +19,108 @@ RSpec.describe AlertManagement::AlertPresenter do
} }
end end
let_it_be(:alert) do let_it_be(:alert) { create(:alert_management_alert, project: project, payload: payload) }
create(:alert_management_alert, :with_description, :with_host, :with_service, :with_monitoring_tool, project: project, payload: generic_payload)
end
let(:alert_url) { "http://localhost/#{project.full_path}/-/alert_management/#{alert.iid}/details" } let(:alert_url) { "http://localhost/#{project.full_path}/-/alert_management/#{alert.iid}/details" }
subject(:presenter) { described_class.new(alert) } subject(:presenter) { described_class.new(alert) }
describe '#issue_description' do describe '#issue_description' do
let_it_be(:alert) { create(:alert_management_alert, project: project, payload: {}) }
let(:markdown_line_break) { ' ' } let(:markdown_line_break) { ' ' }
it 'returns an alert issue description' do subject { presenter.issue_description }
expect(presenter.issue_description).to eq(
<<~MARKDOWN.chomp context 'with an empty payload' do
**Start time:** #{presenter.start_time}#{markdown_line_break} it do
**Severity:** #{presenter.severity}#{markdown_line_break} is_expected.to eq(
**Service:** #{alert.service}#{markdown_line_break} <<~MARKDOWN.chomp
**Monitoring tool:** #{alert.monitoring_tool}#{markdown_line_break} **Start time:** #{presenter.start_time}#{markdown_line_break}
**Hosts:** #{alert.hosts.join(' ')}#{markdown_line_break} **Severity:** #{presenter.severity}#{markdown_line_break}
**Description:** #{alert.description}#{markdown_line_break} **GitLab alert:** #{alert_url}
**GitLab alert:** #{alert_url}
MARKDOWN
#### Alert Details )
end
**title:** Alert title#{markdown_line_break} end
**start_time:** 2020-04-27T10:10:22.265949279Z#{markdown_line_break}
**custom.alert.fields:** ["one", "two"]#{markdown_line_break} context 'with optional alert attributes' do
**yet.another:** 73 let_it_be(:alert) do
MARKDOWN create(:alert_management_alert, :with_description, :with_host, :with_service, :with_monitoring_tool, project: project, payload: payload)
) end
before do
allow(alert.parsed_payload).to receive(:full_query).and_return('metric > 1')
end
it do
is_expected.to eq(
<<~MARKDOWN.chomp
**Start time:** #{presenter.start_time}#{markdown_line_break}
**Severity:** #{presenter.severity}#{markdown_line_break}
**full_query:** `metric > 1`#{markdown_line_break}
**Service:** #{alert.service}#{markdown_line_break}
**Monitoring tool:** #{alert.monitoring_tool}#{markdown_line_break}
**Hosts:** #{alert.hosts.join(' ')}#{markdown_line_break}
**Description:** #{alert.description}#{markdown_line_break}
**GitLab alert:** #{alert_url}
#### Alert Details
**title:** Alert title#{markdown_line_break}
**start_time:** 2020-04-27T10:10:22.265949279Z#{markdown_line_break}
**custom.alert.fields:** ["one", "two"]#{markdown_line_break}
**yet.another:** 73
MARKDOWN
)
end
end
context 'with incident markdown' do
before do
allow(alert.parsed_payload).to receive(:alert_markdown).and_return('**`markdown example`**')
end
it do
is_expected.to eq(
<<~MARKDOWN.chomp
**Start time:** #{presenter.start_time}#{markdown_line_break}
**Severity:** #{presenter.severity}#{markdown_line_break}
**GitLab alert:** #{alert_url}
---
**`markdown example`**
MARKDOWN
)
end
end
context 'with metrics_dashboard_url' do
before do
allow(alert.parsed_payload).to receive(:metrics_dashboard_url).and_return('https://gitlab.com/metrics')
end
it do
is_expected.to eq(
<<~MARKDOWN.chomp
**Start time:** #{presenter.start_time}#{markdown_line_break}
**Severity:** #{presenter.severity}#{markdown_line_break}
**GitLab alert:** #{alert_url}
[](https://gitlab.com/metrics)
MARKDOWN
)
end
end end
end end
describe '#metrics_dashboard_url' do describe '#start_time' do
it 'is not defined' do it 'formats the start time of the alert' do
expect(presenter.metrics_dashboard_url).to be_nil alert.started_at = Time.utc(2019, 5, 5)
expect(presenter.start_time). to eq('05 May 2019, 12:00AM (UTC)')
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe AlertManagement::PrometheusAlertPresenter do
let_it_be(:project) { create(:project) }
let(:payload) do
{
'annotations' => {
'title' => 'Alert title',
'gitlab_incident_markdown' => '**`markdown example`**',
'custom annotation' => 'custom annotation value'
},
'startsAt' => '2020-04-27T10:10:22.265949279Z',
'generatorURL' => 'http://8d467bd4607a:9090/graph?g0.expr=vector%281%29&g0.tab=1'
}
end
let!(:alert) do
create(:alert_management_alert, :prometheus, project: project, payload: payload)
end
let(:alert_url) { "http://localhost/#{project.full_path}/-/alert_management/#{alert.iid}/details" }
subject(:presenter) { described_class.new(alert) }
describe '#issue_description' do
let(:markdown_line_break) { ' ' }
it 'returns an alert issue description' do
expect(presenter.issue_description).to eq(
<<~MARKDOWN.chomp
**Start time:** #{presenter.start_time}#{markdown_line_break}
**Severity:** #{presenter.severity}#{markdown_line_break}
**full_query:** `vector(1)`#{markdown_line_break}
**Monitoring tool:** Prometheus#{markdown_line_break}
**GitLab alert:** #{alert_url}
#### Alert Details
**annotations.custom annotation:** custom annotation value#{markdown_line_break}
**annotations.gitlab_incident_markdown:** **`markdown example`**#{markdown_line_break}
**annotations.title:** Alert title#{markdown_line_break}
**startsAt:** 2020-04-27T10:10:22.265949279Z#{markdown_line_break}
**generatorURL:** http://8d467bd4607a:9090/graph?g0.expr=vector%281%29&g0.tab=1
---
**`markdown example`**
MARKDOWN
)
end
end
describe '#metrics_dashboard_url' do
subject { presenter.metrics_dashboard_url }
context 'for a non-prometheus alert' do
it { is_expected.to be_nil }
end
context 'for a self-managed prometheus alert' do
include_context 'self-managed prometheus alert attributes'
it { is_expected.to eq(dashboard_url_for_alert) }
end
context 'for a gitlab-managed prometheus alert' do
include_context 'gitlab-managed prometheus alert attributes'
it { is_expected.to eq(dashboard_url_for_alert) }
end
end
end
...@@ -66,7 +66,7 @@ RSpec.describe AlertManagement::CreateAlertIssueService do ...@@ -66,7 +66,7 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
end end
it 'sets the issue description' do it 'sets the issue description' do
expect(created_issue.description).to include(alert_presenter.issue_summary_markdown.strip) expect(created_issue.description).to include(alert_presenter.send(:issue_summary_markdown).strip)
end end
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