Skip to content

Allow Escalation Rules to notify a specific User

Sean Arnold requested to merge 330648-allow-user-selection-escalation-rules into master

What does this MR do?

This allows Escalation Rules to reference a specific User to notify, rather just an Oncall Schedule (added in !64274 (merged), !6143 (merged), !61966 (merged))l.

To do this, we've added a new column to the incident_management_escalation_rules table, and removed the NOT NULL constraint from the oncall_schedule_id column.

Database Changes

Up
== 20210702062712 RemoveNullConstraintForScheduleOnEscalationRules: migrating ==
-- change_column_null(:incident_management_escalation_rules, :oncall_schedule_id, true)
   -> 0.0015s
== 20210702062712 RemoveNullConstraintForScheduleOnEscalationRules: migrated (0.0016s)


== 20210630235045 AddUserColumnToEscalationRules: migrating ===================
-- add_column(:incident_management_escalation_rules, :user_id, :integer, {:null=>true})
   -> 0.0025s
== 20210630235045 AddUserColumnToEscalationRules: migrated (0.0026s) ==========

== 20210701041314 AddForeignKeyAndIndexForIncidentManagementEscalationRule: migrating
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:incident_management_escalation_rules, :user_id, {:name=>"index_on_user_escalation_rule", :algorithm=>:concurrently})
   -> 0.0041s
-- execute("SET statement_timeout TO 0")
   -> 0.0004s
-- add_index(:incident_management_escalation_rules, :user_id, {:name=>"index_on_user_escalation_rule", :algorithm=>:concurrently})
   -> 0.0032s
-- execute("RESET ALL")
   -> 0.0004s
-- transaction_open?()
   -> 0.0000s
-- foreign_keys(:incident_management_escalation_rules)
   -> 0.0031s
-- execute("ALTER TABLE incident_management_escalation_rules\nADD CONSTRAINT fk_0314ee86eb\nFOREIGN KEY (user_id)\nREFERENCES users (id)\nON DELETE SET NULL\nNOT VALID;\n")
   -> 0.0023s
-- execute("ALTER TABLE incident_management_escalation_rules VALIDATE CONSTRAINT fk_0314ee86eb;")
   -> 0.0094s
== 20210701041314 AddForeignKeyAndIndexForIncidentManagementEscalationRule: migrated (0.0325s)

== 20210702062712 RemoveNullConstraintFromPendingEscalationsAlert: migrating ==
-- change_column_null(:incident_management_pending_alert_escalations, :schedule_id, true)
   -> 0.0015s
== 20210702062712 RemoveNullConstraintFromPendingEscalationsAlert: migrated (0.0016s)

== 20210702062842 AddUserColumnToPendingAlertEscalations: migrating ===========
-- add_column(:incident_management_pending_alert_escalations, :user_id, :integer, {:null=>true})
   -> 0.0014s
== 20210702062842 AddUserColumnToPendingAlertEscalations: migrated (0.0015s) ==

== 20210702063006 AddForeignKeyAndIndexForUserPendingAlertEscalations: migrating
-- add_index(:incident_management_pending_alert_escalations, :user_id, {:name=>"index_on_user_pending_escalations_alert"})
   -> 0.0095s
-- add_foreign_key(:incident_management_pending_alert_escalations, :users, {:column=>:user_id, :on_delete=>:nullify})
   -> 0.0107s
== 20210702063006 AddForeignKeyAndIndexForUserPendingAlertEscalations: migrated (0.0203s)
Down
== 20210702063006 AddForeignKeyAndIndexForUserPendingAlertEscalations: reverting
-- remove_index(:incident_management_pending_alert_escalations, :user_id, {:name=>"index_on_user_pending_escalations_alert"})
   -> 0.0172s
-- remove_foreign_key(:incident_management_pending_alert_escalations, {:column=>:user_id})
   -> 0.0070s
== 20210702063006 AddForeignKeyAndIndexForUserPendingAlertEscalations: reverted (0.0244s)

== 20210702062842 AddUserColumnToPendingAlertEscalations: reverting ===========
-- remove_column(:incident_management_pending_alert_escalations, :user_id)
   -> 0.0017s
== 20210702062842 AddUserColumnToPendingAlertEscalations: reverted (0.0087s) ==

== 20210702062712 RemoveNullConstraintFromPendingEscalationsAlert: reverting ==
== 20210702062712 RemoveNullConstraintFromPendingEscalationsAlert: reverted (0.0000s)

= 20210701041314 AddForeignKeyAndIndexForIncidentManagementEscalationRule: reverting
-- transaction_open?()
   -> 0.0000s
-- index_exists?(:incident_management_escalation_rules, :user_id, {:name=>"index_on_user_escalation_rule", :algorithm=>:concurrently})
   -> 0.0037s
-- execute("SET statement_timeout TO 0")
   -> 0.0005s
-- remove_index(:incident_management_escalation_rules, {:name=>"index_on_user_escalation_rule", :algorithm=>:concurrently, :column=>:user_id})
   -> 0.0072s
-- execute("RESET ALL")
   -> 0.0004s
-- remove_foreign_key(:incident_management_escalation_rules, {:column=>:user_id})
   -> 0.0086s
== 20210701041314 AddForeignKeyAndIndexForIncidentManagementEscalationRule: reverted (0.0212s)

== 20210630235045 AddUserColumnToEscalationRules: reverting ===================
-- remove_column(:incident_management_escalation_rules, :user_id)
   -> 0.0012s
== 20210630235045 AddUserColumnToEscalationRules: reverted (0.0099s) ==========

== 20210630234746 RemoveNullConstraintForScheduleOnEscalationRules: reverting =
== 20210630234746 RemoveNullConstraintForScheduleOnEscalationRules: reverted (0.0000s)

GraphQL Changes

We also adjust the GraphQL mutation & associated types to allow a user to be selected when creating and updating

Overview of changes:

  • Add User to the EscalationRuleType
  • Added a username field to the mutation
  • Add error handling and validation for the User
Example GraphQL mutation: Mutation:

mutation CreateEscalationPolicy($input: EscalationPolicyCreateInput!) {
  escalationPolicyCreate(input: $input) {
    escalationPolicy {
      id
      name
      description
      rules {
        status
        elapsedTimeSeconds
        oncallSchedule {
          name
          iid
        }
        user {
          username
        }
      }
    }
    errors
  }
}

Input:


{
  "input": {
    "projectPath": "root/autodevops-deploy-test",
    "name": "Let the boss know",
    "description":"Test description",
    "rules": [
      {
        "oncallScheduleIid": "3",
        "elapsedTimeSeconds": 60,
        "status": "ACKNOWLEDGED"
      },
      {
        "username":"root",
        "elapsedTimeSeconds": 120,
        "status": "RESOLVED"
      }

    ]
  }
}

Service / Behaviour changes

I've made the changes necessary to send notifications to users, rather than via schedules in the IncidentManagement::PendingEscalations::ProcessService.

Screenshots (strongly suggested)

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

Does this MR contain changes to processing or storing of credentials or tokens, authorization and authentication methods or other items described in the security review guidelines? If not, then delete this Security section.

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team

Related to #330648 (closed)

Edited by Sean Arnold

Merge request reports