Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/incident_management')
-rw-r--r--app/services/incident_management/incidents/create_service.rb2
-rw-r--r--app/services/incident_management/link_alerts/base_service.rb27
-rw-r--r--app/services/incident_management/link_alerts/create_service.rb42
-rw-r--r--app/services/incident_management/link_alerts/destroy_service.rb30
-rw-r--r--app/services/incident_management/pager_duty/process_webhook_service.rb22
-rw-r--r--app/services/incident_management/timeline_events/base_service.rb29
-rw-r--r--app/services/incident_management/timeline_events/create_service.rb13
-rw-r--r--app/services/incident_management/timeline_events/destroy_service.rb2
-rw-r--r--app/services/incident_management/timeline_events/update_service.rb43
9 files changed, 182 insertions, 28 deletions
diff --git a/app/services/incident_management/incidents/create_service.rb b/app/services/incident_management/incidents/create_service.rb
index f44842650b7..49019278871 100644
--- a/app/services/incident_management/incidents/create_service.rb
+++ b/app/services/incident_management/incidents/create_service.rb
@@ -23,7 +23,7 @@ module IncidentManagement
description: description,
issue_type: ISSUE_TYPE,
severity: severity,
- alert_management_alert: alert
+ alert_management_alerts: [alert].compact
},
spam_params: nil
).execute
diff --git a/app/services/incident_management/link_alerts/base_service.rb b/app/services/incident_management/link_alerts/base_service.rb
new file mode 100644
index 00000000000..474a63ab528
--- /dev/null
+++ b/app/services/incident_management/link_alerts/base_service.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module IncidentManagement
+ module LinkAlerts
+ class BaseService < ::BaseProjectService
+ private
+
+ attr_reader :incident
+
+ def allowed?
+ current_user&.can?(:admin_issue, project)
+ end
+
+ def success
+ ServiceResponse.success(payload: { incident: incident })
+ end
+
+ def error(message)
+ ServiceResponse.error(message: message)
+ end
+
+ def error_no_permissions
+ error(_('You have insufficient permissions to manage alerts for this project'))
+ end
+ end
+ end
+end
diff --git a/app/services/incident_management/link_alerts/create_service.rb b/app/services/incident_management/link_alerts/create_service.rb
new file mode 100644
index 00000000000..5e5a974efdd
--- /dev/null
+++ b/app/services/incident_management/link_alerts/create_service.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module IncidentManagement
+ module LinkAlerts
+ class CreateService < BaseService
+ # @param incident [Issue] an incident to link alerts
+ # @param current_user [User]
+ # @param alert_references [[String]] a list of alert references. Can be either a short reference or URL
+ # Examples:
+ # "^alert#IID"
+ # "https://gitlab.com/company/project/-/alert_management/IID/details"
+ def initialize(incident, current_user, alert_references)
+ @incident = incident
+ @current_user = current_user
+ @alert_references = alert_references
+
+ super(project: incident.project, current_user: current_user)
+ end
+
+ def execute
+ return error_no_permissions unless allowed?
+
+ references = extract_alerts_from_references
+ incident.alert_management_alerts << references if references.present?
+
+ success
+ end
+
+ private
+
+ attr_reader :alert_references
+
+ def extract_alerts_from_references
+ text = alert_references.join(' ')
+ extractor = Gitlab::ReferenceExtractor.new(project, current_user)
+ extractor.analyze(text, {})
+
+ extractor.alerts
+ end
+ end
+ end
+end
diff --git a/app/services/incident_management/link_alerts/destroy_service.rb b/app/services/incident_management/link_alerts/destroy_service.rb
new file mode 100644
index 00000000000..baeedaf74b6
--- /dev/null
+++ b/app/services/incident_management/link_alerts/destroy_service.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module IncidentManagement
+ module LinkAlerts
+ class DestroyService < BaseService
+ # @param incident [Issue] an incident to unlink alert from
+ # @param current_user [User]
+ # @param alert [AlertManagement::Alert] an alert to unlink from the incident
+ def initialize(incident, current_user, alert)
+ @incident = incident
+ @current_user = current_user
+ @alert = alert
+
+ super(project: incident.project, current_user: current_user)
+ end
+
+ def execute
+ return error_no_permissions unless allowed?
+
+ incident.alert_management_alerts.delete(alert)
+
+ success
+ end
+
+ private
+
+ attr_reader :alert
+ end
+ end
+end
diff --git a/app/services/incident_management/pager_duty/process_webhook_service.rb b/app/services/incident_management/pager_duty/process_webhook_service.rb
index a49e639ea62..3ce2674616e 100644
--- a/app/services/incident_management/pager_duty/process_webhook_service.rb
+++ b/app/services/incident_management/pager_duty/process_webhook_service.rb
@@ -9,8 +9,8 @@ module IncidentManagement
# https://developer.pagerduty.com/docs/webhooks/webhook-behavior/#size-limit
PAGER_DUTY_PAYLOAD_SIZE_LIMIT = 55.kilobytes
- # https://developer.pagerduty.com/docs/webhooks/v2-overview/#webhook-types
- PAGER_DUTY_PROCESSABLE_EVENT_TYPES = %w(incident.trigger).freeze
+ # https://developer.pagerduty.com/docs/db0fa8c8984fc-overview#event-types
+ PAGER_DUTY_PROCESSABLE_EVENT_TYPES = %w(incident.triggered).freeze
def initialize(project, payload)
super(project: project)
@@ -33,16 +33,18 @@ module IncidentManagement
attr_reader :payload
def process_incidents
- pager_duty_processable_events.each do |event|
- ::IncidentManagement::PagerDuty::ProcessIncidentWorker.perform_async(project.id, event['incident'])
- end
+ event = pager_duty_processable_event
+ return unless event
+
+ ::IncidentManagement::PagerDuty::ProcessIncidentWorker
+ .perform_async(project.id, event['incident'])
end
- def pager_duty_processable_events
- strong_memoize(:pager_duty_processable_events) do
- ::PagerDuty::WebhookPayloadParser
- .call(payload.to_h)
- .filter { |msg| msg['event'].to_s.in?(PAGER_DUTY_PROCESSABLE_EVENT_TYPES) }
+ def pager_duty_processable_event
+ strong_memoize(:pager_duty_processable_event) do
+ event = ::PagerDuty::WebhookPayloadParser.call(payload.to_h)
+
+ event if event['event'].to_s.in?(PAGER_DUTY_PROCESSABLE_EVENT_TYPES)
end
end
diff --git a/app/services/incident_management/timeline_events/base_service.rb b/app/services/incident_management/timeline_events/base_service.rb
index 7168e2fdd38..e0ca4320091 100644
--- a/app/services/incident_management/timeline_events/base_service.rb
+++ b/app/services/incident_management/timeline_events/base_service.rb
@@ -5,6 +5,8 @@ module IncidentManagement
class BaseService
include Gitlab::Utils::UsageData
+ AUTOCREATE_TAGS = [TimelineEventTag::START_TIME_TAG_NAME, TimelineEventTag::END_TIME_TAG_NAME].freeze
+
def allowed?
user&.can?(:admin_incident_management_timeline_event, incident)
end
@@ -24,6 +26,33 @@ module IncidentManagement
def error_in_save(timeline_event)
error(timeline_event.errors.full_messages.to_sentence)
end
+
+ def track_timeline_event(event, project)
+ namespace = project.namespace
+ track_usage_event(event, user.id)
+
+ return unless Feature.enabled?(:route_hll_to_snowplow_phase2, namespace)
+
+ Gitlab::Tracking.event(
+ self.class.to_s,
+ event,
+ project: project,
+ namespace: namespace,
+ user: user,
+ label: 'redis_hll_counters.incident_management.incident_management_total_unique_counts_monthly',
+ context: [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: event).to_context]
+ )
+ end
+
+ def auto_create_predefined_tags(new_tags)
+ new_tags = new_tags.map(&:downcase)
+
+ tags_to_create = AUTOCREATE_TAGS.select { |tag| tag.downcase.in?(new_tags) }
+
+ tags_to_create.each do |name|
+ project.incident_management_timeline_event_tags.create(name: name)
+ end
+ end
end
end
end
diff --git a/app/services/incident_management/timeline_events/create_service.rb b/app/services/incident_management/timeline_events/create_service.rb
index 71ff5b64515..06e8fc32335 100644
--- a/app/services/incident_management/timeline_events/create_service.rb
+++ b/app/services/incident_management/timeline_events/create_service.rb
@@ -5,7 +5,6 @@ module IncidentManagement
DEFAULT_ACTION = 'comment'
DEFAULT_EDITABLE = false
DEFAULT_AUTO_CREATED = false
- AUTOCREATE_TAGS = [TimelineEventTag::START_TIME_TAG_NAME, TimelineEventTag::END_TIME_TAG_NAME].freeze
class CreateService < TimelineEvents::BaseService
def initialize(incident, user, params)
@@ -106,7 +105,7 @@ module IncidentManagement
create_timeline_event_tag_links(timeline_event, params[:timeline_event_tag_names])
- track_usage_event(:incident_management_timeline_event_created, user.id)
+ track_timeline_event("incident_management_timeline_event_created", project)
success(timeline_event)
else
@@ -153,16 +152,6 @@ module IncidentManagement
IncidentManagement::TimelineEventTagLink.insert_all(tag_links) if tag_links.any?
end
- def auto_create_predefined_tags(new_tags)
- new_tags = new_tags.map(&:downcase)
-
- tags_to_create = AUTOCREATE_TAGS.select { |tag| tag.downcase.in?(new_tags) }
-
- tags_to_create.each do |name|
- project.incident_management_timeline_event_tags.create(name: name)
- end
- end
-
def validate_tags(project, tag_names)
return [] unless tag_names&.any?
diff --git a/app/services/incident_management/timeline_events/destroy_service.rb b/app/services/incident_management/timeline_events/destroy_service.rb
index e1c6bbbdb85..aba46cdda27 100644
--- a/app/services/incident_management/timeline_events/destroy_service.rb
+++ b/app/services/incident_management/timeline_events/destroy_service.rb
@@ -18,7 +18,7 @@ module IncidentManagement
if timeline_event.destroy
add_system_note(incident, user)
- track_usage_event(:incident_management_timeline_event_deleted, user.id)
+ track_timeline_event('incident_management_timeline_event_deleted', project)
success(timeline_event)
else
error_in_save(timeline_event)
diff --git a/app/services/incident_management/timeline_events/update_service.rb b/app/services/incident_management/timeline_events/update_service.rb
index 8d4e29c6857..4949a5a0bd1 100644
--- a/app/services/incident_management/timeline_events/update_service.rb
+++ b/app/services/incident_management/timeline_events/update_service.rb
@@ -13,21 +13,41 @@ module IncidentManagement
def initialize(timeline_event, user, params)
@timeline_event = timeline_event
@incident = timeline_event.incident
+ @project = incident.project
@user = user
@note = params[:note]
@occurred_at = params[:occurred_at]
@validation_context = VALIDATION_CONTEXT
+ @timeline_event_tags = params[:timeline_event_tag_names]
end
def execute
return error_no_permissions unless allowed?
- timeline_event.assign_attributes(update_params)
+ unless timeline_event_tags.nil?
+ auto_create_predefined_tags(timeline_event_tags)
- if timeline_event.save(context: validation_context)
+ # Refetches the tag objects to consider predefined tags as well
+ new_tags = timeline_event
+ .project
+ .incident_management_timeline_event_tags
+ .by_names(timeline_event_tags)
+
+ non_existing_tags = validate_tags(new_tags)
+
+ return error("#{_("Following tags don't exist")}: #{non_existing_tags}") if non_existing_tags.any?
+ end
+
+ begin
+ timeline_event_saved = update_timeline_event_and_event_tags(new_tags)
+ rescue ActiveRecord::RecordInvalid
+ error_in_save(timeline_event)
+ end
+
+ if timeline_event_saved
add_system_note(timeline_event)
- track_usage_event(:incident_management_timeline_event_edited, user.id)
+ track_timeline_event('incident_management_timeline_event_edited', timeline_event.project)
success(timeline_event)
else
error_in_save(timeline_event)
@@ -36,7 +56,18 @@ module IncidentManagement
private
- attr_reader :timeline_event, :incident, :user, :note, :occurred_at, :validation_context
+ attr_reader :timeline_event, :incident, :project, :user,
+ :note, :occurred_at, :validation_context, :timeline_event_tags
+
+ def update_timeline_event_and_event_tags(new_tags)
+ ApplicationRecord.transaction do
+ timeline_event.timeline_event_tags = new_tags unless timeline_event_tags.nil?
+
+ timeline_event.assign_attributes(update_params)
+
+ timeline_event.save!(context: validation_context)
+ end
+ end
def update_params
{ updated_by_user: user, note: note, occurred_at: occurred_at }.compact
@@ -61,6 +92,10 @@ module IncidentManagement
:none
end
+ def validate_tags(new_tags)
+ timeline_event_tags.map(&:downcase) - new_tags.map(&:name).map(&:downcase)
+ end
+
def allowed?
user&.can?(:edit_incident_management_timeline_event, timeline_event)
end