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
58572385
Commit
58572385
authored
Jan 20, 2021
by
Emily Ring
Committed by
Michael Kozono
Jan 20, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add GraphQL query for single Terraform State
Add terraformState query to GraphQL Updated associated docs
parent
c639d5ca
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
254 additions
and
14 deletions
+254
-14
app/finders/terraform/states_finder.rb
app/finders/terraform/states_finder.rb
+28
-0
app/graphql/resolvers/terraform/states_resolver.rb
app/graphql/resolvers/terraform/states_resolver.rb
+9
-9
app/graphql/types/project_type.rb
app/graphql/types/project_type.rb
+7
-1
app/models/terraform/state.rb
app/models/terraform/state.rb
+1
-0
changelogs/unreleased/291140-query-single-state.yml
changelogs/unreleased/291140-query-single-state.yml
+5
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+11
-1
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+28
-1
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+2
-1
spec/finders/terraform/states_finder_spec.rb
spec/finders/terraform/states_finder_spec.rb
+45
-0
spec/graphql/resolvers/terraform/states_resolver_spec.rb
spec/graphql/resolvers/terraform/states_resolver_spec.rb
+19
-1
spec/graphql/types/project_type_spec.rb
spec/graphql/types/project_type_spec.rb
+7
-0
spec/models/terraform/state_spec.rb
spec/models/terraform/state_spec.rb
+9
-0
spec/requests/api/graphql/project/terraform/state_spec.rb
spec/requests/api/graphql/project/terraform/state_spec.rb
+83
-0
No files found.
app/finders/terraform/states_finder.rb
0 → 100644
View file @
58572385
# frozen_string_literal: true
module
Terraform
class
StatesFinder
def
initialize
(
project
,
current_user
,
params:
{})
@project
=
project
@current_user
=
current_user
@params
=
params
end
def
execute
return
::
Terraform
::
State
.
none
unless
can_read_terraform_states?
states
=
project
.
terraform_states
states
=
states
.
with_name
(
params
[
:name
])
if
params
[
:name
].
present?
states
.
ordered_by_name
end
private
attr_reader
:project
,
:current_user
,
:params
def
can_read_terraform_states?
current_user
.
can?
(
:read_terraform_state
,
project
)
end
end
end
app/graphql/resolvers/terraform/states_resolver.rb
View file @
58572385
...
...
@@ -3,20 +3,20 @@
module
Resolvers
module
Terraform
class
StatesResolver
<
BaseResolver
type
Types
::
Terraform
::
StateType
,
null:
true
type
Types
::
Terraform
::
StateType
.
connection_type
,
null:
true
alias_method
:project
,
:object
def
resolve
(
**
args
)
return
::
Terraform
::
State
.
none
unless
can_read_terraform_states?
project
.
terraform_states
.
ordered_by_name
when_single
do
argument
:name
,
GraphQL
::
STRING_TYPE
,
required:
true
,
description:
'Name of the Terraform state.'
end
private
def
can_read_terraform_states?
current_user
.
can?
(
:read_terraform_state
,
project
)
def
resolve
(
**
args
)
::
Terraform
::
StatesFinder
.
new
(
project
,
current_user
,
params:
args
)
.
execute
end
end
end
...
...
app/graphql/types/project_type.rb
View file @
58572385
...
...
@@ -305,10 +305,16 @@ module Types
description:
'Title of the label'
end
field
:terraform_state
,
Types
::
Terraform
::
StateType
,
null:
true
,
description:
'Find a single Terraform state by name.'
,
resolver:
Resolvers
::
Terraform
::
StatesResolver
.
single
field
:terraform_states
,
Types
::
Terraform
::
StateType
.
connection_type
,
null:
true
,
description:
'Terraform states associated with the project'
,
description:
'Terraform states associated with the project
.
'
,
resolver:
Resolvers
::
Terraform
::
StatesResolver
field
:pipeline_analytics
,
Types
::
Ci
::
AnalyticsType
,
null:
true
,
...
...
app/models/terraform/state.rb
View file @
58572385
...
...
@@ -22,6 +22,7 @@ module Terraform
scope
:versioning_not_enabled
,
->
{
where
(
versioning_enabled:
false
)
}
scope
:ordered_by_name
,
->
{
order
(
:name
)
}
scope
:with_name
,
->
(
name
)
{
where
(
name:
name
)
}
validates
:project_id
,
presence:
true
validates
:uuid
,
presence:
true
,
uniqueness:
true
,
length:
{
is:
UUID_LENGTH
},
...
...
changelogs/unreleased/291140-query-single-state.yml
0 → 100644
View file @
58572385
---
title
:
Add GraphQL query for single Terraform state
merge_request
:
51145
author
:
type
:
added
doc/api/graphql/reference/gitlab_schema.graphql
View file @
58572385
...
...
@@ -19280,7 +19280,17 @@ type Project {
tagList
:
String
"""
Terraform
states
associated
with
the
project
Find
a
single
Terraform
state
by
name
.
"""
terraformState
(
"""
Name
of
the
Terraform
state
.
"""
name
:
String
!
):
TerraformState
"""
Terraform
states
associated
with
the
project
.
"""
terraformStates
(
"""
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
58572385
...
...
@@ -55993,9 +55993,36 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "terraformState",
"description": "Find a single Terraform state by name.",
"args": [
{
"name": "name",
"description": "Name of the Terraform state.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "TerraformState",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "terraformStates",
"description": "Terraform states associated with the project",
"description": "Terraform states associated with the project
.
",
"args": [
{
"name": "after",
doc/api/graphql/reference/index.md
View file @
58572385
...
...
@@ -2778,7 +2778,8 @@ Autogenerated return type of PipelineRetry.
|
`statistics`
| ProjectStatistics | Statistics of the project |
|
`suggestionCommitMessage`
| String | The commit message used to apply merge request suggestions |
|
`tagList`
| String | List of project topics (not Git tags) |
|
`terraformStates`
| TerraformStateConnection | Terraform states associated with the project |
|
`terraformState`
| TerraformState | Find a single Terraform state by name. |
|
`terraformStates`
| TerraformStateConnection | Terraform states associated with the project. |
|
`userPermissions`
| ProjectPermissions! | Permissions for the current user on the resource |
|
`visibility`
| String | Visibility of the project |
|
`vulnerabilities`
| VulnerabilityConnection | Vulnerabilities reported on the project |
...
...
spec/finders/terraform/states_finder_spec.rb
0 → 100644
View file @
58572385
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Terraform
::
StatesFinder
do
describe
'#execute'
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:state_1
)
{
create
(
:terraform_state
,
project:
project
)
}
let_it_be
(
:state_2
)
{
create
(
:terraform_state
,
project:
project
)
}
let
(
:user
)
{
project
.
creator
}
subject
{
described_class
.
new
(
project
,
user
).
execute
}
it
{
is_expected
.
to
contain_exactly
(
state_1
,
state_2
)
}
context
'user does not have permission'
do
let
(
:user
)
{
create
(
:user
)
}
before
do
project
.
add_guest
(
user
)
end
it
{
is_expected
.
to
be_empty
}
end
context
'filtering by name'
do
let
(
:params
)
{
{
name:
name_param
}
}
subject
{
described_class
.
new
(
project
,
user
,
params:
params
).
execute
}
context
'name does not match'
do
let
(
:name_param
)
{
'other-name'
}
it
{
is_expected
.
to
be_empty
}
end
context
'name does match'
do
let
(
:name_param
)
{
state_1
.
name
}
it
{
is_expected
.
to
contain_exactly
(
state_1
)
}
end
end
end
end
spec/graphql/resolvers/terraform/states_resolver_spec.rb
View file @
58572385
...
...
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec
.
describe
Resolvers
::
Terraform
::
StatesResolver
do
include
GraphqlHelpers
it
{
expect
(
described_class
.
type
).
to
eq
(
Types
::
Terraform
::
StateT
ype
)
}
it
{
expect
(
described_class
).
to
have_nullable_graphql_type
(
Types
::
Terraform
::
StateType
.
connection_t
ype
)
}
it
{
expect
(
described_class
.
null
).
to
be_truthy
}
describe
'#resolve'
do
...
...
@@ -31,3 +31,21 @@ RSpec.describe Resolvers::Terraform::StatesResolver do
end
end
end
RSpec
.
describe
Resolvers
::
Terraform
::
StatesResolver
.
single
do
it
{
expect
(
described_class
).
to
be
<
Resolvers
::
Terraform
::
StatesResolver
}
describe
'arguments'
do
subject
{
described_class
.
arguments
[
argument
]
}
describe
'name'
do
let
(
:argument
)
{
'name'
}
it
do
expect
(
subject
).
to
be_present
expect
(
subject
.
type
.
to_s
).
to
eq
(
'String!'
)
expect
(
subject
.
description
).
to
be_present
end
end
end
end
spec/graphql/types/project_type_spec.rb
View file @
58572385
...
...
@@ -159,6 +159,13 @@ RSpec.describe GitlabSchema.types['Project'] do
it
{
is_expected
.
to
have_graphql_type
(
Types
::
ContainerExpirationPolicyType
)
}
end
describe
'terraform state field'
do
subject
{
described_class
.
fields
[
'terraformState'
]
}
it
{
is_expected
.
to
have_graphql_type
(
Types
::
Terraform
::
StateType
)
}
it
{
is_expected
.
to
have_graphql_resolver
(
Resolvers
::
Terraform
::
StatesResolver
.
single
)
}
end
describe
'terraform states field'
do
subject
{
described_class
.
fields
[
'terraformStates'
]
}
...
...
spec/models/terraform/state_spec.rb
View file @
58572385
...
...
@@ -25,6 +25,15 @@ RSpec.describe Terraform::State do
it
{
expect
(
subject
.
map
(
&
:name
)).
to
eq
(
names
.
sort
)
}
end
describe
'.with_name'
do
let_it_be
(
:matching_name
)
{
create
(
:terraform_state
,
name:
'matching-name'
)
}
let_it_be
(
:other_name
)
{
create
(
:terraform_state
,
name:
'other-name'
)
}
subject
{
described_class
.
with_name
(
matching_name
.
name
)
}
it
{
is_expected
.
to
contain_exactly
(
matching_name
)
}
end
end
describe
'#destroy'
do
...
...
spec/requests/api/graphql/project/terraform/state_spec.rb
0 → 100644
View file @
58572385
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'query a single terraform state'
do
include
GraphqlHelpers
include
::
API
::
Helpers
::
RelatedResourcesHelpers
let_it_be
(
:terraform_state
)
{
create
(
:terraform_state
,
:with_version
,
:locked
)
}
let
(
:latest_version
)
{
terraform_state
.
latest_version
}
let
(
:project
)
{
terraform_state
.
project
}
let
(
:current_user
)
{
project
.
creator
}
let
(
:data
)
{
graphql_data
.
dig
(
'project'
,
'terraformState'
)
}
let
(
:query
)
do
graphql_query_for
(
:project
,
{
fullPath:
project
.
full_path
},
query_graphql_field
(
:terraformState
,
{
name:
terraform_state
.
name
},
%{
id
name
lockedAt
createdAt
updatedAt
latestVersion {
id
serial
createdAt
updatedAt
createdByUser {
id
}
job {
name
}
}
lockedByUser {
id
}
}
)
)
end
before
do
post_graphql
(
query
,
current_user:
current_user
)
end
it_behaves_like
'a working graphql query'
it
'returns terraform state data'
do
expect
(
data
).
to
match
(
a_hash_including
({
'id'
=>
global_id_of
(
terraform_state
),
'name'
=>
terraform_state
.
name
,
'lockedAt'
=>
terraform_state
.
locked_at
.
iso8601
,
'createdAt'
=>
terraform_state
.
created_at
.
iso8601
,
'updatedAt'
=>
terraform_state
.
updated_at
.
iso8601
,
'lockedByUser'
=>
{
'id'
=>
global_id_of
(
terraform_state
.
locked_by_user
)
},
'latestVersion'
=>
{
'id'
=>
eq
(
global_id_of
(
latest_version
)),
'serial'
=>
eq
(
latest_version
.
version
),
'createdAt'
=>
eq
(
latest_version
.
created_at
.
iso8601
),
'updatedAt'
=>
eq
(
latest_version
.
updated_at
.
iso8601
),
'createdByUser'
=>
{
'id'
=>
eq
(
global_id_of
(
latest_version
.
created_by_user
))
},
'job'
=>
{
'name'
=>
eq
(
latest_version
.
build
.
name
)
}
}
}))
end
context
'unauthorized users'
do
let
(
:current_user
)
{
nil
}
it
{
expect
(
data
).
to
be_nil
}
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