summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-02-09 03:07:46 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-02-09 03:07:46 +0000
commit38ff3a81189c8323d323946afcf7dad62c84b9aa (patch)
treef5763c753d647f63ec06daea3f83f2e0e6d5be4d
parentc46d8e7601c032d954c9f35761ae14dc4bacf6ce (diff)
downloadgitlab-ce-38ff3a81189c8323d323946afcf7dad62c84b9aa.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/boards/components/board_list_header.vue4
-rw-r--r--app/assets/javascripts/groups_projects/components/transfer_locations.vue18
-rw-r--r--app/controllers/projects/settings/repository_controller.rb15
-rw-r--r--app/models/commit_user_mention.rb4
-rw-r--r--app/models/protected_branch.rb9
-rw-r--r--app/views/protected_branches/shared/_protected_branch.html.haml19
-rw-r--r--config/feature_flags/development/limited_capacity_seat_refresh_worker_high.yml8
-rw-r--r--config/feature_flags/development/limited_capacity_seat_refresh_worker_low.yml8
-rw-r--r--config/feature_flags/development/limited_capacity_seat_refresh_worker_medium.yml8
-rw-r--r--config/feature_flags/ops/automatic_lock_writes_on_table.yml2
-rw-r--r--config/initializers/1_settings.rb3
-rw-r--r--config/sidekiq_queues.yml2
-rw-r--r--db/migrate/20230207015819_initialize_conversion_of_commit_user_mentions_note_id_to_bigint.rb16
-rw-r--r--db/post_migrate/20230201153450_add_index_on_lfs_objects_file.rb14
-rw-r--r--db/post_migrate/20230207015850_backfill_commit_user_mentions_note_id_for_bigint_conversion.rb16
-rw-r--r--db/schema_migrations/202302011534501
-rw-r--r--db/schema_migrations/202302070158191
-rw-r--r--db/schema_migrations/202302070158501
-rw-r--r--db/structure.sql30
-rw-r--r--doc/administration/operations/fast_ssh_key_lookup.md157
-rw-r--r--doc/administration/operations/gitlab_sshd.md139
-rw-r--r--doc/administration/operations/index.md1
-rw-r--r--doc/ci/jobs/ci_job_token.md109
-rw-r--r--doc/install/aws/manual_install_aws.md2
-rw-r--r--doc/user/admin_area/settings/index.md2
-rw-r--r--doc/user/application_security/get-started-security.md3
-rw-r--r--doc/user/group/compliance_frameworks.md5
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/controllers/projects/settings/repository_controller_spec.rb34
-rw-r--r--spec/frontend/boards/components/board_list_header_spec.js30
-rw-r--r--spec/frontend/groups_projects/components/transfer_locations_spec.js21
-rw-r--r--spec/models/protected_branch_spec.rb18
-rw-r--r--spec/services/ci/job_token_scope/remove_project_service_spec.rb2
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb1
34 files changed, 482 insertions, 224 deletions
diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue
index a87f824fa88..e0a3086c1e0 100644
--- a/app/assets/javascripts/boards/components/board_list_header.vue
+++ b/app/assets/javascripts/boards/components/board_list_header.vue
@@ -135,7 +135,9 @@ export default {
},
isSettingsShown() {
return (
- this.listType !== ListType.backlog && this.showListHeaderButton && !this.list.collapsed
+ this.listType !== ListType.backlog &&
+ this.listType !== ListType.closed &&
+ !this.list.collapsed
);
},
uniqueKey() {
diff --git a/app/assets/javascripts/groups_projects/components/transfer_locations.vue b/app/assets/javascripts/groups_projects/components/transfer_locations.vue
index e0c8ce36e3c..360af772a10 100644
--- a/app/assets/javascripts/groups_projects/components/transfer_locations.vue
+++ b/app/assets/javascripts/groups_projects/components/transfer_locations.vue
@@ -25,6 +25,7 @@ export const i18n = {
'ProjectTransfer|An error occurred fetching the transfer locations, please refresh the page and try again.',
),
ALERT_DISMISS_LABEL: __('Dismiss'),
+ NO_RESULTS_TEXT: __('No results found.'),
};
export default {
@@ -90,6 +91,9 @@ export default {
hasGroupTransferLocations() {
return this.groupTransferLocations.length;
},
+ hasAdditionalDropdownItems() {
+ return this.filteredAdditionalDropdownItems.length;
+ },
selectedText() {
return this.value?.humanName || this.label;
},
@@ -99,6 +103,17 @@ export default {
showAdditionalDropdownItems() {
return !this.isLoading && this.filteredAdditionalDropdownItems.length;
},
+ hasNoResults() {
+ if (this.isLoading || this.isSearchLoading) {
+ return false;
+ }
+
+ return (
+ !this.hasAdditionalDropdownItems &&
+ !this.hasUserTransferLocations &&
+ !this.hasGroupTransferLocations
+ );
+ },
},
watch: {
searchTerm() {
@@ -274,6 +289,9 @@ export default {
>{{ item.humanName }}</gl-dropdown-item
>
</div>
+ <gl-dropdown-item v-if="hasNoResults" button-class="gl-text-gray-900!" disabled>{{
+ $options.i18n.NO_RESULTS_TEXT
+ }}</gl-dropdown-item>
<gl-loading-icon v-if="isLoading" class="gl-mb-3" size="sm" />
<gl-intersection-observer v-if="hasNextPageOfGroups" @appear="handleLoadMoreGroups" />
</gl-dropdown>
diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb
index 6d099aa8b3d..74d730db026 100644
--- a/app/controllers/projects/settings/repository_controller.rb
+++ b/app/controllers/projects/settings/repository_controller.rb
@@ -88,25 +88,20 @@ module Projects
# rubocop: disable CodeReuse/ActiveRecord
def define_protected_refs
- @protected_branches = @project.protected_branches.order(:name).page(params[:page])
+ @protected_branches = fetch_protected_branches(@project)
@protected_tags = @project.protected_tags.order(:name).page(params[:page])
@protected_branch = @project.protected_branches.new
@protected_tag = @project.protected_tags.new
@protected_tags_count = @protected_tags.reduce(0) { |sum, tag| sum + tag.matching(@project.repository.tag_names).size }
-
- if Feature.enabled?(:group_protected_branches)
- @protected_group_branches = if @project.root_namespace.is_a?(Group)
- @project.root_namespace.protected_branches.order(:name).page(params[:page])
- else
- []
- end
- end
-
load_gon_index
end
# rubocop: enable CodeReuse/ActiveRecord
+ def fetch_protected_branches(project)
+ project.protected_branches.sorted_by_name.page(params[:page])
+ end
+
def remote_mirror
@remote_mirror = project.remote_mirrors.first_or_initialize
end
diff --git a/app/models/commit_user_mention.rb b/app/models/commit_user_mention.rb
index 680d20b61cf..4d464f353ee 100644
--- a/app/models/commit_user_mention.rb
+++ b/app/models/commit_user_mention.rb
@@ -1,5 +1,9 @@
# frozen_string_literal: true
class CommitUserMention < UserMention
+ include IgnorableColumns
+
+ ignore_column :note_id_convert_to_bigint, remove_with: '16.0', remove_after: '2023-05-22'
+
belongs_to :note
end
diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb
index cab35304778..b3331b99a6b 100644
--- a/app/models/protected_branch.rb
+++ b/app/models/protected_branch.rb
@@ -12,6 +12,7 @@ class ProtectedBranch < ApplicationRecord
scope :requiring_code_owner_approval, -> { where(code_owner_approval_required: true) }
scope :allowing_force_push, -> { where(allow_force_push: true) }
scope :sorted_by_name, -> { order(name: :asc) }
+ scope :sorted_by_namespace_and_name, -> { order(:namespace_id, :name) }
scope :for_group, ->(group) { where(group: group) }
@@ -121,6 +122,14 @@ class ProtectedBranch < ApplicationRecord
name == project.default_branch
end
+ def group_level?
+ entity.is_a?(Group)
+ end
+
+ def project_level?
+ entity.is_a?(Project)
+ end
+
def entity
group || project
end
diff --git a/app/views/protected_branches/shared/_protected_branch.html.haml b/app/views/protected_branches/shared/_protected_branch.html.haml
index b4fd7a24b41..c2a5dd8a9b0 100644
--- a/app/views/protected_branches/shared/_protected_branch.html.haml
+++ b/app/views/protected_branches/shared/_protected_branch.html.haml
@@ -1,14 +1,15 @@
- can_admin_entity = protected_branch_can_admin_entity?(protected_branch_entity)
- url = protected_branch_path_by_entity(protected_branch, protected_branch_entity)
+- protected_branch_test_type = protected_branch.project_level? ? 'project-level' : 'group-level'
-%tr.js-protected-branch-edit-form{ data: { url: url, testid: 'protected-branch' } }
+%tr.js-protected-branch-edit-form{ data: { url: url, testid: 'protected-branch', test_type: protected_branch_test_type } }
%td
%span.ref-name= protected_branch.name
- - if protected_branch_entity.is_a?(Project) && protected_branch_entity.root_ref?(protected_branch.name)
- = gl_badge_tag s_('ProtectedBranch|default'), variant: :info
+ - if protected_branch.project_level?
+ - if protected_branch_entity.root_ref?(protected_branch.name)
+ = gl_badge_tag s_('ProtectedBranch|default'), variant: :info
- - if protected_branch_entity.is_a?(Project)
%div
- if protected_branch.wildcard?
- matching_branches = protected_branch.matching(repository.branch_names)
@@ -18,8 +19,12 @@
= yield
- = render_if_exists 'protected_branches/ee/code_owner_approval_table', protected_branch: protected_branch, protected_branch_entity: protected_branch_entity
+ = render_if_exists 'protected_branches/ee/code_owner_approval_table', can_update: local_assigns[:can_update], protected_branch: protected_branch, protected_branch_entity: protected_branch_entity
- if can_admin_entity
- %td
- = link_to s_('ProtectedBranch|Unprotect'), [protected_branch_entity, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], aria: { label: s_('ProtectedBranch|Unprotect branch') }, data: { confirm: s_('ProtectedBranch|Branch will be writable for developers. Are you sure?'), confirm_btn_variant: 'danger' }, method: :delete, class: "btn gl-button btn-danger btn-sm"
+ %td.text-right{ data: { testid: 'protected-branch-action' } }
+ - if local_assigns[:is_inherited]
+ %span.has-tooltip{ data: { container: 'body' }, title: s_('ProtectedBranch|Inherited - This setting can be changed at the group level'), 'aria-hidden': 'true' }
+ = sprite_icon 'lock'
+ - else
+ = link_to s_('ProtectedBranch|Unprotect'), [protected_branch_entity, protected_branch, { update_section: 'js-protected-branches-settings' }], disabled: local_assigns[:disabled], aria: { label: s_('ProtectedBranch|Unprotect branch') }, data: { confirm: s_('ProtectedBranch|Branch will be writable for developers. Are you sure?'), confirm_btn_variant: 'danger' }, method: :delete, class: "btn gl-button btn-danger btn-sm"
diff --git a/config/feature_flags/development/limited_capacity_seat_refresh_worker_high.yml b/config/feature_flags/development/limited_capacity_seat_refresh_worker_high.yml
new file mode 100644
index 00000000000..def6101ee2f
--- /dev/null
+++ b/config/feature_flags/development/limited_capacity_seat_refresh_worker_high.yml
@@ -0,0 +1,8 @@
+---
+name: limited_capacity_seat_refresh_worker_high
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104099/
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382725"
+milestone: '15.9'
+type: development
+group: group::utilization
+default_enabled: false
diff --git a/config/feature_flags/development/limited_capacity_seat_refresh_worker_low.yml b/config/feature_flags/development/limited_capacity_seat_refresh_worker_low.yml
new file mode 100644
index 00000000000..ac89bf2cd87
--- /dev/null
+++ b/config/feature_flags/development/limited_capacity_seat_refresh_worker_low.yml
@@ -0,0 +1,8 @@
+---
+name: limited_capacity_seat_refresh_worker_low
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104099/
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382725"
+milestone: '15.9'
+type: development
+group: group::utilization
+default_enabled: false
diff --git a/config/feature_flags/development/limited_capacity_seat_refresh_worker_medium.yml b/config/feature_flags/development/limited_capacity_seat_refresh_worker_medium.yml
new file mode 100644
index 00000000000..1169d3fdc2d
--- /dev/null
+++ b/config/feature_flags/development/limited_capacity_seat_refresh_worker_medium.yml
@@ -0,0 +1,8 @@
+---
+name: limited_capacity_seat_refresh_worker_medium
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104099/
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/382725"
+milestone: '15.9'
+type: development
+group: group::utilization
+default_enabled: false
diff --git a/config/feature_flags/ops/automatic_lock_writes_on_table.yml b/config/feature_flags/ops/automatic_lock_writes_on_table.yml
index ade0bcb0d19..4e9ba8824a6 100644
--- a/config/feature_flags/ops/automatic_lock_writes_on_table.yml
+++ b/config/feature_flags/ops/automatic_lock_writes_on_table.yml
@@ -5,4 +5,4 @@ rollout_issue_url:
milestone: '15.7'
type: ops
group: group::pods
-default_enabled: false
+default_enabled: true
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 8a44e4077f4..e85510e3a11 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -835,6 +835,9 @@ Gitlab.ee do
Settings.cron_jobs['notify_seats_exceeded_batch_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['notify_seats_exceeded_batch_worker']['cron'] ||= '0 3 * * *'
Settings.cron_jobs['notify_seats_exceeded_batch_worker']['job_class'] ||= 'GitlabSubscriptions::NotifySeatsExceededBatchWorker'
+ Settings.cron_jobs['gitlab_subscriptionsschedule_refresh_seats_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['gitlab_subscriptions_schedule_refresh_seats_worker']['cron'] ||= "0 */6 * * *"
+ Settings.cron_jobs['gitlab_subscriptions_schedule_refresh_seats_worker']['job_class'] = 'GitlabSubscriptions::ScheduleRefreshSeatsWorker'
end
end
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 067c4730f0a..2c8169e423e 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -213,6 +213,8 @@
- 1
- - gitlab_shell
- 2
+- - gitlab_subscriptions_refresh_seats
+ - 1
- - gitlab_subscriptions_trials_apply_trial
- 1
- - google_cloud_create_cloudsql_instance
diff --git a/db/migrate/20230207015819_initialize_conversion_of_commit_user_mentions_note_id_to_bigint.rb b/db/migrate/20230207015819_initialize_conversion_of_commit_user_mentions_note_id_to_bigint.rb
new file mode 100644
index 00000000000..bede8624c2b
--- /dev/null
+++ b/db/migrate/20230207015819_initialize_conversion_of_commit_user_mentions_note_id_to_bigint.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class InitializeConversionOfCommitUserMentionsNoteIdToBigint < Gitlab::Database::Migration[2.1]
+ TABLE = :commit_user_mentions
+ COLUMNS = %i[note_id]
+
+ enable_lock_retries!
+
+ def up
+ initialize_conversion_of_integer_to_bigint(TABLE, COLUMNS)
+ end
+
+ def down
+ revert_initialize_conversion_of_integer_to_bigint(TABLE, COLUMNS)
+ end
+end
diff --git a/db/post_migrate/20230201153450_add_index_on_lfs_objects_file.rb b/db/post_migrate/20230201153450_add_index_on_lfs_objects_file.rb
new file mode 100644
index 00000000000..669b3faf3d6
--- /dev/null
+++ b/db/post_migrate/20230201153450_add_index_on_lfs_objects_file.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AddIndexOnLfsObjectsFile < Gitlab::Database::Migration[2.1]
+ INDEX_NAME = 'index_lfs_objects_on_file'
+
+ # TODO: Index to be created synchronously in https://gitlab.com/gitlab-org/gitlab/-/issues/390401
+ def up
+ prepare_async_index :lfs_objects, :file, name: INDEX_NAME
+ end
+
+ def down
+ unprepare_async_index :lfs_objects, :file, name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20230207015850_backfill_commit_user_mentions_note_id_for_bigint_conversion.rb b/db/post_migrate/20230207015850_backfill_commit_user_mentions_note_id_for_bigint_conversion.rb
new file mode 100644
index 00000000000..d690c00dc7c
--- /dev/null
+++ b/db/post_migrate/20230207015850_backfill_commit_user_mentions_note_id_for_bigint_conversion.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class BackfillCommitUserMentionsNoteIdForBigintConversion < Gitlab::Database::Migration[2.1]
+ TABLE = :commit_user_mentions
+ COLUMNS = %i[note_id]
+
+ restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+ def up
+ backfill_conversion_of_integer_to_bigint(TABLE, COLUMNS)
+ end
+
+ def down
+ revert_backfill_conversion_of_integer_to_bigint(TABLE, COLUMNS)
+ end
+end
diff --git a/db/schema_migrations/20230201153450 b/db/schema_migrations/20230201153450
new file mode 100644
index 00000000000..75f2f582af7
--- /dev/null
+++ b/db/schema_migrations/20230201153450
@@ -0,0 +1 @@
+f1af51a9623eb1ca9464c74897dababb3dbfba324453cdc36625da820e198663 \ No newline at end of file
diff --git a/db/schema_migrations/20230207015819 b/db/schema_migrations/20230207015819
new file mode 100644
index 00000000000..5f501f9a7ac
--- /dev/null
+++ b/db/schema_migrations/20230207015819
@@ -0,0 +1 @@
+fb2aae23e613c0e930b88c6ff67382330b7379e3664bb74477ebf7aa48f52e8e \ No newline at end of file
diff --git a/db/schema_migrations/20230207015850 b/db/schema_migrations/20230207015850
new file mode 100644
index 00000000000..a936f67d58e
--- /dev/null
+++ b/db/schema_migrations/20230207015850
@@ -0,0 +1 @@
+cecda7c2b2e82768edcc45546adf028ba7839c26ed403c35e12614b341760fbf \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 4d5e58cd072..1170892789e 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -225,6 +225,15 @@ RETURN NULL;
END
$$;
+CREATE FUNCTION trigger_17c3a95ee58a() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+ NEW."note_id_convert_to_bigint" := NEW."note_id";
+ RETURN NEW;
+END;
+$$;
+
CREATE FUNCTION trigger_1a857e8db6cd() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -234,7 +243,7 @@ BEGIN
END;
$$;
-CREATE FUNCTION trigger_7f4fcd5aa322() RETURNS trigger
+CREATE FUNCTION trigger_3207b8d0d6f3() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
@@ -243,25 +252,25 @@ BEGIN
END;
$$;
-CREATE FUNCTION trigger_c5a5f48f12b0() RETURNS trigger
+CREATE FUNCTION trigger_7f4fcd5aa322() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
- NEW."note_id_convert_to_bigint" := NEW."note_id";
+ NEW."id_convert_to_bigint" := NEW."id";
RETURN NEW;
END;
$$;
-CREATE FUNCTION trigger_c7107f30d69d() RETURNS trigger
+CREATE FUNCTION trigger_c5a5f48f12b0() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
- NEW."id_convert_to_bigint" := NEW."id";
+ NEW."note_id_convert_to_bigint" := NEW."note_id";
RETURN NEW;
END;
$$;
-CREATE FUNCTION trigger_3207b8d0d6f3() RETURNS trigger
+CREATE FUNCTION trigger_c7107f30d69d() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
@@ -14262,7 +14271,8 @@ CREATE TABLE commit_user_mentions (
mentioned_users_ids integer[],
mentioned_projects_ids integer[],
mentioned_groups_ids integer[],
- commit_id character varying NOT NULL
+ commit_id character varying NOT NULL,
+ note_id_convert_to_bigint bigint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE commit_user_mentions_id_seq
@@ -33515,14 +33525,16 @@ CREATE TRIGGER nullify_merge_request_metrics_build_data_on_update BEFORE UPDATE
CREATE TRIGGER projects_loose_fk_trigger AFTER DELETE ON projects REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
+CREATE TRIGGER trigger_17c3a95ee58a BEFORE INSERT OR UPDATE ON commit_user_mentions FOR EACH ROW EXECUTE FUNCTION trigger_17c3a95ee58a();
+
CREATE TRIGGER trigger_1a857e8db6cd BEFORE INSERT OR UPDATE ON vulnerability_occurrences FOR EACH ROW EXECUTE FUNCTION trigger_1a857e8db6cd();
+CREATE TRIGGER trigger_3207b8d0d6f3 BEFORE INSERT OR UPDATE ON ci_build_needs FOR EACH ROW EXECUTE FUNCTION trigger_3207b8d0d6f3();
+
CREATE TRIGGER trigger_7f4fcd5aa322 BEFORE INSERT OR UPDATE ON sent_notifications FOR EACH ROW EXECUTE FUNCTION trigger_7f4fcd5aa322();
CREATE TRIGGER trigger_c5a5f48f12b0 BEFORE INSERT OR UPDATE ON epic_user_mentions FOR EACH ROW EXECUTE FUNCTION trigger_c5a5f48f12b0();
-CREATE TRIGGER trigger_3207b8d0d6f3 BEFORE INSERT OR UPDATE ON ci_build_needs FOR EACH ROW EXECUTE FUNCTION trigger_3207b8d0d6f3();
-
CREATE TRIGGER trigger_c7107f30d69d BEFORE INSERT OR UPDATE ON merge_request_metrics FOR EACH ROW EXECUTE FUNCTION trigger_c7107f30d69d();
CREATE TRIGGER trigger_delete_project_namespace_on_project_delete AFTER DELETE ON projects FOR EACH ROW WHEN ((old.project_namespace_id IS NOT NULL)) EXECUTE FUNCTION delete_associated_project_namespace();
diff --git a/doc/administration/operations/fast_ssh_key_lookup.md b/doc/administration/operations/fast_ssh_key_lookup.md
index b3cdbd05b29..4b7d7aaa479 100644
--- a/doc/administration/operations/fast_ssh_key_lookup.md
+++ b/doc/administration/operations/fast_ssh_key_lookup.md
@@ -25,10 +25,6 @@ GitLab Shell solves this by providing a way to authorize SSH users via a fast,
indexed lookup in the GitLab database. This page describes how to enable the fast
lookup of authorized SSH keys.
-WARNING:
-OpenSSH version 6.9+ is required because `AuthorizedKeysCommand` must be
-able to accept a fingerprint. Check the version of OpenSSH on your server with `sshd -V`.
-
## Fast lookup is required for Geo **(PREMIUM)**
Unlike [Cloud Native GitLab](https://docs.gitlab.com/charts/), Omnibus GitLab by default
@@ -51,12 +47,29 @@ secondary nodes, but **Write to "authorized keys" file**
must be unchecked only on the primary node, because it is reflected
automatically on the secondary if database replication is working.
-## Setting up fast lookup via GitLab Shell
+## Set up fast lookup
GitLab Shell provides a way to authorize SSH users via a fast, indexed lookup
to the GitLab database. GitLab Shell uses the fingerprint of the SSH key to
check whether the user is authorized to access GitLab.
+Fast lookup can be enabled with the following SSH servers:
+
+- [`gitlab-sshd`](gitlab_sshd.md)
+- OpenSSH
+
+### `gitlab-sshd`
+
+To set up `gitlab-sshd`, see [the `gitlab-sshd` documentation](gitlab_sshd.md).
+After `gitlab-sshd` is enabled, GitLab Shell and `gitlab-sshd` are configured
+to use fast lookup automatically.
+
+### OpenSSH
+
+WARNING:
+OpenSSH version 6.9+ is required because `AuthorizedKeysCommand` must be
+able to accept a fingerprint. Check the version of OpenSSH on your server with `sshd -V`.
+
Add the following to your `sshd_config` file. This file is usually located at
`/etc/ssh/sshd_config`, but it is at `/assets/sshd_config` if you're using
Omnibus Docker:
@@ -119,7 +132,7 @@ Then you can backup and delete your `authorized_keys` file for best performance.
The current users' keys are already present in the database, so there is no need for migration
or for users to re-add their keys.
-## How to go back to using the `authorized_keys` file
+### How to go back to using the `authorized_keys` file
This overview is brief. Refer to the above instructions for more context.
@@ -132,138 +145,6 @@ This overview is brief. Refer to the above instructions for more context.
1. Remove the `AuthorizedKeysCommand` lines from `/etc/ssh/sshd_config` or from `/assets/sshd_config` if you are using Omnibus Docker.
1. Reload `sshd`: `sudo service sshd reload`.
-## Use `gitlab-sshd` instead of OpenSSH
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299109) in GitLab 14.5 as an **Alpha** release for self-managed customers.
-> - Ready for production use with [Cloud Native GitLab in GitLab 15.1](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/2540) and [Omnibus GitLab in GitLab 15.9](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5937).
-
-`gitlab-sshd` is [a standalone SSH server](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/sshd)
-written in Go. It is provided as a part of the `gitlab-shell` package. It has a lower memory
-use as a OpenSSH alternative, and supports
-[group access restriction by IP address](../../user/group/index.md) for applications
-running behind the proxy.
-
-`gitlab-sshd` is a lightweight alternative to OpenSSH for providing
-[SSH operations](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/71a7f34a476f778e62f8fe7a453d632d395eaf8f/doc/features.md).
-While OpenSSH uses a restricted shell approach, `gitlab-sshd` behaves more like a
-modern multi-threaded server application, responding to incoming requests. The major
-difference is that OpenSSH uses SSH as a transport protocol while `gitlab-sshd` uses Remote Procedure Calls (RPCs). See [the blog post](https://about.gitlab.com/blog/2022/08/17/why-we-have-implemented-our-own-sshd-solution-on-gitlab-sass/) for more details.
-
-The capabilities of GitLab Shell are not limited to Git operations.
-
-If you are considering switching from OpenSSH to `gitlab-sshd`, consider these concerns:
-
-- `gitlab-sshd` supports the PROXY protocol. It can run behind proxy servers that rely
- on it, such as HAProxy. The PROXY protocol is not enabled by default, but [it can be enabled](#proxy-protocol-support).
-- `gitlab-sshd` **does not** support SSH certificates. For more details, read
- [issue #495](https://gitlab.com/gitlab-org/gitlab-shell/-/issues/495).
-
-To use `gitlab-sshd`:
-
-::Tabs
-
-:::TabTitle Linux package (Omnibus)
-
-The following instructions enable `gitlab-sshd` on a different port than OpenSSH:
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_sshd['enable'] = true
- gitlab_sshd['listen_address'] = '[::]:2222' # Adjust the port accordingly
- ```
-
-1. Optional. By default, Omnibus GitLab generates SSH host keys for `gitlab-sshd` if
-they do not exist in `/var/opt/gitlab/gitlab-sshd`. If you wish to disable this automatic generation, add this line:
-
- ```ruby
- gitlab_sshd['generate_host_keys'] = false
- ```
-
-1. Save the file and reconfigure GitLab:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
-By default, `gitlab-sshd` runs as the `git` user. As a result, `gitlab-sshd` cannot
-run on privileged port numbers lower than 1024. This means users must
-access Git with the `gitlab-sshd` port, or use a load balancer that
-directs SSH traffic to the `gitlab-sshd` port to hide this.
-
-Users may see host key warnings because the newly-generated host keys
-differ from the OpenSSH host keys. Consider disabling host key
-generation and copy the existing OpenSSH host keys into
-`/var/opt/gitlab/gitlab-sshd` if this is an issue.
-
-:::TabTitle Helm chart (Kubernetes)
-
-The following instructions switch OpenSSH in favor of `gitlab-sshd`:
-
-1. Set the `gitlab-shell` charts `sshDaemon` option to
- [`gitlab-sshd`](https://docs.gitlab.com/charts/charts/gitlab/gitlab-shell/index.html#installation-command-line-options).
- For example:
-
- ```yaml
- gitlab:
- gitlab-shell:
- sshDaemon: gitlab-sshd
- ```
-
-1. Perform a Helm upgrade.
-
-By default, `gitlab-sshd` listens for:
-
-- External requests on port 22 (`global.shell.port`).
-- Internal requests on port 2222 (`gitlab.gitlab-shell.service.internalPort`).
-
-You can [configure different ports in the Helm chart](https://docs.gitlab.com/charts/charts/gitlab/gitlab-shell/#configuration).
-
-::EndTabs
-
-### PROXY protocol support
-
-When a load balancer is used in front of `gitlab-sshd`, GitLab reports the IP
-address of the proxy instead of the actual IP address of the client. `gitlab-sshd`
-supports the [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) to
-obtain the real IP address.
-
-::Tabs
-
-:::TabTitle Linux package (Omnibus)
-
-To enable the PROXY protocol:
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_sshd['proxy_protocol'] = true
- # # Proxy protocol policy ("use", "require", "reject", "ignore"), "use" is the default value
- gitlab_sshd['proxy_policy'] = "use"
- ```
-
-1. Save the file and reconfigure GitLab:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
-:::TabTitle Helm chart (Kubernetes)
-
-1. Set the [`gitlab.gitlab-shell.config` options](https://docs.gitlab.com/charts/charts/gitlab/gitlab-shell/index.html#installation-command-line-options). For example:
-
- ```yaml
- gitlab:
- gitlab-shell:
- config:
- proxyProtocol: true
- proxyPolicy: "use"
- ```
-
-1. Perform a Helm upgrade.
-
-::EndTabs
-
## SELinux support and limitations
GitLab supports `authorized_keys` database lookups with [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux).
diff --git a/doc/administration/operations/gitlab_sshd.md b/doc/administration/operations/gitlab_sshd.md
new file mode 100644
index 00000000000..7b61631fe3a
--- /dev/null
+++ b/doc/administration/operations/gitlab_sshd.md
@@ -0,0 +1,139 @@
+---
+stage: Create
+group: Source Code
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# `gitlab-sshd` **(FREE SELF)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299109) in GitLab 14.5 as an **Alpha** release for self-managed customers.
+> - Ready for production use with [Cloud Native GitLab in GitLab 15.1](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/2540) and [Omnibus GitLab in GitLab 15.9](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5937).
+
+`gitlab-sshd` is [a standalone SSH server](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/main/internal/sshd)
+written in Go. It is provided as a part of the `gitlab-shell` package. It has a lower memory
+use as a OpenSSH alternative, and supports
+[group access restriction by IP address](../../user/group/index.md) for applications
+running behind the proxy.
+
+`gitlab-sshd` is a lightweight alternative to OpenSSH for providing
+[SSH operations](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/71a7f34a476f778e62f8fe7a453d632d395eaf8f/doc/features.md).
+While OpenSSH uses a restricted shell approach, `gitlab-sshd` behaves more like a
+modern multi-threaded server application, responding to incoming requests. The major
+difference is that OpenSSH uses SSH as a transport protocol while `gitlab-sshd` uses Remote Procedure Calls (RPCs). See [the blog post](https://about.gitlab.com/blog/2022/08/17/why-we-have-implemented-our-own-sshd-solution-on-gitlab-sass/) for more details.
+
+The capabilities of GitLab Shell are not limited to Git operations.
+
+If you are considering switching from OpenSSH to `gitlab-sshd`, consider these concerns:
+
+- `gitlab-sshd` supports the PROXY protocol. It can run behind proxy servers that rely
+ on it, such as HAProxy. The PROXY protocol is not enabled by default, but [it can be enabled](#proxy-protocol-support).
+- `gitlab-sshd` **does not** support SSH certificates. For more details, read
+ [issue #495](https://gitlab.com/gitlab-org/gitlab-shell/-/issues/495).
+
+## Enable `gitlab-sshd`
+
+To use `gitlab-sshd`:
+
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+The following instructions enable `gitlab-sshd` on a different port than OpenSSH:
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_sshd['enable'] = true
+ gitlab_sshd['listen_address'] = '[::]:2222' # Adjust the port accordingly
+ ```
+
+1. Optional. By default, Omnibus GitLab generates SSH host keys for `gitlab-sshd` if
+they do not exist in `/var/opt/gitlab/gitlab-sshd`. If you wish to disable this automatic generation, add this line:
+
+ ```ruby
+ gitlab_sshd['generate_host_keys'] = false
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+By default, `gitlab-sshd` runs as the `git` user. As a result, `gitlab-sshd` cannot
+run on privileged port numbers lower than 1024. This means users must
+access Git with the `gitlab-sshd` port, or use a load balancer that
+directs SSH traffic to the `gitlab-sshd` port to hide this.
+
+Users may see host key warnings because the newly-generated host keys
+differ from the OpenSSH host keys. Consider disabling host key
+generation and copy the existing OpenSSH host keys into
+`/var/opt/gitlab/gitlab-sshd` if this is an issue.
+
+:::TabTitle Helm chart (Kubernetes)
+
+The following instructions switch OpenSSH in favor of `gitlab-sshd`:
+
+1. Set the `gitlab-shell` charts `sshDaemon` option to
+ [`gitlab-sshd`](https://docs.gitlab.com/charts/charts/gitlab/gitlab-shell/index.html#installation-command-line-options).
+ For example:
+
+ ```yaml
+ gitlab:
+ gitlab-shell:
+ sshDaemon: gitlab-sshd
+ ```
+
+1. Perform a Helm upgrade.
+
+By default, `gitlab-sshd` listens for:
+
+- External requests on port 22 (`global.shell.port`).
+- Internal requests on port 2222 (`gitlab.gitlab-shell.service.internalPort`).
+
+You can [configure different ports in the Helm chart](https://docs.gitlab.com/charts/charts/gitlab/gitlab-shell/#configuration).
+
+::EndTabs
+
+## PROXY protocol support
+
+When a load balancer is used in front of `gitlab-sshd`, GitLab reports the IP
+address of the proxy instead of the actual IP address of the client. `gitlab-sshd`
+supports the [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) to
+obtain the real IP address.
+
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+To enable the PROXY protocol:
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_sshd['proxy_protocol'] = true
+ # # Proxy protocol policy ("use", "require", "reject", "ignore"), "use" is the default value
+ gitlab_sshd['proxy_policy'] = "use"
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Set the [`gitlab.gitlab-shell.config` options](https://docs.gitlab.com/charts/charts/gitlab/gitlab-shell/index.html#installation-command-line-options). For example:
+
+ ```yaml
+ gitlab:
+ gitlab-shell:
+ config:
+ proxyProtocol: true
+ proxyPolicy: "use"
+ ```
+
+1. Perform a Helm upgrade.
+
+::EndTabs
diff --git a/doc/administration/operations/index.md b/doc/administration/operations/index.md
index 527a72c5933..f6ab46b9fbf 100644
--- a/doc/administration/operations/index.md
+++ b/doc/administration/operations/index.md
@@ -17,6 +17,7 @@ Keep your GitLab instance up and running smoothly.
to restart Sidekiq.
- [Multiple Sidekiq processes](../sidekiq/extra_sidekiq_processes.md): Configure multiple Sidekiq processes to ensure certain queues always have dedicated workers, no matter the number of jobs that must be processed. **(FREE SELF)**
- [Puma](puma.md): Understand Puma and puma-worker-killer.
+- [`gitlab-sshd`](gitlab_sshd.md): Use GitLab SSH daemon instead of OpenSSH.
- Speed up SSH operations by
[Authorizing SSH users via a fast, indexed lookup to the GitLab database](fast_ssh_key_lookup.md), and/or
by [doing away with user SSH keys stored on GitLab entirely in favor of SSH certificates](ssh_certificates.md).
diff --git a/doc/ci/jobs/ci_job_token.md b/doc/ci/jobs/ci_job_token.md
index 4ae4456c56c..d9cfbdf124e 100644
--- a/doc/ci/jobs/ci_job_token.md
+++ b/doc/ci/jobs/ci_job_token.md
@@ -61,26 +61,96 @@ your [runners](../runners/index.md) to be secure. Avoid:
If you have an insecure GitLab Runner configuration, you increase the risk that someone
tries to steal tokens from other jobs.
-## Limit GitLab CI/CD job token access
+## Configure CI/CD job token access
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/328553) in GitLab 14.1. [Deployed behind the `:ci_scoped_job_token` feature flag](../../user/feature_flags.md), disabled by default.
-> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/332272) in GitLab 14.4.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/332272) in GitLab 14.6.
-
-You can limit the access scope of a project's CI/CD job token to increase the
+You can control what projects a CI/CD job token can access to increase the
job token's security. A job token might give extra permissions that aren't necessary
to access specific private resources.
-If a job token is leaked it could potentially be used to access data that is private
+
+If a job token is leaked, it could potentially be used to access private data
to the job token's user. By limiting the job token access scope, private data cannot
be accessed unless projects are explicitly authorized.
-Control the job token access scope with an allowlist of other projects authorized
-to be accessed by authenticating with the current project's job token. By default
-the token scope only allows access to the same project where the token comes from.
+There is a proposal to add more strategic control of the access permissions,
+see [epic 3559](https://gitlab.com/groups/gitlab-org/-/epics/3559).
+
+### Allow access to your project with a job token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346298/) in GitLab 15.9. [Deployed behind the `:inbound_ci_scoped_job_token` feature flag](../../user/feature_flags.md), enabled by default.
+
+Control your project's job token scope by creating an **inbound** allowlist of projects which can
+access your project through its `CI_JOB_TOKEN`.
+
+For example, you can add project `B` to the inbound allowlist for project `A`. Jobs
+in the pipeline for "allowed project" `B` can now use the CI/CD job token to authenticate
+API calls to access project `A`.
+
+By default the allowlist includes your current project.
+
+It is a security risk to disable this feature, so project maintainers or owners should
+keep this setting enabled at all times. Add projects to the allowlist only when cross-project
+access is needed.
+
+### Disable the inbound job token scope allowlist
+
+WARNING:
+It is a security risk to disable the allowlist. A malicious user could try to compromise
+a pipeline created in an unauthorized project. If the pipeline was created by one of
+your maintainers, the job token could be used in an attempt to access your project.
+
+You can disable the inbound job token scope allowlist for testing or a similar reason,
+but you should enable it again as soon as possible.
+
+Prerequisite:
+
+- You must have at least the Maintainer role for the project.
+
+To disable the inbound job token scope allowlist:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Token Access**.
+1. Toggle **Allow access to this project with a CI_JOB_TOKEN** to disabled.
+ Enabled by default in new projects.
+
+### Add a project to the inbound job token scope allowlist
+
+You can add projects to the inbound allowlist for a project. Projects added to the allowlist
+can make API calls from running pipelines by using the CI/CD job token.
+
+Prerequisite:
+
+- You must have at least the Maintainer role in the current project and at least
+ the Guest role in the allowed project.
+- You must not have more than 100 projects added to the allowlist.
+
+To add a project:
+
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Token Access**.
+1. Verify **Allow access to this project with a CI_JOB_TOKEN** is enabled.
+1. Under **Allow CI job tokens from the following projects to access this project**,
+ add projects to the allowlist.
+
+### Limit your project's job token access
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/328553) in GitLab 14.1. [Deployed behind the `:ci_scoped_job_token` feature flag](../../user/feature_flags.md), disabled by default.
+> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/332272) in GitLab 14.4.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/332272) in GitLab 14.6.
+
+NOTE:
+This feature is disabled by default for all new projects and is [scheduled for removal](https://gitlab.com/gitlab-org/gitlab/-/issues/383084)
+in GitLab 16.0. Project maintainers or owners should enable the **inbound** access control instead.
+
+Control your project's job token scope by creating an **outbound** allowlist of projects which
+can be accessed by your project's job token.
+
+By default, the allowlist includes your current project.
Other projects can be added and removed by maintainers with access to both projects.
-This setting is disabled by default for all new projects. It is recommended that project maintainers or owners enable this
-setting at all times, and configure the allowlist for cross-project access if needed.
+With the setting disabled, all projects are considered in the allowlist and the job token is
+limited only by the user's access permissions.
For example, when the setting is enabled, jobs in a pipeline in project `A` have
a `CI_JOB_TOKEN` scope limited to project `A`. If the job needs to use the token
@@ -88,7 +158,13 @@ to make an API request to a private project `B`, then `B` must be added to the a
If project `B` is public or internal, it's not required to be added to the allowlist.
The job token scope is only for controlling access to private projects.
-### Configure the job token scope limit
+### Configure the outbound job token scope
+
+Prerequisite:
+
+- You must not have more than 100 projects added to the token's scope.
+
+To configure the outbound job token scope:
1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Settings > CI/CD**.
@@ -97,9 +173,6 @@ The job token scope is only for controlling access to private projects.
1. Optional. Add existing projects to the token's access scope. The user adding a
project must have the Maintainer role in both projects.
-There is [a proposal](https://gitlab.com/groups/gitlab-org/-/epics/3559) to improve
-the feature with more strategic control of the access permissions.
-
## Download an artifact from a different pipeline **(PREMIUM)**
> `CI_JOB_TOKEN` for artifacts download with the API was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/2346) in GitLab 9.5.
@@ -157,10 +230,10 @@ CI job token failures are usually shown as responses like `404 Not Found` or sim
While troubleshooting CI/CD job token authentication issues, be aware that:
-- When the [CI/CD job token limit](#limit-gitlab-cicd-job-token-access) is enabled,
+- When the [CI/CD job token scopes](#configure-cicd-job-token-access) are enabled,
and the job token is being used to access a different project:
- The user that executes the job must be a member of the project that is being accessed.
- The user must have the [permissions](../../user/permissions.md) to perform the action.
- - The target project must be [allowlisted for the job token scope limit](#configure-the-job-token-scope-limit).
+ - The accessed project must have the project attempting to access it [added to the inbound allowlist](#add-a-project-to-the-inbound-job-token-scope-allowlist).
- The CI job token becomes invalid if the job is no longer running, has been erased,
or if the project is in the process of being deleted.
diff --git a/doc/install/aws/manual_install_aws.md b/doc/install/aws/manual_install_aws.md
index 5d8138e4705..29e0c56a16b 100644
--- a/doc/install/aws/manual_install_aws.md
+++ b/doc/install/aws/manual_install_aws.md
@@ -613,7 +613,7 @@ Remember to run `sudo gitlab-ctl reconfigure` after saving the changes to the `g
The public SSH keys for users allowed to access GitLab are stored in `/var/opt/gitlab/.ssh/authorized_keys`. Typically we'd use shared storage so that all the instances are able to access this file when a user performs a Git action over SSH. Because we do not have shared storage in our setup, we update our configuration to authorize SSH users via indexed lookup in the GitLab database.
-Follow the instructions at [Setting up fast lookup via GitLab Shell](../../administration/operations/fast_ssh_key_lookup.md#setting-up-fast-lookup-via-gitlab-shell) to switch from using the `authorized_keys` file to the database.
+Follow the instructions at [Set up fast SSH key lookup](../../administration/operations/fast_ssh_key_lookup.md#set-up-fast-lookup) to switch from using the `authorized_keys` file to the database.
If you do not configure fast lookup, Git actions over SSH results in the following error:
diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md
index 2b5c3b5ee21..262c6eef6df 100644
--- a/doc/user/admin_area/settings/index.md
+++ b/doc/user/admin_area/settings/index.md
@@ -117,7 +117,7 @@ The **Metrics and profiling** settings contain:
The **Network** settings contain:
- Performance optimization - Various settings that affect GitLab performance, including:
- - [Write to `authorized_keys` file](../../../administration/operations/fast_ssh_key_lookup.md#setting-up-fast-lookup-via-gitlab-shell).
+ - [Write to `authorized_keys` file](../../../administration/operations/fast_ssh_key_lookup.md#set-up-fast-lookup).
- [Push event activities limit and bulk push events](push_event_activities_limit.md).
- [User and IP rate limits](user_and_ip_rate_limits.md) - Configure limits for web and API requests.
These rate limits can be overridden:
diff --git a/doc/user/application_security/get-started-security.md b/doc/user/application_security/get-started-security.md
index 788100fa57e..cec2090e5ef 100644
--- a/doc/user/application_security/get-started-security.md
+++ b/doc/user/application_security/get-started-security.md
@@ -27,7 +27,8 @@ The following steps help you get the most from GitLab application security tools
1. Consider creating [labels](../project/labels.md) and [issue boards](../project/issue_board.md) to
help manage issues created from vulnerabilities. Issue boards allow all stakeholders to have a
common view of all issues and track remediation progress.
-1. Use [scheduled pipelines](../../ci/pipelines/schedules.md#scheduled-pipelines) to regularly scan important branches such as `default` or those used for maintenance releases.
+1. Enforce scheduled security scanning jobs by using a [scan execution policy](policies/scan-execution-policies.md).
+ - These scheduled jobs run independently from any other security scans you may have defined in a compliance framework pipeline or in the project's `.gitlab-ci.yml` file.
- Running regular dependency and [container scans](container_scanning/index.md) surface newly-discovered vulnerabilities that already exist in your repository.
- Scheduled scans are most useful for projects or important branches with low development activity where pipeline scans are infrequent.
1. Create a [scan result policy](policies/index.md) to limit new vulnerabilities from being merged
diff --git a/doc/user/group/compliance_frameworks.md b/doc/user/group/compliance_frameworks.md
index a926acf5b08..0940f120466 100644
--- a/doc/user/group/compliance_frameworks.md
+++ b/doc/user/group/compliance_frameworks.md
@@ -14,13 +14,16 @@ requirements or needs additional oversight. The label can optionally enforce
[compliance pipeline configuration](#configure-a-compliance-pipeline) to the projects on which it is
[applied](../project/settings/index.md#add-a-compliance-framework-to-a-project).
-Group owners can create, edit, and delete compliance frameworks:
+Compliance frameworks are created on top-level groups. Group owners can create, edit, and delete compliance frameworks:
1. On the top bar, select **Main menu > Groups > View all groups** and find your group.
1. On the left sidebar, select **Settings** > **General**.
1. Expand the **Compliance frameworks** section.
1. Create, edit, or delete compliance frameworks.
+Subgroups and projects have access to all compliance frameworks created on their top-level group. However, compliance frameworks cannot be created, edited,
+or deleted at the subgroup or project level. Project owners can choose a framework to apply to their projects.
+
## Default compliance frameworks
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375036) in GitLab 15.6.
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ae9b654d73d..10e7c4a438c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -34433,6 +34433,9 @@ msgstr ""
msgid "ProtectedBranch|Does not apply to users allowed to push. Optional sections are not enforced."
msgstr ""
+msgid "ProtectedBranch|Inherited - This setting can be changed at the group level"
+msgstr ""
+
msgid "ProtectedBranch|Keep stable branches secure and force developers to use merge requests."
msgstr ""
diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb
index 51ea2e5d7c6..781e4ff7b00 100644
--- a/spec/controllers/projects/settings/repository_controller_spec.rb
+++ b/spec/controllers/projects/settings/repository_controller_spec.rb
@@ -19,40 +19,6 @@ RSpec.describe Projects::Settings::RepositoryController, feature_category: :sour
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:show)
end
-
- context 'when feature flag `group_protected_branches` disabled' do
- before do
- stub_feature_flags(group_protected_branches: false)
- end
-
- it 'does not assign instance variable `protected_group_branches`' do
- get :show, params: base_params
-
- expect(assigns).not_to include(:protected_group_branches)
- end
- end
-
- context 'when feature flag `group_protected_branches` enabled' do
- context 'when the root namespace is a user' do
- it 'assigns empty instance variable `protected_group_branches`' do
- get :show, params: base_params
-
- expect(assigns[:protected_group_branches]).to eq([])
- end
- end
-
- context 'when the root namespace is a group' do
- let_it_be(:project) { create(:project_empty_repo, :public, :in_group) }
-
- let(:protected_group_branch) { create(:protected_branch, group: project.root_namespace, project: nil) }
-
- it 'assigns instance variable `protected_group_branches`' do
- get :show, params: base_params
-
- expect(assigns[:protected_group_branches]).to include(protected_group_branch)
- end
- end
- end
end
describe 'PUT cleanup' do
diff --git a/spec/frontend/boards/components/board_list_header_spec.js b/spec/frontend/boards/components/board_list_header_spec.js
index a16b99728c3..80e77921459 100644
--- a/spec/frontend/boards/components/board_list_header_spec.js
+++ b/spec/frontend/boards/components/board_list_header_spec.js
@@ -35,6 +35,7 @@ describe('Board List Header Component', () => {
withLocalStorage = true,
currentUserId = 1,
listQueryHandler = jest.fn().mockResolvedValue(boardListQueryResponse()),
+ injectedProps = {},
} = {}) => {
const boardId = '1';
@@ -76,6 +77,7 @@ describe('Board List Header Component', () => {
currentUserId,
isEpicBoard: false,
disabled: false,
+ ...injectedProps,
},
}),
);
@@ -86,6 +88,7 @@ describe('Board List Header Component', () => {
const findAddIssueButton = () => wrapper.findComponent({ ref: 'newIssueBtn' });
const findTitle = () => wrapper.find('.board-title');
const findCaret = () => wrapper.findByTestId('board-title-caret');
+ const findSettingsButton = () => wrapper.findComponent({ ref: 'settingsBtn' });
describe('Add issue button', () => {
const hasNoAddButton = [ListType.closed];
@@ -126,6 +129,33 @@ describe('Board List Header Component', () => {
});
});
+ describe('Settings Button', () => {
+ describe('with disabled=true', () => {
+ const hasSettings = [
+ ListType.assignee,
+ ListType.milestone,
+ ListType.iteration,
+ ListType.label,
+ ];
+ const hasNoSettings = [ListType.backlog, ListType.closed];
+
+ it.each(hasSettings)('does render for List Type `%s` when disabled=true', (listType) => {
+ createComponent({ listType, injectedProps: { disabled: true } });
+
+ expect(findSettingsButton().exists()).toBe(true);
+ });
+
+ it.each(hasNoSettings)(
+ 'does not render for List Type `%s` when disabled=true',
+ (listType) => {
+ createComponent({ listType });
+
+ expect(findSettingsButton().exists()).toBe(false);
+ },
+ );
+ });
+ });
+
describe('expanding / collapsing the column', () => {
it('should display collapse icon when column is expanded', async () => {
createComponent();
diff --git a/spec/frontend/groups_projects/components/transfer_locations_spec.js b/spec/frontend/groups_projects/components/transfer_locations_spec.js
index 74424ee3230..77c0966ba1e 100644
--- a/spec/frontend/groups_projects/components/transfer_locations_spec.js
+++ b/spec/frontend/groups_projects/components/transfer_locations_spec.js
@@ -15,7 +15,7 @@ import { mountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import createMockApollo from 'helpers/mock_apollo_helper';
import { __ } from '~/locale';
-import TransferLocations from '~/groups_projects/components/transfer_locations.vue';
+import TransferLocations, { i18n } from '~/groups_projects/components/transfer_locations.vue';
import { getTransferLocations } from '~/api/projects_api';
import currentUserNamespaceQuery from '~/projects/settings/graphql/queries/current_user_namespace.query.graphql';
@@ -374,4 +374,23 @@ describe('TransferLocations', () => {
expect(wrapper.findByRole('group', { name: label }).exists()).toBe(true);
});
});
+
+ describe('when there are no results', () => {
+ it('displays no results message', async () => {
+ mockResolvedGetTransferLocations({
+ data: [],
+ page: '1',
+ nextPage: null,
+ total: '0',
+ totalPages: '1',
+ prevPage: null,
+ });
+
+ createComponent({ propsData: { showUserTransferLocations: false } });
+
+ await showDropdown();
+
+ expect(wrapper.findComponent(GlDropdownItem).text()).toBe(i18n.NO_RESULTS_TEXT);
+ });
+ });
});
diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb
index d5e9b04f03e..71e22f848cc 100644
--- a/spec/models/protected_branch_spec.rb
+++ b/spec/models/protected_branch_spec.rb
@@ -526,4 +526,22 @@ RSpec.describe ProtectedBranch do
it { is_expected.not_to be_default_branch }
end
end
+
+ describe '#group_level?' do
+ context 'when entity is a Group' do
+ before do
+ subject.assign_attributes(project: nil, group: build(:group))
+ end
+
+ it { is_expected.to be_group_level }
+ end
+
+ context 'when entity is a Project' do
+ before do
+ subject.assign_attributes(project: build(:project), group: nil)
+ end
+
+ it { is_expected.not_to be_group_level }
+ end
+ end
end
diff --git a/spec/services/ci/job_token_scope/remove_project_service_spec.rb b/spec/services/ci/job_token_scope/remove_project_service_spec.rb
index c3f9081cbd8..e154d8c0422 100644
--- a/spec/services/ci/job_token_scope/remove_project_service_spec.rb
+++ b/spec/services/ci/job_token_scope/remove_project_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe Ci::JobTokenScope::RemoveProjectService do
+RSpec.describe Ci::JobTokenScope::RemoveProjectService, feature_category: :continuous_integration do
let(:service) { described_class.new(project, current_user) }
let_it_be(:project) { create(:project, ci_outbound_job_token_scope_enabled: true).tap(&:save!) }
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index c444e1f383c..c583631e4d5 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -303,6 +303,7 @@ RSpec.describe 'Every Sidekiq worker' do
'Gitlab::JiraImport::Stage::StartImportWorker' => 5,
'Gitlab::PhabricatorImport::ImportTasksWorker' => 5,
'GitlabPerformanceBarStatsWorker' => 3,
+ 'GitlabSubscriptions::RefreshSeatsWorker' => 0,
'GitlabShellWorker' => 3,
'GitlabServicePingWorker' => 3,
'GroupDestroyWorker' => 3,