Spike: Refactor and consolidate all "tool" dropdowns to use GraphQL

Consolidate all three scanner tool dropdowns (Project, Group, Instance) to use the same scanner_filter.vue component. And migrate the population of the dropdown items to use the GraphQL Vulnerability Scanners Query.

- Project Group Instance
- 2022-07-18_at_1.17_PM 2022-07-18_at_1.18_PM 2022-07-18_at_1.18_PM
Current
_Proposal_
scanner_filter.vue
_same_
simple_filter.vue
_scanner_filter.vue_
simple_filter.vue
_scanner_filter.vue_
Current
_Proposal_
HAML
_GraphQL_
Hard coded
_GraphQL_
Hard coded
_GraphQL_

Here are the GraphQL Vulnerability Scanners Queries that we should and possibly utilize instead:

Queries Sample Data
image image

💪 Why this is important

All three scanner tool dropdowns currently use multiple sources to populate the dropdown items. Because it's not a single source, it can easily jeopardize data integrity and make it very difficult to maintain. So if we wanted to make any changes, we would need to make the adjustments in 3 separate areas, which increases the delivery and engineering time 😖 Versus if all 3 were consolidated and using a shared component, any maintenance or feature addition could be made to a just a singular point. This means we can deliver a feature in a shorter amount of time and with more reliability 👍

optional read: To better understand the problem with the complication of the current architecture and the importance of this issue, here's how the tool dropdown works 🤓:

Click to expand

1️⃣ How the tool dropdown items are populated

There are 3 dropdowns - Project, Group, and Instance. They populate the dropdown items from different sources 😖

Instance and Group

These two views are using the simple_filter.vue component. The dropdown items are populated from hard-coded data 😱 (code).

It does not support the display of group data (as that's only available in scanner_filter.vue which is only being used by the Project view).

image

Project

It uses the scanner_filter.vue component (which extends from the simple_filter.vue). The dropdown items use the "scanners" injected from the data-scanners passed through in HAML's data attribute. Not GraphQL query.

Code | Introduced in this MR https://gitlab.com/gitlab-org/gitlab/-/merge_requests/51696/diffs

Sample data looks like this:

data-scanners="[
  { id: 151, vendor: "GitLab", report_type: "DEPENDENCY_SCANNING" },
  { id: 155, vendor: "GitLab", report_type: "SAST" },
  { id: 156, vendor: "GitLab", report_type: "SAST" },
  { id: 184, vendor: "GitLab", report_type: "DEPENDENCY_SCANNING" },
  { id: 162, vendor: "GitLab", report_type: "API_FUZZING" },
  { id: 161, vendor: "GitLab", report_type: "SECRET_DETECTION" },
  { id: 160, vendor: "GitLab", report_type: "COVERAGE_FUZZING" },
  { id: 157, vendor: "GitLab", report_type: "SAST" },
  { id: 158, vendor: "GitLab", report_type: "SAST" },
  { id: 153, vendor: "GitLab", report_type: "CLUSTER_IMAGE_SCANNING" },
  { id: 152, vendor: "GitLab", report_type: "CONTAINER_SCANNING" },
  { id: 159, vendor: "GitLab", report_type: "SAST" },
  { id: 154, vendor: "GitLab", report_type: "DAST" },
]"

It supports the display of group data. MR > https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49710

image

2️⃣ How the tool dropdown filtering works

The filtering happens with a vulnerabilities GraphQL query request

Group.vulnerabilities
Project.vulnerabilities
Query.vulnerabilities (Instance)

Group and Instance

The following arguments are used to conduct the filtering:

reportType: [] Filter vulnerabilities by report type.
 Group    Instance  
 2022-07-15_at_10.25_PM  2022-07-15_at_10.29_PM

Project

The following arguments are used to conduct the filtering

reportType: [] Filter vulnerabilities by report type.
scannerId: [] Filter vulnerabilities by scanner ID.

Example:

2022-07-15_at_9.58_PM

Scanner ID

The great thing is that we're using GraphQL to do the filtering. However because the project doesn't use GraphQL to populate the dropdown items, the FE need to do some additional manual work. The FE need to update the id to a compatible scanner_id format to make the GraphQL request. The scanner ID was introduced in this MR > https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60556.

Here's the data coming from HAML where we're utilizing the id:

data-scanner = [
  { id: 155, vendor: "GitLab", report_type: "SAST" }, // 👈
  { id: 156, vendor: "GitLab", report_type: "SAST" }, // 👈
  // ...
  { id: 157, vendor: "GitLab", report_type: "SAST" }, // 👈
  { id: 158, vendor: "GitLab", report_type: "SAST" }, // 👈
  // ...
  { id: 159, vendor: "GitLab", report_type: "SAST" }, // 👈
  { id: 154, vendor: "GitLab", report_type: "DAST" },
];

Which will then need to convert it to the compatibility scannerId > Code:

const scannerIds = [
  "gid://gitlab/Vulnerabilities::Scanner/155",
  "gid://gitlab/Vulnerabilities::Scanner/156",
  "gid://gitlab/Vulnerabilities::Scanner/157",
  "gid://gitlab/Vulnerabilities::Scanner/158",
  "gid://gitlab/Vulnerabilities::Scanner/159",
]

This can be resolved if the FE consumes the dropdown data from GraphQL's vulnerability scanner query. No additional data manipulation will be required.

🕵️ Finding Verdict

Many of the complications can be completely removed if a shared component is used where we populate the data from a single source with Graphql Query.

🌟 Proposal

  1. Keep it DRY by consolidating all three scanner tool dropdowns (Project, Group, Instance) to use the same scanner_filter.vue component
  2. Update all dropdowns to populate data from a single source of truth with GraphQL query
Edited by Samantha Ming