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
cfcd84cb
Commit
cfcd84cb
authored
Dec 03, 2020
by
Max Woolf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ability to update compliance frameworks via GraphQL
Adds a new UpdateService and updateComplianceFramework mutation
parent
5559a68e
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
559 additions
and
0 deletions
+559
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+51
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+159
-0
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/compliance_management/frameworks/update.rb
...phql/mutations/compliance_management/frameworks/update.rb
+52
-0
ee/app/services/compliance_management/frameworks/update_service.rb
...rvices/compliance_management/frameworks/update_service.rb
+35
-0
ee/changelogs/unreleased/255340-update-compliance-framework.yml
...ngelogs/unreleased/255340-update-compliance-framework.yml
+5
-0
ee/spec/graphql/mutations/compliance_management/frameworks/update_spec.rb
...mutations/compliance_management/frameworks/update_spec.rb
+69
-0
ee/spec/requests/api/graphql/mutations/compliance_management/frameworks/update_spec.rb
...mutations/compliance_management/frameworks/update_spec.rb
+94
-0
ee/spec/services/compliance_management/frameworks/update_service_spec.rb
...s/compliance_management/frameworks/update_service_spec.rb
+80
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
No files found.
doc/api/graphql/reference/gitlab_schema.graphql
View file @
cfcd84cb
...
@@ -14593,6 +14593,7 @@ type Mutation {
...
@@ -14593,6 +14593,7 @@ type Mutation {
updateBoard
(
input
:
UpdateBoardInput
!):
UpdateBoardPayload
updateBoard
(
input
:
UpdateBoardInput
!):
UpdateBoardPayload
updateBoardEpicUserPreferences
(
input
:
UpdateBoardEpicUserPreferencesInput
!):
UpdateBoardEpicUserPreferencesPayload
updateBoardEpicUserPreferences
(
input
:
UpdateBoardEpicUserPreferencesInput
!):
UpdateBoardEpicUserPreferencesPayload
updateBoardList
(
input
:
UpdateBoardListInput
!):
UpdateBoardListPayload
updateBoardList
(
input
:
UpdateBoardListInput
!):
UpdateBoardListPayload
updateComplianceFramework
(
input
:
UpdateComplianceFrameworkInput
!):
UpdateComplianceFrameworkPayload
updateContainerExpirationPolicy
(
input
:
UpdateContainerExpirationPolicyInput
!):
UpdateContainerExpirationPolicyPayload
updateContainerExpirationPolicy
(
input
:
UpdateContainerExpirationPolicyInput
!):
UpdateContainerExpirationPolicyPayload
updateDevopsAdoptionSegment
(
input
:
UpdateDevopsAdoptionSegmentInput
!):
UpdateDevopsAdoptionSegmentPayload
updateDevopsAdoptionSegment
(
input
:
UpdateDevopsAdoptionSegmentInput
!):
UpdateDevopsAdoptionSegmentPayload
updateEpic
(
input
:
UpdateEpicInput
!):
UpdateEpicPayload
updateEpic
(
input
:
UpdateEpicInput
!):
UpdateEpicPayload
...
@@ -23359,6 +23360,56 @@ type UpdateBoardPayload {
...
@@ -23359,6 +23360,56 @@ type UpdateBoardPayload {
errors
:
[
String
!]!
errors
:
[
String
!]!
}
}
"""
Autogenerated input type of UpdateComplianceFramework
"""
input
UpdateComplianceFrameworkInput
{
"""
A
unique
identifier
for
the
client
performing
the
mutation
.
"""
clientMutationId
:
String
"""
New
color
representation
of
the
compliance
framework
in
hex
format
.
e
.
g
.
#FCA121
"""
color
:
String
"""
New
description
for
the
compliance
framework
"""
description
:
String
"""
The
global
ID
of
the
compliance
framework
to
update
"""
id
:
ComplianceManagementFrameworkID
!
"""
New
name
for
the
compliance
framework
"""
name
:
String
}
"""
Autogenerated return type of UpdateComplianceFramework
"""
type
UpdateComplianceFrameworkPayload
{
"""
A
unique
identifier
for
the
client
performing
the
mutation
.
"""
clientMutationId
:
String
"""
The
compliance
framework
after
mutation
"""
complianceFramework
:
ComplianceFramework
"""
Errors
encountered
during
execution
of
the
mutation
.
"""
errors
:
[
String
!]!
}
"""
"""
Autogenerated input type of UpdateContainerExpirationPolicy
Autogenerated input type of UpdateContainerExpirationPolicy
"""
"""
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
cfcd84cb
...
@@ -43261,6 +43261,33 @@
...
@@ -43261,6 +43261,33 @@
"isDeprecated": false,
"isDeprecated": false,
"deprecationReason": null
"deprecationReason": null
},
},
{
"name": "updateComplianceFramework",
"description": null,
"args": [
{
"name": "input",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "UpdateComplianceFrameworkInput",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "UpdateComplianceFrameworkPayload",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
{
"name": "updateContainerExpirationPolicy",
"name": "updateContainerExpirationPolicy",
"description": null,
"description": null,
...
@@ -68342,6 +68369,138 @@
...
@@ -68342,6 +68369,138 @@
"enumValues": null,
"enumValues": null,
"possibleTypes": null
"possibleTypes": null
},
},
{
"kind": "INPUT_OBJECT",
"name": "UpdateComplianceFrameworkInput",
"description": "Autogenerated input type of UpdateComplianceFramework",
"fields": null,
"inputFields": [
{
"name": "id",
"description": "The global ID of the compliance framework to update",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ComplianceManagementFrameworkID",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "name",
"description": "New name for the compliance framework",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "description",
"description": "New description for the compliance framework",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "color",
"description": "New color representation of the compliance framework in hex format. e.g. #FCA121",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "UpdateComplianceFrameworkPayload",
"description": "Autogenerated return type of UpdateComplianceFramework",
"fields": [
{
"name": "clientMutationId",
"description": "A unique identifier for the client performing the mutation.",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "complianceFramework",
"description": "The compliance framework after mutation",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "ComplianceFramework",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "errors",
"description": "Errors encountered during execution of the mutation.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
{
"kind": "INPUT_OBJECT",
"kind": "INPUT_OBJECT",
"name": "UpdateContainerExpirationPolicyInput",
"name": "UpdateContainerExpirationPolicyInput",
doc/api/graphql/reference/index.md
View file @
cfcd84cb
...
@@ -3554,6 +3554,16 @@ Autogenerated return type of UpdateBoard.
...
@@ -3554,6 +3554,16 @@ Autogenerated return type of UpdateBoard.
|
`clientMutationId`
| String | A unique identifier for the client performing the mutation. |
|
`clientMutationId`
| String | A unique identifier for the client performing the mutation. |
|
`errors`
| String! => Array | Errors encountered during execution of the mutation. |
|
`errors`
| String! => Array | Errors encountered during execution of the mutation. |
### UpdateComplianceFrameworkPayload
Autogenerated return type of UpdateComplianceFramework.
| Field | Type | Description |
| ----- | ---- | ----------- |
|
`clientMutationId`
| String | A unique identifier for the client performing the mutation. |
|
`complianceFramework`
| ComplianceFramework | The compliance framework after mutation |
|
`errors`
| String! => Array | Errors encountered during execution of the mutation. |
### UpdateContainerExpirationPolicyPayload
### UpdateContainerExpirationPolicyPayload
Autogenerated return type of UpdateContainerExpirationPolicy.
Autogenerated return type of UpdateContainerExpirationPolicy.
...
...
ee/app/graphql/ee/types/mutation_type.rb
View file @
cfcd84cb
...
@@ -11,6 +11,7 @@ module EE
...
@@ -11,6 +11,7 @@ module EE
mount_mutation
::
Mutations
::
Clusters
::
AgentTokens
::
Create
mount_mutation
::
Mutations
::
Clusters
::
AgentTokens
::
Create
mount_mutation
::
Mutations
::
Clusters
::
AgentTokens
::
Delete
mount_mutation
::
Mutations
::
Clusters
::
AgentTokens
::
Delete
mount_mutation
::
Mutations
::
ComplianceManagement
::
Frameworks
::
Destroy
mount_mutation
::
Mutations
::
ComplianceManagement
::
Frameworks
::
Destroy
mount_mutation
::
Mutations
::
ComplianceManagement
::
Frameworks
::
Update
mount_mutation
::
Mutations
::
Issues
::
SetIteration
mount_mutation
::
Mutations
::
Issues
::
SetIteration
mount_mutation
::
Mutations
::
Issues
::
SetWeight
mount_mutation
::
Mutations
::
Issues
::
SetWeight
mount_mutation
::
Mutations
::
Issues
::
SetEpic
mount_mutation
::
Mutations
::
Issues
::
SetEpic
...
...
ee/app/graphql/mutations/compliance_management/frameworks/update.rb
0 → 100644
View file @
cfcd84cb
# frozen_string_literal: true
module
Mutations
module
ComplianceManagement
module
Frameworks
class
Update
<
::
Mutations
::
BaseMutation
graphql_name
'UpdateComplianceFramework'
authorize
:manage_compliance_framework
argument
:id
,
::
Types
::
GlobalIDType
[
::
ComplianceManagement
::
Framework
],
required:
true
,
description:
'The global ID of the compliance framework to update'
argument
:name
,
GraphQL
::
STRING_TYPE
,
required:
false
,
description:
'New name for the compliance framework'
argument
:description
,
GraphQL
::
STRING_TYPE
,
required:
false
,
description:
'New description for the compliance framework'
argument
:color
,
GraphQL
::
STRING_TYPE
,
required:
false
,
description:
'New color representation of the compliance framework in hex format. e.g. #FCA121'
field
:compliance_framework
,
Types
::
ComplianceManagement
::
ComplianceFrameworkType
,
null:
true
,
description:
"The compliance framework after mutation"
def
resolve
(
id
:,
**
args
)
framework
=
authorized_find!
(
id:
id
)
::
ComplianceManagement
::
Frameworks
::
UpdateService
.
new
(
framework:
framework
,
current_user:
current_user
,
params:
args
).
execute
{
compliance_framework:
framework
,
errors:
errors_on_object
(
framework
)
}
end
private
def
find_object
(
id
:)
GitlabSchema
.
object_from_id
(
id
,
expected_type:
::
ComplianceManagement
::
Framework
)
end
end
end
end
end
ee/app/services/compliance_management/frameworks/update_service.rb
0 → 100644
View file @
cfcd84cb
# frozen_string_literal: true
module
ComplianceManagement
module
Frameworks
class
UpdateService
<
BaseService
attr_reader
:framework
,
:current_user
,
:params
def
initialize
(
framework
:,
current_user
:,
params
:)
@framework
=
framework
@current_user
=
current_user
@params
=
params
end
def
execute
return
error
unless
permitted?
framework
.
update
(
params
)
?
success
:
error
end
def
success
ServiceResponse
.
success
(
payload:
{
framework:
framework
})
end
def
error
ServiceResponse
.
error
(
message:
_
(
'Failed to update framework'
),
payload:
framework
.
errors
)
end
private
def
permitted?
can?
current_user
,
:manage_compliance_framework
,
framework
end
end
end
end
ee/changelogs/unreleased/255340-update-compliance-framework.yml
0 → 100644
View file @
cfcd84cb
---
title
:
Add ability to update compliance frameworks via GraphQL
merge_request
:
49157
author
:
type
:
added
ee/spec/graphql/mutations/compliance_management/frameworks/update_spec.rb
0 → 100644
View file @
cfcd84cb
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Mutations
::
ComplianceManagement
::
Frameworks
::
Update
do
include
GraphqlHelpers
let_it_be
(
:framework
)
{
create
(
:compliance_framework
)
}
let
(
:user
)
{
framework
.
namespace
.
owner
}
let
(
:mutation
)
{
described_class
.
new
(
object:
nil
,
context:
{
current_user:
user
},
field:
nil
)
}
let
(
:params
)
do
{
name:
'New Name'
,
description:
'New Description'
,
color:
'#AAAAA1'
}
end
subject
{
mutation
.
resolve
(
id:
global_id_of
(
framework
),
**
params
)
}
context
'feature is enabled and licensed'
do
before
do
stub_licensed_features
(
custom_compliance_frameworks:
true
)
stub_feature_flags
(
ff_custom_compliance_frameworks:
true
)
end
context
'parameters are valid'
do
it
'returns the new object'
do
response
=
subject
[
:compliance_framework
]
expect
(
response
.
name
).
to
eq
(
'New Name'
)
expect
(
response
.
description
).
to
eq
(
'New Description'
)
expect
(
response
.
color
).
to
eq
(
'#AAAAA1'
)
end
it
'returns no errors'
do
expect
(
subject
[
:errors
]).
to
be_empty
end
context
'current_user is not authorized to update framework'
do
let_it_be
(
:user
)
{
create
(
:user
)
}
it
'raises an error'
do
expect
{
subject
}.
to
raise_error
(
Gitlab
::
Graphql
::
Errors
::
ResourceNotAvailable
)
end
end
end
context
'parameters are invalid'
do
let
(
:params
)
do
{
name:
''
,
description:
''
,
color:
'AAAAA1'
}
end
it
'does not change the framework attributes'
do
expect
{
subject
}.
not_to
change
{
framework
.
name
}
expect
{
subject
}.
not_to
change
{
framework
.
description
}
expect
{
subject
}.
not_to
change
{
framework
.
color
}
end
it
'returns validation errors'
do
expect
(
subject
[
:errors
]).
to
contain_exactly
(
"Name can't be blank"
,
"Description can't be blank"
,
"Color must be a valid color code"
)
end
end
end
end
ee/spec/requests/api/graphql/mutations/compliance_management/frameworks/update_spec.rb
0 → 100644
View file @
cfcd84cb
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'Update a compliance framework'
do
include
GraphqlHelpers
let_it_be
(
:framework
)
{
create
(
:compliance_framework
)
}
let
(
:mutation
)
{
graphql_mutation
(
:update_compliance_framework
,
{
id:
global_id_of
(
framework
),
**
params
})
}
let
(
:current_user
)
{
framework
.
namespace
.
owner
}
let
(
:params
)
do
{
name:
'New Name'
,
description:
'New Description'
,
color:
'#AAC112'
}
end
subject
{
post_graphql_mutation
(
mutation
,
current_user:
current_user
)
}
def
mutation_response
graphql_mutation_response
(
:update_compliance_framework
)
end
context
'feature is unlicensed'
do
before
do
stub_licensed_features
(
custom_compliance_frameworks:
false
)
end
it_behaves_like
'a mutation that returns top-level errors'
,
errors:
[
"The resource that you are attempting to access does not exist or you don't have permission to perform this action"
]
end
context
'feature is licensed but disabled'
do
before
do
stub_licensed_features
(
custom_compliance_frameworks:
false
)
end
it_behaves_like
'a mutation that returns top-level errors'
,
errors:
[
"The resource that you are attempting to access does not exist or you don't have permission to perform this action"
]
end
context
'feature is licensed and enabled'
do
before
do
stub_licensed_features
(
custom_compliance_frameworks:
true
)
stub_feature_flags
(
ff_custom_compliance_frameworks:
true
)
end
context
'with valid params'
do
it
'returns an empty array of errors'
do
subject
expect
(
mutation_response
[
'errors'
]).
to
be_empty
end
it
'returns the updated framework'
do
subject
expect
(
mutation_response
[
'complianceFramework'
][
'name'
]).
to
eq
'New Name'
expect
(
mutation_response
[
'complianceFramework'
][
'description'
]).
to
eq
'New Description'
expect
(
mutation_response
[
'complianceFramework'
][
'color'
]).
to
eq
'#AAC112'
end
context
'current_user is not permitted to update framework'
do
let_it_be
(
:current_user
)
{
create
(
:user
)
}
it_behaves_like
'a mutation that returns top-level errors'
,
errors:
[
"The resource that you are attempting to access does not exist or you don't have permission to perform this action"
]
end
end
context
'with invalid params'
do
let
(
:params
)
do
{
name:
''
,
description:
''
,
color:
'NOTACOLOR'
}
end
it
'returns an array of errors'
do
subject
expect
(
mutation_response
[
'errors'
]).
to
contain_exactly
"Color must be a valid color code"
,
"Description can't be blank"
,
"Name can't be blank"
end
it
'does not update the framework'
do
expect
{
subject
}.
not_to
change
{
framework
.
name
}
expect
{
subject
}.
not_to
change
{
framework
.
description
}
expect
{
subject
}.
not_to
change
{
framework
.
color
}
end
end
end
end
ee/spec/services/compliance_management/frameworks/update_service_spec.rb
0 → 100644
View file @
cfcd84cb
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
ComplianceManagement
::
Frameworks
::
UpdateService
do
let_it_be
(
:namespace
)
{
create
(
:namespace
)
}
let_it_be
(
:framework
)
{
create
(
:compliance_framework
,
namespace:
namespace
)
}
let
(
:current_user
)
{
namespace
.
owner
}
let
(
:params
)
{
{
color:
'#000001'
,
description:
'New Description'
,
name:
'New Name'
}
}
subject
{
described_class
.
new
(
framework:
framework
,
current_user:
current_user
,
params:
params
)
}
shared_examples
'a failed update request'
do
it
'does not update the compliance framework'
do
expect
{
subject
.
execute
}.
not_to
change
{
framework
.
name
}
expect
{
subject
.
execute
}.
not_to
change
{
framework
.
description
}
expect
{
subject
.
execute
}.
not_to
change
{
framework
.
color
}
end
it
'is unsuccessful'
do
expect
(
subject
.
execute
.
success?
).
to
be
false
end
end
context
'feature is disabled'
do
before
do
stub_feature_flags
(
ff_custom_compliance_frameworks:
false
)
end
it_behaves_like
'a failed update request'
end
context
'feature is licensed but disabled'
do
before
do
stub_feature_flags
(
ff_custom_compliance_frameworks:
false
)
stub_licensed_features
(
custom_compliance_frameworks:
true
)
end
it_behaves_like
'a failed update request'
end
context
'current_user is not the namespace owner'
do
let
(
:current_user
)
{
create
(
:user
)
}
it_behaves_like
'a failed update request'
end
context
'when feature is enabled and licensed'
do
before
do
stub_licensed_features
(
custom_compliance_frameworks:
true
)
stub_feature_flags
(
ff_custom_compliance_frameworks:
true
)
end
context
'with an invalid param passed'
do
let
(
:params
)
{
{
color:
'0001'
,
description:
''
,
name:
'New Name'
}
}
it
'is unsuccessful'
do
expect
(
subject
.
execute
.
success?
).
to
be
false
end
it
'has appropriate errors'
do
expect
(
subject
.
execute
.
payload
.
full_messages
).
to
contain_exactly
'Color must be a valid color code'
,
"Description can't be blank"
end
end
context
'with valid params passed'
do
it
'updates the compliance framework with valid params'
do
subject
.
execute
expect
(
framework
.
name
).
to
eq
(
'New Name'
)
expect
(
framework
.
color
).
to
eq
(
'#000001'
)
expect
(
framework
.
description
).
to
eq
(
'New Description'
)
end
it
'is successful'
do
expect
(
subject
.
execute
.
success?
).
to
be
true
end
end
end
end
locale/gitlab.pot
View file @
cfcd84cb
...
@@ -11679,6 +11679,9 @@ msgstr ""
...
@@ -11679,6 +11679,9 @@ msgstr ""
msgid "Failed to update environment!"
msgid "Failed to update environment!"
msgstr ""
msgstr ""
msgid "Failed to update framework"
msgstr ""
msgid "Failed to update issue status"
msgid "Failed to update issue status"
msgstr ""
msgstr ""
...
...
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