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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-08-18 09:11:01 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-18 09:11:01 +0300
commit514ace363222f19595375f59b123b5e27c2b9b8a (patch)
tree955d0b886197f5ae104fa29706084dc13061112f /app/models/concerns/incident_management
parent25d4a24f831382d37fabc1b6dd3fde26a6c34d4b (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/concerns/incident_management')
-rw-r--r--app/models/concerns/incident_management/escalatable.rb104
1 files changed, 104 insertions, 0 deletions
diff --git a/app/models/concerns/incident_management/escalatable.rb b/app/models/concerns/incident_management/escalatable.rb
new file mode 100644
index 00000000000..78dce63f59e
--- /dev/null
+++ b/app/models/concerns/incident_management/escalatable.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+module IncidentManagement
+ # Shared functionality for a `#status` field, representing
+ # whether action is required. In EE, this corresponds
+ # to paging functionality with EscalationPolicies.
+ #
+ # This module is only responsible for setting the status and
+ # possible status-related timestamps (EX triggered_at/resolved_at)
+ # for the implementing class. The relationships between these
+ # values and other related timestamps/logic should be managed from
+ # the object class itself. (EX Alert#ended_at = Alert#resolved_at)
+ module Escalatable
+ extend ActiveSupport::Concern
+
+ STATUSES = {
+ triggered: 0,
+ acknowledged: 1,
+ resolved: 2,
+ ignored: 3
+ }.freeze
+
+ STATUS_DESCRIPTIONS = {
+ triggered: 'Investigation has not started',
+ acknowledged: 'Someone is actively investigating the problem',
+ resolved: 'The problem has been addressed',
+ ignored: 'No action will be taken'
+ }.freeze
+
+ included do
+ validates :status, presence: true
+
+ # Ascending sort order sorts statuses: Ignored > Resolved > Acknowledged > Triggered
+ # Descending sort order sorts statuses: Triggered > Acknowledged > Resolved > Ignored
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/221242#what-is-the-expected-correct-behavior
+ scope :order_status, -> (sort_order) { order(status: sort_order == :asc ? :desc : :asc) }
+
+ state_machine :status, initial: :triggered do
+ state :triggered, value: STATUSES[:triggered]
+
+ state :acknowledged, value: STATUSES[:acknowledged]
+
+ state :resolved, value: STATUSES[:resolved] do
+ validates :resolved_at, presence: true
+ end
+
+ state :ignored, value: STATUSES[:ignored]
+
+ state :triggered, :acknowledged, :ignored do
+ validates :resolved_at, absence: true
+ end
+
+ event :trigger do
+ transition any => :triggered
+ end
+
+ event :acknowledge do
+ transition any => :acknowledged
+ end
+
+ event :resolve do
+ transition any => :resolved
+ end
+
+ event :ignore do
+ transition any => :ignored
+ end
+
+ before_transition to: [:triggered, :acknowledged, :ignored] do |escalatable, _transition|
+ escalatable.resolved_at = nil
+ end
+
+ before_transition to: :resolved do |escalatable, transition|
+ resolved_at = transition.args.first
+ escalatable.resolved_at = resolved_at || Time.current
+ end
+ end
+
+ class << self
+ def status_value(name)
+ state_machine_statuses[name]
+ end
+
+ def status_name(raw_status)
+ state_machine_statuses.key(raw_status)
+ end
+
+ def status_names
+ @status_names ||= state_machine_statuses.keys
+ end
+
+ private
+
+ def state_machine_statuses
+ @state_machine_statuses ||= state_machines[:status].states.to_h { |s| [s.name, s.value] }
+ end
+ end
+
+ def status_event_for(status)
+ self.class.state_machines[:status].events.transitions_for(self, to: status.to_s.to_sym).first&.event
+ end
+ end
+ end
+end