Skip to content

GraphQL types for escalation policy and rules

Sean Arnold requested to merge 268356-add-escalation-policy-graphql into master

What does this MR do?

This adds the GraphQL types for the Escalation Policy and Escalation Rule models. These will be used as part of the Escalation Policy MVC.

GraphQL Query / Response

Request:

{
  project(fullPath:"root/autodevops-deploy-test") {
    name
    incidentManagementEscalationPolicies {
      nodes {
        id
        name
        description
        rules {
          id
          status
          elapsedTimeSeconds
          oncallSchedule {
            iid
            name
          }
        }
      }
    }
  }
}

Response:

{
  "data": {
    "project": {
      "name": "Autodevops Deploy Test",
      "incidentManagementEscalationPolicies": {
        "nodes": [
          {
            "id": "gid://gitlab/IncidentManagement::EscalationPolicy/1",
            "name": "Test",
            "description": "Test policy for MR",
            "rules": [
              {
                "id": "gid://gitlab/IncidentManagement::EscalationRule/3",
                "status": "ACKNOWLEDGED",
                "elapsedTimeSeconds": 300,
                "oncallSchedule": {
                  "iid": "3",
                  "name": "Test schedule"
                }
              },
              {
                "id": "gid://gitlab/IncidentManagement::EscalationRule/4",
                "status": "ACKNOWLEDGED",
                "elapsedTimeSeconds": 300,
                "oncallSchedule": {
                  "iid": "1",
                  "name": "Incident response team schedule"
                }
              },
              {
                "id": "gid://gitlab/IncidentManagement::EscalationRule/2",
                "status": "RESOLVED",
                "elapsedTimeSeconds": 60,
                "oncallSchedule": {
                  "iid": "3",
                  "name": "sch"
                }
              }
            ]
          }
        ]
      }
    }
  }
}

We use lookahead to remove N+1 from the nested resources required:

SQL queries for a request
  Feature::FlipperGate Load (0.4ms)  SELECT "feature_gates".* FROM "feature_gates" WHERE "feature_gates"."feature_key" = 'performance_bar_stats' /*application:web,correlation_id:01F5FC9A7FFP2NK74EAHZ6TS3D,line:/lib/feature.rb:80:in `enabled?'*/
  ↳ lib/feature.rb:80:in `enabled?'
Started POST "/api/graphql" for 127.0.0.1 at 2021-05-12 16:10:34 +1200
Processing by GraphqlController#execute as */*
  Parameters: {"query"=>"# {\n#   project(fullPath:\"group22/22_2\") {\n#     projectMembers {\n#       nodes {\n#         id\n#         user {\n#           name\n#         }\n#       }\n#     }\n#   }\n# }\n\n{\n  project(fullPath:\"root/autodevops-deploy-test\") {\n    name\n    incidentManagementEscalationPolicies {\n      nodes {\n        id\n        name\n        rules {\n          id\n          elapsedTimeSeconds\n          oncallSchedule {\n            name\n          }\n        }\n      }\n    }\n  }\n}", "variables"=>"[FILTERED]", "operationName"=>nil, "graphql"=>{"query"=>"# {\n#   project(fullPath:\"group22/22_2\") {\n#     projectMembers {\n#       nodes {\n#         id\n#         user {\n#           name\n#         }\n#       }\n#     }\n#   }\n# }\n\n{\n  project(fullPath:\"root/autodevops-deploy-test\") {\n    name\n    incidentManagementEscalationPolicies {\n      nodes {\n        id\n        name\n        rules {\n          id\n          elapsedTimeSeconds\n          oncallSchedule {\n            name\n          }\n        }\n      }\n    }\n  }\n}", "variables"=>"[FILTERED]", "operationName"=>nil}}
  User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/app/controllers/concerns/impersonation.rb:7:in `current_user'*/
  ↳ app/controllers/concerns/impersonation.rb:7:in `current_user'
  SQL (1.0ms)  SELECT "projects"."id" AS t0_r0, "projects"."name" AS t0_r1, "projects"."path" AS t0_r2, "projects"."description" AS t0_r3, "projects"."created_at" AS t0_r4, "projects"."updated_at" AS t0_r5, "projects"."creator_id" AS t0_r6, "projects"."namespace_id" AS t0_r7, "projects"."last_activity_at" AS t0_r8, "projects"."import_url" AS t0_r9, "projects"."visibility_level" AS t0_r10, "projects"."archived" AS t0_r11, "projects"."avatar" AS t0_r12, "projects"."merge_requests_template" AS t0_r13, "projects"."star_count" AS t0_r14, "projects"."merge_requests_rebase_enabled" AS t0_r15, "projects"."import_type" AS t0_r16, "projects"."import_source" AS t0_r17, "projects"."approvals_before_merge" AS t0_r18, "projects"."reset_approvals_on_push" AS t0_r19, "projects"."merge_requests_ff_only_enabled" AS t0_r20, "projects"."issues_template" AS t0_r21, "projects"."mirror" AS t0_r22, "projects"."mirror_last_update_at" AS t0_r23, "projects"."mirror_last_successful_update_at" AS t0_r24, "projects"."mirror_user_id" AS t0_r25, "projects"."shared_runners_enabled" AS t0_r26, "projects"."runners_token" AS t0_r27, "projects"."build_coverage_regex" AS t0_r28, "projects"."build_allow_git_fetch" AS t0_r29, "projects"."build_timeout" AS t0_r30, "projects"."mirror_trigger_builds" AS t0_r31, "projects"."pending_delete" AS t0_r32, "projects"."public_builds" AS t0_r33, "projects"."last_repository_check_failed" AS t0_r34, "projects"."last_repository_check_at" AS t0_r35, "projects"."container_registry_enabled" AS t0_r36, "projects"."only_allow_merge_if_pipeline_succeeds" AS t0_r37, "projects"."has_external_issue_tracker" AS t0_r38, "projects"."repository_storage" AS t0_r39, "projects"."repository_read_only" AS t0_r40, "projects"."request_access_enabled" AS t0_r41, "projects"."has_external_wiki" AS t0_r42, "projects"."ci_config_path" AS t0_r43, "projects"."lfs_enabled" AS t0_r44, "projects"."description_html" AS t0_r45, "projects"."only_allow_merge_if_all_discussions_are_resolved" AS t0_r46, "projects"."repository_size_limit" AS t0_r47, "projects"."printing_merge_request_link_enabled" AS t0_r48, "projects"."auto_cancel_pending_pipelines" AS t0_r49, "projects"."service_desk_enabled" AS t0_r50, "projects"."cached_markdown_version" AS t0_r51, "projects"."delete_error" AS t0_r52, "projects"."last_repository_updated_at" AS t0_r53, "projects"."disable_overriding_approvers_per_merge_request" AS t0_r54, "projects"."storage_version" AS t0_r55, "projects"."resolve_outdated_diff_discussions" AS t0_r56, "projects"."remote_mirror_available_overridden" AS t0_r57, "projects"."only_mirror_protected_branches" AS t0_r58, "projects"."pull_mirror_available_overridden" AS t0_r59, "projects"."jobs_cache_index" AS t0_r60, "projects"."external_authorization_classification_label" AS t0_r61, "projects"."mirror_overwrites_diverged_branches" AS t0_r62, "projects"."pages_https_only" AS t0_r63, "projects"."external_webhook_token" AS t0_r64, "projects"."packages_enabled" AS t0_r65, "projects"."merge_requests_author_approval" AS t0_r66, "projects"."pool_repository_id" AS t0_r67, "projects"."runners_token_encrypted" AS t0_r68, "projects"."bfg_object_map" AS t0_r69, "projects"."detected_repository_languages" AS t0_r70, "projects"."merge_requests_disable_committers_approval" AS t0_r71, "projects"."require_password_to_approve" AS t0_r72, "projects"."emails_disabled" AS t0_r73, "projects"."max_pages_size" AS t0_r74, "projects"."max_artifacts_size" AS t0_r75, "projects"."pull_mirror_branch_prefix" AS t0_r76, "projects"."remove_source_branch_after_merge" AS t0_r77, "projects"."marked_for_deletion_at" AS t0_r78, "projects"."marked_for_deletion_by_user_id" AS t0_r79, "projects"."autoclose_referenced_issues" AS t0_r80, "projects"."suggestion_commit_message" AS t0_r81, "routes"."id" AS t1_r0, "routes"."source_id" AS t1_r1, "routes"."source_type" AS t1_r2, "routes"."path" AS t1_r3, "routes"."created_at" AS t1_r4, "routes"."updated_at" AS t1_r5, "routes"."name" AS t1_r6 FROM "projects" LEFT OUTER JOIN "routes" ON "routes"."source_type" = 'Project' AND "routes"."source_id" = "projects"."id" WHERE ((LOWER(routes.path) = LOWER('root/autodevops-deploy-test'))) /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/lib/gitlab/graphql/loaders/full_path_model_loader.rb:19:in `block in find'*/
  ↳ lib/gitlab/graphql/loaders/full_path_model_loader.rb:19:in `block in find'
  Group Load (0.5ms)  SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."type" = 'Group' AND "namespaces"."id" = 1 AND "namespaces"."type" = 'Group' LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/ee/app/policies/ee/project_policy.rb:308:in `block (2 levels) in <module:ProjectPolicy>'*/
  ↳ ee/app/policies/ee/project_policy.rb:308:in `block (2 levels) in <module:ProjectPolicy>'
  IncidentManagement::EscalationPolicy Load (0.3ms)  SELECT "incident_management_escalation_policies".* FROM "incident_management_escalation_policies" WHERE "incident_management_escalation_policies"."project_id" = 21 ORDER BY "incident_management_escalation_policies"."id" DESC LIMIT 100 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/lib/gitlab/graphql/pagination/keyset/connection.rb:108:in `nodes'*/
  ↳ lib/gitlab/graphql/pagination/keyset/connection.rb:108:in `nodes'
  IncidentManagement::EscalationRule Load (0.2ms)  SELECT "incident_management_escalation_rules".* FROM "incident_management_escalation_rules" WHERE "incident_management_escalation_rules"."policy_id" = 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/lib/gitlab/graphql/pagination/keyset/connection.rb:108:in `nodes'*/
  ↳ lib/gitlab/graphql/pagination/keyset/connection.rb:108:in `nodes'
  IncidentManagement::OncallSchedule Load (0.2ms)  SELECT "incident_management_oncall_schedules".* FROM "incident_management_oncall_schedules" WHERE "incident_management_oncall_schedules"."id" IN (5, 8, 12) /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/lib/gitlab/graphql/pagination/keyset/connection.rb:108:in `nodes'*/
  ↳ lib/gitlab/graphql/pagination/keyset/connection.rb:108:in `nodes'
  Project Load (0.6ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = 4 LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/ee/app/policies/incident_management/oncall_schedule_policy.rb:5:in `block in <class:OncallSchedulePolicy>'*/
  ↳ ee/app/policies/incident_management/oncall_schedule_policy.rb:5:in `block in <class:OncallSchedulePolicy>'
  Group Load (0.6ms)  SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."type" = 'Group' AND "namespaces"."id" = 24 AND "namespaces"."type" = 'Group' LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/ee/app/policies/ee/project_policy.rb:304:in `block (2 levels) in <module:ProjectPolicy>'*/
  ↳ ee/app/policies/ee/project_policy.rb:304:in `block (2 levels) in <module:ProjectPolicy>'
  SamlProvider Load (0.4ms)  SELECT "saml_providers".* FROM "saml_providers" WHERE "saml_providers"."group_id" = 24 LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/ee/lib/gitlab/auth/group_saml/sso_enforcer.rb:35:in `group_access_restricted?'*/
  ↳ ee/lib/gitlab/auth/group_saml/sso_enforcer.rb:35:in `group_access_restricted?'
  Project Load (0.6ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = 4301 LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/ee/app/policies/incident_management/oncall_schedule_policy.rb:5:in `block in <class:OncallSchedulePolicy>'*/
  ↳ ee/app/policies/incident_management/oncall_schedule_policy.rb:5:in `block in <class:OncallSchedulePolicy>'
  Group Load (0.5ms)  SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."type" = 'Group' AND "namespaces"."id" = 4374 AND "namespaces"."type" = 'Group' LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/ee/app/policies/ee/project_policy.rb:304:in `block (2 levels) in <module:ProjectPolicy>'*/
  ↳ ee/app/policies/ee/project_policy.rb:304:in `block (2 levels) in <module:ProjectPolicy>'
  SamlProvider Load (0.3ms)  SELECT "saml_providers".* FROM "saml_providers" WHERE "saml_providers"."group_id" = 4374 LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/ee/lib/gitlab/auth/group_saml/sso_enforcer.rb:35:in `group_access_restricted?'*/
  ↳ ee/lib/gitlab/auth/group_saml/sso_enforcer.rb:35:in `group_access_restricted?'
  Project Load (0.6ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = 4303 LIMIT 1 /*application:web,correlation_id:01F5FC9VDY9A885EYB81THFX94,endpoint_id:GraphqlController#execute,line:/ee/app/policies/incident_management/oncall_schedule_policy.rb:5:in `block in <class:OncallSchedulePolicy>'*/
  ↳ ee/app/policies/incident_management/oncall_schedule_policy.rb:5:in `block in <class:OncallSchedulePolicy>'
  CACHE Group Load (0.1ms)  SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."type" = 'Group' AND "namespaces"."id" = 4374 AND "namespaces"."type" = 'Group' LIMIT 1
  ↳ ee/app/policies/ee/project_policy.rb:304:in `block (2 levels) in <module:ProjectPolicy>'
  CACHE SamlProvider Load (0.1ms)  SELECT "saml_providers".* FROM "saml_providers" WHERE "saml_providers"."group_id" = 4374 LIMIT 1  [["group_id", 4374], ["LIMIT", 1]]
  ↳ ee/lib/gitlab/auth/group_saml/sso_enforcer.rb:35:in `group_access_restricted?'
Completed 200 OK in 175ms (Views: 0.3ms | ActiveRecord: 6.7ms | Elasticsearch: 0.0ms | Allocations: 124031)

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 #268356 (closed)

Edited by Sean Arnold

Merge request reports