Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
		
							parent
							
								
									91035102b4
								
							
						
					
					
						commit
						849c67f6da
					
				|  | @ -66,6 +66,7 @@ class AwarenessChannel < ApplicationCable::Channel # rubocop:disable Gitlab/Name | ||||||
|     { |     { | ||||||
|       id: user.id, |       id: user.id, | ||||||
|       name: user.name, |       name: user.name, | ||||||
|  |       username: user.username, | ||||||
|       avatar_url: user.avatar_url(size: 36), |       avatar_url: user.avatar_url(size: 36), | ||||||
|       last_activity: last_activity, |       last_activity: last_activity, | ||||||
|       last_activity_humanized: ActionController::Base.helpers.distance_of_time_in_words( |       last_activity_humanized: ActionController::Base.helpers.distance_of_time_in_words( | ||||||
|  |  | ||||||
|  | @ -3,11 +3,8 @@ | ||||||
| module Ci | module Ci | ||||||
|   class SecureFile < Ci::ApplicationRecord |   class SecureFile < Ci::ApplicationRecord | ||||||
|     include FileStoreMounter |     include FileStoreMounter | ||||||
|     include IgnorableColumns |  | ||||||
|     include Limitable |     include Limitable | ||||||
| 
 | 
 | ||||||
|     ignore_column :permissions, remove_with: '15.2', remove_after: '2022-06-22' |  | ||||||
| 
 |  | ||||||
|     FILE_SIZE_LIMIT = 5.megabytes.freeze |     FILE_SIZE_LIMIT = 5.megabytes.freeze | ||||||
|     CHECKSUM_ALGORITHM = 'sha256' |     CHECKSUM_ALGORITHM = 'sha256' | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,12 +1,8 @@ | ||||||
| - add_page_specific_style 'page_bundles/runner_details' | - add_page_specific_style 'page_bundles/runner_details' | ||||||
| 
 | 
 | ||||||
| - add_to_breadcrumbs _('Runners'), group_runners_path(@group) | - add_to_breadcrumbs _('Runners'), group_runners_path(@group) | ||||||
|  | - title = "##{@runner.id} (#{@runner.short_sha})" | ||||||
|  | - breadcrumb_title title | ||||||
|  | - page_title title | ||||||
| 
 | 
 | ||||||
| - if Feature.enabled?(:group_runner_view_ui, @group) | #js-group-runner-show{ data: {runner_id: @runner.id, runners_path: group_runners_path(@group), edit_group_runner_path: edit_group_runner_path(@group, @runner)} } | ||||||
|   - title = "##{@runner.id} (#{@runner.short_sha})" |  | ||||||
|   - breadcrumb_title title |  | ||||||
|   - page_title title |  | ||||||
| 
 |  | ||||||
|   #js-group-runner-show{ data: {runner_id: @runner.id, runners_path: group_runners_path(@group), edit_group_runner_path: edit_group_runner_path(@group, @runner)} } |  | ||||||
| - else |  | ||||||
|   = render 'shared/runners/runner_details', runner: @runner |  | ||||||
|  |  | ||||||
|  | @ -21,8 +21,9 @@ | ||||||
| 
 | 
 | ||||||
|       - else |       - else | ||||||
|         %p |         %p | ||||||
|           - register_2fa_token = _('We recommend cloud-based mobile authenticator apps such as Authy, Duo Mobile, and LastPass. They can restore access if you lose your hardware device.') |           - register_2fa_token = _('We recommend using cloud-based authenticator applications that can restore access if you lose your hardware device.') | ||||||
|           = register_2fa_token.html_safe |           = register_2fa_token.html_safe | ||||||
|  |           = link_to _('What are some examples?'), help_page_path('user/profile/account/two_factor_authentication', anchor: 'enable-one-time-password'), target: '_blank', rel: 'noopener noreferrer' | ||||||
|         .row.gl-mb-3 |         .row.gl-mb-3 | ||||||
|           .col-md-4.gl-min-w-fit-content |           .col-md-4.gl-min-w-fit-content | ||||||
|             .gl-p-2.gl-mb-3{ style: 'background: #fff' } |             .gl-p-2.gl-mb-3{ style: 'background: #fff' } | ||||||
|  |  | ||||||
|  | @ -1,8 +0,0 @@ | ||||||
| --- |  | ||||||
| name: enforce_security_report_validation |  | ||||||
| introduced_by_url: |  | ||||||
| rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351000 |  | ||||||
| milestone: '14.9' |  | ||||||
| type: development |  | ||||||
| group: group::threat insights |  | ||||||
| default_enabled: true |  | ||||||
|  | @ -1,8 +0,0 @@ | ||||||
| --- |  | ||||||
| name: group_runner_view_ui |  | ||||||
| introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89638/ |  | ||||||
| rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/364811 |  | ||||||
| milestone: '15.1' |  | ||||||
| type: development |  | ||||||
| group: group::runner |  | ||||||
| default_enabled: false |  | ||||||
|  | @ -3,7 +3,7 @@ table_name: project_statistics | ||||||
| classes: | classes: | ||||||
| - ProjectStatistics | - ProjectStatistics | ||||||
| feature_categories: | feature_categories: | ||||||
| - source_code_management | - utilization | ||||||
| description: TODO | description: Records statistics about the usage of various product features | ||||||
| introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/3ef4f74b1acc9399db320b53dffc592542de0126 | introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/7754 | ||||||
| milestone: '9.0' | milestone: '8.16' | ||||||
|  |  | ||||||
|  | @ -11,32 +11,83 @@ GitLab by default supports the [Gravatar](https://gravatar.com) avatar service. | ||||||
| 
 | 
 | ||||||
| Libravatar is another service that delivers your avatar (profile picture) to | Libravatar is another service that delivers your avatar (profile picture) to | ||||||
| other websites. The Libravatar API is | other websites. The Libravatar API is | ||||||
| [heavily based on gravatar](https://wiki.libravatar.org/api/), so you can | [heavily based on Gravatar](https://wiki.libravatar.org/api/), so you can | ||||||
| switch to the Libravatar avatar service or even your own Libravatar | switch to the Libravatar avatar service or even your own Libravatar | ||||||
| server. | server. | ||||||
| 
 | 
 | ||||||
| ## Configuration | ## Change the Libravatar service to your own service | ||||||
| 
 | 
 | ||||||
| In the [`gitlab.yml` gravatar section](https://gitlab.com/gitlab-org/gitlab/-/blob/672bd3902d86b78d730cea809fce312ec49d39d7/config/gitlab.yml.example#L122), set | In the [`gitlab.yml` gravatar section](https://gitlab.com/gitlab-org/gitlab/-/blob/68dac188ec6b1b03d53365e7579422f44cbe7a1c/config/gitlab.yml.example#L469-476), set | ||||||
| the configuration options as follows: | the configuration options as follows: | ||||||
| 
 | 
 | ||||||
| ### For HTTP | **For Omnibus installations** | ||||||
| 
 | 
 | ||||||
| ```yaml | 1. Edit `/etc/gitlab/gitlab.rb`: | ||||||
|   gravatar: |  | ||||||
|     enabled: true |  | ||||||
|     # gravatar URLs: possible placeholders: %{hash} %{size} %{email} %{username} |  | ||||||
|     plain_url: "http://cdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" |  | ||||||
| ``` |  | ||||||
| 
 | 
 | ||||||
| ### For HTTPS |    ```ruby | ||||||
|  |    gitlab_rails['gravatar_enabled'] = true | ||||||
|  |    #### For HTTPS | ||||||
|  |    gitlab_rails['gravatar_ssl_url'] = "https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" | ||||||
|  |    #### Use this line instead for HTTP | ||||||
|  |    # gitlab_rails['gravatar_plain_url'] = "http://cdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" | ||||||
|  |    ``` | ||||||
| 
 | 
 | ||||||
| ```yaml | 1. To apply the changes, run `sudo gitlab-ctl reconfigure`. | ||||||
|   gravatar: | 
 | ||||||
|     enabled: true | **For installations from source** | ||||||
|     # gravatar URLs: possible placeholders: %{hash} %{size} %{email} %{username} | 
 | ||||||
|     ssl_url: "https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" | 1. Edit `config/gitlab.yml`: | ||||||
| ``` | 
 | ||||||
|  |    ```yaml | ||||||
|  |      gravatar: | ||||||
|  |        enabled: true | ||||||
|  |        # default: https://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon | ||||||
|  |        plain_url: "http://cdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" | ||||||
|  |        # default: https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon | ||||||
|  |        ssl_url: https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  | 1. Save the file, and then [restart](restart_gitlab.md#installations-from-source) | ||||||
|  |    GitLab for the changes to take effect. | ||||||
|  | 
 | ||||||
|  | ## Set the Libravatar service to default (Gravatar) | ||||||
|  | 
 | ||||||
|  | **For Omnibus installations** | ||||||
|  | 
 | ||||||
|  | 1. Delete `gitlab_rails['gravatar_ssl_url']` or `gitlab_rails['gravatar_plain_url']` from `/etc/gitlab/gitlab.rb`. | ||||||
|  | 1. To apply the changes, run `sudo gitlab-ctl reconfigure`. | ||||||
|  | 
 | ||||||
|  | **For installations from source** | ||||||
|  | 
 | ||||||
|  | 1. Remove `gravatar:` section from `config/gitlab.yml`. | ||||||
|  | 1. Save the file, then [restart](restart_gitlab.md#installations-from-source) | ||||||
|  |    GitLab to apply the changes. | ||||||
|  | 
 | ||||||
|  | ## Disable Gravatar service | ||||||
|  | 
 | ||||||
|  | To disable Gravatar, for example, to prohibit third-party services, complete the following steps: | ||||||
|  | 
 | ||||||
|  | **For Omnibus installations** | ||||||
|  | 
 | ||||||
|  | 1. Edit `/etc/gitlab/gitlab.rb`: | ||||||
|  | 
 | ||||||
|  |    ```ruby | ||||||
|  |    gitlab_rails['gravatar_enabled'] = false | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  | 1. To apply the changes, run `sudo gitlab-ctl reconfigure`. | ||||||
|  | 
 | ||||||
|  | **For installations from source** | ||||||
|  | 
 | ||||||
|  | 1. Edit `config/gitlab.yml`: | ||||||
|  | 
 | ||||||
|  |    ```yaml | ||||||
|  |      gravatar: | ||||||
|  |        enabled: false | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  | 1. Save the file, then [restart](restart_gitlab.md#installations-from-source) | ||||||
|  |    GitLab to apply the changes. | ||||||
| 
 | 
 | ||||||
| ### Your own Libravatar server | ### Your own Libravatar server | ||||||
| 
 | 
 | ||||||
|  | @ -44,30 +95,10 @@ If you are [running your own Libravatar service](https://wiki.libravatar.org/run | ||||||
| the URL is different in the configuration, but you must provide the same | the URL is different in the configuration, but you must provide the same | ||||||
| placeholders so GitLab can parse the URL correctly. | placeholders so GitLab can parse the URL correctly. | ||||||
| 
 | 
 | ||||||
| For example, you host a service on `http://libravatar.example.com` and the | For example, you host a service on `https://libravatar.example.com` and the | ||||||
| `plain_url` you must supply in `gitlab.yml` is | `ssl_url` you must supply in `gitlab.yml` is: | ||||||
| 
 | 
 | ||||||
| `http://libravatar.example.com/avatar/%{hash}?s=%{size}&d=identicon` | `https://libravatar.example.com/avatar/%{hash}?s=%{size}&d=identicon` | ||||||
| 
 |  | ||||||
| ### Omnibus GitLab example |  | ||||||
| 
 |  | ||||||
| In `/etc/gitlab/gitlab.rb`: |  | ||||||
| 
 |  | ||||||
| #### For HTTP |  | ||||||
| 
 |  | ||||||
| ```ruby |  | ||||||
| gitlab_rails['gravatar_enabled'] = true |  | ||||||
| gitlab_rails['gravatar_plain_url'] = "http://cdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| #### For HTTPS |  | ||||||
| 
 |  | ||||||
| ```ruby |  | ||||||
| gitlab_rails['gravatar_enabled'] = true |  | ||||||
| gitlab_rails['gravatar_ssl_url'] = "https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Then run `sudo gitlab-ctl reconfigure` for the changes to take effect. |  | ||||||
| 
 | 
 | ||||||
| ## Default URL for missing images | ## Default URL for missing images | ||||||
| 
 | 
 | ||||||
|  | @ -77,7 +108,7 @@ service. | ||||||
| 
 | 
 | ||||||
| To use a set other than `identicon`, replace the `&d=identicon` portion of the | To use a set other than `identicon`, replace the `&d=identicon` portion of the | ||||||
| URL with another supported set. For example, you can use the `retro` set, in | URL with another supported set. For example, you can use the `retro` set, in | ||||||
| which case the URL would look like: `plain_url: "http://cdn.libravatar.org/avatar/%{hash}?s=%{size}&d=retro"` | which case the URL would look like: `ssl_url: "https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=retro"` | ||||||
| 
 | 
 | ||||||
| ## Usage examples for Microsoft Office 365 | ## Usage examples for Microsoft Office 365 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -150,7 +150,7 @@ the page is rendered to HTML. There can be only **one** level 1 heading per page | ||||||
| 
 | 
 | ||||||
| - For each subsection, increment the heading level. In other words, increment the number of `#` characters | - For each subsection, increment the heading level. In other words, increment the number of `#` characters | ||||||
|   in front of the heading. |   in front of the heading. | ||||||
| - Avoid headings greater than `H5` (`#####`). If you need more than five headings, move the topics to a new page instead. | - Avoid headings greater than `H5` (`#####`). If you need more than five heading levels, move the topics to a new page instead. | ||||||
|   Headings greater than `H5` do not display in the right sidebar navigation. |   Headings greater than `H5` do not display in the right sidebar navigation. | ||||||
| - Do not skip a level. For example: `##` > `####`. | - Do not skip a level. For example: `##` > `####`. | ||||||
| - Leave one blank line before and after the heading. | - Leave one blank line before and after the heading. | ||||||
|  |  | ||||||
|  | @ -178,6 +178,9 @@ All validations are skipped when running in `RAILS_ENV=production`. | ||||||
| 
 | 
 | ||||||
| ## Create a new feature flag | ## Create a new feature flag | ||||||
| 
 | 
 | ||||||
|  | NOTE: | ||||||
|  | GitLab Pages uses [a different process](../pages/index.md#feature-flags) for feature flags. | ||||||
|  | 
 | ||||||
| The GitLab codebase provides [`bin/feature-flag`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/bin/feature-flag), | The GitLab codebase provides [`bin/feature-flag`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/bin/feature-flag), | ||||||
| a dedicated tool to create new feature flag definitions. | a dedicated tool to create new feature flag definitions. | ||||||
| The tool asks various questions about the new feature flag, then creates | The tool asks various questions about the new feature flag, then creates | ||||||
|  |  | ||||||
|  | @ -236,3 +236,29 @@ make acceptance | ||||||
| # so we want to have the latest changes in the build that is tested | # so we want to have the latest changes in the build that is tested | ||||||
| make && go test ./ -run TestRedirect | make && go test ./ -run TestRedirect | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | ## Contributing | ||||||
|  | 
 | ||||||
|  | ### Feature flags | ||||||
|  | 
 | ||||||
|  | WARNING: | ||||||
|  | All newly-introduced feature flags should be [disabled by default](https://about.gitlab.com/handbook/product-development-flow/feature-flag-lifecycle/#feature-flags-in-gitlab-development). | ||||||
|  | 
 | ||||||
|  | Consider adding a [feature flag](../feature_flags/index.md) for any non-trivial changes. | ||||||
|  | Feature flags can make the release and rollback of these changes easier, avoiding | ||||||
|  | incidents and downtime. To add a new feature flag to GitLab Pages: | ||||||
|  | 
 | ||||||
|  | 1. Create the feature flag in | ||||||
|  |    [`internal/feature/feature.go`](https://gitlab.com/gitlab-org/gitlab-pages/-/blob/master/internal/feature/feature.go), | ||||||
|  |    which must be **off** by default. | ||||||
|  | 1. Create an issue to track the feature flag using the `Feature Flag` template. | ||||||
|  | 1. Add the `~"feature flag"` label to any merge requests that handle feature flags. | ||||||
|  | 
 | ||||||
|  | For GitLab Pages, the feature flags are controlled by environment variables at a global level. It | ||||||
|  | A deployment at the service level is required to change the state of a feature flag. | ||||||
|  | Example of an merge request enabling a GitLab Pages feature flag: | ||||||
|  | [Enforce GitLab Pages rate limits](https://gitlab.com/gitlab-com/gl-infra/k8s-workloads/gitlab-com/-/merge_requests/1500) | ||||||
|  | 
 | ||||||
|  | ## Related topics | ||||||
|  | 
 | ||||||
|  | - [Feature flags in the development of GitLab](../feature_flags/index.md) | ||||||
|  |  | ||||||
|  | @ -109,66 +109,6 @@ You should use a local terminal to run the commands needed for migrating to GitL | ||||||
| 
 | 
 | ||||||
| The following example demonstrates how to change the state name. The same workflow is needed to migrate to GitLab-managed Terraform state from a different state storage backend. | The following example demonstrates how to change the state name. The same workflow is needed to migrate to GitLab-managed Terraform state from a different state storage backend. | ||||||
| 
 | 
 | ||||||
| ## Use your GitLab backend as a remote data source |  | ||||||
| 
 |  | ||||||
| You can use a GitLab-managed Terraform state backend as a |  | ||||||
| [Terraform data source](https://www.terraform.io/language/state/remote-state-data). |  | ||||||
| 
 |  | ||||||
| 1. In your `main.tf` or other relevant file, declare these variables. Leave the values empty. |  | ||||||
| 
 |  | ||||||
|    ```hcl |  | ||||||
|    variable "example_remote_state_address" { |  | ||||||
|      type = string |  | ||||||
|      description = "Gitlab remote state file address" |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    variable "example_username" { |  | ||||||
|      type = string |  | ||||||
|      description = "Gitlab username to query remote state" |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    variable "example_access_token" { |  | ||||||
|      type = string |  | ||||||
|      description = "GitLab access token to query remote state" |  | ||||||
|    } |  | ||||||
|    ``` |  | ||||||
| 
 |  | ||||||
| 1. To override the values from the previous step, create a file named `example.auto.tfvars`. This file should **not** be versioned in your project repository. |  | ||||||
| 
 |  | ||||||
|    ```plaintext |  | ||||||
|    example_remote_state_address = "https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>" |  | ||||||
|    example_username = "<GitLab username>" |  | ||||||
|    example_access_token = "<GitLab Personal Access Token>" |  | ||||||
|    ``` |  | ||||||
| 
 |  | ||||||
| 1. In a `.tf` file, define the data source by using [Terraform input variables](https://www.terraform.io/language/values/variables): |  | ||||||
| 
 |  | ||||||
|    ```hcl |  | ||||||
|    data "terraform_remote_state" "example" { |  | ||||||
|      backend = "http" |  | ||||||
| 
 |  | ||||||
|      config = { |  | ||||||
|        address = var.example_remote_state_address |  | ||||||
|        username = var.example_username |  | ||||||
|        password = var.example_access_token |  | ||||||
|      } |  | ||||||
|    } |  | ||||||
|    ``` |  | ||||||
| 
 |  | ||||||
|    - **address**: The URL of the remote state backend you want to use as a data source. |  | ||||||
|      For example, `https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>`. |  | ||||||
|    - **username**: The username to authenticate with the data source. If you are using |  | ||||||
|      a [Personal Access Token](../../profile/personal_access_tokens.md) for |  | ||||||
|      authentication, this value is your GitLab username. If you are using GitLab CI/CD, this value is `'gitlab-ci-token'`. |  | ||||||
|    - **password**: The password to authenticate with the data source. If you are using a Personal Access Token for |  | ||||||
|      authentication, this value is the token value (the token must have the **API** scope). |  | ||||||
|      If you are using GitLab CI/CD, this value is the contents of the `${CI_JOB_TOKEN}` CI/CD variable. |  | ||||||
| 
 |  | ||||||
| Outputs from the data source can now be referenced in your Terraform resources |  | ||||||
| using `data.terraform_remote_state.example.outputs.<OUTPUT-NAME>`. |  | ||||||
| 
 |  | ||||||
| To read the Terraform state in the target project, you need at least the Developer role. |  | ||||||
| 
 |  | ||||||
| ### Set up the initial backend | ### Set up the initial backend | ||||||
| 
 | 
 | ||||||
| ```shell | ```shell | ||||||
|  | @ -264,6 +204,66 @@ commands will detect it and remind you to do so if necessary. | ||||||
| If you type `yes`, it copies your state from the old location to the new | If you type `yes`, it copies your state from the old location to the new | ||||||
| location. You can then go back to running it in GitLab CI/CD. | location. You can then go back to running it in GitLab CI/CD. | ||||||
| 
 | 
 | ||||||
|  | ## Use your GitLab backend as a remote data source | ||||||
|  | 
 | ||||||
|  | You can use a GitLab-managed Terraform state backend as a | ||||||
|  | [Terraform data source](https://www.terraform.io/language/state/remote-state-data). | ||||||
|  | 
 | ||||||
|  | 1. In your `main.tf` or other relevant file, declare these variables. Leave the values empty. | ||||||
|  | 
 | ||||||
|  |    ```hcl | ||||||
|  |    variable "example_remote_state_address" { | ||||||
|  |      type = string | ||||||
|  |      description = "Gitlab remote state file address" | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    variable "example_username" { | ||||||
|  |      type = string | ||||||
|  |      description = "Gitlab username to query remote state" | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    variable "example_access_token" { | ||||||
|  |      type = string | ||||||
|  |      description = "GitLab access token to query remote state" | ||||||
|  |    } | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  | 1. To override the values from the previous step, create a file named `example.auto.tfvars`. This file should **not** be versioned in your project repository. | ||||||
|  | 
 | ||||||
|  |    ```plaintext | ||||||
|  |    example_remote_state_address = "https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>" | ||||||
|  |    example_username = "<GitLab username>" | ||||||
|  |    example_access_token = "<GitLab Personal Access Token>" | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  | 1. In a `.tf` file, define the data source by using [Terraform input variables](https://www.terraform.io/language/values/variables): | ||||||
|  | 
 | ||||||
|  |    ```hcl | ||||||
|  |    data "terraform_remote_state" "example" { | ||||||
|  |      backend = "http" | ||||||
|  | 
 | ||||||
|  |      config = { | ||||||
|  |        address = var.example_remote_state_address | ||||||
|  |        username = var.example_username | ||||||
|  |        password = var.example_access_token | ||||||
|  |      } | ||||||
|  |    } | ||||||
|  |    ``` | ||||||
|  | 
 | ||||||
|  |    - **address**: The URL of the remote state backend you want to use as a data source. | ||||||
|  |      For example, `https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>`. | ||||||
|  |    - **username**: The username to authenticate with the data source. If you are using | ||||||
|  |      a [Personal Access Token](../../profile/personal_access_tokens.md) for | ||||||
|  |      authentication, this value is your GitLab username. If you are using GitLab CI/CD, this value is `'gitlab-ci-token'`. | ||||||
|  |    - **password**: The password to authenticate with the data source. If you are using a Personal Access Token for | ||||||
|  |      authentication, this value is the token value (the token must have the **API** scope). | ||||||
|  |      If you are using GitLab CI/CD, this value is the contents of the `${CI_JOB_TOKEN}` CI/CD variable. | ||||||
|  | 
 | ||||||
|  | Outputs from the data source can now be referenced in your Terraform resources | ||||||
|  | using `data.terraform_remote_state.example.outputs.<OUTPUT-NAME>`. | ||||||
|  | 
 | ||||||
|  | To read the Terraform state in the target project, you need at least the Developer role. | ||||||
|  | 
 | ||||||
| ## Manage Terraform state files | ## Manage Terraform state files | ||||||
| 
 | 
 | ||||||
| > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273592) in GitLab 13.8. | > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273592) in GitLab 13.8. | ||||||
|  |  | ||||||
|  | @ -28,6 +28,11 @@ local repository, GitLab stops updating the branch. This prevents data loss. | ||||||
| Deleted branches and tags in the upstream repository are not reflected in the | Deleted branches and tags in the upstream repository are not reflected in the | ||||||
| downstream repository. | downstream repository. | ||||||
| 
 | 
 | ||||||
|  | NOTE: | ||||||
|  | Items deleted from the downstream pull mirror repository, but still in the upstream repository, | ||||||
|  | are restored upon the next pull. For example: a branch deleted _only_ in the mirrored repository | ||||||
|  | reappears after the next pull. | ||||||
|  | 
 | ||||||
| ## How pull mirroring works | ## How pull mirroring works | ||||||
| 
 | 
 | ||||||
| After you configure a GitLab repository as a pull mirror: | After you configure a GitLab repository as a pull mirror: | ||||||
|  |  | ||||||
|  | @ -93,11 +93,7 @@ module Gitlab | ||||||
| 
 | 
 | ||||||
|               log_warnings(problem_type: 'schema_validation_fails') unless schema_validation_errors.empty? |               log_warnings(problem_type: 'schema_validation_fails') unless schema_validation_errors.empty? | ||||||
| 
 | 
 | ||||||
|               if Feature.enabled?(:enforce_security_report_validation, @project) |               @errors += schema_validation_errors | ||||||
|                 @errors += schema_validation_errors |  | ||||||
|               else |  | ||||||
|                 @warnings += schema_validation_errors |  | ||||||
|               end |  | ||||||
|             end |             end | ||||||
| 
 | 
 | ||||||
|             def populate_warnings |             def populate_warnings | ||||||
|  | @ -130,11 +126,7 @@ module Gitlab | ||||||
|             def add_unsupported_report_version_message |             def add_unsupported_report_version_message | ||||||
|               log_warnings(problem_type: 'using_unsupported_schema_version') |               log_warnings(problem_type: 'using_unsupported_schema_version') | ||||||
| 
 | 
 | ||||||
|               if Feature.enabled?(:enforce_security_report_validation, @project) |               handle_unsupported_report_version | ||||||
|                 handle_unsupported_report_version(treat_as: :error) |  | ||||||
|               else |  | ||||||
|                 handle_unsupported_report_version(treat_as: :warning) |  | ||||||
|               end |  | ||||||
|             end |             end | ||||||
| 
 | 
 | ||||||
|             def report_uses_deprecated_schema_version? |             def report_uses_deprecated_schema_version? | ||||||
|  | @ -145,14 +137,14 @@ module Gitlab | ||||||
|               SUPPORTED_VERSIONS[report_type].include?(report_version) |               SUPPORTED_VERSIONS[report_type].include?(report_version) | ||||||
|             end |             end | ||||||
| 
 | 
 | ||||||
|             def handle_unsupported_report_version(treat_as:) |             def handle_unsupported_report_version | ||||||
|               if report_version.nil? |               if report_version.nil? | ||||||
|                 message = "Report version not provided, #{report_type} report type supports versions: #{supported_schema_versions}" |                 message = "Report version not provided, #{report_type} report type supports versions: #{supported_schema_versions}" | ||||||
|               else |               else | ||||||
|                 message = "Version #{report_version} for report type #{report_type} is unsupported, supported versions for this report type are: #{supported_schema_versions}" |                 message = "Version #{report_version} for report type #{report_type} is unsupported, supported versions for this report type are: #{supported_schema_versions}" | ||||||
|               end |               end | ||||||
| 
 | 
 | ||||||
|               add_message_as(level: treat_as, message: message) |               add_message_as(level: :error, message: message) | ||||||
|             end |             end | ||||||
| 
 | 
 | ||||||
|             def supported_schema_versions |             def supported_schema_versions | ||||||
|  |  | ||||||
|  | @ -43512,9 +43512,6 @@ msgstr "" | ||||||
| msgid "We recommend a work email address." | msgid "We recommend a work email address." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "We recommend cloud-based mobile authenticator apps such as Authy, Duo Mobile, and LastPass. They can restore access if you lose your hardware device." |  | ||||||
| msgstr "" |  | ||||||
| 
 |  | ||||||
| msgid "We recommend leaving all SAST analyzers enabled" | msgid "We recommend leaving all SAST analyzers enabled" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -43524,6 +43521,9 @@ msgstr "" | ||||||
| msgid "We recommend that you buy additional Pipeline minutes to resume normal service." | msgid "We recommend that you buy additional Pipeline minutes to resume normal service." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "We recommend using cloud-based authenticator applications that can restore access if you lose your hardware device." | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "We sent you an email with reset password instructions" | msgid "We sent you an email with reset password instructions" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -43824,6 +43824,9 @@ msgstr "" | ||||||
| msgid "What are project audit events?" | msgid "What are project audit events?" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "What are some examples?" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "What does the setting affect?" | msgid "What does the setting affect?" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -36,6 +36,7 @@ RSpec.describe AwarenessChannel, :clean_gitlab_redis_shared_state, type: :channe | ||||||
|           collaborator = { |           collaborator = { | ||||||
|             id: user.id, |             id: user.id, | ||||||
|             name: user.name, |             name: user.name, | ||||||
|  |             username: user.username, | ||||||
|             avatar_url: user.avatar_url(size: 36), |             avatar_url: user.avatar_url(size: 36), | ||||||
|             last_activity: Time.zone.now, |             last_activity: Time.zone.now, | ||||||
|             last_activity_humanized: ActionController::Base.helpers.distance_of_time_in_words( |             last_activity_humanized: ActionController::Base.helpers.distance_of_time_in_words( | ||||||
|  |  | ||||||
|  | @ -149,79 +149,39 @@ RSpec.describe "Group Runners" do | ||||||
|       create(:ci_runner, :group, groups: [group], description: 'runner-foo', contacted_at: Time.zone.now) |       create(:ci_runner, :group, groups: [group], description: 'runner-foo', contacted_at: Time.zone.now) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     context 'when group_runner_view_ui is disabled' do |     it 'user views runner details' do | ||||||
|       before do |       visit group_runner_path(group, runner) | ||||||
|         stub_feature_flags(group_runner_view_ui: false) |  | ||||||
|       end |  | ||||||
| 
 | 
 | ||||||
|       it 'user edits the runner to be protected' do |       expect(page).to have_content "#{s_('Runners|Description')} runner-foo" | ||||||
|         visit edit_group_runner_path(group, runner) |  | ||||||
| 
 |  | ||||||
|         expect(page.find_field('runner[access_level]')).not_to be_checked |  | ||||||
| 
 |  | ||||||
|         check 'runner_access_level' |  | ||||||
|         click_button 'Save changes' |  | ||||||
| 
 |  | ||||||
|         expect(page).to have_content 'Protected Yes' |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       context 'when a runner has a tag' do |  | ||||||
|         before do |  | ||||||
|           runner.update!(tag_list: ['tag']) |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         it 'user edits runner not to run untagged jobs' do |  | ||||||
|           visit edit_group_runner_path(group, runner) |  | ||||||
| 
 |  | ||||||
|           expect(page.find_field('runner[run_untagged]')).to be_checked |  | ||||||
| 
 |  | ||||||
|           uncheck 'runner_run_untagged' |  | ||||||
|           click_button 'Save changes' |  | ||||||
| 
 |  | ||||||
|           expect(page).to have_content 'Can run untagged jobs No' |  | ||||||
|         end |  | ||||||
|       end |  | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     context 'when group_runner_view_ui is enabled' do |     it 'user edits the runner to be protected' do | ||||||
|  |       visit edit_group_runner_path(group, runner) | ||||||
|  | 
 | ||||||
|  |       expect(page.find_field('runner[access_level]')).not_to be_checked | ||||||
|  | 
 | ||||||
|  |       check 'runner_access_level' | ||||||
|  |       click_button _('Save changes') | ||||||
|  | 
 | ||||||
|  |       expect(page).to have_content "#{s_('Runners|Configuration')} #{s_('Runners|Protected')}" | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     context 'when a runner has a tag' do | ||||||
|       before do |       before do | ||||||
|         stub_feature_flags(group_runner_view_ui: true) |         runner.update!(tag_list: ['tag1']) | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       it 'user views runner details' do |       it 'user edits runner not to run untagged jobs' do | ||||||
|         visit group_runner_path(group, runner) |  | ||||||
| 
 |  | ||||||
|         expect(page).to have_content "#{s_('Runners|Description')} runner-foo" |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       it 'user edits the runner to be protected' do |  | ||||||
|         visit edit_group_runner_path(group, runner) |         visit edit_group_runner_path(group, runner) | ||||||
| 
 | 
 | ||||||
|         expect(page.find_field('runner[access_level]')).not_to be_checked |         page.find_field('runner[tag_list]').set('tag1, tag2') | ||||||
| 
 | 
 | ||||||
|         check 'runner_access_level' |         uncheck 'runner_run_untagged' | ||||||
|         click_button _('Save changes') |         click_button _('Save changes') | ||||||
| 
 | 
 | ||||||
|         expect(page).to have_content "#{s_('Runners|Configuration')} #{s_('Runners|Protected')}" |         # Tags can be in any order | ||||||
|       end |         expect(page).to have_content /#{s_('Runners|Tags')}.*tag1/ | ||||||
| 
 |         expect(page).to have_content /#{s_('Runners|Tags')}.*tag2/ | ||||||
|       context 'when a runner has a tag' do |  | ||||||
|         before do |  | ||||||
|           runner.update!(tag_list: ['tag1']) |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         it 'user edits runner not to run untagged jobs' do |  | ||||||
|           visit edit_group_runner_path(group, runner) |  | ||||||
| 
 |  | ||||||
|           page.find_field('runner[tag_list]').set('tag1, tag2') |  | ||||||
| 
 |  | ||||||
|           uncheck 'runner_run_untagged' |  | ||||||
|           click_button _('Save changes') |  | ||||||
| 
 |  | ||||||
|           # Tags can be in any order |  | ||||||
|           expect(page).to have_content /#{s_('Runners|Tags')}.*tag1/ |  | ||||||
|           expect(page).to have_content /#{s_('Runners|Tags')}.*tag2/ |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -6,6 +6,10 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|   let_it_be(:project) { create(:project) } |   let_it_be(:project) { create(:project) } | ||||||
| 
 | 
 | ||||||
|   let(:supported_dast_versions) { described_class::SUPPORTED_VERSIONS[:dast].join(', ') } |   let(:supported_dast_versions) { described_class::SUPPORTED_VERSIONS[:dast].join(', ') } | ||||||
|  |   let(:deprecated_schema_version_message) { } | ||||||
|  |   let(:missing_schema_version_message) do | ||||||
|  |     "Report version not provided, dast report type supports versions: #{supported_dast_versions}" | ||||||
|  |   end | ||||||
| 
 | 
 | ||||||
|   let(:scanner) do |   let(:scanner) do | ||||||
|     { |     { | ||||||
|  | @ -24,7 +28,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       expect(described_class::SUPPORTED_VERSIONS.keys).to eq(described_class::DEPRECATED_VERSIONS.keys) |       expect(described_class::SUPPORTED_VERSIONS.keys).to eq(described_class::DEPRECATED_VERSIONS.keys) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     context 'when a schema JSON file exists for a particular report type version' do |     context 'when all files under schema path are explicitly listed' do | ||||||
|       # We only care about the part that comes before report-format.json |       # We only care about the part that comes before report-format.json | ||||||
|       # https://rubular.com/r/N8Juz7r8hYDYgD |       # https://rubular.com/r/N8Juz7r8hYDYgD | ||||||
|       filename_regex = /(?<report_type>[-\w]*)\-report-format.json/ |       filename_regex = /(?<report_type>[-\w]*)\-report-format.json/ | ||||||
|  | @ -38,7 +42,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|           matches = filename_regex.match(file) |           matches = filename_regex.match(file) | ||||||
|           report_type = matches[:report_type].tr("-", "_").to_sym |           report_type = matches[:report_type].tr("-", "_").to_sym | ||||||
| 
 | 
 | ||||||
|           it "#{report_type} #{version} is in the constant" do |           it "#{report_type} #{version}" do | ||||||
|             expect(described_class::SUPPORTED_VERSIONS[report_type]).to include(version) |             expect(described_class::SUPPORTED_VERSIONS[report_type]).to include(version) | ||||||
|           end |           end | ||||||
|         end |         end | ||||||
|  | @ -68,7 +72,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       let(:report_type) { :dast } |       let(:report_type) { :dast } | ||||||
|       let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } |       let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } | ||||||
| 
 | 
 | ||||||
|       context 'when the report is valid' do |       context 'and the report is valid' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version, |             'version' => report_version, | ||||||
|  | @ -79,7 +83,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         it { is_expected.to be_truthy } |         it { is_expected.to be_truthy } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report is invalid' do |       context 'and the report is invalid' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version |             'version' => report_version | ||||||
|  | @ -118,7 +122,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) |         stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report passes schema validation' do |       context 'and the report passes schema validation' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => '10.0.0', |             'version' => '10.0.0', | ||||||
|  | @ -143,34 +147,14 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report does not pass schema validation' do |       context 'and the report does not pass schema validation' do | ||||||
|         context 'when enforce_security_report_validation is enabled' do |         let(:report_data) do | ||||||
|           before do |           { | ||||||
|             stub_feature_flags(enforce_security_report_validation: true) |             'version' => 'V2.7.0' | ||||||
|           end |           } | ||||||
| 
 |  | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => 'V2.7.0' |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_falsey } |  | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when enforce_security_report_validation is disabled' do |         it { is_expected.to be_falsey } | ||||||
|           before do |  | ||||||
|             stub_feature_flags(enforce_security_report_validation: false) |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => 'V2.7.0' |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_truthy } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -178,100 +162,67 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       let(:report_type) { :dast } |       let(:report_type) { :dast } | ||||||
|       let(:report_version) { "12.37.0" } |       let(:report_version) { "12.37.0" } | ||||||
| 
 | 
 | ||||||
|       context 'when enforce_security_report_validation is enabled' do |       context 'and the report is valid' do | ||||||
|         before do |         let(:report_data) do | ||||||
|           stub_feature_flags(enforce_security_report_validation: true) |           { | ||||||
|  |             'version' => report_version, | ||||||
|  |             'vulnerabilities' => [] | ||||||
|  |           } | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when the report is valid' do |         it { is_expected.to be_falsey } | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version, |  | ||||||
|               'vulnerabilities' => [] |  | ||||||
|             } |  | ||||||
|           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: 'using_unsupported_schema_version', | ||||||
|  |             security_report_scanner_id: 'gemnasium', | ||||||
|  |             security_report_scanner_version: '2.1.0' | ||||||
|  |           ) | ||||||
|  | 
 | ||||||
|  |           subject | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       context 'and the report is invalid' do | ||||||
|  |         let(:report_data) do | ||||||
|  |           { | ||||||
|  |             'version' => report_version | ||||||
|  |           } | ||||||
|  |         end | ||||||
|  | 
 | ||||||
|  |         context 'and scanner information is empty' do | ||||||
|  |           let(:scanner) { {} } | ||||||
| 
 | 
 | ||||||
|           it '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: 'schema_validation_fails', | ||||||
|  |               security_report_scanner_id: nil, | ||||||
|  |               security_report_scanner_version: nil | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|             expect(Gitlab::AppLogger).to receive(:info).with( |             expect(Gitlab::AppLogger).to receive(:info).with( | ||||||
|               message: "security report schema validation problem", |               message: "security report schema validation problem", | ||||||
|               security_report_type: report_type, |               security_report_type: report_type, | ||||||
|               security_report_version: report_version, |               security_report_version: report_version, | ||||||
|               project_id: project.id, |               project_id: project.id, | ||||||
|               security_report_failure: 'using_unsupported_schema_version', |               security_report_failure: 'using_unsupported_schema_version', | ||||||
|               security_report_scanner_id: 'gemnasium', |               security_report_scanner_id: nil, | ||||||
|               security_report_scanner_version: '2.1.0' |               security_report_scanner_version: nil | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|             subject |             subject | ||||||
|           end |           end | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when the report is invalid' do |         it { is_expected.to be_falsey } | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           context 'when scanner information is empty' do |  | ||||||
|             let(:scanner) { {} } |  | ||||||
| 
 |  | ||||||
|             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: nil, |  | ||||||
|                 security_report_scanner_version: nil |  | ||||||
|               ) |  | ||||||
| 
 |  | ||||||
|               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: nil, |  | ||||||
|                 security_report_scanner_version: nil |  | ||||||
|               ) |  | ||||||
| 
 |  | ||||||
|               subject |  | ||||||
|             end |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_falsey } |  | ||||||
|         end |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       context 'when enforce_security_report_validation is disabled' do |  | ||||||
|         before do |  | ||||||
|           stub_feature_flags(enforce_security_report_validation: false) |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         context 'when the report is valid' do |  | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version, |  | ||||||
|               'vulnerabilities' => [] |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_truthy } |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         context 'when the report is invalid' do |  | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_truthy } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -284,19 +235,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         } |         } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       before do |  | ||||||
|         stub_feature_flags(enforce_security_report_validation: true) |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       it { is_expected.to be_falsey } |       it { is_expected.to be_falsey } | ||||||
| 
 |  | ||||||
|       context 'when enforce_security_report_validation is disabled' do |  | ||||||
|         before do |  | ||||||
|           stub_feature_flags(enforce_security_report_validation: false) |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         it { is_expected.to be_truthy } |  | ||||||
|       end |  | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  | @ -307,7 +246,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       let(:report_type) { :dast } |       let(:report_type) { :dast } | ||||||
|       let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } |       let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } | ||||||
| 
 | 
 | ||||||
|       context 'when the report is valid' do |       context 'and the report is valid' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version, |             'version' => report_version, | ||||||
|  | @ -318,34 +257,20 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         it { is_expected.to be_empty } |         it { is_expected.to be_empty } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report is invalid' do |       context 'and the report is invalid' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version |             'version' => report_version | ||||||
|           } |           } | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when enforce_security_report_validation is enabled' do |         let(:expected_errors) do | ||||||
|           before do |           [ | ||||||
|             stub_feature_flags(enforce_security_report_validation: project) |             'root is missing required keys: vulnerabilities' | ||||||
|           end |           ] | ||||||
| 
 |  | ||||||
|           let(:expected_errors) do |  | ||||||
|             [ |  | ||||||
|               'root is missing required keys: vulnerabilities' |  | ||||||
|             ] |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to match_array(expected_errors) } |  | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when enforce_security_report_validation is disabled' do |         it { is_expected.to match_array(expected_errors) } | ||||||
|           before do |  | ||||||
|             stub_feature_flags(enforce_security_report_validation: false) |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_empty } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -363,7 +288,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) |         stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report passes schema validation' do |       context 'and the report passes schema validation' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => '10.0.0', |             'version' => '10.0.0', | ||||||
|  | @ -374,41 +299,21 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         it { is_expected.to be_empty } |         it { is_expected.to be_empty } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report does not pass schema validation' do |       context 'and the report does not pass schema validation' do | ||||||
|         context 'when enforce_security_report_validation is enabled' do |         let(:report_data) do | ||||||
|           before do |           { | ||||||
|             stub_feature_flags(enforce_security_report_validation: true) |             'version' => 'V2.7.0' | ||||||
|           end |           } | ||||||
| 
 |  | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => 'V2.7.0' |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           let(:expected_errors) do |  | ||||||
|             [ |  | ||||||
|               "property '/version' does not match pattern: ^[0-9]+\\.[0-9]+\\.[0-9]+$", |  | ||||||
|               "root is missing required keys: vulnerabilities" |  | ||||||
|             ] |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to match_array(expected_errors) } |  | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when enforce_security_report_validation is disabled' do |         let(:expected_errors) do | ||||||
|           before do |           [ | ||||||
|             stub_feature_flags(enforce_security_report_validation: false) |             "property '/version' does not match pattern: ^[0-9]+\\.[0-9]+\\.[0-9]+$", | ||||||
|           end |             "root is missing required keys: vulnerabilities" | ||||||
| 
 |           ] | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => 'V2.7.0' |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_empty } |  | ||||||
|         end |         end | ||||||
|  | 
 | ||||||
|  |         it { is_expected.to match_array(expected_errors) } | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -416,71 +321,38 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       let(:report_type) { :dast } |       let(:report_type) { :dast } | ||||||
|       let(:report_version) { "12.37.0" } |       let(:report_version) { "12.37.0" } | ||||||
| 
 | 
 | ||||||
|       context 'when enforce_security_report_validation is enabled' do |       context 'and the report is valid' do | ||||||
|         before do |         let(:report_data) do | ||||||
|           stub_feature_flags(enforce_security_report_validation: true) |           { | ||||||
|  |             'version' => report_version, | ||||||
|  |             'vulnerabilities' => [] | ||||||
|  |           } | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when the report is valid' do |         let(:expected_errors) do | ||||||
|           let(:report_data) do |           [ | ||||||
|             { |             "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}" | ||||||
|               'version' => report_version, |           ] | ||||||
|               'vulnerabilities' => [] |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           let(:expected_errors) do |  | ||||||
|             [ |  | ||||||
|               "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}" |  | ||||||
|             ] |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to match_array(expected_errors) } |  | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when the report is invalid' do |         it { is_expected.to match_array(expected_errors) } | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           let(:expected_errors) do |  | ||||||
|             [ |  | ||||||
|               "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}", |  | ||||||
|               "root is missing required keys: vulnerabilities" |  | ||||||
|             ] |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to match_array(expected_errors) } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when enforce_security_report_validation is disabled' do |       context 'and the report is invalid' do | ||||||
|         before do |         let(:report_data) do | ||||||
|           stub_feature_flags(enforce_security_report_validation: false) |           { | ||||||
|  |             'version' => report_version | ||||||
|  |           } | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when the report is valid' do |         let(:expected_errors) do | ||||||
|           let(:report_data) do |           [ | ||||||
|             { |             "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}", | ||||||
|               'version' => report_version, |             "root is missing required keys: vulnerabilities" | ||||||
|               'vulnerabilities' => [] |           ] | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_empty } |  | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when the report is invalid' do |         it { is_expected.to match_array(expected_errors) } | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_empty } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -501,14 +373,6 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       it { is_expected.to match_array(expected_errors) } |       it { is_expected.to match_array(expected_errors) } | ||||||
| 
 |  | ||||||
|       context 'when enforce_security_report_validation is disabled' do |  | ||||||
|         before do |  | ||||||
|           stub_feature_flags(enforce_security_report_validation: false) |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         it { is_expected.to be_empty } |  | ||||||
|       end |  | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  | @ -519,7 +383,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       let(:report_type) { :dast } |       let(:report_type) { :dast } | ||||||
|       let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } |       let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } | ||||||
| 
 | 
 | ||||||
|       context 'when the report is valid' do |       context 'and the report is valid' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version, |             'version' => report_version, | ||||||
|  | @ -530,7 +394,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         it { is_expected.to be_empty } |         it { is_expected.to be_empty } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report is invalid' do |       context 'and the report is invalid' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version |             'version' => report_version | ||||||
|  | @ -560,7 +424,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) |         stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report passes schema validation' do |       context 'and the report passes schema validation' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version, |             'version' => report_version, | ||||||
|  | @ -571,7 +435,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         it { is_expected.to match_array(expected_deprecation_warnings) } |         it { is_expected.to match_array(expected_deprecation_warnings) } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report does not pass schema validation' do |       context 'and the report does not pass schema validation' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => 'V2.7.0' |             'version' => 'V2.7.0' | ||||||
|  | @ -604,7 +468,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       let(:report_type) { :dast } |       let(:report_type) { :dast } | ||||||
|       let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } |       let(:report_version) { described_class::SUPPORTED_VERSIONS[report_type].last } | ||||||
| 
 | 
 | ||||||
|       context 'when the report is valid' do |       context 'and the report is valid' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version, |             'version' => report_version, | ||||||
|  | @ -615,34 +479,14 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         it { is_expected.to be_empty } |         it { is_expected.to be_empty } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report is invalid' do |       context 'and the report is invalid' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => report_version |             'version' => report_version | ||||||
|           } |           } | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when enforce_security_report_validation is enabled' do |         it { is_expected.to be_empty } | ||||||
|           before do |  | ||||||
|             stub_feature_flags(enforce_security_report_validation: project) |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_empty } |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         context 'when enforce_security_report_validation is disabled' do |  | ||||||
|           before do |  | ||||||
|             stub_feature_flags(enforce_security_report_validation: false) |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           let(:expected_warnings) do |  | ||||||
|             [ |  | ||||||
|               'root is missing required keys: vulnerabilities' |  | ||||||
|             ] |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to match_array(expected_warnings) } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -660,7 +504,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) |         stub_const("#{described_class}::DEPRECATED_VERSIONS", deprecations_hash) | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report passes schema validation' do |       context 'and the report passes schema validation' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'vulnerabilities' => [] |             'vulnerabilities' => [] | ||||||
|  | @ -670,35 +514,14 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|         it { is_expected.to be_empty } |         it { is_expected.to be_empty } | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when the report does not pass schema validation' do |       context 'and the report does not pass schema validation' do | ||||||
|         let(:report_data) do |         let(:report_data) do | ||||||
|           { |           { | ||||||
|             'version' => 'V2.7.0' |             'version' => 'V2.7.0' | ||||||
|           } |           } | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when enforce_security_report_validation is enabled' do |         it { is_expected.to be_empty } | ||||||
|           before do |  | ||||||
|             stub_feature_flags(enforce_security_report_validation: true) |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_empty } |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         context 'when enforce_security_report_validation is disabled' do |  | ||||||
|           before do |  | ||||||
|             stub_feature_flags(enforce_security_report_validation: false) |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           let(:expected_warnings) do |  | ||||||
|             [ |  | ||||||
|               "property '/version' does not match pattern: ^[0-9]+\\.[0-9]+\\.[0-9]+$", |  | ||||||
|               "root is missing required keys: vulnerabilities" |  | ||||||
|             ] |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to match_array(expected_warnings) } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -706,71 +529,25 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       let(:report_type) { :dast } |       let(:report_type) { :dast } | ||||||
|       let(:report_version) { "12.37.0" } |       let(:report_version) { "12.37.0" } | ||||||
| 
 | 
 | ||||||
|       context 'when enforce_security_report_validation is enabled' do |       context 'and the report is valid' do | ||||||
|         before do |         let(:report_data) do | ||||||
|           stub_feature_flags(enforce_security_report_validation: true) |           { | ||||||
|  |             'version' => report_version, | ||||||
|  |             'vulnerabilities' => [] | ||||||
|  |           } | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when the report is valid' do |         it { is_expected.to be_empty } | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version, |  | ||||||
|               'vulnerabilities' => [] |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_empty } |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         context 'when the report is invalid' do |  | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to be_empty } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'when enforce_security_report_validation is disabled' do |       context 'and the report is invalid' do | ||||||
|         before do |         let(:report_data) do | ||||||
|           stub_feature_flags(enforce_security_report_validation: false) |           { | ||||||
|  |             'version' => report_version | ||||||
|  |           } | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         context 'when the report is valid' do |         it { is_expected.to be_empty } | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version, |  | ||||||
|               'vulnerabilities' => [] |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           let(:expected_warnings) do |  | ||||||
|             [ |  | ||||||
|               "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}" |  | ||||||
|             ] |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to match_array(expected_warnings) } |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         context 'when the report is invalid' do |  | ||||||
|           let(:report_data) do |  | ||||||
|             { |  | ||||||
|               'version' => report_version |  | ||||||
|             } |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           let(:expected_warnings) do |  | ||||||
|             [ |  | ||||||
|               "Version 12.37.0 for report type dast is unsupported, supported versions for this report type are: #{supported_dast_versions}", |  | ||||||
|               "root is missing required keys: vulnerabilities" |  | ||||||
|             ] |  | ||||||
|           end |  | ||||||
| 
 |  | ||||||
|           it { is_expected.to match_array(expected_warnings) } |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -784,21 +561,6 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       it { is_expected.to be_empty } |       it { is_expected.to be_empty } | ||||||
| 
 |  | ||||||
|       context 'when enforce_security_report_validation is disabled' do |  | ||||||
|         before do |  | ||||||
|           stub_feature_flags(enforce_security_report_validation: false) |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         let(:expected_warnings) do |  | ||||||
|           [ |  | ||||||
|             "root is missing required keys: version", |  | ||||||
|             "Report version not provided, dast report type supports versions: #{supported_dast_versions}" |  | ||||||
|           ] |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         it { is_expected.to match_array(expected_warnings) } |  | ||||||
|       end |  | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue