GraphQL filter for vulnerabilities by container images with vulnerabilities
Why are we doing this work
To support #337883 (closed), we need a graphql query to get all images scanned.
Relevant links
Non-functional requirements
-
Documentation: -
Feature flag: -
Performance: -
Testing:
Implementation plan
Graphql Schema
Project
project(fullPath: 'gitlab-org/gitlab') {
clusterAgents(hasVulnerabilities: true) { ... }
vulnerabilityContainerImages { ... }
}
Group
group(fullPath: 'gitlab-org') {
clusterAgents(hasVulnerabilities: true) { ... }
vulnerabilityContainerImages { ... }
}
Instance Security Dashboard
instanceSecurityDashboard\ {
clusterAgents(hasVulnerabilities: true) { ... }
vulnerabilityContainerImages { ... }
}
Model Changes
-
backend Add distinct_container_images
scope toVulnerabilities::Read
model to select the distinct images:
scope :distinct_container_images, -> { where('location_image IS NOT NULL').distinct.select(:location_image).pluck(:location_image) }
-
backend Add has_vulnerabilities
scope toClusters::Agent
model which checks ifcluster_agent_id
exists invulnerability_reads
table
scope :has_vulnerabilities, -> do
joins('inner join vulnerability_reads on cluster_agents.id = CAST(vulnerability_reads.cluster_agent_id AS INTEGER)')
.distinct
end
-
backend Add 'for_projects scope to
Clusters::Agents::ProjectAuthorization`
scope :for_projects, -> (project_ids) { where(project_id: project_ids) }
-
backend Add cluster_agents
toee/app/models/ee/group.rb
def cluster_agents
::Clusters::Agents::GroupAuthorization.where(group: self)
end
-
backend Add cluster_agents
toee/app/models/instance_security_dashboard.rb
def cluster_agents
return Clusters::Agent.none if projects.empty?
Clusters::Agents::ProjectAuthorization.for_projects(projects)
end
Resolver and graphql type changes
-
backend Add has_vulnerabilities
argument toResolvers::Clusters::AgentsResolver
argument :has_vulnerabilities, GraphQL::Types::Boolean,
required: false,
default_value: false,
description: 'Returns only the cluster agents which have atleast one vulnerability.'
-
backend Update Clusters::AgentsFinder
to check ifhas_vulnerabilities
argument is present and renameproject
toobject
so that it can takegroup
orinstance_security_dashboard
:
module Clusters
class AgentsFinder
- def initialize(project, current_user, params: {})
- @project = project
+ def initialize(object, current_user, params: {})
+ @object = object
@current_user = current_user
@params = params
end
def execute
- return ::Clusters::Agent.none unless can_read_cluster_agents?
+ return ::Clusters::Agent.none if object.is_a?(Project) && !can_read_cluster_agents?
- agents = project.cluster_agents
+ agents = object.cluster_agents
agents = agents.with_name(params[:name]) if params[:name].present?
+ agents = agents.has_vulnerabilities if params[:has_vulnerabilities].present?
agents.ordered_by_name
end
private
- attr_reader :project, :current_user, :params
+ attr_reader :object, :current_user, :params
def can_read_cluster_agents?
- current_user.can?(:read_cluster, project)
+ current_user.can?(:read_cluster, object)
end
end
end
-
backend Update ee/app/graphql/ee/types/group_type.rb
,ee/app/graphql/ee/types/project_type.rb
,ee/app/graphql/types/instance_security_dashboard_type.rb
to include :
field :cluster_agents,
::Types::Clusters::AgentType.connection_type,
extras: [:lookahead],
null: true,
description: '...',
resolver: ::Resolvers::Clusters::AgentsResolver
field :vulnerability_container_images,
type: [GraphQL::Types::String],
null: true,
description: '...'
def vulnerability_container_images
object.vulnerability_reads.distinct_container_images
end
Edited by Alan (Maciej) Paruszewski