Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-07-27 18:10:54 +00:00
parent 99befc3927
commit c241fef181
44 changed files with 344 additions and 228 deletions

View file

@ -36,9 +36,13 @@ workflow:
# they serve no purpose and will run anyway when the changes are merged.
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^release-tools\/\d+\.\d+\.\d+-rc\d+$/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/ && $CI_PROJECT_PATH == "gitlab-org/gitlab"'
when: never
# For merge requests, create a pipeline.
# For merged result pipelines, set $QA_IMAGE, since $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA is only available for merged result pipelines.
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"'
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
# Also run (detached) merge request pipelines.
- if: '$CI_MERGE_REQUEST_IID'
# For the 2-hourly scheduled pipelines, we set specific variables
# For the 2-hourly scheduled pipelines, we set specific variables.
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "schedule" && $FREQUENCY == "2-hourly"'
variables:
CRYSTALBALL: "true"
@ -88,6 +92,9 @@ variables:
RSPEC_FAIL_FAST_ENABLED: "true" # Set it to "false" to disable RSpec fail-fast
SIMPLECOV: "true"
# For the default QA image, we use $CI_COMMIT_SHA as tag since it's always available and we override it for specific workflow.rules (see above)
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
# Preparing custom clone path to reduce space used by all random forks
# on GitLab.com's Shared Runners. Our main forks - especially the security
# ones - will have this variable overwritten in the project settings, so that

View file

@ -370,19 +370,11 @@
when: never
- <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *ci-build-images-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
- <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *code-qa-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
- <<: *if-dot-com-gitlab-org-default-branch
changes: *code-qa-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
- <<: *if-dot-com-gitlab-org-schedule
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
.build-images:rules:build-assets-image:
rules:
@ -594,24 +586,16 @@
when: never
- <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *ci-qa-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
allow_failure: true
- <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *qa-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
allow_failure: true
- <<: *if-dot-com-gitlab-org-and-security-merge-request
changes: *code-patterns
when: manual
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
allow_failure: true
- <<: *if-dot-com-gitlab-org-schedule
allow_failure: true
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
###############
# Rails rules #
@ -1298,17 +1282,11 @@
when: never
- <<: *if-dot-com-gitlab-org-merge-request
changes: *ci-review-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
- <<: *if-dot-com-gitlab-org-merge-request
changes: *frontend-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
allow_failure: true
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-qa-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
allow_failure: true
# The rule needs to be duplicated between `on_success` and `on_failure`
@ -1344,13 +1322,9 @@
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-patterns
when: manual
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
allow_failure: true
- <<: *if-dot-com-gitlab-org-merge-request
changes: *qa-patterns
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
allow_failure: true
# The rule needs to be duplicated between `on_success` and `on_failure`

View file

@ -46,7 +46,7 @@ export default {
return timeIntervalInWords(this.job.queued);
},
runnerHelpUrl() {
return helpPagePath('ci/runners/index.html', {
return helpPagePath('ci/runners/configure_runners.html', {
anchor: 'set-maximum-job-timeout-for-a-runner',
});
},

View file

@ -304,7 +304,7 @@ class Admin::UsersController < Admin::ApplicationController
end
def user
@user ||= find_routable!(User, params[:id])
@user ||= find_routable!(User, params[:id], request.path_info)
end
def build_canonical_path(user)

View file

@ -3,7 +3,7 @@
module ProjectUnauthorized
module ControllerActions
def self.on_routable_not_found
lambda do |routable|
lambda do |routable, path_info|
return unless routable.is_a?(Project)
label = routable.external_authorization_classification_label

View file

@ -3,13 +3,13 @@
module RoutableActions
extend ActiveSupport::Concern
def find_routable!(routable_klass, requested_full_path, extra_authorization_proc: nil)
routable = routable_klass.find_by_full_path(requested_full_path, follow_redirects: request.get?)
def find_routable!(routable_klass, routable_full_path, path_info, extra_authorization_proc: nil)
routable = routable_klass.find_by_full_path(routable_full_path, follow_redirects: request.get?)
if routable_authorized?(routable, extra_authorization_proc)
ensure_canonical_path(routable, requested_full_path)
ensure_canonical_path(routable, routable_full_path)
routable
else
perform_not_found_actions(routable, not_found_actions)
perform_not_found_actions(routable, not_found_actions, path_info)
route_not_found unless performed?
@ -21,11 +21,11 @@ module RoutableActions
[ProjectUnauthorized::ControllerActions.on_routable_not_found]
end
def perform_not_found_actions(routable, actions)
def perform_not_found_actions(routable, actions, path_info)
actions.each do |action|
break if performed?
instance_exec(routable, &action)
instance_exec(routable, path_info, &action)
end
end
@ -42,13 +42,13 @@ module RoutableActions
end
end
def ensure_canonical_path(routable, requested_full_path)
def ensure_canonical_path(routable, routable_full_path)
return unless request.get?
canonical_path = routable.full_path
if canonical_path != requested_full_path
if !request.xhr? && request.format.html? && canonical_path.casecmp(requested_full_path) != 0
flash[:notice] = "#{routable.class.to_s.titleize} '#{requested_full_path}' was moved to '#{canonical_path}'. Please update any links and bookmarks that may still have the old path."
if canonical_path != routable_full_path
if !request.xhr? && request.format.html? && canonical_path.casecmp(routable_full_path) != 0
flash[:notice] = "#{routable.class.to_s.titleize} '#{routable_full_path}' was moved to '#{canonical_path}'. Please update any links and bookmarks that may still have the old path."
end
redirect_to build_canonical_path(routable), status: :moved_permanently

View file

@ -24,7 +24,7 @@ class Groups::ApplicationController < ApplicationController
end
def group
@group ||= find_routable!(Group, params[:group_id] || params[:id])
@group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
end
def group_projects

View file

@ -13,6 +13,6 @@ class Groups::Clusters::ApplicationsController < Clusters::ApplicationsControlle
end
def group
@group ||= find_routable!(Group, params[:group_id] || params[:id])
@group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
end
end

View file

@ -13,6 +13,6 @@ class Groups::Clusters::IntegrationsController < Clusters::IntegrationsControlle
end
def group
@group ||= find_routable!(Group, params[:group_id] || params[:id])
@group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
end
end

View file

@ -15,7 +15,7 @@ class Groups::ClustersController < Clusters::ClustersController
end
def group
@group ||= find_routable!(Group, params[:group_id] || params[:id])
@group ||= find_routable!(Group, params[:group_id] || params[:id], request.path_info)
end
def metrics_dashboard_params

View file

@ -6,7 +6,7 @@ class Profiles::GroupsController < Profiles::ApplicationController
feature_category :users
def update
group = find_routable!(Group, params[:id])
group = find_routable!(Group, params[:id], request.path_info)
notification_setting = current_user.notification_settings_for(group)
if notification_setting.update(update_params)

View file

@ -26,7 +26,7 @@ class Projects::ApplicationController < ApplicationController
path = File.join(params[:namespace_id], params[:project_id] || params[:id])
auth_proc = ->(project) { !project.pending_delete? }
@project = find_routable!(Project, path, extra_authorization_proc: auth_proc)
@project = find_routable!(Project, path, request.path_info, extra_authorization_proc: auth_proc)
end
def build_canonical_path(project)

View file

@ -10,6 +10,6 @@ class Projects::Clusters::ApplicationsController < Clusters::ApplicationsControl
end
def project
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]))
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.path_info)
end
end

View file

@ -10,6 +10,6 @@ class Projects::Clusters::IntegrationsController < ::Clusters::IntegrationsContr
end
def project
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]))
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.path_info)
end
end

View file

@ -17,7 +17,7 @@ class Projects::ClustersController < Clusters::ClustersController
end
def project
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]))
@project ||= find_routable!(Project, File.join(params[:namespace_id], params[:project_id]), request.path_info)
end
def repository

View file

@ -172,7 +172,7 @@ class UsersController < ApplicationController
private
def user
@user ||= find_routable!(User, params[:username])
@user ||= find_routable!(User, params[:username], request.path_info)
end
def personal_projects

View file

@ -119,14 +119,6 @@ module BoardsHelper
}
end
def boards_link_text
if current_board_parent.multiple_issue_boards_available?
s_("IssueBoards|Boards")
else
s_("IssueBoards|Board")
end
end
def recent_boards_path
recent_project_boards_path(@project) if current_board_parent.is_a?(Project)
end

View file

@ -67,15 +67,6 @@ module NavHelper
%w(dev_ops_report usage_trends)
end
def group_issues_sub_menu_items
%w[
groups#issues
milestones#index
boards#index
boards#show
]
end
private
def get_header_links

View file

@ -2,26 +2,23 @@
= form_errors(@application_setting)
%fieldset
%p
- link_to_restart = link_to(_('restart'), help_page_path('administration/restart_gitlab'))
= _('Enable a Prometheus metrics endpoint at %{metrics_path} to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available %{link}.').html_safe % { metrics_path: "<code>#{metrics_path}</code>".html_safe, link: link_to(_('here'), admin_health_check_path) }
= _('This setting requires a %{link_to_restart} to take effect.').html_safe % { link_to_restart: link_to_restart }
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/index')
.form-group
.form-check
= f.check_box :prometheus_metrics_enabled, class: 'form-check-input'
= f.label :prometheus_metrics_enabled, class: 'form-check-label' do
= _("Enable Prometheus Metrics")
= _("Enable health and performance metrics endpoint")
.form-text.text-muted
= _('Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required.')
= link_to _('Learn More.'), help_page_path('administration/monitoring/prometheus/gitlab_metrics.md'), target: '_blank'
- unless Gitlab::Metrics.metrics_folder_present?
.form-text.text-muted
%strong.cred= _("WARNING:")
= _("Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory.").html_safe % { environment_variable: prometheus_multiproc_dir, code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/gitlab_metrics', anchor: 'metrics-shared-directory')
.form-group
= f.label :metrics_method_call_threshold, _('Method Call Threshold (ms)'), class: 'label-bold'
= f.label :metrics_method_call_threshold, _('Method call threshold (ms)'), class: 'label-bold'
= f.number_field :metrics_method_call_threshold, class: 'form-control gl-form-input'
.form-text.text-muted
A method call is only tracked when it takes longer to complete than
the given amount of milliseconds.
Only track method calls that take longer to complete than the given duration.
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"

View file

@ -11,7 +11,7 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Enable and configure Prometheus metrics.')
= _('Monitor the health and performance of GitLab with Prometheus.')
.settings-content
= render 'prometheus'

View file

@ -1,4 +1,4 @@
= form_for [:admin, @group] do |f|
= gitlab_ui_form_for [:admin, @group] do |f|
= form_errors(@group)
= render 'shared/group_form', f: f
= render 'shared/group_form_description', f: f

View file

@ -1,10 +1,9 @@
- return unless render_setting_to_allow_project_access_token_creation?(group)
.form-group.gl-mb-3
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :resource_access_token_creation_allowed, checked: group.namespace_settings.resource_access_token_creation_allowed?, class: 'custom-control-input', data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' }
= f.label :resource_access_token_creation_allowed, class: 'custom-control-label' do
%span= s_('GroupSettings|Allow project access token creation')
- project_access_tokens_link = help_page_path('user/project/settings/project_access_tokens')
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: project_access_tokens_link }
%p.help-text= s_('GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- project_access_tokens_link = help_page_path('user/project/settings/project_access_tokens')
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: project_access_tokens_link }
= f.gitlab_ui_checkbox_component :resource_access_token_creation_allowed,
s_('GroupSettings|Allow project access token creation'),
checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed?, data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' } },
help_text: s_('GroupSettings|Users can create %{link_start}project access tokens%{link_end} for projects in this group.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }

View file

@ -1,42 +1,5 @@
- issues_count = cached_issuables_count(@group, type: :issues)
- merge_requests_count = cached_issuables_count(@group, type: :merge_requests)
- if group_sidebar_link?(:issues)
= nav_link(path: group_issues_sub_menu_items, unless: -> { current_path?('issues_analytics#show') }) do
= link_to issues_group_path(@group), data: { qa_selector: 'group_issues_item' }, class: 'has-sub-items' do
.nav-icon-container
= sprite_icon('issues')
%span.nav-item-name
= _('Issues')
%span.badge.badge-pill.count= issues_count
%ul.sidebar-sub-level-items{ data: { qa_selector: 'group_issues_sidebar_submenu'} }
= nav_link(path: group_issues_sub_menu_items, html_options: { class: "fly-out-top-item" } ) do
= link_to issues_group_path(@group) do
%strong.fly-out-top-item-name
= _('Issues')
%span.badge.badge-pill.count.issue_counter.fly-out-badge= issues_count
%li.divider.fly-out-top-item
= nav_link(path: 'groups#issues', html_options: { class: 'home' }) do
= link_to issues_group_path(@group), title: _('List') do
%span
= _('List')
- if group_sidebar_link?(:boards)
= nav_link(path: ['boards#index', 'boards#show']) do
= link_to group_boards_path(@group), title: boards_link_text, data: { qa_selector: 'group_issue_boards_link' } do
%span
= boards_link_text
- if group_sidebar_link?(:milestones)
= nav_link(path: 'milestones#index') do
= link_to group_milestones_path(@group), title: _('Milestones'), data: { qa_selector: 'group_milestones_link' } do
%span
= _('Milestones')
= render_if_exists 'layouts/nav/sidebar/group_iterations_link'
- if group_sidebar_link?(:merge_requests)
= nav_link(path: 'groups#merge_requests') do
= link_to merge_requests_group_path(@group) do

View file

@ -1,6 +1,6 @@
- label_class = local_assigns.fetch(:bold_label, false) ? 'font-weight-bold' : ''
.gl-form-checkbox.custom-control.custom-checkbox
= form.check_box :request_access_enabled, class: 'custom-control-input', data: { qa_selector: 'request_access_checkbox' }
= form.label :request_access_enabled, class: 'custom-control-label' do
%span{ class: label_class }= _('Allow users to request access (if visibility is public or internal)')
= form.gitlab_ui_checkbox_component :request_access_enabled,
_('Allow users to request access (if visibility is public or internal)'),
label_options: { class: label_class },
checkbox_options: { data: { qa_selector: 'request_access_checkbox' } }

View file

@ -12,4 +12,5 @@ const ROOT_PATH = path.resolve(__dirname, '../..');
// lib/gitlab.rb: Gitlab.jh?
// Since IS_EE already satisifies the conditions of not being a FOSS_ONLY.
// const isFossOnly = JSON.parse(process.env.FOSS_ONLY || 'false');
module.exports = IS_EE && fs.existsSync(path.join(ROOT_PATH, 'jh'));
const isEEOnly = JSON.parse(process.env.EE_ONLY || 'false');
module.exports = IS_EE && !isEEOnly && fs.existsSync(path.join(ROOT_PATH, 'jh'));

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddStateToMembers < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
def up
with_lock_retries do
add_column :members, :state, :integer, limit: 2, default: 0
end
end
def down
with_lock_retries do
remove_column :members, :state
end
end
end

View file

@ -0,0 +1 @@
1585d2912058ce3a9225233c23707a3679a3f8df2078c71b5cc48f28b7bb9392

View file

@ -14707,7 +14707,8 @@ CREATE TABLE members (
requested_at timestamp without time zone,
expires_at date,
ldap boolean DEFAULT false NOT NULL,
override boolean DEFAULT false NOT NULL
override boolean DEFAULT false NOT NULL,
state smallint DEFAULT 0
);
CREATE SEQUENCE members_id_seq

View file

@ -8,10 +8,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
To enable the GitLab Prometheus metrics:
1. Log into GitLab as a user with [administrator permissions](../../../user/permissions.md).
1. Log in to GitLab as a user with [administrator permissions](../../../user/permissions.md).
1. On the top bar, select **Menu >** **{admin}** **Admin**.
1. On the left sidebar, select **Settings > Metrics and profiling**.
1. Find the **Metrics - Prometheus** section, and click **Enable Prometheus Metrics**.
1. Find the **Metrics - Prometheus** section, and select **Add link to Prometheus**.
1. [Restart GitLab](../../restart_gitlab.md#omnibus-gitlab-restart) for the changes to take effect.
For installations from source you must configure it yourself.

View file

@ -932,63 +932,6 @@ variables:
The DAST job does not require the project's repository to be present when running, so by default
[`GIT_STRATEGY`](../../../ci/runners/configure_runners.md#git-strategy) is set to `none`.
## Running DAST in an offline environment
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
to external resources through the internet, some adjustments are required for the DAST job to
successfully run. For more information, see [Offline environments](../offline_deployments/index.md).
### Requirements for offline DAST support
To use DAST in an offline environment, you need:
- GitLab Runner with the [`docker` or `kubernetes` executor](#prerequisites).
- Docker Container Registry with a locally available copy of the DAST
[container image](https://gitlab.com/security-products/dast), found in the
[DAST container registry](https://gitlab.com/security-products/dast/container_registry).
Note that GitLab Runner has a [default `pull policy` of `always`](https://docs.gitlab.com/runner/executors/docker.html#using-the-always-pull-policy),
meaning the runner tries to pull Docker images from the GitLab container registry even if a local
copy is available. The GitLab Runner [`pull_policy` can be set to `if-not-present`](https://docs.gitlab.com/runner/executors/docker.html#using-the-if-not-present-pull-policy)
in an offline environment if you prefer using only locally available Docker images. However, we
recommend keeping the pull policy setting to `always` if not in an offline environment, as this
enables the use of updated scanners in your CI/CD pipelines.
### Make GitLab DAST analyzer images available inside your Docker registry
For DAST, import the following default DAST analyzer image from `registry.gitlab.com` to your [local Docker container registry](../../packages/container_registry/index.md):
- `registry.gitlab.com/security-products/dast:latest`
The process for importing Docker images into a local offline Docker registry depends on
**your network security policy**. Please consult your IT staff to find an accepted and approved
process by which external resources can be imported or temporarily accessed.
These scanners are [periodically updated](../vulnerabilities/index.md#vulnerability-scanner-maintenance)
with new definitions, and you may be able to make occasional updates on your own.
For details on saving and transporting Docker images as a file, see Docker's documentation on
[`docker save`](https://docs.docker.com/engine/reference/commandline/save/),
[`docker load`](https://docs.docker.com/engine/reference/commandline/load/),
[`docker export`](https://docs.docker.com/engine/reference/commandline/export/), and
[`docker import`](https://docs.docker.com/engine/reference/commandline/import/).
### Set DAST CI/CD job variables to use local DAST analyzers
Add the following configuration to your `.gitlab-ci.yml` file. You must replace `image` to refer to
the DAST Docker image hosted on your local Docker container registry:
```yaml
include:
- template: DAST.gitlab-ci.yml
dast:
image: registry.example.com/namespace/dast:latest
```
The DAST job should now use local copies of the DAST analyzers to scan your code and generate
security reports without requiring internet access.
Alternatively, you can use the CI/CD variable `SECURE_ANALYZERS_PREFIX` to override the base registry address of the `dast` image.
## On-demand scans
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218465) in GitLab 13.2.

View file

@ -0,0 +1,63 @@
---
stage: Secure
group: Dynamic Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: reference, howto
---
# Run DAST in an offline environment
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
to external resources through the internet, some adjustments are required for the DAST job to
successfully run. For more information, see [Offline environments](../offline_deployments/index.md).
## Requirements for offline DAST support
To use DAST in an offline environment, you need:
- GitLab Runner with the [`docker` or `kubernetes` executor](index.md#prerequisites).
- Docker Container Registry with a locally available copy of the DAST
[container image](https://gitlab.com/security-products/dast), found in the
[DAST container registry](https://gitlab.com/security-products/dast/container_registry).
Note that GitLab Runner has a [default `pull policy` of `always`](https://docs.gitlab.com/runner/executors/docker.html#using-the-always-pull-policy),
meaning the runner tries to pull Docker images from the GitLab container registry even if a local
copy is available. The GitLab Runner [`pull_policy` can be set to `if-not-present`](https://docs.gitlab.com/runner/executors/docker.html#using-the-if-not-present-pull-policy)
in an offline environment if you prefer using only locally available Docker images. However, we
recommend keeping the pull policy setting to `always` if not in an offline environment, as this
enables the use of updated scanners in your CI/CD pipelines.
## Make GitLab DAST analyzer images available inside your Docker registry
For DAST, import the following default DAST analyzer image from `registry.gitlab.com` to your [local Docker container registry](../../packages/container_registry/index.md):
- `registry.gitlab.com/security-products/dast:latest`
The process for importing Docker images into a local offline Docker registry depends on
**your network security policy**. Please consult your IT staff to find an accepted and approved
process by which external resources can be imported or temporarily accessed.
These scanners are [periodically updated](../vulnerabilities/index.md#vulnerability-scanner-maintenance)
with new definitions, and you may be able to make occasional updates on your own.
For details on saving and transporting Docker images as a file, see Docker's documentation on
[`docker save`](https://docs.docker.com/engine/reference/commandline/save/),
[`docker load`](https://docs.docker.com/engine/reference/commandline/load/),
[`docker export`](https://docs.docker.com/engine/reference/commandline/export/), and
[`docker import`](https://docs.docker.com/engine/reference/commandline/import/).
## Set DAST CI/CD job variables to use local DAST analyzers
Add the following configuration to your `.gitlab-ci.yml` file. You must replace `image` to refer to
the DAST Docker image hosted on your local Docker container registry:
```yaml
include:
- template: DAST.gitlab-ci.yml
dast:
image: registry.example.com/namespace/dast:latest
```
The DAST job should now use local copies of the DAST analyzers to scan your code and generate
security reports without requiring internet access.
Alternatively, you can use the CI/CD variable `SECURE_ANALYZERS_PREFIX` to override the base registry address of the `dast` image.

View file

@ -87,7 +87,7 @@ above. You can find more information at each of the pages below:
- [Container scanning offline directions](../container_scanning/index.md#running-container-scanning-in-an-offline-environment)
- [SAST offline directions](../sast/index.md#running-sast-in-an-offline-environment)
- [DAST offline directions](../dast/index.md#running-dast-in-an-offline-environment)
- [DAST offline directions](../dast/run_dast_offline.md#run-dast-in-an-offline-environment)
- [License Compliance offline directions](../../compliance/license_compliance/index.md#running-license-compliance-in-an-offline-environment)
- [Dependency Scanning offline directions](../dependency_scanning/index.md#running-dependency-scanning-in-an-offline-environment)

View file

@ -52,9 +52,6 @@ module Gitlab
tracking_category: 'Growth::Conversion::Experiment::ShowTrialStatusInSidebar',
rollout_strategy: :group
},
trial_onboarding_issues: {
tracking_category: 'Growth::Conversion::Experiment::TrialOnboardingIssues'
},
learn_gitlab_a: {
tracking_category: 'Growth::Conversion::Experiment::LearnGitLabA',
rollout_strategy: :user

View file

@ -328,6 +328,9 @@ excluded_attributes:
- :release_id
project_members:
- :source_id
- :state
group_members:
- :state
metrics:
- :merge_request_id
- :pipeline_id

View file

@ -0,0 +1,101 @@
# frozen_string_literal: true
module Sidebars
module Groups
module Menus
class IssuesMenu < ::Sidebars::Menu
include Gitlab::Utils::StrongMemoize
override :configure_menu_items
def configure_menu_items
return unless can?(context.current_user, :read_group_issues, context.group)
add_item(list_menu_item)
add_item(boards_menu_item)
add_item(milestones_menu_item)
true
end
override :link
def link
issues_group_path(context.group)
end
override :title
def title
_('Issues')
end
override :sprite_icon
def sprite_icon
'issues'
end
override :has_pill?
def has_pill?
true
end
override :pill_count
def pill_count
strong_memoize(:pill_count) do
count_service = ::Groups::OpenIssuesCountService
count = count_service.new(context.group, context.current_user).count
format_cached_count(count_service, count)
end
end
override :pill_html_options
def pill_html_options
{
class: 'issue_counter'
}
end
private
def list_menu_item
::Sidebars::MenuItem.new(
title: _('List'),
link: issues_group_path(context.group),
active_routes: { path: 'groups#issues' },
container_html_options: { aria: { label: _('Issues') } },
item_id: :issue_list
)
end
def boards_menu_item
unless can?(context.current_user, :read_group_boards, context.group)
return ::Sidebars::NilMenuItem.new(item_id: :boards)
end
title = context.group.multiple_issue_boards_available? ? s_('IssueBoards|Boards') : s_('IssueBoards|Board')
::Sidebars::MenuItem.new(
title: title,
link: group_boards_path(context.group),
active_routes: { path: %w[boards#index boards#show] },
item_id: :boards
)
end
def milestones_menu_item
unless can?(context.current_user, :read_group_milestones, context.group)
return ::Sidebars::NilMenuItem.new(item_id: :milestones)
end
::Sidebars::MenuItem.new(
title: _('Milestones'),
link: group_milestones_path(context.group),
active_routes: { path: 'milestones#index' },
item_id: :milestones
)
end
end
end
end
end
Sidebars::Groups::Menus::IssuesMenu.prepend_mod_with('Sidebars::Groups::Menus::IssuesMenu')

View file

@ -8,6 +8,7 @@ module Sidebars
set_scope_menu(Sidebars::Groups::Menus::ScopeMenu.new(context))
add_menu(Sidebars::Groups::Menus::GroupInformationMenu.new(context))
add_menu(Sidebars::Groups::Menus::IssuesMenu.new(context))
end
override :render_raw_menus_partial

View file

@ -12118,9 +12118,6 @@ msgstr ""
msgid "Enable PlantUML"
msgstr ""
msgid "Enable Prometheus Metrics"
msgstr ""
msgid "Enable Pseudonymizer data collection"
msgstr ""
@ -12142,15 +12139,12 @@ msgstr ""
msgid "Enable What's new: Current tier only"
msgstr ""
msgid "Enable a Prometheus metrics endpoint at %{metrics_path} to expose a variety of statistics on the health and performance of GitLab. Additional information on authenticating and connecting to the metrics endpoint is available %{link}."
msgid "Enable a Prometheus endpoint that exposes health and performance statistics. The Health Check menu item appears in the Monitoring section of the Admin Area. Restart required."
msgstr ""
msgid "Enable access to the performance bar for non-administrators in a given group."
msgstr ""
msgid "Enable and configure Prometheus metrics."
msgstr ""
msgid "Enable and disable Service Desk. Some additional configuration might be required. %{link_start}Learn more%{link_end}."
msgstr ""
@ -12184,6 +12178,9 @@ msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
msgid "Enable health and performance metrics endpoint"
msgstr ""
msgid "Enable in-product marketing emails"
msgstr ""
@ -19260,6 +19257,9 @@ msgstr ""
msgid "Learn More"
msgstr ""
msgid "Learn More."
msgstr ""
msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
msgstr ""
@ -20723,7 +20723,7 @@ msgstr ""
msgid "Method"
msgstr ""
msgid "Method Call Threshold (ms)"
msgid "Method call threshold (ms)"
msgstr ""
msgid "Metric was successfully added."
@ -21354,6 +21354,9 @@ msgstr ""
msgid "Monitor Settings"
msgstr ""
msgid "Monitor the health and performance of GitLab with Prometheus."
msgstr ""
msgid "Monitor your errors by integrating with Sentry."
msgstr ""
@ -31806,6 +31809,9 @@ msgstr ""
msgid "SuperSonics|Expires on"
msgstr ""
msgid "SuperSonics|Export license usage file"
msgstr ""
msgid "SuperSonics|Free trial"
msgstr ""
@ -33816,9 +33822,6 @@ msgstr ""
msgid "This setting can be overridden in each project."
msgstr ""
msgid "This setting requires a %{link_to_restart} to take effect."
msgstr ""
msgid "This subscription is for"
msgstr ""
@ -38867,9 +38870,6 @@ msgstr ""
msgid "help"
msgstr ""
msgid "here"
msgstr ""
msgid "http:"
msgstr ""
@ -39610,9 +39610,6 @@ msgstr ""
msgid "reset it."
msgstr ""
msgid "restart"
msgstr ""
msgid "revised"
msgstr ""

View file

@ -8,8 +8,6 @@ module QA
view 'app/views/layouts/nav/sidebar/_group_menus.html.haml' do
element :general_settings_link
element :group_issues_item
element :group_milestones_link
element :group_settings
end
@ -63,7 +61,7 @@ module QA
def go_to_milestones
hover_issues do
within_submenu do
click_element(:group_milestones_link)
click_element(:sidebar_menu_item_link, menu_item: 'Milestones')
end
end
end
@ -81,8 +79,8 @@ module QA
def hover_issues
within_sidebar do
scroll_to_element(:group_issues_item)
find_element(:group_issues_item).hover
scroll_to_element(:sidebar_menu_link, menu_item: 'Issues')
find_element(:sidebar_menu_link, menu_item: 'Issues').hover
yield
end

View file

@ -10,7 +10,7 @@ RSpec.describe RoutableActions do
def routable
@klass = params[:type].constantize
@routable = find_routable!(params[:type].constantize, params[:id])
@routable = find_routable!(params[:type].constantize, params[:id], '/')
end
def show
@ -135,7 +135,7 @@ RSpec.describe RoutableActions do
end
it 'performs checks in the context of the controller' do
check = lambda { |routable| redirect_to routable }
check = lambda { |routable, path_info| redirect_to routable }
allow(subject).to receive(:not_found_actions).and_return([check])
get_routable(routable)

View file

@ -490,7 +490,7 @@ RSpec.describe 'Admin updates settings' do
it 'change Prometheus settings' do
page.within('.as-prometheus') do
check 'Enable Prometheus Metrics'
check 'Enable health and performance metrics endpoint'
click_button 'Save changes'
end

View file

@ -112,16 +112,6 @@ RSpec.describe NavHelper do
it { is_expected.to all(be_a(String)) }
end
describe '.group_issues_sub_menu_items' do
subject { helper.group_issues_sub_menu_items }
before do
allow(helper).to receive(:current_user).and_return(nil)
end
it { is_expected.to all(be_a(String)) }
end
describe '#page_has_markdown?' do
using RSpec::Parameterized::TableSyntax

View file

@ -0,0 +1,54 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Sidebars::Groups::Menus::IssuesMenu do
let_it_be(:owner) { create(:user) }
let_it_be(:group) do
build(:group, :private).tap do |g|
g.add_owner(owner)
end
end
let(:user) { owner }
let(:context) { Sidebars::Groups::Context.new(current_user: user, container: group) }
let(:menu) { described_class.new(context) }
describe 'Menu Items' do
subject { menu.renderable_items.index { |e| e.item_id == item_id } }
shared_examples 'menu access rights' do
specify { is_expected.not_to be_nil }
describe 'when the user does not have access' do
let(:user) { nil }
specify { is_expected.to be_nil }
end
end
describe 'List' do
let(:item_id) { :issue_list }
specify { is_expected.not_to be_nil }
it_behaves_like 'menu access rights'
end
describe 'Boards' do
let(:item_id) { :boards }
it_behaves_like 'menu access rights'
end
describe 'Milestones' do
let(:item_id) { :milestones }
it_behaves_like 'menu access rights'
end
end
it_behaves_like 'pill_count formatted results' do
let(:count_service) { ::Groups::OpenIssuesCountService }
end
end

View file

@ -10,7 +10,7 @@ RSpec.describe API::Groups do
let_it_be(:user2) { create(:user) }
let_it_be(:user3) { create(:user) }
let_it_be(:admin) { create(:admin) }
let_it_be(:group1) { create(:group, avatar: File.open(uploaded_image_temp_path)) }
let_it_be(:group1) { create(:group, path: 'some_path', avatar: File.open(uploaded_image_temp_path)) }
let_it_be(:group2) { create(:group, :private) }
let_it_be(:project1) { create(:project, namespace: group1) }
let_it_be(:project2) { create(:project, namespace: group2) }

View file

@ -39,4 +39,30 @@ RSpec.describe 'layouts/nav/sidebar/_group' do
expect(rendered).to have_link('Members', href: group_group_members_path(group))
end
end
describe 'Issues' do
it 'has a default link to the issue list path' do
render
expect(rendered).to have_link('Issues', href: issues_group_path(group))
end
it 'has a link to the issue list page' do
render
expect(rendered).to have_link('List', href: issues_group_path(group))
end
it 'has a link to the boards page' do
render
expect(rendered).to have_link('Board', href: group_boards_path(group))
end
it 'has a link to the milestones page' do
render
expect(rendered).to have_link('Milestones', href: group_milestones_path(group))
end
end
end