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
c797a78f
Commit
c797a78f
authored
Sep 04, 2020
by
Emily Ring
Committed by
Thong Kuah
Sep 04, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Create cluster agent graphql query
parent
5bdbf365
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
381 additions
and
1 deletion
+381
-1
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+60
-0
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+165
-0
ee/app/finders/clusters/agents_finder.rb
ee/app/finders/clusters/agents_finder.rb
+24
-0
ee/app/graphql/ee/types/project_type.rb
ee/app/graphql/ee/types/project_type.rb
+6
-0
ee/app/graphql/resolvers/clusters/agents_resolver.rb
ee/app/graphql/resolvers/clusters/agents_resolver.rb
+17
-0
ee/changelogs/unreleased/emilyring-agent-graphql-query.yml
ee/changelogs/unreleased/emilyring-agent-graphql-query.yml
+5
-0
ee/spec/finders/clusters/agents_finder_spec.rb
ee/spec/finders/clusters/agents_finder_spec.rb
+34
-0
ee/spec/graphql/resolvers/clusters/agents_resolver_spec.rb
ee/spec/graphql/resolvers/clusters/agents_resolver_spec.rb
+26
-0
ee/spec/graphql/types/project_type_spec.rb
ee/spec/graphql/types/project_type_spec.rb
+44
-1
No files found.
doc/api/graphql/reference/gitlab_schema.graphql
View file @
c797a78f
...
@@ -1715,6 +1715,26 @@ type ClusterAgent {
...
@@ -1715,6 +1715,26 @@ type ClusterAgent {
updatedAt
:
Time
updatedAt
:
Time
}
}
"""
The connection type for ClusterAgent.
"""
type
ClusterAgentConnection
{
"""
A
list
of
edges
.
"""
edges
:
[
ClusterAgentEdge
]
"""
A
list
of
nodes
.
"""
nodes
:
[
ClusterAgent
]
"""
Information
to
aid
in
pagination
.
"""
pageInfo
:
PageInfo
!
}
"""
"""
Autogenerated input type of ClusterAgentDelete
Autogenerated input type of ClusterAgentDelete
"""
"""
...
@@ -1745,6 +1765,21 @@ type ClusterAgentDeletePayload {
...
@@ -1745,6 +1765,21 @@ type ClusterAgentDeletePayload {
errors
:
[
String
!]!
errors
:
[
String
!]!
}
}
"""
An edge in a connection.
"""
type
ClusterAgentEdge
{
"""
A
cursor
for
use
in
pagination
.
"""
cursor
:
String
!
"""
The
item
at
the
end
of
the
edge
.
"""
node
:
ClusterAgent
}
type
ClusterAgentToken
{
type
ClusterAgentToken
{
"""
"""
Cluster
agent
this
token
is
associated
with
Cluster
agent
this
token
is
associated
with
...
@@ -11318,6 +11353,31 @@ type Project {
...
@@ -11318,6 +11353,31 @@ type Project {
last
:
Int
last
:
Int
):
BoardConnection
):
BoardConnection
"""
Cluster
agents
associated
with
the
project
"""
clusterAgents
(
"""
Returns
the
elements
in
the
list
that
come
after
the
specified
cursor
.
"""
after
:
String
"""
Returns
the
elements
in
the
list
that
come
before
the
specified
cursor
.
"""
before
:
String
"""
Returns
the
first
_n_
elements
from
the
list
.
"""
first
:
Int
"""
Returns
the
last
_n_
elements
from
the
list
.
"""
last
:
Int
):
ClusterAgentConnection
"""
"""
Compliance
frameworks
associated
with
the
project
Compliance
frameworks
associated
with
the
project
"""
"""
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
c797a78f
...
@@ -4681,6 +4681,73 @@
...
@@ -4681,6 +4681,73 @@
"enumValues": null,
"enumValues": null,
"possibleTypes": null
"possibleTypes": null
},
},
{
"kind": "OBJECT",
"name": "ClusterAgentConnection",
"description": "The connection type for ClusterAgent.",
"fields": [
{
"name": "edges",
"description": "A list of edges.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "ClusterAgentEdge",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "nodes",
"description": "A list of nodes.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "ClusterAgent",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "pageInfo",
"description": "Information to aid in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "PageInfo",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
{
"kind": "INPUT_OBJECT",
"kind": "INPUT_OBJECT",
"name": "ClusterAgentDeleteInput",
"name": "ClusterAgentDeleteInput",
...
@@ -4769,6 +4836,51 @@
...
@@ -4769,6 +4836,51 @@
"enumValues": null,
"enumValues": null,
"possibleTypes": null
"possibleTypes": null
},
},
{
"kind": "OBJECT",
"name": "ClusterAgentEdge",
"description": "An edge in a connection.",
"fields": [
{
"name": "cursor",
"description": "A cursor for use in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "node",
"description": "The item at the end of the edge.",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "ClusterAgent",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
{
"kind": "OBJECT",
"kind": "OBJECT",
"name": "ClusterAgentToken",
"name": "ClusterAgentToken",
...
@@ -33855,6 +33967,59 @@
...
@@ -33855,6 +33967,59 @@
"isDeprecated": false,
"isDeprecated": false,
"deprecationReason": null
"deprecationReason": null
},
},
{
"name": "clusterAgents",
"description": "Cluster agents associated with the project",
"args": [
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "before",
"description": "Returns the elements in the list that come before the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": "Returns the first _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "last",
"description": "Returns the last _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "ClusterAgentConnection",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
{
"name": "complianceFrameworks",
"name": "complianceFrameworks",
"description": "Compliance frameworks associated with the project",
"description": "Compliance frameworks associated with the project",
ee/app/finders/clusters/agents_finder.rb
0 → 100644
View file @
c797a78f
# frozen_string_literal: true
module
Clusters
class
AgentsFinder
def
initialize
(
project
,
current_user
)
@project
=
project
@current_user
=
current_user
end
def
execute
return
::
Clusters
::
Agent
.
none
unless
can_read_cluster_agents?
project
.
cluster_agents
end
private
attr_reader
:project
,
:current_user
def
can_read_cluster_agents?
project
.
feature_available?
(
:cluster_agents
)
&&
current_user
.
can?
(
:read_cluster
,
project
)
end
end
end
ee/app/graphql/ee/types/project_type.rb
View file @
c797a78f
...
@@ -93,6 +93,12 @@ module EE
...
@@ -93,6 +93,12 @@ module EE
description:
'DAST Site Profiles associated with the project'
,
description:
'DAST Site Profiles associated with the project'
,
resolve:
->
(
obj
,
_args
,
_ctx
)
{
obj
.
dast_site_profiles
.
with_dast_site
}
resolve:
->
(
obj
,
_args
,
_ctx
)
{
obj
.
dast_site_profiles
.
with_dast_site
}
field
:cluster_agents
,
::
Types
::
Clusters
::
AgentType
.
connection_type
,
null:
true
,
description:
'Cluster agents associated with the project'
,
resolver:
::
Resolvers
::
Clusters
::
AgentsResolver
def
self
.
requirements_available?
(
project
,
user
)
def
self
.
requirements_available?
(
project
,
user
)
::
Feature
.
enabled?
(
:requirements_management
,
project
,
default_enabled:
true
)
&&
Ability
.
allowed?
(
user
,
:read_requirement
,
project
)
::
Feature
.
enabled?
(
:requirements_management
,
project
,
default_enabled:
true
)
&&
Ability
.
allowed?
(
user
,
:read_requirement
,
project
)
end
end
...
...
ee/app/graphql/resolvers/clusters/agents_resolver.rb
0 → 100644
View file @
c797a78f
# frozen_string_literal: true
module
Resolvers
module
Clusters
class
AgentsResolver
<
BaseResolver
type
Types
::
Clusters
::
AgentType
,
null:
true
alias_method
:project
,
:object
def
resolve
(
**
args
)
::
Clusters
::
AgentsFinder
.
new
(
project
,
context
[
:current_user
])
.
execute
end
end
end
end
ee/changelogs/unreleased/emilyring-agent-graphql-query.yml
0 → 100644
View file @
c797a78f
---
title
:
Add GraphQL endpoint for retrieving cluster agents for a project
merge_request
:
38833
author
:
type
:
added
ee/spec/finders/clusters/agents_finder_spec.rb
0 → 100644
View file @
c797a78f
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Clusters
::
AgentsFinder
do
describe
'#execute'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
,
maintainer_projects:
[
project
])
}
let
(
:feature_available
)
{
true
}
let!
(
:matching_agent
)
{
create
(
:cluster_agent
,
project:
project
)
}
let!
(
:wrong_project
)
{
create
(
:cluster_agent
)
}
subject
{
described_class
.
new
(
project
,
user
).
execute
}
before
do
stub_licensed_features
(
cluster_agents:
feature_available
)
end
it
{
is_expected
.
to
contain_exactly
(
matching_agent
)
}
context
'feature is not available'
do
let
(
:feature_available
)
{
false
}
it
{
is_expected
.
to
be_empty
}
end
context
'user does not have permission'
do
let
(
:user
)
{
create
(
:user
,
developer_projects:
[
project
])
}
it
{
is_expected
.
to
be_empty
}
end
end
end
ee/spec/graphql/resolvers/clusters/agents_resolver_spec.rb
0 → 100644
View file @
c797a78f
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Resolvers
::
Clusters
::
AgentsResolver
do
include
GraphqlHelpers
it
{
expect
(
described_class
.
type
).
to
eq
(
Types
::
Clusters
::
AgentType
)
}
it
{
expect
(
described_class
.
null
).
to
be_truthy
}
describe
'#resolve'
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:finder
)
{
double
(
execute: :result
)
}
let
(
:project
)
{
create
(
:project
)
}
subject
{
resolve
(
described_class
,
obj:
project
,
ctx:
{
current_user:
user
})
}
it
'calls the agents finder'
do
expect
(
::
Clusters
::
AgentsFinder
).
to
receive
(
:new
)
.
with
(
project
,
user
).
and_return
(
finder
)
expect
(
subject
).
to
eq
(
:result
)
end
end
end
ee/spec/graphql/types/project_type_spec.rb
View file @
c797a78f
...
@@ -17,7 +17,7 @@ RSpec.describe GitlabSchema.types['Project'] do
...
@@ -17,7 +17,7 @@ RSpec.describe GitlabSchema.types['Project'] do
expected_fields
=
%w[
expected_fields
=
%w[
vulnerabilities sast_ci_configuration vulnerability_scanners requirement_states_count
vulnerabilities sast_ci_configuration vulnerability_scanners requirement_states_count
vulnerability_severities_count packages compliance_frameworks vulnerability_severities_count
vulnerability_severities_count packages compliance_frameworks vulnerability_severities_count
security_dashboard_path iterations
security_dashboard_path iterations
cluster_agents
]
]
expect
(
described_class
).
to
include_graphql_fields
(
*
expected_fields
)
expect
(
described_class
).
to
include_graphql_fields
(
*
expected_fields
)
...
@@ -185,4 +185,47 @@ RSpec.describe GitlabSchema.types['Project'] do
...
@@ -185,4 +185,47 @@ RSpec.describe GitlabSchema.types['Project'] do
expect
(
vulnerabilities
.
first
[
'severity'
]).
to
eq
(
'CRITICAL'
)
expect
(
vulnerabilities
.
first
[
'severity'
]).
to
eq
(
'CRITICAL'
)
end
end
end
end
describe
'cluster_agents'
do
let_it_be
(
:cluster_agent
)
{
create
(
:cluster_agent
,
project:
project
,
name:
'agent-name'
)
}
let_it_be
(
:query
)
do
%(
query {
project(fullPath: "#{project.full_path}") {
clusterAgents {
nodes {
id
name
createdAt
updatedAt
project {
id
}
}
}
}
}
)
end
subject
{
GitlabSchema
.
execute
(
query
,
context:
{
current_user:
user
}).
as_json
}
before
do
stub_licensed_features
(
cluster_agents:
true
)
project
.
add_maintainer
(
user
)
end
it
'returns associated cluster agents'
do
agents
=
subject
.
dig
(
'data'
,
'project'
,
'clusterAgents'
,
'nodes'
)
expect
(
agents
.
count
).
to
be
(
1
)
expect
(
agents
.
first
[
'id'
]).
to
eq
(
cluster_agent
.
to_global_id
.
to_s
)
expect
(
agents
.
first
[
'name'
]).
to
eq
(
'agent-name'
)
expect
(
agents
.
first
[
'createdAt'
]).
to
be_present
expect
(
agents
.
first
[
'updatedAt'
]).
to
be_present
expect
(
agents
.
first
[
'project'
][
'id'
]).
to
eq
(
project
.
to_global_id
.
to_s
)
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