Commit b84b1252 authored by Sean Arnold's avatar Sean Arnold Committed by Tetiana Chupryna

Return alert IIDs and title in create response

parent ddbff944
......@@ -18,7 +18,11 @@ module Projects
token = extract_alert_manager_token(request)
result = notify_service.execute(token, integration)
head result.http_status
if result.success?
render json: AlertManagement::AlertSerializer.new.represent(result.payload[:alerts]), code: result.http_status
else
head result.http_status
end
end
private
......
......@@ -30,7 +30,11 @@ module Projects
token = extract_alert_manager_token(request)
result = notify_service.execute(token)
head result.http_status
if result.success?
render json: AlertManagement::AlertSerializer.new.represent(result.payload[:alerts]), code: result.http_status
else
head result.http_status
end
end
def create
......
# frozen_string_literal: true
module AlertManagement
class AlertEntity < Grape::Entity
expose :iid
expose :title
end
end
# frozen_string_literal: true
module AlertManagement
class AlertSerializer < BaseSerializer
entity AlertManagement::AlertEntity
end
end
......@@ -4,6 +4,7 @@ module AlertManagement
class ProcessPrometheusAlertService
extend ::Gitlab::Utils::Override
include ::AlertManagement::AlertProcessing
include ::AlertManagement::Responses
def initialize(project, payload)
@project = project
......@@ -18,7 +19,7 @@ module AlertManagement
complete_post_processing_tasks
ServiceResponse.success
success(alert)
end
private
......@@ -40,9 +41,5 @@ module AlertManagement
def resolving_alert?
incoming_payload.resolved?
end
def bad_request
ServiceResponse.error(message: 'Bad Request', http_status: :bad_request)
end
end
end
# frozen_string_literal: true
module AlertManagement
# Module to hold common response logic for AlertManagement services.
module Responses
def success(alerts)
ServiceResponse.success(payload: { alerts: Array(alerts) })
end
def bad_request
ServiceResponse.error(message: 'Bad Request', http_status: :bad_request)
end
def unauthorized
ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized)
end
def unprocessable_entity
ServiceResponse.error(message: 'Unprocessable Entity', http_status: :unprocessable_entity)
end
def forbidden
ServiceResponse.error(message: 'Forbidden', http_status: :forbidden)
end
end
end
......@@ -5,6 +5,7 @@ module Projects
class NotifyService
extend ::Gitlab::Utils::Override
include ::AlertManagement::AlertProcessing
include ::AlertManagement::Responses
def initialize(project, payload)
@project = project
......@@ -23,7 +24,7 @@ module Projects
complete_post_processing_tasks
ServiceResponse.success
success(alert)
end
private
......@@ -46,18 +47,6 @@ module Projects
def valid_token?(token)
token == integration.token
end
def bad_request
ServiceResponse.error(message: 'Bad Request', http_status: :bad_request)
end
def unauthorized
ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized)
end
def forbidden
ServiceResponse.error(message: 'Forbidden', http_status: :forbidden)
end
end
end
end
......@@ -6,6 +6,7 @@ module Projects
class NotifyService
include Gitlab::Utils::StrongMemoize
include ::IncidentManagement::Settings
include ::AlertManagement::Responses
# This set of keys identifies a payload as a valid Prometheus
# payload and thus processable by this service. See also
......@@ -27,9 +28,9 @@ module Projects
return unprocessable_entity unless self.class.processable?(payload)
return unauthorized unless valid_alert_manager_token?(token, integration)
process_prometheus_alerts
alert_responses = process_prometheus_alerts
ServiceResponse.success
alert_response(alert_responses)
end
def self.processable?(payload)
......@@ -128,23 +129,17 @@ module Projects
end
def process_prometheus_alerts
alerts.each do |alert|
alerts.map do |alert|
AlertManagement::ProcessPrometheusAlertService
.new(project, alert.to_h)
.execute
end
end
def bad_request
ServiceResponse.error(message: 'Bad Request', http_status: :bad_request)
end
def unauthorized
ServiceResponse.error(message: 'Unauthorized', http_status: :unauthorized)
end
def alert_response(alert_responses)
alerts = alert_responses.map { |resp| resp.payload[:alert] }.compact
def unprocessable_entity
ServiceResponse.error(message: 'Unprocessable Entity', http_status: :unprocessable_entity)
success(alerts)
end
end
end
......
......@@ -196,6 +196,25 @@ WARNING:
Using your authorization key in the URL is insecure, as it's visible in server logs. We recommend
using one of the above header options if your tooling supports it.
## Response Body
The JSON response body contains a list of any alerts created within the request:
```json
[
{
"iid": 1,
"title": "Incident title"
},
{
"iid": 2,
"title": "Second Incident title"
}
]
```
Successful responses return a `200` response code.
## Triggering test alerts
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3066) in GitLab in 13.2.
......
......@@ -5,6 +5,7 @@ module AlertManagement
class NetworkAlertService
extend ::Gitlab::Utils::Override
include ::AlertManagement::AlertProcessing
include ::AlertManagement::Responses
MONITORING_TOOL = Gitlab::AlertManagement::Payload::MONITORING_TOOLS.fetch(:cilium)
......@@ -20,7 +21,7 @@ module AlertManagement
return bad_request unless alert.persisted?
ServiceResponse.success
success(alert)
end
private
......
......@@ -16,7 +16,9 @@ RSpec.describe Projects::Alerting::NotificationsController do
end
shared_examples 'process alert payload' do |notify_service_class|
let(:service_response) { ServiceResponse.success }
let(:alert_1) { build(:alert_management_alert, project: project) }
let(:alert_2) { build(:alert_management_alert, project: project) }
let(:service_response) { ServiceResponse.success(payload: { alerts: [alert_1, alert_2] }) }
let(:notify_service) { instance_double(notify_service_class, execute: service_response) }
before do
......@@ -30,9 +32,13 @@ RSpec.describe Projects::Alerting::NotificationsController do
context 'when notification service succeeds' do
let(:permitted_params) { ActionController::Parameters.new(payload).permit! }
it 'responds with ok' do
it 'responds with the alert data' do
make_request
expect(json_response).to contain_exactly(
{ 'iid' => alert_1.iid, 'title' => alert_1.title },
{ 'iid' => alert_2.iid, 'title' => alert_2.title }
)
expect(response).to have_gitlab_http_status(:ok)
end
......
......@@ -160,7 +160,9 @@ RSpec.describe Projects::Prometheus::AlertsController do
end
describe 'POST #notify' do
let(:service_response) { ServiceResponse.success }
let(:alert_1) { build(:alert_management_alert, :prometheus, project: project) }
let(:alert_2) { build(:alert_management_alert, :prometheus, project: project) }
let(:service_response) { ServiceResponse.success(payload: { alerts: [alert_1, alert_2] }) }
let(:notify_service) { instance_double(Projects::Prometheus::Alerts::NotifyService, execute: service_response) }
before do
......@@ -173,10 +175,15 @@ RSpec.describe Projects::Prometheus::AlertsController do
end
it 'returns ok if notification succeeds' do
expect(notify_service).to receive(:execute).and_return(ServiceResponse.success)
expect(notify_service).to receive(:execute).and_return(service_response)
post :notify, params: project_params, session: { as: :json }
expect(json_response).to contain_exactly(
{ 'iid' => alert_1.iid, 'title' => alert_1.title },
{ 'iid' => alert_2.iid, 'title' => alert_2.title }
)
expect(response).to have_gitlab_http_status(:ok)
end
......
......@@ -218,8 +218,7 @@ RSpec.describe Projects::Prometheus::Alerts::NotifyService do
.to receive(:new)
.with(project, kind_of(Hash))
.exactly(3).times
.and_return(process_service)
expect(process_service).to receive(:execute).exactly(3).times
.and_call_original
subject
end
......
......@@ -3,7 +3,10 @@
# This shared_example requires the following variables:
# - `service`, the service which includes AlertManagement::AlertProcessing
RSpec.shared_examples 'creates an alert management alert or errors' do
it { is_expected.to be_success }
specify do
expect(subject).to be_success
expect(subject.payload).to match(alerts: all(a_kind_of(AlertManagement::Alert)))
end
it 'creates AlertManagement::Alert' do
expect(Gitlab::AppLogger).not_to receive(:warn)
......@@ -89,6 +92,7 @@ RSpec.shared_examples 'adds an alert management alert event' do
expect { subject }.to change { alert.reload.events }.by(1)
expect(subject).to be_success
expect(subject.payload).to match(alerts: all(a_kind_of(AlertManagement::Alert)))
end
it_behaves_like 'does not create an alert management alert'
......
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