Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
7b87582b
Commit
7b87582b
authored
Mar 08, 2021
by
Sean Arnold
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add OncallRotationUpdate mutation
-Move shared logic to base - Update docs
parent
0ac6ffdd
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
166 additions
and
93 deletions
+166
-93
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+10
-0
ee/app/graphql/ee/types/mutation_type.rb
ee/app/graphql/ee/types/mutation_type.rb
+1
-0
ee/app/graphql/mutations/incident_management/oncall_rotation/base.rb
...hql/mutations/incident_management/oncall_rotation/base.rb
+90
-0
ee/app/graphql/mutations/incident_management/oncall_rotation/create.rb
...l/mutations/incident_management/oncall_rotation/create.rb
+1
-93
ee/app/graphql/mutations/incident_management/oncall_rotation/update.rb
...l/mutations/incident_management/oncall_rotation/update.rb
+64
-0
No files found.
doc/api/graphql/reference/index.md
View file @
7b87582b
...
@@ -4316,6 +4316,16 @@ Autogenerated return type of OncallRotationDestroy.
...
@@ -4316,6 +4316,16 @@ Autogenerated return type of OncallRotationDestroy.
|
`errors`
|
[
`[String!]!`
](
#string
)
| Errors encountered during execution of the mutation. |
|
`errors`
|
[
`[String!]!`
](
#string
)
| Errors encountered during execution of the mutation. |
|
`oncallRotation`
|
[
`IncidentManagementOncallRotation`
](
#incidentmanagementoncallrotation
)
| The on-call rotation. |
|
`oncallRotation`
|
[
`IncidentManagementOncallRotation`
](
#incidentmanagementoncallrotation
)
| The on-call rotation. |
### `OncallRotationUpdatePayload`
Autogenerated return type of OncallRotationUpdate.
| Field | Type | Description |
| ----- | ---- | ----------- |
|
`clientMutationId`
|
[
`String`
](
#string
)
| A unique identifier for the client performing the mutation. |
|
`errors`
|
[
`[String!]!`
](
#string
)
| Errors encountered during execution of the mutation. |
|
`oncallRotation`
|
[
`IncidentManagementOncallRotation`
](
#incidentmanagementoncallrotation
)
| The on-call rotation. |
### `OncallScheduleCreatePayload`
### `OncallScheduleCreatePayload`
Autogenerated return type of OncallScheduleCreate.
Autogenerated return type of OncallScheduleCreate.
...
...
ee/app/graphql/ee/types/mutation_type.rb
View file @
7b87582b
...
@@ -67,6 +67,7 @@ module EE
...
@@ -67,6 +67,7 @@ module EE
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallSchedule
::
Update
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallSchedule
::
Update
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallSchedule
::
Destroy
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallSchedule
::
Destroy
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallRotation
::
Create
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallRotation
::
Create
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallRotation
::
Update
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallRotation
::
Destroy
mount_mutation
::
Mutations
::
IncidentManagement
::
OncallRotation
::
Destroy
mount_mutation
::
Mutations
::
AppSec
::
Fuzzing
::
Api
::
CiConfiguration
::
Create
mount_mutation
::
Mutations
::
AppSec
::
Fuzzing
::
Api
::
CiConfiguration
::
Create
...
...
ee/app/graphql/mutations/incident_management/oncall_rotation/base.rb
View file @
7b87582b
...
@@ -4,6 +4,9 @@ module Mutations
...
@@ -4,6 +4,9 @@ module Mutations
module
IncidentManagement
module
IncidentManagement
module
OncallRotation
module
OncallRotation
class
Base
<
BaseMutation
class
Base
<
BaseMutation
MAXIMUM_PARTICIPANTS
=
100
TIME_FORMAT
=
/^(0\d|1\d|2[0-3]):[0-5]\d$/
.
freeze
field
:oncall_rotation
,
field
:oncall_rotation
,
::
Types
::
IncidentManagement
::
OncallRotationType
,
::
Types
::
IncidentManagement
::
OncallRotationType
,
null:
true
,
null:
true
,
...
@@ -33,6 +36,93 @@ module Mutations
...
@@ -33,6 +36,93 @@ module Mutations
::
IncidentManagement
::
OncallRotationsFinder
.
new
(
current_user
,
project
,
schedule
,
args
).
execute
.
first
::
IncidentManagement
::
OncallRotationsFinder
.
new
(
current_user
,
project
,
schedule
,
args
).
execute
.
first
end
end
def
service_params
(
schedule
,
participants
,
args
)
rotation_length
=
args
[
:rotation_length
][
:length
]
rotation_length_unit
=
args
[
:rotation_length
][
:unit
]
starts_at
=
parse_datetime
(
schedule
,
args
[
:starts_at
])
ends_at
=
parse_datetime
(
schedule
,
args
[
:ends_at
])
if
args
[
:ends_at
]
active_period_start
,
active_period_end
=
active_period_times
(
args
)
args
.
slice
(
:name
).
merge
(
length:
rotation_length
,
length_unit:
rotation_length_unit
,
starts_at:
starts_at
,
ends_at:
ends_at
,
participants:
find_participants
(
participants
),
active_period_start:
active_period_start
,
active_period_end:
active_period_end
)
end
def
parse_datetime
(
schedule
,
timestamp
)
timestamp
.
asctime
.
in_time_zone
(
schedule
.
timezone
)
end
def
find_participants
(
user_array
)
raise_too_many_users_error
if
user_array
.
size
>
MAXIMUM_PARTICIPANTS
usernames
=
user_array
.
map
{
|
h
|
h
[
:username
]
}
raise_duplicate_users_error
if
usernames
.
size
!=
usernames
.
uniq
.
size
matched_users
=
UsersFinder
.
new
(
current_user
,
username:
usernames
).
execute
.
order_by
(
:username
)
raise_user_not_found
if
matched_users
.
size
!=
user_array
.
size
user_array
=
user_array
.
sort_by!
{
|
h
|
h
[
:username
]
}
user_array
.
map
.
with_index
{
|
param
,
i
|
param
.
to_h
.
merge
(
user:
matched_users
[
i
])
}
end
def
active_period_times
(
args
)
active_period_args
=
args
.
dig
(
:active_period
)
return
[
nil
,
nil
]
if
active_period_args
.
blank?
start_time
=
active_period_args
[
:start_time
]
end_time
=
active_period_args
[
:end_time
]
raise
invalid_time_error
unless
TIME_FORMAT
.
match?
(
start_time
)
raise
invalid_time_error
unless
TIME_FORMAT
.
match?
(
end_time
)
# We parse the times into dates to compare.
# Time.parse parses a timestamp into a Time with todays date
# Time.parse("22:11") => 2021-02-23 22:11:00 +0000
parsed_from
=
Time
.
parse
(
start_time
)
parsed_to
=
Time
.
parse
(
end_time
)
# Overnight shift times will be supported via
# https://gitlab.com/gitlab-org/gitlab/-/issues/322079
if
parsed_to
<
parsed_from
raise
::
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"'start_time' time must be before 'end_time' time"
end
[
start_time
,
end_time
]
end
def
raise_project_not_found
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
'The project could not be found'
end
def
raise_schedule_not_found
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
'The schedule could not be found'
end
def
raise_too_many_users_error
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"A maximum of
#{
MAXIMUM_PARTICIPANTS
}
participants can be added"
end
def
raise_duplicate_users_error
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"A duplicate username is included in the participant list"
end
def
raise_user_not_found
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"A provided username couldn't be matched to a user"
end
def
invalid_time_error
::
Gitlab
::
Graphql
::
Errors
::
ArgumentError
.
new
'Time given is invalid'
end
end
end
end
end
end
end
...
...
ee/app/graphql/mutations/incident_management/oncall_rotation/create.rb
View file @
7b87582b
...
@@ -42,9 +42,6 @@ module Mutations
...
@@ -42,9 +42,6 @@ module Mutations
required:
true
,
required:
true
,
description:
'The usernames of users participating in the on-call rotation.'
description:
'The usernames of users participating in the on-call rotation.'
MAXIMUM_PARTICIPANTS
=
100
TIME_FORMAT
=
/^(0\d|1\d|2[0-3]):[0-5]\d$/
.
freeze
def
resolve
(
iid
:,
project_path
:,
participants
:,
**
args
)
def
resolve
(
iid
:,
project_path
:,
participants
:,
**
args
)
project
=
Project
.
find_by_full_path
(
project_path
)
project
=
Project
.
find_by_full_path
(
project_path
)
...
@@ -60,7 +57,7 @@ module Mutations
...
@@ -60,7 +57,7 @@ module Mutations
schedule
,
schedule
,
project
,
project
,
current_user
,
current_user
,
create_
service_params
(
schedule
,
participants
,
args
)
service_params
(
schedule
,
participants
,
args
)
).
execute
).
execute
response
(
result
)
response
(
result
)
...
@@ -68,95 +65,6 @@ module Mutations
...
@@ -68,95 +65,6 @@ module Mutations
rescue
ActiveRecord
::
RecordInvalid
=>
e
rescue
ActiveRecord
::
RecordInvalid
=>
e
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
e
.
message
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
e
.
message
end
end
private
def
create_service_params
(
schedule
,
participants
,
args
)
rotation_length
=
args
[
:rotation_length
][
:length
]
rotation_length_unit
=
args
[
:rotation_length
][
:unit
]
starts_at
=
parse_datetime
(
schedule
,
args
[
:starts_at
])
ends_at
=
parse_datetime
(
schedule
,
args
[
:ends_at
])
if
args
[
:ends_at
]
active_period_start
,
active_period_end
=
active_period_times
(
args
)
args
.
slice
(
:name
).
merge
(
length:
rotation_length
,
length_unit:
rotation_length_unit
,
starts_at:
starts_at
,
ends_at:
ends_at
,
participants:
find_participants
(
participants
),
active_period_start:
active_period_start
,
active_period_end:
active_period_end
)
end
def
parse_datetime
(
schedule
,
timestamp
)
timestamp
.
asctime
.
in_time_zone
(
schedule
.
timezone
)
end
def
find_participants
(
user_array
)
raise_too_many_users_error
if
user_array
.
size
>
MAXIMUM_PARTICIPANTS
usernames
=
user_array
.
map
{
|
h
|
h
[
:username
]
}
raise_duplicate_users_error
if
usernames
.
size
!=
usernames
.
uniq
.
size
matched_users
=
UsersFinder
.
new
(
current_user
,
username:
usernames
).
execute
.
order_by
(
:username
)
raise_user_not_found
if
matched_users
.
size
!=
user_array
.
size
user_array
=
user_array
.
sort_by!
{
|
h
|
h
[
:username
]
}
user_array
.
map
.
with_index
{
|
param
,
i
|
param
.
to_h
.
merge
(
user:
matched_users
[
i
])
}
end
def
active_period_times
(
args
)
active_period_args
=
args
.
dig
(
:active_period
)
return
[
nil
,
nil
]
if
active_period_args
.
blank?
start_time
=
active_period_args
[
:start_time
]
end_time
=
active_period_args
[
:end_time
]
raise
invalid_time_error
unless
TIME_FORMAT
.
match?
(
start_time
)
raise
invalid_time_error
unless
TIME_FORMAT
.
match?
(
end_time
)
# We parse the times into dates to compare.
# Time.parse parses a timestamp into a Time with todays date
# Time.parse("22:11") => 2021-02-23 22:11:00 +0000
parsed_from
=
Time
.
parse
(
start_time
)
parsed_to
=
Time
.
parse
(
end_time
)
# Overnight shift times will be supported via
# https://gitlab.com/gitlab-org/gitlab/-/issues/322079
if
parsed_to
<
parsed_from
raise
::
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"'start_time' time must be before 'end_time' time"
end
[
start_time
,
end_time
]
end
def
raise_project_not_found
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
'The project could not be found'
end
def
raise_schedule_not_found
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
'The schedule could not be found'
end
def
raise_too_many_users_error
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"A maximum of
#{
MAXIMUM_PARTICIPANTS
}
participants can be added"
end
def
raise_duplicate_users_error
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"A duplicate username is included in the participant list"
end
def
raise_user_not_found
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
"A provided username couldn't be matched to a user"
end
def
invalid_time_error
::
Gitlab
::
Graphql
::
Errors
::
ArgumentError
.
new
'Time given is invalid'
end
end
end
end
end
end
end
...
...
ee/app/graphql/mutations/incident_management/oncall_rotation/update.rb
0 → 100644
View file @
7b87582b
# frozen_string_literal: true
module
Mutations
module
IncidentManagement
module
OncallRotation
class
Update
<
Base
include
ResolvesProject
graphql_name
'OncallRotationUpdate'
argument
:id
,
::
Types
::
GlobalIDType
[
::
IncidentManagement
::
OncallRotation
],
required:
true
,
description:
'The ID of the on-call schedule to create the on-call rotation in.'
argument
:name
,
GraphQL
::
STRING_TYPE
,
required:
true
,
description:
'The name of the on-call rotation.'
argument
:starts_at
,
Types
::
IncidentManagement
::
OncallRotationDateInputType
,
required:
true
,
description:
'The start date and time of the on-call rotation, in the timezone of the on-call schedule.'
argument
:ends_at
,
Types
::
IncidentManagement
::
OncallRotationDateInputType
,
required:
false
,
description:
'The end date and time of the on-call rotation, in the timezone of the on-call schedule.'
argument
:rotation_length
,
Types
::
IncidentManagement
::
OncallRotationLengthInputType
,
required:
true
,
description:
'The rotation length of the on-call rotation.'
argument
:active_period
,
Types
::
IncidentManagement
::
OncallRotationActivePeriodInputType
,
required:
false
,
description:
'The active period of time that the on-call rotation should take place.'
argument
:participants
,
[
Types
::
IncidentManagement
::
OncallUserInputType
],
required:
true
,
description:
'The usernames of users participating in the on-call rotation.'
def
resolve
(
id
:,
participants
:,
**
args
)
rotation
=
authorized_find!
(
id:
id
)
result
=
::
IncidentManagement
::
OncallRotations
::
EditService
.
new
(
rotation
,
current_user
,
service_params
(
rotation
.
schedule
,
participants
,
args
)
).
execute
response
(
result
)
end
private
def
find_object
(
id
:)
GitlabSchema
.
object_from_id
(
id
,
expected_type:
::
IncidentManagement
::
OncallRotation
)
end
def
raise_rotation_not_found
raise
Gitlab
::
Graphql
::
Errors
::
ArgumentError
,
'The rotation could not be found'
end
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment