Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/observability/components/observability_app.vue13
-rw-r--r--app/assets/javascripts/reports/codequality_report/constants.js7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js6
-rw-r--r--app/assets/javascripts/vue_shared/constants.js4
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb6
-rw-r--r--app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml61
-rw-r--r--app/views/projects/pipeline_schedules/_table.html.haml20
-rw-r--r--app/views/projects/runners/_shared_runners.html.haml6
-rw-r--r--config/feature_flags/development/indifferent_wal_location_keys.yml8
-rw-r--r--config/open_api.yml2
-rw-r--r--data/removals/15_6/15-6-nfs-git-repository-storage.yml29
-rw-r--r--doc/administration/audit_events.md13
-rw-r--r--doc/administration/auth/ldap/ldap-troubleshooting.md32
-rw-r--r--doc/ci/environments/deployment_approvals.md25
-rw-r--r--doc/development/documentation/site_architecture/deployment_process.md29
-rw-r--r--doc/update/removals.md17
-rw-r--r--doc/user/application_security/dast/proxy-based.md106
-rw-r--r--lib/api/api.rb2
-rw-r--r--lib/api/rubygem_packages.rb46
-rw-r--r--lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb8
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb101
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb15
-rw-r--r--spec/features/runners_spec.rb20
-rw-r--r--spec/frontend/observability/observability_app_spec.js36
-rw-r--r--spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb22
25 files changed, 338 insertions, 296 deletions
diff --git a/app/assets/javascripts/observability/components/observability_app.vue b/app/assets/javascripts/observability/components/observability_app.vue
index 4f5e27be46f..173de7d82fe 100644
--- a/app/assets/javascripts/observability/components/observability_app.vue
+++ b/app/assets/javascripts/observability/components/observability_app.vue
@@ -1,4 +1,7 @@
<script>
+import { darkModeEnabled } from '~/lib/utils/color_utils';
+import { setUrlParams } from '~/lib/utils/url_utility';
+
export default {
props: {
observabilityIframeSrc: {
@@ -6,6 +9,14 @@ export default {
required: true,
},
},
+ computed: {
+ iframeSrcWithParams() {
+ return setUrlParams(
+ { theme: darkModeEnabled() ? 'dark' : 'light', username: gon?.current_username },
+ this.observabilityIframeSrc,
+ );
+ },
+ },
mounted() {
window.addEventListener('message', this.messageHandler);
},
@@ -37,6 +48,6 @@ export default {
data-testid="observability-ui-iframe"
frameborder="0"
height="100%"
- :src="observabilityIframeSrc"
+ :src="iframeSrcWithParams"
></iframe>
</template>
diff --git a/app/assets/javascripts/reports/codequality_report/constants.js b/app/assets/javascripts/reports/codequality_report/constants.js
index 8a556381224..5e81245037f 100644
--- a/app/assets/javascripts/reports/codequality_report/constants.js
+++ b/app/assets/javascripts/reports/codequality_report/constants.js
@@ -16,12 +16,7 @@ export const SEVERITY_ICONS = {
unknown: 'severity-unknown',
};
-// This is the icons mapping for the code Quality Merge-Request Widget Extension
-// once the refactor_mr_widgets_extensions flag is activated the above SEVERITY_ICONS
-// need be removed and this variable needs to be rename to SEVERITY_ICONS
-// Rollout Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/341759
-
-export const SEVERITY_ICONS_EXTENSION = {
+export const SEVERITY_ICONS_MR_WIDGET = {
info: 'severityInfo',
minor: 'severityLow',
major: 'severityMedium',
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js
index 68347ac269e..75da975bba0 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js
@@ -1,7 +1,7 @@
import { n__, s__, sprintf } from '~/locale';
import axios from '~/lib/utils/axios_utils';
import { EXTENSION_ICONS } from '~/vue_merge_request_widget/constants';
-import { SEVERITY_ICONS_EXTENSION } from '~/reports/codequality_report/constants';
+import { SEVERITY_ICONS_MR_WIDGET } from '~/reports/codequality_report/constants';
import { parseCodeclimateMetrics } from '~/reports/codequality_report/store/utils/codequality_parser';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
@@ -86,7 +86,7 @@ export default {
href: e.urlPath,
},
icon: {
- name: SEVERITY_ICONS_EXTENSION[e.severity],
+ name: SEVERITY_ICONS_MR_WIDGET[e.severity],
},
});
});
@@ -100,7 +100,7 @@ export default {
href: e.urlPath,
},
icon: {
- name: SEVERITY_ICONS_EXTENSION[e.severity],
+ name: SEVERITY_ICONS_MR_WIDGET[e.severity],
},
});
});
diff --git a/app/assets/javascripts/vue_shared/constants.js b/app/assets/javascripts/vue_shared/constants.js
index a851f84ed2f..2f85a29fb84 100644
--- a/app/assets/javascripts/vue_shared/constants.js
+++ b/app/assets/javascripts/vue_shared/constants.js
@@ -13,7 +13,9 @@ export const SHORT_DATE_FORMAT = 'd mmm, yyyy';
export const ISO_SHORT_FORMAT = 'yyyy-mm-dd';
-export const DATE_FORMATS = [SHORT_DATE_FORMAT, ISO_SHORT_FORMAT];
+export const LONG_DATE_FORMAT_WITH_TZ = 'yyyy-mm-dd HH:MM:ss Z';
+
+export const DATE_FORMATS = [SHORT_DATE_FORMAT, ISO_SHORT_FORMAT, LONG_DATE_FORMAT_WITH_TZ];
const getTimeLabel = (days) => n__('1 day', '%d days', days);
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index 8aef1c3d24d..1c3008181b2 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -122,9 +122,9 @@ module Projects
.page(params[:specific_page]).per(NUMBER_OF_RUNNERS_PER_PAGE)
.with_tags
- @shared_runners = ::Ci::Runner.instance_type.active.with_tags
-
- @shared_runners_count = @shared_runners.count(:all)
+ active_shared_runners = ::Ci::Runner.instance_type.active
+ @shared_runners_count = active_shared_runners.count(:all)
+ @shared_runners = active_shared_runners.page(params[:shared_runners_page]).per(NUMBER_OF_RUNNERS_PER_PAGE).with_tags
@group_runners = ::Ci::Runner.belonging_to_parent_group_of_project(@project.id).with_tags
end
diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
index 7b16564dfa2..9dc12a2ca41 100644
--- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
+++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
@@ -1,33 +1,38 @@
- if pipeline_schedule
%tr.pipeline-schedule-table-row
- %td
- = pipeline_schedule.description
- %td.branch-name-cell.gl-text-truncate
- - if pipeline_schedule.for_tag?
- = sprite_icon('tag', size: 12, css_class: 'gl-vertical-align-middle!' )
- - else
- = sprite_icon('fork', size: 12, css_class: 'gl-vertical-align-middle!')
- - if pipeline_schedule.ref.present?
- = link_to pipeline_schedule.ref_for_display, project_ref_path(@project, pipeline_schedule.ref_for_display), class: "ref-name"
- %td
- - if pipeline_schedule.last_pipeline
- .status-icon-container{ class: "ci-status-icon-#{pipeline_schedule.last_pipeline.status}" }
- = link_to project_pipeline_path(@project, pipeline_schedule.last_pipeline.id) do
- = ci_icon_for_status(pipeline_schedule.last_pipeline.status)
- %span ##{pipeline_schedule.last_pipeline.id}
- - else
- = s_("PipelineSchedules|None")
- %td.gl-text-gray-500{ 'data-testid': 'next-run-cell' }
- - if pipeline_schedule.active? && pipeline_schedule.next_run_at
- = time_ago_with_tooltip(pipeline_schedule.real_next_run)
- - else
- = s_("PipelineSchedules|Inactive")
- %td
- - if pipeline_schedule.owner
- = render Pajamas::AvatarComponent.new(pipeline_schedule.owner, size: 24, class: "gl-mr-2")
- = link_to user_path(pipeline_schedule.owner) do
- = pipeline_schedule.owner&.name
- %td
+ %td{ role: 'cell', data: { label: _('Description') } }
+ %div
+ = pipeline_schedule.description
+ %td.branch-name-cell.gl-text-truncate{ role: 'cell', data: { label: s_("PipelineSchedules|Target") } }
+ %div
+ - if pipeline_schedule.for_tag?
+ = sprite_icon('tag', size: 12, css_class: 'gl-vertical-align-middle!' )
+ - else
+ = sprite_icon('fork', size: 12, css_class: 'gl-vertical-align-middle!')
+ - if pipeline_schedule.ref.present?
+ = link_to pipeline_schedule.ref_for_display, project_ref_path(@project, pipeline_schedule.ref_for_display), class: "ref-name"
+ %td{ role: 'cell', data: { label: _("Last Pipeline") } }
+ %div
+ - if pipeline_schedule.last_pipeline
+ .status-icon-container{ class: "ci-status-icon-#{pipeline_schedule.last_pipeline.status}" }
+ = link_to project_pipeline_path(@project, pipeline_schedule.last_pipeline.id) do
+ = ci_icon_for_status(pipeline_schedule.last_pipeline.status)
+ %span.gl-text-blue-500! ##{pipeline_schedule.last_pipeline.id}
+ - else
+ = s_("PipelineSchedules|None")
+ %td.gl-text-gray-500{ role: 'cell', data: { label: s_("PipelineSchedules|Next Run") }, 'data-testid': 'next-run-cell' }
+ %div
+ - if pipeline_schedule.active? && pipeline_schedule.next_run_at
+ = time_ago_with_tooltip(pipeline_schedule.real_next_run)
+ - else
+ = s_("PipelineSchedules|Inactive")
+ %td{ role: 'cell', data: { label: _("Owner") } }
+ %div
+ - if pipeline_schedule.owner
+ = render Pajamas::AvatarComponent.new(pipeline_schedule.owner, size: 24, class: "gl-mr-2")
+ = link_to user_path(pipeline_schedule.owner) do
+ = pipeline_schedule.owner&.name
+ %td{ role: 'cell', data: { label: _('Actions') } }
.float-right.btn-group
- if can?(current_user, :play_pipeline_schedule, pipeline_schedule)
= link_to play_pipeline_schedule_path(pipeline_schedule), method: :post, title: _('Play'), class: 'btn gl-button btn-default btn-icon' do
diff --git a/app/views/projects/pipeline_schedules/_table.html.haml b/app/views/projects/pipeline_schedules/_table.html.haml
index d0c7ea77263..2f96ac6a534 100644
--- a/app/views/projects/pipeline_schedules/_table.html.haml
+++ b/app/views/projects/pipeline_schedules/_table.html.haml
@@ -1,12 +1,12 @@
.table-holder
- %table.table.ci-table
- %thead
- %tr
- %th= _("Description")
- %th= s_("PipelineSchedules|Target")
- %th= _("Last Pipeline")
- %th= s_("PipelineSchedules|Next Run")
- %th= _("Owner")
- %th
-
+ %table.table.ci-table.responsive-table.b-table.gl-table.b-table-stacked-md{ role: 'table' }
+ %thead{ role: 'rowgroup' }
+ %tr{ role: 'row' }
+ %th.table-th-transparent.border-bottom{ role: 'cell', style: 'width: 34%' }= _("Description")
+ %th.table-th-transparent.border-bottom{ role: 'cell' }= s_("PipelineSchedules|Target")
+ %th.table-th-transparent.border-bottom{ role: 'cell' }= _("Last Pipeline")
+ %th.table-th-transparent.border-bottom{ role: 'cell' }= s_("PipelineSchedules|Next Run")
+ %th.table-th-transparent.border-bottom{ role: 'cell' }= _("Owner")
+ %th.table-th-transparent.border-bottom{ role: 'cell' }
+ %tbody{ role: 'rowgroup' }
= render partial: "pipeline_schedule", collection: @schedules
diff --git a/app/views/projects/runners/_shared_runners.html.haml b/app/views/projects/runners/_shared_runners.html.haml
index 4689e70d907..8b18a6a9c05 100644
--- a/app/views/projects/runners/_shared_runners.html.haml
+++ b/app/views/projects/runners/_shared_runners.html.haml
@@ -6,5 +6,7 @@
= _('This GitLab instance does not provide any shared runners yet. Instance administrators can register shared runners in the admin area.')
- else
%h5.gl-mt-6.gl-mb-0 #{_('Available shared runners:')} #{@shared_runners_count}
- %ul.bordered-list.available-shared-runners
- = render partial: 'projects/runners/runner', collection: @shared_runners, as: :runner
+ %div{ data: { testid: 'available-shared-runners' } }
+ %ul.bordered-list
+ = render partial: 'projects/runners/runner', collection: @shared_runners, as: :runner
+ = paginate @shared_runners, theme: "gitlab", param_name: "shared_runners_page", params: { expand_runners: true, anchor: 'js-runners-settings' }
diff --git a/config/feature_flags/development/indifferent_wal_location_keys.yml b/config/feature_flags/development/indifferent_wal_location_keys.yml
deleted file mode 100644
index 2d89ad82085..00000000000
--- a/config/feature_flags/development/indifferent_wal_location_keys.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: indifferent_wal_location_keys
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101096
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/377989
-milestone: '15.5'
-type: development
-group: group::source code
-default_enabled: false
diff --git a/config/open_api.yml b/config/open_api.yml
index 9fceb1f0596..66a08621538 100644
--- a/config/open_api.yml
+++ b/config/open_api.yml
@@ -103,6 +103,8 @@ metadata:
description: Operations related to releases
- name: resource_milestone_events
description: Operations about resource milestone events
+ - name: rubygem_packages
+ description: Operations related to RubyGems
- name: suggestions
description: Operations related to suggestions
- name: system_hooks
diff --git a/data/removals/15_6/15-6-nfs-git-repository-storage.yml b/data/removals/15_6/15-6-nfs-git-repository-storage.yml
new file mode 100644
index 00000000000..fabfa2629eb
--- /dev/null
+++ b/data/removals/15_6/15-6-nfs-git-repository-storage.yml
@@ -0,0 +1,29 @@
+- title: "NFS as Git repository storage is no longer supported. Migrate to Gitaly Cluster as soon as possible" # (required) Actionable title. e.g., The `confidential` field for a `Note` is deprecated. Use `internal` instead.
+ announcement_milestone: "14.0" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-06-22" # The date of the milestone release when this feature was first announced as deprecated
+ removal_milestone: "15.6" # The milestone when this feature is planned to be removed
+ removal_date: "2022-11-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
+ breaking_change: false # (required) Change to true if this removal is a breaking change.
+ reporter: mjwood # (required) GitLab username of the person reporting the removal
+ stage: create # (required) String value of the stage that the feature was created in. e.g., Growth
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351243
+ body: | # (required) Do not modify this line, instead modify the lines below.
+ As of November 22, 2022, we are removing support for customers utilizing NFS for Git repository storage. This was originally planned for May 22, 2022, but in an effort to allow continued maturity of Gitaly Cluster, we chose to extend our removal of support date until now. Please see our official [Statement of Support](https://about.gitlab.com/support/statement-of-support/#gitaly-and-nfs) for further information.
+
+ This change in support follows the development deprecation for NFS for Git repository storage that occurred in GitLab 14.0.
+
+ Gitaly Cluster offers tremendous benefits for our customers such as:
+
+ - [Variable replication factors](https://docs.gitlab.com/ee/administration/gitaly/index.html#replication-factor).
+ - [Strong consistency](https://docs.gitlab.com/ee/administration/gitaly/index.html#strong-consistency).
+ - [Distributed read capabilities](https://docs.gitlab.com/ee/administration/gitaly/index.html#distributed-reads).
+
+ We encourage customers currently using NFS for Git repositories to migrate as soon as possible by reviewing our documentation on
+ [migrating to Gitaly Cluster](https://docs.gitlab.com/ee/administration/gitaly/index.html#migrate-to-gitaly-cluster).
+#
+# OPTIONAL FIELDS
+#
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md
index d10c1616eaf..9f00a46dbb6 100644
--- a/doc/administration/audit_events.md
+++ b/doc/administration/audit_events.md
@@ -58,6 +58,17 @@ To view instance audit events:
1. On the top bar, select **Main menu > Admin**.
1. On the left sidebar, select **Monitoring > Audit Events**.
+## Time zones
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/242014) in GitLab 15.7, GitLab UI shows dates and times in the user's local time zone instead of UTC.
+
+The time zone used for audit events depends on where you view them:
+
+- In GitLab UI, your local time zone (GitLab 15.6 and later) or UTC (GitLab 15.5 and earlier) is used.
+- The [Audit Events API](../api/audit_events.md) returns dates and times in UTC by default, or the [configured time zone](timezone.md) on a self-managed GitLab instance.
+- In `audit_json.log`, UTC is used.
+- In CSV exports, UTC is used.
+
## List of events
You can view different events depending on the version of GitLab you have.
@@ -315,7 +326,7 @@ The first row contains the headers, which are listed in the following table alon
| Target Details | Details of the target |
| Action | Description of the action |
| IP Address | IP address of the author who performed the action |
-| Created At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
+| Created At (UTC) | Date (in ISO 8601 format) that the audit event was created. |
### Limitation
diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md
index 499c3c64af7..15ce3c595c5 100644
--- a/doc/administration/auth/ldap/ldap-troubleshooting.md
+++ b/doc/administration/auth/ldap/ldap-troubleshooting.md
@@ -831,6 +831,38 @@ ldapsearch -D "cn=admin,dc=ldap-testing,dc=example,dc=com" \
The `bind_dn`, `password`, `port`, `host`, and `base` are all
identical to what's configured in the `gitlab.rb`.
+#### Use ldapsearch with `start_tls` encryption
+
+The previous example performs an LDAP test in plaintext to port 389. If you are using [`start_tls` encryption](index.md#basic-configuration-settings), in
+the `ldapsearch` command include:
+
+- The `-Z` flag.
+- The FQDN of the LDAP server.
+
+You must include these because, during TLS negotiation, the FQDN of the LDAP server is evaluated against its certificate:
+
+```shell
+ldapsearch -D "cn=admin,dc=ldap-testing,dc=example,dc=com" \
+ -w Password1 \
+ -p 389 \
+ -h "testing.ldap.com" \
+ -b "dc=ldap-testing,dc=example,dc=com" -Z
+```
+
+#### Use ldapsearch with `simple_tls` encryption
+
+If you are using [`simple_tls` encryption](index.md#basic-configuration-settings) (usually on port 636), include the following in the `ldapsearch` command:
+
+- The LDAP server FQDN with the `-H` flag and the port.
+- The full constructed URI.
+
+```shell
+ldapsearch -D "cn=admin,dc=ldap-testing,dc=example,dc=com" \
+ -w Password1 \
+ -H "ldaps://testing.ldap.com:636" \
+ -b "dc=ldap-testing,dc=example,dc=com"
+```
+
For more information, see the [official `ldapsearch` documentation](https://linux.die.net/man/1/ldapsearch).
### Using **AdFind** (Windows)
diff --git a/doc/ci/environments/deployment_approvals.md b/doc/ci/environments/deployment_approvals.md
index d7fa31b583b..a4815a85bc1 100644
--- a/doc/ci/environments/deployment_approvals.md
+++ b/doc/ci/environments/deployment_approvals.md
@@ -134,6 +134,8 @@ To approve or reject a deployment to a protected environment using the UI:
1. On the left sidebar, select **Deployments > Environments**.
1. Select the environment's name.
1. In the deployment's row, select **Approval options** (**{thumb-up}**).
+ Before approving or rejecting the deployment, you can view the number of approvals granted and
+ remaining, also who has approved or rejected it.
1. Optional. Add a comment which describes your reason for approving or rejecting the deployment.
1. Select **Approve** or **Reject**.
@@ -154,6 +156,29 @@ curl --data "status=approved&comment=Looks good to me" \
--header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/1/approval"
```
+### View the approval details of a deployment
+
+Prerequisites:
+
+- Permission to deploy to the protected environment.
+
+A deployment to a protected environment can only proceed after all required approvals have been
+granted.
+
+To view the approval details of a deployment:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. On the left sidebar, select **Deployments > Environments**.
+1. Select the environment's name.
+1. In the deployment's row, select **Approval options** (**{thumb-up}**).
+
+The approval status details are shown:
+
+- Eligible approvers
+- Number of approvals granted, and number of approvals required
+- Users who have granted approval
+- History of approvals or rejections
+
## How to see blocked deployments
### Using the UI
diff --git a/doc/development/documentation/site_architecture/deployment_process.md b/doc/development/documentation/site_architecture/deployment_process.md
index 18cc27adaaa..2ba69ca0987 100644
--- a/doc/development/documentation/site_architecture/deployment_process.md
+++ b/doc/development/documentation/site_architecture/deployment_process.md
@@ -167,30 +167,5 @@ If you do not have the Maintainer role to perform this task, ask for help in the
## Docker files
-The [`dockerfiles` directory](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/dockerfiles/) contains all needed
-Dockerfiles to build and deploy <https://docs.gitlab.com>. It is heavily inspired by Docker's
-[Dockerfile](https://github.com/docker/docker.github.io/blob/06ed03db13895bfe867761b6fc2ad40acf6026dd/Dockerfile).
-
-| Dockerfile | Docker image | Description |
-|:---------------------------------------------------------------------------------------------------------------------------|:------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| [`bootstrap.Dockerfile`](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/dockerfiles/bootstrap.Dockerfile) | `gitlab-docs:bootstrap` | Contains all the dependencies that are needed to build the website. If the gems are updated and `Gemfile{,.lock}` changes, the image must be rebuilt. |
-| [`builder.onbuild.Dockerfile`](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/dockerfiles/builder.onbuild.Dockerfile) | `gitlab-docs:builder-onbuild` | Base image to build the docs website. It uses `ONBUILD` to perform all steps and depends on `gitlab-docs:bootstrap`. |
-| [`nginx.onbuild.Dockerfile`](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/dockerfiles/nginx.onbuild.Dockerfile) | `gitlab-docs:nginx-onbuild` | Base image to use for building documentation archives. It uses `ONBUILD` to perform all required steps to copy the archive, and relies upon its parent `Dockerfile.builder.onbuild` that is invoked when building single documentation archives (see the `Dockerfile` of each branch) |
-| [`archives.Dockerfile`](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/dockerfiles/archives.Dockerfile) | `gitlab-docs:archives` | Contains all the versions of the website in one archive. It copies all generated HTML files from every version in one location. |
-
-### How to build the images
-
-Although build images are built automatically via GitLab CI/CD, you can build and tag all tooling images locally:
-
-1. Make sure you have [Docker installed](https://docs.docker.com/get-docker/).
-1. Make sure you're in the `dockerfiles/` directory of the `gitlab-docs` repository.
-1. Build the images:
-
- ```shell
- docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:bootstrap -f Dockerfile.bootstrap ../
- docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:builder-onbuild -f Dockerfile.builder.onbuild ../
- docker build -t registry.gitlab.com/gitlab-org/gitlab-docs:nginx-onbuild -f Dockerfile.nginx.onbuild ../
- ```
-
-For each image, there's a manual job under the `images` stage in
-[`.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/.gitlab-ci.yml) which can be invoked at any time.
+The [`dockerfiles` directory](https://gitlab.com/gitlab-org/gitlab-docs/-/tree/main/dockerfiles) contains Dockerfiles needed
+to build, test, and deploy <https://docs.gitlab.com>.
diff --git a/doc/update/removals.md b/doc/update/removals.md
index a1cb9305441..34f60dec249 100644
--- a/doc/update/removals.md
+++ b/doc/update/removals.md
@@ -46,6 +46,23 @@ To change the approvals required for a merge request, you should no longer use t
Instead, use the [`/approval_rules` endpoint](https://docs.gitlab.com/ee/api/merge_request_approvals.html#merge-request-level-mr-approvals) to [create](https://docs.gitlab.com/ee/api/merge_request_approvals.html#create-merge-request-level-rule) or [update](https://docs.gitlab.com/ee/api/merge_request_approvals.html#update-merge-request-level-rule) the approval rules for a merge request.
+## Removed in 15.6
+
+### NFS as Git repository storage is no longer supported. Migrate to Gitaly Cluster as soon as possible
+
+As of November 22, 2022, we are removing support for customers utilizing NFS for Git repository storage. This was originally planned for May 22, 2022, but in an effort to allow continued maturity of Gitaly Cluster, we chose to extend our removal of support date until now. Please see our official [Statement of Support](https://about.gitlab.com/support/statement-of-support/#gitaly-and-nfs) for further information.
+
+This change in support follows the development deprecation for NFS for Git repository storage that occurred in GitLab 14.0.
+
+Gitaly Cluster offers tremendous benefits for our customers such as:
+
+- [Variable replication factors](https://docs.gitlab.com/ee/administration/gitaly/index.html#replication-factor).
+- [Strong consistency](https://docs.gitlab.com/ee/administration/gitaly/index.html#strong-consistency).
+- [Distributed read capabilities](https://docs.gitlab.com/ee/administration/gitaly/index.html#distributed-reads).
+
+We encourage customers currently using NFS for Git repositories to migrate as soon as possible by reviewing our documentation on
+[migrating to Gitaly Cluster](https://docs.gitlab.com/ee/administration/gitaly/index.html#migrate-to-gitaly-cluster).
+
## Removed in 15.4
### SAST analyzer consolidation and CI/CD template changes
diff --git a/doc/user/application_security/dast/proxy-based.md b/doc/user/application_security/dast/proxy-based.md
index ec98b809fb7..ed6ee99aa52 100644
--- a/doc/user/application_security/dast/proxy-based.md
+++ b/doc/user/application_security/dast/proxy-based.md
@@ -175,95 +175,7 @@ When the snippet is committed to the `.gitlab-ci.yml` file, pipelines include a
### API scan
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10928) in GitLab 12.10.
-> - A new DAST API scanning engine was introduced in GitLab 13.10.
-
-Using an API specification as a scan's target is a useful way to seed URLs for scanning an API.
-Vulnerability rules in an API scan are different than those in a normal website scan.
-
-A new DAST API scanning engine is available in GitLab 13.12 and later. For more details, see [DAST API scanning engine](../dast_api). The new scanning engine supports REST, SOAP, GraphQL, and generic APIs using forms, XML, and JSON. Testing can be performed using OpenAPI, Postman Collections, and HTTP Archive (HAR) documents.
-
-The target API instance's base URL is provided by using the `DAST_API_TARGET_URL` variable or an `environment_url.txt` file.
-
-#### Specification format
-
-API scans support OpenAPI V2 and OpenAPI V3 specifications. You can define these specifications using `JSON` or `YAML`.
-
-#### Import API specification from a URL
-
-If your API specification is accessible at a URL, you can pass that URL in directly as the target.
-The specification does not have to be hosted on the same host as the API being tested.
-
-```yaml
-include:
- - template: DAST-API.gitlab-ci.yml
-
-variables:
- DAST_API_SPECIFICATION: http://my.api/api-specification.yml
-```
-
-#### Import API specification from a file
-
-If your API specification file is in your repository, you can provide its filename as the target.
-
-```yaml
-dast:
- variables:
- GIT_STRATEGY: fetch
- DAST_API_SPECIFICATION: api-specification.yml
-```
-
-#### Full API scan
-
-API scans support full scanning, which can be enabled by using the `DAST_FULL_SCAN_ENABLED`
-CI/CD variable. Domain validation is not supported for full API scans.
-
-#### Host override
-
-Specifications often define a host, which contains a domain name and a port. The
-host referenced may be different than the host of the API's review instance.
-This can cause incorrect URLs to be imported, or a scan on an incorrect host.
-Use the `DAST_API_HOST_OVERRIDE` CI/CD variable to override these values.
-
-WARNING:
-When using the API host override feature, you cannot use the `$DAST_WEBSITE` variable to override the hostname.
-A host override is _only_ supported when importing the API specification from a URL. Attempts to override the
-host throw an error when the API specification is imported from a file. This is due to a limitation in the
-ZAP OpenAPI extension.
-
-For example, with a OpenAPI V3 specification containing:
-
-```yaml
-servers:
- - url: https://api.host.com
-```
-
-If the test version of the API is running at `https://api-test.host.com`, then
-the following DAST configuration can be used:
-
-```yaml
-include:
- - template: DAST-API.gitlab-ci.yml
-
-variables:
- DAST_API_SPECIFICATION: http://api-test.host.com/api-specification.yml
- DAST_API_HOST_OVERRIDE: api-test.host.com
-```
-
-#### Authentication using headers
-
-Tokens in request headers are often used as a way to authenticate API requests.
-You can achieve this by using the `DAST_REQUEST_HEADERS` CI/CD variable.
-Headers are applied to every request DAST makes.
-
-```yaml
-include:
- - template: DAST-API.gitlab-ci.yml
-
-variables:
- DAST_API_SPECIFICATION: http://api-test.api.com/api-specification.yml
- DAST_REQUEST_HEADERS: "Authorization: Bearer my.token"
-```
+- The [DAST API analyzer](../dast_api/index.md) is used for scanning web APIs. Web API technologies such as GraphQL, REST, and SOAP are supported.
### URL scan
@@ -437,11 +349,11 @@ including a large number of false positives.
|:-------------------------------------------------|:--------------|:------------------------------|
| `DAST_ADVERTISE_SCAN` | boolean | Set to `true` to add a `Via` header to every request sent, advertising that the request was sent as part of a GitLab DAST scan. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/334947) in GitLab 14.1. |
| `DAST_AGGREGATE_VULNERABILITIES` | boolean | Vulnerability aggregation is set to `true` by default. To disable this feature and see each vulnerability individually set to `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/254043) in GitLab 14.0. |
-| `DAST_API_HOST_OVERRIDE` <sup>1</sup> | string | Used to override domains defined in API specification files. Only supported when importing the API specification from a URL. Example: `example.com:8080`. |
-| `DAST_API_SPECIFICATION` <sup>1</sup> | URL or string | The API specification to import. The specification can be hosted at a URL, or the name of a file present in the `/zap/wrk` directory. The variable `DAST_WEBSITE` must be specified if this is omitted. |
+| `DAST_API_HOST_OVERRIDE` <sup>1</sup> | string | **{warning}** **[Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/383467)** in GitLab 15.7. Replaced by [DAST API scan](../dast_api/index.md#available-cicd-variables). Used to override domains defined in API specification files. Only supported when importing the API specification from a URL. Example: `example.com:8080`. |
+| `DAST_API_SPECIFICATION` <sup>1</sup> | URL or string | **{warning}** **[Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/383467)** in GitLab 15.7. Replaced by [DAST API scan](../dast_api/index.md#available-cicd-variables). The API specification to import. The specification can be hosted at a URL, or the name of a file present in the `/zap/wrk` directory. The variable `DAST_WEBSITE` must be specified if this is omitted. |
| `DAST_AUTH_REPORT` <sup>2</sup> | boolean | Used in combination with exporting the `gl-dast-debug-auth-report.html` artifact to aid in debugging authentication issues. |
-| `DAST_AUTH_EXCLUDE_URLS` <sup>2</sup> | URLs | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/289959)** in GitLab 14.0. Replaced by `DAST_EXCLUDE_URLS`. The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. Not supported for API scans. |
-| `DAST_AUTH_URL` <sup>1,2</sup> | URL | The URL of the page containing the sign-in HTML form on the target website. `DAST_USERNAME` and `DAST_PASSWORD` are submitted with the login form to create an authenticated scan. Not supported for API scans. Example: `https://login.example.com`. |
+| `DAST_AUTH_EXCLUDE_URLS` <sup>2</sup> | URLs | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/289959)** in GitLab 14.0. Replaced by `DAST_EXCLUDE_URLS`. The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. |
+| `DAST_AUTH_URL` <sup>1,2</sup> | URL | The URL of the page containing the sign-in HTML form on the target website. `DAST_USERNAME` and `DAST_PASSWORD` are submitted with the login form to create an authenticated scan. Example: `https://login.example.com`. |
| `DAST_AUTH_VERIFICATION_LOGIN_FORM` <sup>2</sup> | boolean | Verifies successful authentication by checking for the lack of a login form once the login form has been submitted. |
| `DAST_AUTH_VERIFICATION_SELECTOR` <sup>2</sup> | selector | Verifies successful authentication by checking for presence of a selector once the login form has been submitted. Example: `css:.user-photo`. |
| `DAST_AUTH_VERIFICATION_URL` <sup>1,2</sup> | URL | A URL only accessible to logged in users that DAST can use to confirm successful authentication. If provided, DAST exits if it cannot access the URL. Example: `"http://example.com/loggedin_page"`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207335) in GitLab 13.8. |
@@ -449,9 +361,9 @@ including a large number of false positives.
| `DAST_BROWSER_PATH_TO_LOGIN_FORM` <sup>1,2</sup> | selector | Comma-separated list of selectors that are selected prior to attempting to enter `DAST_USERNAME` and `DAST_PASSWORD` into the login form. Example: `"css:.navigation-menu,css:.login-menu-item"`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326633) in GitLab 14.1. |
| `DAST_DEBUG` <sup>1</sup> | boolean | Enable debug message output. Default: `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
| `DAST_EXCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from running during the scan. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). For example, `HTTP Parameter Override` has a rule ID of `10026`. Cannot be used when `DAST_ONLY_INCLUDE_RULES` is set. **Note:** In earlier versions of GitLab the excluded rules were executed but vulnerabilities they generated were suppressed. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118641) in GitLab 12.10. |
-| `DAST_EXCLUDE_URLS` <sup>1,2</sup> | URLs | The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. Not supported for API scans. Example, `http://example.com/sign-out`. |
+| `DAST_EXCLUDE_URLS` <sup>1,2</sup> | URLs | The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. Example, `http://example.com/sign-out`. |
| `DAST_FIRST_SUBMIT_FIELD` <sup>2</sup> | string | The `id` or `name` of the element that when selected submits the username form of a multi-page login process. For example, `css:button[type='user-submit']`. [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/9894) in GitLab 12.4. |
-| `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | boolean | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/293595)** in GitLab 14.0. Set to `true` to require domain validation when running DAST full scans. Not supported for API scans. Default: `false` |
+| `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | boolean | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/293595)** in GitLab 14.0. Set to `true` to require domain validation when running DAST full scans. Default: `false` |
| `DAST_FULL_SCAN_ENABLED` <sup>1</sup> | boolean | Set to `true` to run a [ZAP Full Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Full-Scan) instead of a [ZAP Baseline Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan). Default: `false` |
| `DAST_HTML_REPORT` | string | The filename of the HTML report written at the end of a scan. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
| `DAST_INCLUDE_ALPHA_VULNERABILITIES` | boolean | Set to `true` to include alpha passive and active scan rules. Default: `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
@@ -475,7 +387,7 @@ including a large number of false positives.
| `DAST_USERNAME` <sup>1,2</sup> | string | The username to authenticate to in the website. Example: `admin` |
| `DAST_USERNAME_FIELD` <sup>1,2</sup> | string | The selector of username field at the sign-in HTML form. Example: `name:username` |
| `DAST_XML_REPORT` | string | The filename of the XML report written at the end of a scan. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
-| `DAST_WEBSITE` <sup>1</sup> | URL | The URL of the website to scan. The variable `DAST_API_SPECIFICATION` must be specified if this is omitted. |
+| `DAST_WEBSITE` <sup>1</sup> | URL | The URL of the website to scan. |
| `DAST_ZAP_CLI_OPTIONS` | string | ZAP server command-line options. For example, `-Xmx3072m` would set the Java maximum memory allocation pool size. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
| `DAST_ZAP_LOG_CONFIGURATION` | string | Set to a semicolon-separated list of additional log4j properties for the ZAP Server. Example: `logger.httpsender.name=org.parosproxy.paros.network.HttpSender;logger.httpsender.level=debug;logger.sitemap.name=org.parosproxy.paros.model.SiteMap;logger.sitemap.level=debug;` |
| `SECURE_ANALYZERS_PREFIX` | URL | Set the Docker registry base address from which to download the analyzer. |
@@ -987,7 +899,7 @@ A site profile contains:
- **Scan method**: A type of method to perform API testing. The supported methods are OpenAPI, Postman Collections, and HTTP Archive (HAR) documents.
- **File URL**: The URL of the OpenAPI, Postman Collection, or HTTP Archive file.
-When an API site type is selected, a [host override](#host-override) is used to ensure the API being scanned is on the same host as the target. This is done to reduce the risk of running an active scan against the wrong API.
+When an API site type is selected, a host override is used to ensure the API being scanned is on the same host as the target. This is done to reduce the risk of running an active scan against the wrong API.
When configured, request headers and password fields are encrypted using [`aes-256-gcm`](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) before being stored in the database.
This data can only be read and decrypted with a valid secrets file.
diff --git a/lib/api/api.rb b/lib/api/api.rb
index f69dfa9d444..318c3d4133b 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -254,6 +254,7 @@ module API
mount ::API::Repositories
mount ::API::ResourceAccessTokens
mount ::API::ResourceMilestoneEvents
+ mount ::API::RubygemPackages
mount ::API::Snippets
mount ::API::SnippetRepositoryStorageMoves
mount ::API::Statistics
@@ -320,7 +321,6 @@ module API
mount ::API::ResourceLabelEvents
mount ::API::ResourceStateEvents
mount ::API::RpmProjectPackages
- mount ::API::RubygemPackages
mount ::API::Search
mount ::API::Settings
mount ::API::SidekiqMetrics
diff --git a/lib/api/rubygem_packages.rb b/lib/api/rubygem_packages.rb
index 87cf1f66223..c2665c78c60 100644
--- a/lib/api/rubygem_packages.rb
+++ b/lib/api/rubygem_packages.rb
@@ -32,15 +32,20 @@ module API
end
params do
- requires :id, type: String, desc: 'The ID or full path of a project'
+ requires :id, type: [Integer, String], desc: 'The ID or full path of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
namespace ':id/packages/rubygems' do
desc 'Download the spec index file' do
detail 'This feature was introduced in GitLab 13.9'
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 404, message: 'Not Found' }
+ ]
+ tags %w[rubygem_packages]
end
params do
- requires :file_name, type: String, desc: 'Spec file name'
+ requires :file_name, type: String, desc: 'Spec file name', documentation: { type: 'file' }
end
get ":file_name", requirements: FILE_NAME_REQUIREMENTS do
# To be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/299267
@@ -49,9 +54,14 @@ module API
desc 'Download the gemspec file' do
detail 'This feature was introduced in GitLab 13.9'
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 404, message: 'Not Found' }
+ ]
+ tags %w[rubygem_packages]
end
params do
- requires :file_name, type: String, desc: 'Gemspec file name'
+ requires :file_name, type: String, desc: 'Gemspec file name', documentation: { type: 'file' }
end
get "quick/Marshal.#{MARSHAL_VERSION}/:file_name", requirements: FILE_NAME_REQUIREMENTS do
# To be implemented in https://gitlab.com/gitlab-org/gitlab/-/issues/299284
@@ -60,9 +70,16 @@ module API
desc 'Download the .gem package' do
detail 'This feature was introduced in GitLab 13.9'
+ success code: 200
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 403, message: 'Forbidden' },
+ { code: 404, message: 'Not Found' }
+ ]
+ tags %w[rubygem_packages]
end
params do
- requires :file_name, type: String, desc: 'Package file name'
+ requires :file_name, type: String, desc: 'Package file name', documentation: { type: 'file' }
end
get "gems/:file_name", requirements: FILE_NAME_REQUIREMENTS do
authorize_read_package!(user_project)
@@ -80,6 +97,12 @@ module API
namespace 'api/v1' do
desc 'Authorize a gem upload from workhorse' do
detail 'This feature was introduced in GitLab 13.9'
+ success code: 200
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 403, message: 'Forbidden' }
+ ]
+ tags %w[rubygem_packages]
end
post 'gems/authorize' do
authorize_workhorse!(
@@ -91,6 +114,13 @@ module API
desc 'Upload a gem' do
detail 'This feature was introduced in GitLab 13.9'
+ success code: 201
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 403, message: 'Forbidden' },
+ { code: 404, message: 'Not Found' }
+ ]
+ tags %w[rubygem_packages]
end
params do
requires :file, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)', documentation: { type: 'file' }
@@ -133,6 +163,14 @@ module API
desc 'Fetch a list of dependencies' do
detail 'This feature was introduced in GitLab 13.9'
+ success code: 200
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 403, message: 'Forbidden' },
+ { code: 404, message: 'Not Found' }
+ ]
+ is_array true
+ tags %w[rubygem_packages]
end
params do
optional :gems, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma delimited gem names'
diff --git a/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
index 737852d5ccb..f7b8d2514ba 100644
--- a/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
+++ b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
@@ -97,14 +97,8 @@ module Gitlab
end
def databases_in_sync?(wal_locations)
- locations = if Feature.enabled?(:indifferent_wal_location_keys)
- wal_locations.with_indifferent_access
- else
- wal_locations
- end
-
::Gitlab::Database::LoadBalancing.each_load_balancer.all? do |lb|
- if (location = locations[lb.name])
+ if (location = wal_locations.with_indifferent_access[lb.name])
lb.select_up_to_date_host(location)
else
# If there's no entry for a load balancer it means the Sidekiq
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
index 116a00f8385..a0e3e4f4d43 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_large_project_spec.rb
@@ -4,71 +4,53 @@
# rubocop:disable Rails/Pluck, Layout/LineLength, RSpec/MultipleMemoizedHelpers
module QA
- RSpec.describe "Manage", requires_admin: 'creates users', only: { job: 'large-gitlab-import' } do
- describe "Gitlab migration", product_group: :import do
- let(:logger) { Runtime::Logger.logger }
- let(:differ) { RSpec::Support::Differ.new(color: true) }
- let(:gitlab_group) { ENV['QA_LARGE_IMPORT_GROUP'] || 'gitlab-migration' }
- let(:gitlab_project) { ENV['QA_LARGE_IMPORT_REPO'] || 'dri' }
- let(:gitlab_source_address) { ENV['QA_LARGE_IMPORT_SOURCE_URL'] || 'https://staging.gitlab.com' }
-
- let(:import_wait_duration) do
+ RSpec.describe "Manage", only: { job: "large-gitlab-import" } do
+ describe "Gitlab migration", orchestrated: false, product_group: :import do
+ include_context "with gitlab group migration"
+
+ let!(:logger) { Runtime::Logger.logger }
+ let!(:differ) { RSpec::Support::Differ.new(color: true) }
+ let!(:source_gitlab_address) { ENV["QA_LARGE_IMPORT_SOURCE_URL"] || "https://gitlab.com" }
+ let!(:gitlab_source_group) { ENV["QA_LARGE_IMPORT_GROUP"] || "gitlab-migration-large-import-test" }
+ let!(:gitlab_source_project) { ENV["QA_LARGE_IMPORT_REPO"] || "migration-test-project" }
+
+ let!(:import_wait_duration) do
{
- max_duration: (ENV['QA_LARGE_IMPORT_DURATION'] || 3600).to_i,
+ max_duration: (ENV["QA_LARGE_IMPORT_DURATION"] || 3600).to_i,
sleep_interval: 30
}
end
- let(:admin_api_client) { Runtime::API::Client.as_admin }
-
- # explicitly create PAT via api to not create it via UI in environments where admin token env var is not present
- let(:target_api_client) do
- Runtime::API::Client.new(
- user: user,
- personal_access_token: Resource::PersonalAccessToken.fabricate_via_api! do |pat|
- pat.api_client = admin_api_client
- end.token
- )
- end
-
- let(:user) do
- Resource::User.fabricate_via_api! do |usr|
- usr.api_client = admin_api_client
- end
- end
-
- let(:source_api_client) do
+ let!(:source_admin_user) { "no-op" }
+ let!(:source_admin_api_client) do
Runtime::API::Client.new(
- gitlab_source_address,
- personal_access_token: ENV["QA_LARGE_IMPORT_GL_TOKEN"],
+ source_gitlab_address,
+ personal_access_token: ENV["QA_LARGE_IMPORT_GL_TOKEN"] || raise("missing QA_LARGE_IMPORT_GL_TOKEN variable"),
is_new_session: false
)
end
- let(:sandbox) do
+ # alias api client because for large import test it's not an actual admin user
+ let!(:source_api_client) { source_admin_api_client }
+
+ let!(:source_group) do
Resource::Sandbox.fabricate_via_api! do |group|
- group.api_client = admin_api_client
+ group.api_client = source_api_client
+ group.path = gitlab_source_group
end
end
- let(:destination_group) do
- Resource::Group.fabricate_via_api! do |group|
+ # generate unique target group because source group has a static name
+ let!(:target_sandbox) do
+ Resource::Sandbox.fabricate_via_api! do |group|
group.api_client = admin_api_client
- group.sandbox = sandbox
- group.path = "imported-group-destination-#{SecureRandom.hex(4)}"
+ group.path = "qa-sandbox-#{SecureRandom.hex(4)}"
end
end
- # Source group and it's objects
+ # Source objects
#
- let(:source_group) do
- Resource::Sandbox.fabricate_via_api! do |group|
- group.api_client = source_api_client
- group.path = gitlab_group
- end
- end
-
- let(:source_project) { source_group.projects.find { |project| project.name.include?(gitlab_project) }.reload! }
+ let(:source_project) { source_group.projects.find { |project| project.name.include?(gitlab_source_project) }.reload! }
let(:source_branches) { source_project.repository_branches(auto_paginate: true).map { |b| b[:name] } }
let(:source_commits) { source_project.commits(auto_paginate: true).map { |c| c[:id] } }
let(:source_labels) { source_project.labels(auto_paginate: true).map { |l| l.except(:id) } }
@@ -77,38 +59,25 @@ module QA
let(:source_mrs) { fetch_mrs(source_project, source_api_client) }
let(:source_issues) { fetch_issues(source_project, source_api_client) }
- # Imported group and it's objects
+ # Imported objects
#
- let(:imported_group) do
- Resource::BulkImportGroup.fabricate_via_api! do |group|
- group.import_access_token = source_api_client.personal_access_token # token for importing on source instance
- group.api_client = target_api_client # token used by qa framework to access resources in destination instance
- group.gitlab_address = gitlab_source_address
- group.source_group = source_group
- group.sandbox = destination_group
- end
- end
-
- let(:imported_project) { imported_group.projects.find { |project| project.name.include?(gitlab_project) }.reload! }
+ let(:imported_project) { imported_group.projects.find { |project| project.name.include?(gitlab_source_project) }.reload! }
let(:branches) { imported_project.repository_branches(auto_paginate: true).map { |b| b[:name] } }
let(:commits) { imported_project.commits(auto_paginate: true).map { |c| c[:id] } }
let(:labels) { imported_project.labels(auto_paginate: true).map { |l| l.except(:id) } }
let(:milestones) { imported_project.milestones(auto_paginate: true).map { |ms| ms.except(:id, :web_url, :project_id) } }
let(:pipelines) { imported_project.pipelines.map { |pp| pp.except(:id, :web_url, :project_id) } }
- let(:mrs) { fetch_mrs(imported_project, target_api_client) }
- let(:issues) { fetch_issues(imported_project, target_api_client) }
+ let(:mrs) { fetch_mrs(imported_project, api_client) }
+ let(:issues) { fetch_issues(imported_project, api_client) }
let(:import_failures) { imported_group.import_details.sum([]) { |details| details[:failures] } }
before do
- destination_group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
+ Runtime::Feature.enable(:bulk_import_projects) unless Runtime::Feature.enabled?(:bulk_import_projects)
end
# rubocop:disable RSpec/InstanceVariable
after do |example|
- # Log failures for easier debugging
- Runtime::Logger.error("Import failures: #{import_failures}") if example.exception && !import_failures.empty?
-
next unless defined?(@import_time)
# save data for comparison notification creation
@@ -121,7 +90,7 @@ module QA
source: {
name: "GitLab Source",
project_name: source_project.path_with_namespace,
- address: gitlab_source_address,
+ address: source_gitlab_address,
data: {
branches: source_branches.length,
commits: source_commits.length,
@@ -163,7 +132,7 @@ module QA
start = Time.now
# trigger import and log imported group path
- logger.info("== Importing group '#{gitlab_group}' in to '#{imported_group.full_path}' ==")
+ logger.info("== Importing group '#{gitlab_source_group}' in to '#{imported_group.full_path}' ==")
# fetch all objects right after import has started
fetch_source_gitlab_objects
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index e5ae1b04a86..e847225b85b 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -42,13 +42,24 @@ RSpec.describe Projects::Settings::CiCdController do
let_it_be(:project_runner) { create(:ci_runner, :project, projects: [other_project]) }
let_it_be(:shared_runner) { create(:ci_runner, :instance) }
- it 'sets assignable project runners only' do
+ before do
group.add_maintainer(user)
+ end
- get :show, params: { namespace_id: project.namespace, project_id: project }
+ subject { get :show, params: { namespace_id: project.namespace, project_id: project } }
+
+ it 'sets assignable project runners only' do
+ subject
expect(assigns(:assignable_runners)).to contain_exactly(project_runner)
end
+
+ it 'sets shared runners' do
+ subject
+
+ expect(assigns(:shared_runners_count)).to be(1)
+ expect(assigns(:shared_runners)).to contain_exactly(shared_runner)
+ end
end
context 'prevents N+1 queries for tags' do
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index cee0910aef7..b732fafe571 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -117,11 +117,27 @@ RSpec.describe 'Runners' do
it 'user sees CI/CD setting page' do
visit project_runners_path(project)
- expect(page.find('.available-shared-runners')).to have_content(shared_runner.display_name)
+ within '[data-testid="available-shared-runners"]' do
+ expect(page).to have_content(shared_runner.display_name)
+ end
+ end
+
+ context 'when multiple shared runners are configured' do
+ let!(:shared_runner_2) { create(:ci_runner, :instance) }
+
+ it 'adds pagination to the shared runner list' do
+ stub_const('Projects::Settings::CiCdController::NUMBER_OF_RUNNERS_PER_PAGE', 1)
+
+ visit project_runners_path(project)
+
+ within '[data-testid="available-shared-runners"]' do
+ expect(find('.pagination')).not_to be_nil
+ end
+ end
end
end
- context 'when multiple runners are configured' do
+ context 'when multiple project runners are configured' do
let!(:project_runner_2) { create(:ci_runner, :project, projects: [project]) }
it 'adds pagination to the runner list' do
diff --git a/spec/frontend/observability/observability_app_spec.js b/spec/frontend/observability/observability_app_spec.js
index f0b318e69ec..d21cf337ee8 100644
--- a/spec/frontend/observability/observability_app_spec.js
+++ b/spec/frontend/observability/observability_app_spec.js
@@ -1,5 +1,8 @@
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ObservabilityApp from '~/observability/components/observability_app.vue';
+import { darkModeEnabled } from '~/lib/utils/color_utils';
+
+jest.mock('~/lib/utils/color_utils');
describe('Observability root app', () => {
let wrapper;
@@ -32,11 +35,34 @@ describe('Observability root app', () => {
wrapper.destroy();
});
- it('should render an iframe with observabilityIframeSrc as src', () => {
- mountComponent();
- const iframe = findIframe();
- expect(iframe.exists()).toBe(true);
- expect(iframe.attributes('src')).toBe(TEST_IFRAME_SRC);
+ describe('iframe src', () => {
+ const TEST_USERNAME = 'test-user';
+
+ beforeAll(() => {
+ gon.current_username = TEST_USERNAME;
+ });
+
+ it('should render an iframe with observabilityIframeSrc, decorated with light theme and username', () => {
+ darkModeEnabled.mockReturnValueOnce(false);
+ mountComponent();
+ const iframe = findIframe();
+
+ expect(iframe.exists()).toBe(true);
+ expect(iframe.attributes('src')).toBe(
+ `${TEST_IFRAME_SRC}&theme=light&username=${TEST_USERNAME}`,
+ );
+ });
+
+ it('should render an iframe with observabilityIframeSrc decorated with dark theme and username', () => {
+ darkModeEnabled.mockReturnValueOnce(true);
+ mountComponent();
+ const iframe = findIframe();
+
+ expect(iframe.exists()).toBe(true);
+ expect(iframe.attributes('src')).toBe(
+ `${TEST_IFRAME_SRC}&theme=dark&username=${TEST_USERNAME}`,
+ );
+ });
});
it('should not call replace method from vue router if message event does not have url', () => {
diff --git a/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb
index 61b63016f1a..8a9d4ba0b25 100644
--- a/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb
@@ -332,28 +332,6 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqServerMiddleware, :clean_
expect(middleware.send(:databases_in_sync?, locations))
.to eq(false)
end
-
- context 'when "indifferent_wal_location_keys" FF is off' do
- before do
- stub_feature_flags(indifferent_wal_location_keys: false)
- end
-
- it 'returns true when the load balancers are not in sync' do
- locations = {}
-
- Gitlab::Database::LoadBalancing.each_load_balancer do |lb|
- locations[lb.name.to_s] = 'foo'
-
- allow(lb)
- .to receive(:select_up_to_date_host)
- .with('foo')
- .and_return(false)
- end
-
- expect(middleware.send(:databases_in_sync?, locations))
- .to eq(true)
- end
- end
end
end