Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b0c61201a7
commit
8c68904468
20 changed files with 364 additions and 210 deletions
|
@ -261,7 +261,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-bg-gray-10">
|
||||
<div
|
||||
class="gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-bg-gray-10"
|
||||
data-testid="work-item-links"
|
||||
>
|
||||
<div
|
||||
class="gl-px-5 gl-py-3 gl-display-flex gl-justify-content-space-between"
|
||||
:class="{ 'gl-border-b-1 gl-border-b-solid gl-border-b-gray-100': isOpen }"
|
||||
|
|
|
@ -294,7 +294,7 @@ GET /groups/:id/issues?state=opened
|
|||
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
|
||||
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `any`, `today`, `tomorrow`, `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. |
|
||||
| `epic_id` **(PREMIUM)** | integer | no | Return issues associated with the given epic ID. `None` returns issues that are not associated with an epic. `Any` returns issues that are associated with an epic. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46887) in GitLab 13.6)_
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
|
||||
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
|
||||
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
|
||||
|
@ -498,7 +498,7 @@ GET /projects/:id/issues?state=opened
|
|||
| `created_before` | datetime | no | Return issues created on or before the given time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
|
||||
| `due_date` | string | no | Return issues that have no due date, are overdue, or whose due date is this week, this month, or between two weeks ago and next month. Accepts: `0` (no due date), `any`, `today`, `tomorrow`, `overdue`, `week`, `month`, `next_month_and_previous_two_weeks`. |
|
||||
| `epic_id` **(PREMIUM)** | integer | no | Return issues associated with the given epic ID. `None` returns issues that are not associated with an epic. `Any` returns issues that are associated with an epic. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46887) in GitLab 13.6)_
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
|
||||
| `issue_type` | string | no | Filter to a given type of issue. One of `issue`, `incident`, or `test_case`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/260375) in GitLab 13.12)_ |
|
||||
| `iteration_id` **(PREMIUM)** | integer | no | Return issues assigned to the given iteration ID. `None` returns issues that do not belong to an iteration. `Any` returns issues that belong to an iteration. Mutually exclusive with `iteration_title`. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6)_ |
|
||||
|
@ -845,7 +845,7 @@ GET /projects/:id/issues/:issue_iid
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -1011,7 +1011,7 @@ POST /projects/:id/issues
|
|||
| `due_date` | string | no | The due date. Date time string in the format `YYYY-MM-DD`, for example `2016-03-11` |
|
||||
| `epic_id` **(PREMIUM)** | integer | no | ID of the epic to add the issue to. Valid values are greater than or equal to 0. |
|
||||
| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5) |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `iid` | integer/string | no | The internal ID of the project's issue (requires administrator or project owner rights) |
|
||||
| `issue_type` | string | no | The type of issue. One of `issue`, `incident`, or `test_case`. Default is `issue`. |
|
||||
| `labels` | string | no | Comma-separated label names for an issue |
|
||||
|
@ -1179,7 +1179,7 @@ PUT /projects/:id/issues/:issue_iid
|
|||
| `due_date` | string | no | The due date. Date time string in the format `YYYY-MM-DD`, for example `2016-03-11` |
|
||||
| `epic_id` **(PREMIUM)** | integer | no | ID of the epic to add the issue to. Valid values are greater than or equal to 0. |
|
||||
| `epic_iid` **(PREMIUM)** | integer | no | IID of the epic to add the issue to. Valid values are greater than or equal to 0. (deprecated, [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/35157) in API version 5) |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
| `issue_type` | string | no | Updates the type of issue. One of `issue`, `incident`, or `test_case`. |
|
||||
| `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. |
|
||||
|
@ -1325,7 +1325,7 @@ DELETE /projects/:id/issues/:issue_iid
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -1344,10 +1344,10 @@ PUT /projects/:id/issues/:issue_iid/reorder
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of the project's issue |
|
||||
| `move_after_id` | integer | no | The ID of a project's issue that should be placed after this issue |
|
||||
| `move_before_id` | integer | no | The ID of a project's issue that should be placed before this issue |
|
||||
| `move_after_id` | integer | no | The global ID of a project's issue that should be placed after this issue |
|
||||
| `move_before_id` | integer | no | The global ID of a project's issue that should be placed before this issue |
|
||||
|
||||
```shell
|
||||
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/issues/85/reorder?move_after_id=51&move_before_id=92"
|
||||
|
@ -1368,7 +1368,7 @@ POST /projects/:id/issues/:issue_iid/move
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-----------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
| `to_project_id` | integer | yes | The ID of the new project |
|
||||
|
||||
|
@ -1621,7 +1621,7 @@ POST /projects/:id/issues/:issue_iid/subscribe
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -1764,7 +1764,7 @@ POST /projects/:id/issues/:issue_iid/unsubscribe
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -1838,7 +1838,7 @@ POST /projects/:id/issues/:issue_iid/todo
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -1959,7 +1959,7 @@ Supported attributes:
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
| :---------- | :------------- | :------- | :---------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
| `body` | String | yes | The content of a note. Must contain `/promote` at the start of a new line. |
|
||||
|
||||
|
@ -2010,7 +2010,7 @@ POST /projects/:id/issues/:issue_iid/time_estimate
|
|||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|------------------------------------------|
|
||||
| `duration` | string | yes | The duration in human format. e.g: 3h30m |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -2038,7 +2038,7 @@ POST /projects/:id/issues/:issue_iid/reset_time_estimate
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -2067,7 +2067,7 @@ POST /projects/:id/issues/:issue_iid/add_spent_time
|
|||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|------------------------------------------|
|
||||
| `duration` | string | yes | The duration in human format. e.g: 3h30m |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
| `summary` | string | no | A summary of how the time was spent |
|
||||
|
||||
|
@ -2096,7 +2096,7 @@ POST /projects/:id/issues/:issue_iid/reset_spent_time
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -2125,7 +2125,7 @@ GET /projects/:id/issues/:issue_iid/time_stats
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -2156,7 +2156,7 @@ GET /projects/:id/issues/:issue_iid/related_merge_requests
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -2316,7 +2316,7 @@ GET /projects/:id/issues/:issue_iid/closed_by
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
| ----------- | ---------------| -------- | ---------------------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project issue |
|
||||
|
||||
```shell
|
||||
|
@ -2393,7 +2393,7 @@ GET /projects/:id/issues/:issue_iid/participants
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -2437,7 +2437,7 @@ GET /projects/:id/issues/:issue_iid/user_agent_detail
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -2469,7 +2469,7 @@ POST /projects/:id/issues/:issue_iid/metric_images
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
| `file` | file | yes | The image file to be uploaded |
|
||||
| `url` | string | no | The URL to view more metric information |
|
||||
|
@ -2503,7 +2503,7 @@ GET /projects/:id/issues/:issue_iid/metric_images
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
|
||||
```shell
|
||||
|
@ -2541,7 +2541,7 @@ PUT /projects/:id/issues/:issue_iid/metric_images/:image_id
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
| `image_id` | integer | yes | The ID of the image |
|
||||
| `url` | string | no | The URL to view more metric information |
|
||||
|
@ -2574,7 +2574,7 @@ DELETE /projects/:id/issues/:issue_iid/metric_images/:image_id
|
|||
|
||||
| Attribute | Type | Required | Description |
|
||||
|-------------|---------|----------|--------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `id` | integer/string | yes | The global ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `issue_iid` | integer | yes | The internal ID of a project's issue |
|
||||
| `image_id` | integer | yes | The ID of the image |
|
||||
|
||||
|
|
|
@ -403,8 +403,9 @@ pipeline graph. The remaining jobs still run as normal. To see the jobs:
|
|||
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 14.0.
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/328538) in GitLab 14.2.
|
||||
|
||||
You can arrange jobs in the pipeline graph based on their [`needs`](../yaml/index.md#needs)
|
||||
dependencies.
|
||||
To arrange jobs in the pipeline graph based on their [`needs`](../yaml/index.md#needs)
|
||||
dependencies, select **Job dependencies** in the **Group jobs by** section. This option
|
||||
is available for pipelines with 3 or more jobs with `needs` job dependencies.
|
||||
|
||||
Jobs in the leftmost column run first, and jobs that depend on them are grouped in the next columns.
|
||||
|
||||
|
|
|
@ -174,6 +174,7 @@ See [database guidelines](database/index.md).
|
|||
## Domain-specific guides
|
||||
|
||||
- [CI/CD development documentation](cicd/index.md)
|
||||
- [Sec Section development documentation](sec/index.md)
|
||||
|
||||
## Technical Reference by Group
|
||||
|
||||
|
|
68
doc/development/sec/index.md
Normal file
68
doc/development/sec/index.md
Normal file
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Static Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: index, concepts, howto
|
||||
---
|
||||
|
||||
# Sec Section development documentation **(FREE)**
|
||||
|
||||
Development guides that are specific to Sec Section are listed here.
|
||||
|
||||
See [Terminology](../../user/application_security/terminology) for an overview of our shared terminology.
|
||||
|
||||
## Architecture
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Scanning](#scanning)
|
||||
- [Processing, visualization, and management](#processing-visualization-and-management)
|
||||
- [Severity Levels](../../user/application_security/vulnerabilities/severities.md)
|
||||
|
||||
## Overview
|
||||
|
||||
The architecture supporting the Secure features is split into two main parts:
|
||||
|
||||
- Scanning
|
||||
- Processing, visualization, and management
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph G1[Scanning]
|
||||
Scanner
|
||||
Analyzer
|
||||
CI[CI Jobs]
|
||||
end
|
||||
subgraph G2[Processing, visualization, and management]
|
||||
Parsers
|
||||
Database
|
||||
Views
|
||||
Interactions
|
||||
end
|
||||
G1 --Report Artifact--> G2
|
||||
```
|
||||
|
||||
### Scanning
|
||||
|
||||
The scanning part is responsible for finding vulnerabilities in given resources, and exporting results.
|
||||
The scans are executed in CI/CD jobs via several small projects called [Analyzers](../../user/application_security/terminology/#analyzer), which can be found in our [Analyzers sub-group](https://gitlab.com/gitlab-org/security-products/analyzers).
|
||||
The Analyzers are wrappers around security tools called [Scanners](../../user/application_security/terminology/#scanner), developed internally or externally, to integrate them into GitLab.
|
||||
The Analyzers are mainly written in Go.
|
||||
|
||||
Some 3rd party integrators also make additional Scanners available by following our [integration documentation](../integrations/secure.md), which leverages the same architecture.
|
||||
|
||||
The results of the scans are exported as JSON reports that must comply with the [Secure report format](../../user/application_security/terminology/#secure-report-format) and are uploaded as [CI/CD Job Report artifacts](../../ci/pipelines/job_artifacts.md) to make them available for processing after the pipelines completes.
|
||||
|
||||
### Processing, visualization, and management
|
||||
|
||||
After the data is available as a Report Artifact it can be processed by the GitLab Rails application to enable our security features, including:
|
||||
|
||||
- [Security Dashboards](../../user/application_security/security_dashboard/), Merge Request widget, Pipeline view, and so on.
|
||||
- [Interactions with vulnerabilities](../../user/application_security/#interact-with-findings-and-vulnerabilities).
|
||||
- [Approval rules](../../user/application_security/#security-approvals-in-merge-requests).
|
||||
|
||||
Depending on the context, the security reports may be stored either in the database or stay as Report Artifacts for on-demand access.
|
||||
|
||||
## CI/CD template development
|
||||
|
||||
While CI/CD templates are the responsibiility of the Verify section, many are critical to the Sec Section's feature usage.
|
||||
If you are working with CI/CD templates, please read the [development guide for GitLab CI/CD templates](../cicd/templates.md).
|
|
@ -170,3 +170,17 @@ import = BulkImports::Entity.where(namespace_id: Group.id).map(&:bulk_import)
|
|||
|
||||
import.status #=> 3 means that the import timed out.
|
||||
```
|
||||
|
||||
### Error: `404 Group Not Found`
|
||||
|
||||
If you attempt to import a group that has a path comprised of only numbers (for example, `5000`), GitLab attempts to find the group by ID instead of the
|
||||
path. This causes a `404 Group Not Found` error. To solve this, the source group path must be changed to include a non-numerical character using either:
|
||||
|
||||
- The GitLab UI:
|
||||
|
||||
1. On the top bar, select **Menu > Groups** and find your group.
|
||||
1. On the left sidebar, select **Settings > General**.
|
||||
1. Expand **Advanced**.
|
||||
1. Under **Change group URL**, change the group URL to include non-numeric characters.
|
||||
|
||||
- The [Groups API](../../../api/groups.md#update-group).
|
||||
|
|
|
@ -201,6 +201,14 @@ To render an OpenAPI file:
|
|||
|
||||
## Repository size
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/368150) in GitLab 15.3, feature flags `gitaly_revlist_for_repo_size` and `gitaly_catfile_repo_size` for alternative repository size calculations.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default GitLab uses the `du -sk` command to determine the size of a repository. GitLab can use either
|
||||
`git-rev-list` (enabled with feature flag `gitaly_revlist_for_repo_size`) or `git-cat-file` (enabled with feature flag
|
||||
`gitaly_catfile_repo_size`) instead. To switch between different calculation methods, ask an administrator to
|
||||
[enable or disable](../../../administration/feature_flags.md) these feature flags.
|
||||
|
||||
The **Project information** page shows the size of all files in the repository. The size is
|
||||
updated, at most, every 15 minutes. The file size includes repository files, artifacts, and LFS.
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ A public and private key are generated.
|
|||
|
||||
## Add an SSH key to your GitLab account
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271239) in GitLab 15.3, default expiration date suggested in UI.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271239) in GitLab 15.4, default expiration date suggested in UI.
|
||||
|
||||
To use SSH with GitLab, copy your public key to your GitLab account:
|
||||
|
||||
|
|
110
spec/features/work_items/work_item_children_spec.rb
Normal file
110
spec/features/work_items/work_item_children_spec.rb
Normal file
|
@ -0,0 +1,110 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Work item children', :js do
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:project) { create(:project, :public, namespace: group) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:issue) { create(:issue, project: project) }
|
||||
|
||||
context 'for signed in user' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
|
||||
sign_in(user)
|
||||
|
||||
stub_feature_flags(work_items: true)
|
||||
stub_feature_flags(work_items_hierarchy: true)
|
||||
|
||||
visit project_issue_path(project, issue)
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
it 'are not displayed when issue does not have work item children', :aggregate_failures do
|
||||
page.within('[data-testid="work-item-links"]') do
|
||||
expect(find('[data-testid="links-empty"]')).to have_content(_('No child items are currently assigned.'))
|
||||
expect(page).not_to have_selector('[data-testid="add-links-form"]')
|
||||
expect(page).not_to have_selector('[data-testid="links-child"]')
|
||||
end
|
||||
end
|
||||
|
||||
it 'toggles widget body', :aggregate_failures do
|
||||
page.within('[data-testid="work-item-links"]') do
|
||||
expect(page).to have_selector('[data-testid="links-body"]')
|
||||
|
||||
click_button 'Collapse child items'
|
||||
|
||||
expect(page).not_to have_selector('[data-testid="links-body"]')
|
||||
|
||||
click_button 'Expand child items'
|
||||
|
||||
expect(page).to have_selector('[data-testid="links-body"]')
|
||||
end
|
||||
end
|
||||
|
||||
it 'toggles form', :aggregate_failures do
|
||||
page.within('[data-testid="work-item-links"]') do
|
||||
expect(page).not_to have_selector('[data-testid="add-links-form"]')
|
||||
|
||||
click_button 'Add a task'
|
||||
|
||||
expect(page).to have_selector('[data-testid="add-links-form"]')
|
||||
|
||||
click_button 'Cancel'
|
||||
|
||||
expect(page).not_to have_selector('[data-testid="add-links-form"]')
|
||||
end
|
||||
end
|
||||
|
||||
it 'addss a child task', :aggregate_failures do
|
||||
page.within('[data-testid="work-item-links"]') do
|
||||
click_button 'Add a task'
|
||||
|
||||
expect(page).to have_button('Create task', disabled: true)
|
||||
fill_in 'Add a title', with: 'Task 1'
|
||||
|
||||
expect(page).to have_button('Create task', disabled: false)
|
||||
|
||||
click_button 'Create task'
|
||||
|
||||
wait_for_all_requests
|
||||
|
||||
expect(find('[data-testid="links-child"]')).to have_content('Task 1')
|
||||
end
|
||||
end
|
||||
|
||||
it 'removes a child task and undoing', :aggregate_failures do
|
||||
page.within('[data-testid="work-item-links"]') do
|
||||
click_button 'Add a task'
|
||||
fill_in 'Add a title', with: 'Task 1'
|
||||
click_button 'Create task'
|
||||
wait_for_all_requests
|
||||
|
||||
expect(find('[data-testid="links-child"]')).to have_content('Task 1')
|
||||
expect(find('[data-testid="children-count"]')).to have_content('1')
|
||||
|
||||
find('[data-testid="links-menu"]').click
|
||||
click_button 'Remove'
|
||||
|
||||
wait_for_all_requests
|
||||
|
||||
expect(page).not_to have_content('Task 1')
|
||||
expect(find('[data-testid="children-count"]')).to have_content('0')
|
||||
end
|
||||
|
||||
page.within('.gl-toast') do
|
||||
expect(find('.toast-body')).to have_content(_('Child removed'))
|
||||
find('.b-toaster a', text: 'Undo').click
|
||||
end
|
||||
|
||||
wait_for_all_requests
|
||||
|
||||
page.within('[data-testid="work-item-links"]') do
|
||||
expect(find('[data-testid="links-child"]')).to have_content('Task 1')
|
||||
expect(find('[data-testid="children-count"]')).to have_content('1')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -46,7 +46,7 @@ describe('Environments block', () => {
|
|||
});
|
||||
};
|
||||
|
||||
const findText = () => wrapper.find(EnvironmentsBlock).text();
|
||||
const findText = () => wrapper.findComponent(EnvironmentsBlock).text();
|
||||
const findJobDeploymentLink = () => wrapper.find('[data-testid="job-deployment-link"]');
|
||||
const findEnvironmentLink = () => wrapper.find('[data-testid="job-environment-link"]');
|
||||
const findClusterLink = () => wrapper.find('[data-testid="job-cluster-link"]');
|
||||
|
|
|
@ -10,7 +10,7 @@ describe('Erased block', () => {
|
|||
const timeago = getTimeago();
|
||||
const formattedDate = timeago.format(erasedAt);
|
||||
|
||||
const findLink = () => wrapper.find(GlLink);
|
||||
const findLink = () => wrapper.findComponent(GlLink);
|
||||
|
||||
const createComponent = (props) => {
|
||||
wrapper = mount(ErasedBlock, {
|
||||
|
|
|
@ -57,18 +57,18 @@ describe('Job App', () => {
|
|||
await nextTick();
|
||||
};
|
||||
|
||||
const findLoadingComponent = () => wrapper.find(GlLoadingIcon);
|
||||
const findSidebar = () => wrapper.find(Sidebar);
|
||||
const findLoadingComponent = () => wrapper.findComponent(GlLoadingIcon);
|
||||
const findSidebar = () => wrapper.findComponent(Sidebar);
|
||||
const findJobContent = () => wrapper.find('[data-testid="job-content"');
|
||||
const findStuckBlockComponent = () => wrapper.find(StuckBlock);
|
||||
const findStuckBlockComponent = () => wrapper.findComponent(StuckBlock);
|
||||
const findStuckBlockWithTags = () => wrapper.find('[data-testid="job-stuck-with-tags"');
|
||||
const findStuckBlockNoActiveRunners = () =>
|
||||
wrapper.find('[data-testid="job-stuck-no-active-runners"');
|
||||
const findFailedJobComponent = () => wrapper.find(UnmetPrerequisitesBlock);
|
||||
const findEnvironmentsBlockComponent = () => wrapper.find(EnvironmentsBlock);
|
||||
const findErasedBlock = () => wrapper.find(ErasedBlock);
|
||||
const findFailedJobComponent = () => wrapper.findComponent(UnmetPrerequisitesBlock);
|
||||
const findEnvironmentsBlockComponent = () => wrapper.findComponent(EnvironmentsBlock);
|
||||
const findErasedBlock = () => wrapper.findComponent(ErasedBlock);
|
||||
const findArchivedJob = () => wrapper.find('[data-testid="archived-job"]');
|
||||
const findEmptyState = () => wrapper.find(EmptyState);
|
||||
const findEmptyState = () => wrapper.findComponent(EmptyState);
|
||||
const findJobNewIssueLink = () => wrapper.find('[data-testid="job-new-issue"]');
|
||||
const findJobEmptyStateTitle = () => wrapper.find('[data-testid="job-empty-state-title"]');
|
||||
const findJobLogScrollTop = () => wrapper.find('[data-testid="job-controller-scroll-top"]');
|
||||
|
|
|
@ -10,8 +10,8 @@ describe('Job Retry Forward Deployment Modal', () => {
|
|||
let wrapper;
|
||||
|
||||
const retryOutdatedJobDocsUrl = 'url-to-docs';
|
||||
const findLink = () => wrapper.find(GlLink);
|
||||
const findModal = () => wrapper.find(GlModal);
|
||||
const findLink = () => wrapper.findComponent(GlLink);
|
||||
const findModal = () => wrapper.findComponent(GlModal);
|
||||
|
||||
const createWrapper = ({ props = {}, provide = {}, stubs = {} } = {}) => {
|
||||
store = createStore();
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('Job Sidebar Details Container', () => {
|
|||
|
||||
const findJobTimeout = () => wrapper.findByTestId('job-timeout');
|
||||
const findJobTags = () => wrapper.findByTestId('job-tags');
|
||||
const findAllDetailsRow = () => wrapper.findAll(DetailRow);
|
||||
const findAllDetailsRow = () => wrapper.findAllComponents(DetailRow);
|
||||
|
||||
const createWrapper = ({ props = {} } = {}) => {
|
||||
store = createStore();
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('Job Log Header Line', () => {
|
|||
});
|
||||
|
||||
it('renders the line number component', () => {
|
||||
expect(wrapper.find(LineNumber).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(LineNumber).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a span the provided text', () => {
|
||||
|
@ -90,7 +90,7 @@ describe('Job Log Header Line', () => {
|
|||
});
|
||||
|
||||
it('renders the duration badge', () => {
|
||||
expect(wrapper.find(DurationBadge).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(DurationBadge).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,7 +42,7 @@ describe('Job Log Line', () => {
|
|||
});
|
||||
|
||||
it('renders the line number component', () => {
|
||||
expect(wrapper.find(LineNumber).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(LineNumber).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a span the provided text', () => {
|
||||
|
|
|
@ -15,11 +15,11 @@ describe('Sidebar details block', () => {
|
|||
let wrapper;
|
||||
|
||||
const forwardDeploymentFailure = 'forward_deployment_failure';
|
||||
const findModal = () => wrapper.find(JobRetryForwardDeploymentModal);
|
||||
const findModal = () => wrapper.findComponent(JobRetryForwardDeploymentModal);
|
||||
const findArtifactsBlock = () => wrapper.findComponent(ArtifactsBlock);
|
||||
const findCancelButton = () => wrapper.findByTestId('cancel-button');
|
||||
const findNewIssueButton = () => wrapper.findByTestId('job-new-issue');
|
||||
const findRetryButton = () => wrapper.find(JobRetryButton);
|
||||
const findRetryButton = () => wrapper.findComponent(JobRetryButton);
|
||||
const findTerminalLink = () => wrapper.findByTestId('terminal-link');
|
||||
const findEraseLink = () => wrapper.findByTestId('job-log-erase-link');
|
||||
|
||||
|
@ -176,7 +176,7 @@ describe('Sidebar details block', () => {
|
|||
|
||||
describe('with stages', () => {
|
||||
it('renders value provided as selectedStage as selected', () => {
|
||||
expect(wrapper.find(StagesDropdown).props('selectedStage')).toBe('aStage');
|
||||
expect(wrapper.findComponent(StagesDropdown).props('selectedStage')).toBe('aStage');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -184,7 +184,7 @@ describe('Sidebar details block', () => {
|
|||
beforeEach(() => store.dispatch('receiveJobSuccess', job));
|
||||
|
||||
it('does not render jobs container', () => {
|
||||
expect(wrapper.find(JobsContainer).exists()).toBe(false);
|
||||
expect(wrapper.findComponent(JobsContainer).exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -195,7 +195,7 @@ describe('Sidebar details block', () => {
|
|||
});
|
||||
|
||||
it('renders list of jobs', () => {
|
||||
expect(wrapper.find(JobsContainer).exists()).toBe(true);
|
||||
expect(wrapper.findComponent(JobsContainer).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,8 +26,8 @@ describe('Stuck Block Job component', () => {
|
|||
wrapper.find('[data-testid="job-stuck-no-active-runners"]');
|
||||
const findStuckNoRunners = () => wrapper.find('[data-testid="job-stuck-no-runners"]');
|
||||
const findStuckWithTags = () => wrapper.find('[data-testid="job-stuck-with-tags"]');
|
||||
const findRunnerPathLink = () => wrapper.find(GlLink);
|
||||
const findAllBadges = () => wrapper.findAll(GlBadge);
|
||||
const findRunnerPathLink = () => wrapper.findComponent(GlLink);
|
||||
const findAllBadges = () => wrapper.findAllComponents(GlBadge);
|
||||
|
||||
describe('with no runners for project', () => {
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('Unmet Prerequisites Block Job component', () => {
|
|||
});
|
||||
|
||||
it('renders an alert with the correct message', () => {
|
||||
const container = wrapper.find(GlAlert);
|
||||
const container = wrapper.findComponent(GlAlert);
|
||||
const alertMessage =
|
||||
'This job failed because the necessary resources were not successfully created.';
|
||||
|
||||
|
@ -32,7 +32,7 @@ describe('Unmet Prerequisites Block Job component', () => {
|
|||
});
|
||||
|
||||
it('renders link to help page', () => {
|
||||
const helpLink = wrapper.find(GlLink);
|
||||
const helpLink = wrapper.findComponent(GlLink);
|
||||
|
||||
expect(helpLink).not.toBeNull();
|
||||
expect(helpLink.text()).toContain('More information');
|
||||
|
|
|
@ -21,6 +21,51 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
|
||||
let(:validator) { described_class.new(report_type, report_data, report_version, project: project, scanner: scanner) }
|
||||
|
||||
shared_examples 'report is valid' do
|
||||
context 'and the report is valid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version,
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'logs related information' do
|
||||
it 'logs related information' do
|
||||
expect(Gitlab::AppLogger).to receive(:info).with(
|
||||
message: "security report schema validation problem",
|
||||
security_report_type: report_type,
|
||||
security_report_version: report_version,
|
||||
project_id: project.id,
|
||||
security_report_failure: security_report_failure,
|
||||
security_report_scanner_id: 'gemnasium',
|
||||
security_report_scanner_version: '2.1.0'
|
||||
)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'report is invalid' do
|
||||
context 'and the report is invalid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version
|
||||
}
|
||||
end
|
||||
|
||||
let(:security_report_failure) { 'schema_validation_fails' }
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
|
||||
it_behaves_like 'logs related information'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'SUPPORTED_VERSIONS' do
|
||||
schema_path = Rails.root.join("lib", "gitlab", "ci", "parsers", "security", "validators", "schemas")
|
||||
|
||||
|
@ -75,80 +120,16 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
(latest_vendored_version[0...2] << "34").join(".")
|
||||
end
|
||||
|
||||
context 'and the report is valid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version,
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'and the report is invalid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
|
||||
it 'logs related information' do
|
||||
expect(Gitlab::AppLogger).to receive(:info).with(
|
||||
message: "security report schema validation problem",
|
||||
security_report_type: report_type,
|
||||
security_report_version: report_version,
|
||||
project_id: project.id,
|
||||
security_report_failure: 'schema_validation_fails',
|
||||
security_report_scanner_id: 'gemnasium',
|
||||
security_report_scanner_version: '2.1.0'
|
||||
)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
it_behaves_like 'report is valid'
|
||||
it_behaves_like 'report is invalid'
|
||||
end
|
||||
|
||||
context 'when given a supported schema version' do
|
||||
let(:report_type) { :dast }
|
||||
let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last }
|
||||
|
||||
context 'and the report is valid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version,
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
context 'and the report is invalid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
|
||||
it 'logs related information' do
|
||||
expect(Gitlab::AppLogger).to receive(:info).with(
|
||||
message: "security report schema validation problem",
|
||||
security_report_type: report_type,
|
||||
security_report_version: report_version,
|
||||
project_id: project.id,
|
||||
security_report_failure: 'schema_validation_fails',
|
||||
security_report_scanner_id: 'gemnasium',
|
||||
security_report_scanner_version: '2.1.0'
|
||||
)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
it_behaves_like 'report is valid'
|
||||
it_behaves_like 'report is invalid'
|
||||
end
|
||||
|
||||
context 'when given a deprecated schema version' do
|
||||
|
@ -173,21 +154,11 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
}
|
||||
end
|
||||
|
||||
let(:security_report_failure) { 'using_deprecated_schema_version' }
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
|
||||
it 'logs related information' do
|
||||
expect(Gitlab::AppLogger).to receive(:info).with(
|
||||
message: "security report schema validation problem",
|
||||
security_report_type: report_type,
|
||||
security_report_version: report_version,
|
||||
project_id: project.id,
|
||||
security_report_failure: 'using_deprecated_schema_version',
|
||||
security_report_scanner_id: 'gemnasium',
|
||||
security_report_scanner_version: '2.1.0'
|
||||
)
|
||||
|
||||
subject
|
||||
end
|
||||
it_behaves_like 'logs related information'
|
||||
end
|
||||
|
||||
context 'and the report does not pass schema validation' do
|
||||
|
@ -213,21 +184,11 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
}
|
||||
end
|
||||
|
||||
let(:security_report_failure) { 'using_unsupported_schema_version' }
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
|
||||
it 'logs related information' do
|
||||
expect(Gitlab::AppLogger).to receive(:info).with(
|
||||
message: "security report schema validation problem",
|
||||
security_report_type: report_type,
|
||||
security_report_version: report_version,
|
||||
project_id: project.id,
|
||||
security_report_failure: 'using_unsupported_schema_version',
|
||||
security_report_scanner_id: 'gemnasium',
|
||||
security_report_scanner_version: '2.1.0'
|
||||
)
|
||||
|
||||
subject
|
||||
end
|
||||
it_behaves_like 'logs related information'
|
||||
end
|
||||
|
||||
context 'and the report is invalid' do
|
||||
|
@ -282,6 +243,23 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples 'report is valid with no error' do
|
||||
context 'and the report is valid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version,
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_empty }
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'report with expected errors' do
|
||||
it { is_expected.to match_array(expected_errors) }
|
||||
end
|
||||
|
||||
describe '#errors' do
|
||||
subject { validator.errors }
|
||||
|
||||
|
@ -289,16 +267,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
let(:report_type) { :dast }
|
||||
let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last }
|
||||
|
||||
context 'and the report is valid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version,
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_empty }
|
||||
end
|
||||
it_behaves_like 'report is valid with no error'
|
||||
|
||||
context 'and the report is invalid' do
|
||||
let(:report_data) do
|
||||
|
@ -313,7 +282,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
]
|
||||
end
|
||||
|
||||
it { is_expected.to match_array(expected_errors) }
|
||||
it_behaves_like 'report with expected errors'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -331,16 +300,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash)
|
||||
end
|
||||
|
||||
context 'and the report passes schema validation' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => '10.0.0',
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_empty }
|
||||
end
|
||||
it_behaves_like 'report is valid with no error'
|
||||
|
||||
context 'and the report does not pass schema validation' do
|
||||
let(:report_data) do
|
||||
|
@ -356,7 +316,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
]
|
||||
end
|
||||
|
||||
it { is_expected.to match_array(expected_errors) }
|
||||
it_behaves_like 'report with expected errors'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -383,7 +343,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
]
|
||||
end
|
||||
|
||||
it { is_expected.to match_array(expected_errors) }
|
||||
it_behaves_like 'report with expected errors'
|
||||
end
|
||||
|
||||
context 'and the report is invalid' do
|
||||
|
@ -400,7 +360,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
]
|
||||
end
|
||||
|
||||
it { is_expected.to match_array(expected_errors) }
|
||||
it_behaves_like 'report with expected errors'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -426,10 +386,27 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
]
|
||||
end
|
||||
|
||||
it { is_expected.to match_array(expected_errors) }
|
||||
it_behaves_like 'report with expected errors'
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'report is valid with no warning' do
|
||||
context 'and the report is valid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version,
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_empty }
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'report with expected warnings' do
|
||||
it { is_expected.to match_array(expected_deprecation_warnings) }
|
||||
end
|
||||
|
||||
describe '#deprecation_warnings' do
|
||||
subject { validator.deprecation_warnings }
|
||||
|
||||
|
@ -491,7 +468,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
}
|
||||
end
|
||||
|
||||
it { is_expected.to match_array(expected_deprecation_warnings) }
|
||||
it_behaves_like 'report with expected warnings'
|
||||
end
|
||||
|
||||
context 'and the report does not pass schema validation' do
|
||||
|
@ -501,7 +478,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
}
|
||||
end
|
||||
|
||||
it { is_expected.to match_array(expected_deprecation_warnings) }
|
||||
it_behaves_like 'report with expected warnings'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -516,7 +493,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
}
|
||||
end
|
||||
|
||||
it { is_expected.to match_array(expected_deprecation_warnings) }
|
||||
it_behaves_like 'report with expected warnings'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -561,21 +538,11 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
}
|
||||
end
|
||||
|
||||
let(:security_report_failure) { 'schema_validation_fails' }
|
||||
|
||||
it { is_expected.to match_array([message]) }
|
||||
|
||||
it 'logs related information' do
|
||||
expect(Gitlab::AppLogger).to receive(:info).with(
|
||||
message: "security report schema validation problem",
|
||||
security_report_type: report_type,
|
||||
security_report_version: report_version,
|
||||
project_id: project.id,
|
||||
security_report_failure: 'schema_validation_fails',
|
||||
security_report_scanner_id: 'gemnasium',
|
||||
security_report_scanner_version: '2.1.0'
|
||||
)
|
||||
|
||||
subject
|
||||
end
|
||||
it_behaves_like 'logs related information'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -583,16 +550,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
let(:report_type) { :dast }
|
||||
let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last }
|
||||
|
||||
context 'and the report is valid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version,
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_empty }
|
||||
end
|
||||
it_behaves_like 'report is valid with no warning'
|
||||
|
||||
context 'and the report is invalid' do
|
||||
let(:report_data) do
|
||||
|
@ -644,16 +602,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
|
|||
let(:report_type) { :dast }
|
||||
let(:report_version) { "12.37.0" }
|
||||
|
||||
context 'and the report is valid' do
|
||||
let(:report_data) do
|
||||
{
|
||||
'version' => report_version,
|
||||
'vulnerabilities' => []
|
||||
}
|
||||
end
|
||||
|
||||
it { is_expected.to be_empty }
|
||||
end
|
||||
it_behaves_like 'report is valid with no warning'
|
||||
|
||||
context 'and the report is invalid' do
|
||||
let(:report_data) do
|
||||
|
|
Loading…
Reference in a new issue