Skip to content

Modify risk scores finder to group by projects

What does this MR do and why?

Modify the VulnerabilityElasticRiskScoresFinder to also fetch risk scores, grouped by projects. Also fetch the total count of projects with vulnerabilities in a group.

Finder response format -

{
  # risk score for the whole group
  :total_risk_score=>1.0,
  :risk_score_by_project=>{
    # project_id => project_risk_score
    43=>1.0, 45=>0.148, 38=>0.3817, 39=>0.3817, 41=>0.3758, 20=>0.1201, 21=>0.3025
  },
  :total_project_count=>7
}

ES query

Click to expand
GET gitlab-development-vulnerabilities/_search
{
  "size": 0,
  "track_total_hits": true,
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {
                "prefix": {
                  "traversal_ids": {
                    "_name": "namespace:ancestry_filter:descendants",
                    "value": "24-"
                  }
                }
              }
            ],
            "minimum_should_match": 1
          }
        },
        {
          "terms": {
            "state": [
              1,
              4
            ]
          }
        }
      ]
    }
  },
  "aggs": {
    "by_project": {
      "terms": {
        "field": "project_id",
        "size": 65_536
      },
      "aggs": {
        "risk_scores_sum": {
          "sum": {
            "field": "risk_score"
          }
        },
        "created_at_sum": {
          "sum": {
            "field": "created_at"
          }
        }
      }
    },
    "risk_scores_sum": {
      "sum": {
        "field": "risk_score"
      }
    },
    "created_at_sum": {
      "sum": {
        "field": "created_at"
      }
    }
  }
}

Response -

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1736,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "created_at_sum": {
      "value": 3031555145667047,
      "value_as_string": "+98036-02-27T19:34:27.047Z"
    },
    "by_project": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": 43,
          "doc_count": 1100,
          "risk_scores_sum": {
            "value": 0
          },
          "created_at_sum": {
            "value": 1920062013246300,
            "value_as_string": "+62814-05-05T23:14:06.300Z"
          }
        },
        {
          "key": 45,
          "doc_count": 152,
          "risk_scores_sum": {
            "value": 0
          },
          "created_at_sum": {
            "value": 266864797996363,
            "value_as_string": "+10426-08-10T22:33:16.363Z"
          }
        },
        {
          "key": 38,
          "doc_count": 141,
          "risk_scores_sum": {
            "value": 0
          },
          "created_at_sum": {
            "value": 246079801624483,
            "value_as_string": "9767-12-16T20:27:04.483Z"
          }
        },
        {
          "key": 39,
          "doc_count": 141,
          "risk_scores_sum": {
            "value": 0
          },
          "created_at_sum": {
            "value": 246079984513236,
            "value_as_string": "9767-12-18T23:15:13.236Z"
          }
        },
        {
          "key": 41,
          "doc_count": 141,
          "risk_scores_sum": {
            "value": 0
          },
          "created_at_sum": {
            "value": 246116138717842,
            "value_as_string": "9769-02-09T10:05:17.842Z"
          }
        },
        {
          "key": 20,
          "doc_count": 39,
          "risk_scores_sum": {
            "value": 0
          },
          "created_at_sum": {
            "value": 68325785053493,
            "value_as_string": "4135-02-27T16:44:13.493Z"
          }
        },
        {
          "key": 21,
          "doc_count": 22,
          "risk_scores_sum": {
            "value": 0
          },
          "created_at_sum": {
            "value": 38026624515330,
            "value_as_string": "3175-01-06T23:15:15.330Z"
          }
        }
      ]
    },
    "risk_scores_sum": {
      "value": 0
    }
  }
}

References

Screenshots or screen recordings

Before After

How to set up and validate locally

  1. Enable FF Feature.enable(:group_vulnerability_risk_scores_by_project) from rails console.
  2. Select a group with few projects which have vulnerabilities (vulnerabilities can be generated by following these instructions)
  3. From the rails console, find the group and execute the finder
g = Group.find(id)
Security::Security::VulnerabilityElasticRiskScoresFinder.new(g, {group_by: :project}).execute

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to - #579017 (closed)

Edited by Rushik Subba

Merge request reports

Loading