Extend GraphQL's vulnerabilities query
<!-- This template is a great use for issues that are feature::additions or technical tasks for larger issues.-->
### What we have today
The gitlab~10690752 owns 4 Dashboards. The Project Level Security Dashboard, the Group Level Security Dashboard, the Security Center and the Pipeline Security Dashboard. Each of these dashboards display a list of vulnerabilities which can be fetched using GraphQL. Below is a table that demonstrates which query is used to fetch the vulnerabilities for the related dashboard:
| Dashboard | Query Name |
| ------ | ------ |
| Security Center | `vulnerabilities` |
| Group Level Security Dashboard | `group.vulnerabilities` |
| Project Level Security Dashboard | `project.vulnerabilities` |
| Pipeline Security Dashboard | `project.pipeline.securityReportFindings` |
### Problem
This creates an additional complexity in the gitlab~3412464 while fetching the vulnerabilities / findings. Technically speaking, we re-use the `ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_list.vue` component in order to display the vulnerabilities/findings for each dashboard and we have a wrapper component which creates the query for the related dashboard.
### Final Proposal
#### 1. Keep the existing `group.vulnerabilities` and `project.vulnerabilities` queries
* We may need to add and deprecate fields to match what we need for the FE
#### 2. Add `instanceLevelDashboard.vulnerabilties` query
* This should mimic the behavior of `groups` and `projects` calls to `vulnerabilities`.
* This would add a logical query to the `instanceLevelDashboard`
#### 3. Add `project.pipeline.vulnerabilities` query which would eventually supersede the `project.pipeline.securityReportFindings` query
* The idea here is that a security finding is still returned, but matching the response format for the other sub-queries. Fields not available would simply be `null`.
#### 4. Deprecate existing calls
* `project.pipeline.securityReportFindings` will be deprecated in deference to `project.pipeline.vulnerabilities`
* `vulnerabilities` query will be deprecated in deference to `instanceLevelDashboard.vulnerabilties`.
* As discussed, we should not have a top level `vulnerabilities` query.
* This is not to be confused with the singular `vulnerability` query to pull a vulnerability based off of vulnerability id.
### Why This Proposal
* Keep GraphQL conventions
* Add logical filters/sub-queries to existing queries
* There would be a consistent `vulnerabilities` field for `project`, `groups`, `project.pipeline`, and `instanceLevelDashboard`
---
---
### Initial Proposal
I'm going to suggest to deprecate all these queries except the `vulnerabilities` query and extend it by allowing it to receive the following arguments:
| argument | type | default value | description |
| ------ | ------ | ------ | ------ |
| `projectId` | `[ID!]` | `[]` | An array of project ids. |
| `groupId` or `groupFullPath` | `[ID!]` | `[]` | An array of group ids or full paths depending on which one we want use. Our UI is not designed to display multiple groups at the same time, but API-wise it could be beneficial for the user. |
| `isSecurityCenter` | `Boolean` | `false` | Whether we're fetching the vulnerabilities for the security center (user level security dashboard) |
| `pipelineId` | `[ID!]` | `[]` | Similar to `groupId`, we do not display vulnerabilities for multiple pipelines at the same time, but this could still be beneficial for the user. |
So this is what the query would look like to fetch the vulnerabilities:
```graphql
#import "~/graphql_shared/fragments/pageInfoCursorsOnly.fragment.graphql"
#import "../fragments/vulnerability.fragment.graphql"
query vulnerabilities(
$after: String
$first: Int
$projectId: [ID!]
$severity: [VulnerabilitySeverity!]
$reportType: [VulnerabilityReportType!]
$scanner: [String!]
$scannerId: [VulnerabilitiesScannerID!]
$state: [VulnerabilityState!]
$sort: VulnerabilitySort
$hasIssues: Boolean
$hasResolution: Boolean
$groupId: [!ID]
$projectId: [!ID]
$pipelineId: [!ID]
$isSecurityCenter: Boolean
) {
vulnerabilities(
after: $after
first: $first
severity: $severity
reportType: $reportType
state: $state
projectId: $projectId
scanner: $scanner
scannerId: $scannerId
sort: $sort
hasIssues: $hasIssues
hasResolution: $hasResolution
groupId: $groupId # part of the proposal
projectId: $projectId # part of the proposal
pipelineId: $pipelineId # part of the proposal
isSecurityCenter: $isSecurityCenter # part of the proposal
) {
nodes {
...Vulnerability
}
pageInfo {
...PageInfo
}
}
}
```
So for instance providing the `$projectId: ["/root/security-reports"]` argument would return the vulnerabilities for this project, but omitting the `$projectId` and providing `isSecurityCenter: true` would return the security center vulnerabilities.
The only unknown in this proposal is whether we can provide the `findings` in the same query or not. A `Finding` and a `Vulnerability` are different entities in the gitlab~2492649 even though for the end-user and the gitlab~3412464 they are very similar. If we can provide the findings in the same query, it would then remove many complexities in the gitlab~3412464 as we would be able to treat them alike. If this is technically not possible, or hard to implement, we can always reiterate on this proposal and start from providing a single query for the 3 dashboards.
epic