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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/review-apps/main.gitlab-ci.yml2
-rw-r--r--.rubocop_todo/style/redundant_self.yml18
-rw-r--r--Gemfile6
-rw-r--r--Gemfile.checksum10
-rw-r--r--Gemfile.lock16
-rw-r--r--app/assets/javascripts/environments/components/environment_form.vue22
-rw-r--r--app/assets/javascripts/environments/constants.js6
-rw-r--r--app/assets/javascripts/environments/edit.js1
-rw-r--r--app/assets/javascripts/pages/admin/jobs/index/components/cancel_jobs.vue37
-rw-r--r--app/assets/javascripts/pages/admin/jobs/index/components/cancel_jobs_modal.vue (renamed from app/assets/javascripts/pages/admin/jobs/index/components/stop_jobs_modal.vue)24
-rw-r--r--app/assets/javascripts/pages/admin/jobs/index/components/constants.js15
-rw-r--r--app/assets/javascripts/pages/admin/jobs/index/index.js23
-rw-r--r--app/channels/awareness_channel.rb2
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/finders/security/jobs_finder.rb2
-rw-r--r--app/graphql/types/permission_types/base_permission_type.rb2
-rw-r--r--app/helpers/groups_helper.rb2
-rw-r--r--app/models/abuse_report.rb4
-rw-r--r--app/models/analytics/usage_trends/measurement.rb4
-rw-r--r--app/models/application_record.rb6
-rw-r--r--app/models/application_setting_implementation.rb16
-rw-r--r--app/models/audit_event.rb8
-rw-r--r--app/models/award_emoji.rb4
-rw-r--r--app/models/board.rb2
-rw-r--r--app/models/ci/application_record.rb2
-rw-r--r--app/models/ci/bridge.rb4
-rw-r--r--app/models/ci/build.rb28
-rw-r--r--app/models/ci/build_metadata.rb2
-rw-r--r--app/models/ci/build_runner_session.rb4
-rw-r--r--app/models/ci/build_trace_chunk.rb8
-rw-r--r--app/models/ci/deleted_object.rb2
-rw-r--r--app/models/clusters/applications/cert_manager.rb129
-rw-r--r--app/models/clusters/cluster.rb2
-rw-r--r--app/models/ml/experiment.rb6
-rw-r--r--app/policies/group_policy.rb5
-rw-r--r--app/views/groups/merge_requests.html.haml7
-rw-r--r--app/views/projects/environments/edit.html.haml1
-rw-r--r--db/docs/clusters_applications_cert_managers.yml2
-rw-r--r--doc/administration/clusters/kas.md2
-rw-r--r--doc/administration/object_storage.md281
-rw-r--r--doc/development/documentation/topic_types/task.md66
-rw-r--r--doc/integration/arkose.md24
-rw-r--r--doc/integration/omniauth.md23
-rw-r--r--doc/integration/saml.md2930
-rw-r--r--doc/raketasks/backup_gitlab.md2
-rw-r--r--doc/user/packages/nuget_repository/index.md6
-rw-r--r--lib/api/merge_requests.rb5
-rw-r--r--locale/gitlab.pot31
-rw-r--r--spec/controllers/groups_controller_spec.rb47
-rw-r--r--spec/factories/clusters/applications/helm.rb5
-rw-r--r--spec/factories/clusters/clusters.rb1
-rw-r--r--spec/features/admin/admin_jobs_spec.rb4
-rw-r--r--spec/frontend/environments/edit_environment_spec.js1
-rw-r--r--spec/frontend/environments/environment_form_spec.js9
-rw-r--r--spec/frontend/environments/new_environment_spec.js5
-rw-r--r--spec/frontend/pages/admin/jobs/index/components/cancel_jobs_modal_spec.js (renamed from spec/frontend/pages/admin/jobs/index/components/stop_jobs_modal_spec.js)21
-rw-r--r--spec/frontend/pages/admin/jobs/index/components/cancel_jobs_spec.js57
-rw-r--r--spec/graphql/types/ci/runner_architecture_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_platform_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_setup_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_type_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb2
-rw-r--r--spec/graphql/types/ci/runner_web_url_edge_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/runner_instructions_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/runner_releases_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/runner_upgrade_check_spec.rb2
-rw-r--r--spec/models/clusters/applications/cert_manager_spec.rb157
-rw-r--r--spec/models/clusters/cluster_spec.rb3
-rw-r--r--spec/models/ml/experiment_spec.rb17
-rw-r--r--spec/views/admin/application_settings/_jira_connect.html.haml_spec.rb2
-rw-r--r--workhorse/go.mod2
-rw-r--r--workhorse/go.sum4
72 files changed, 3267 insertions, 892 deletions
diff --git a/.gitlab/ci/review-apps/main.gitlab-ci.yml b/.gitlab/ci/review-apps/main.gitlab-ci.yml
index da3a2afcbb6..55d31fe5df7 100644
--- a/.gitlab/ci/review-apps/main.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/main.gitlab-ci.yml
@@ -108,7 +108,7 @@ review-deploy:
- .review-workflow-base
- .review:rules:review-deploy
stage: deploy
- image: ${GITLAB_DEPENDENCY_PROXY_ADDRESS}dtzar/helm-kubectl:3.10.3
+ image: ${GITLAB_DEPENDENCY_PROXY_ADDRESS}dtzar/helm-kubectl:3.9.3
needs:
- review-build-cng
- review-delete-deployment # We always want to start from a clean slate (i.e. no helm release, no k8s namespace)
diff --git a/.rubocop_todo/style/redundant_self.yml b/.rubocop_todo/style/redundant_self.yml
index ae19cf458be..4f5f4fe632f 100644
--- a/.rubocop_todo/style/redundant_self.yml
+++ b/.rubocop_todo/style/redundant_self.yml
@@ -2,25 +2,7 @@
# Cop supports --autocorrect.
Style/RedundantSelf:
Exclude:
- - 'app/channels/awareness_channel.rb'
- - 'app/controllers/application_controller.rb'
- - 'app/finders/security/jobs_finder.rb'
- - 'app/graphql/types/permission_types/base_permission_type.rb'
- - 'app/models/abuse_report.rb'
- - 'app/models/analytics/usage_trends/measurement.rb'
- - 'app/models/application_record.rb'
- 'app/models/application_setting.rb'
- - 'app/models/application_setting_implementation.rb'
- - 'app/models/audit_event.rb'
- - 'app/models/award_emoji.rb'
- - 'app/models/board.rb'
- - 'app/models/ci/application_record.rb'
- - 'app/models/ci/bridge.rb'
- - 'app/models/ci/build.rb'
- - 'app/models/ci/build_metadata.rb'
- - 'app/models/ci/build_runner_session.rb'
- - 'app/models/ci/build_trace_chunk.rb'
- - 'app/models/ci/deleted_object.rb'
- 'app/models/ci/group.rb'
- 'app/models/ci/job_artifact.rb'
- 'app/models/ci/job_token/project_scope_link.rb'
diff --git a/Gemfile b/Gemfile
index 4bbee264aa4..4ba96c983f0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -15,7 +15,7 @@ gem 'bundler-checksum', '~> 0.1.0', path: 'vendor/gems/bundler-checksum', requir
# https://gitlab.com/gitlab-org/gitlab/-/issues/375713
gem 'rails', '~> 6.1.7.1'
-gem 'bootsnap', '~> 1.15.0', require: false
+gem 'bootsnap', '~> 1.16.0', require: false
# Pin openssl to match the version bundled with our supported Rubies.
# See https://stdgems.org/openssl/#gem-version.
@@ -174,9 +174,9 @@ gem 'seed-fu', '~> 2.3.7'
gem 'elasticsearch-model', '~> 7.2'
gem 'elasticsearch-rails', '~> 7.2', require: 'elasticsearch/rails/instrumentation'
gem 'elasticsearch-api', '7.13.3'
-gem 'aws-sdk-core', '~> 3.168.4'
+gem 'aws-sdk-core', '~> 3.169.0'
gem 'aws-sdk-cloudformation', '~> 1'
-gem 'aws-sdk-s3', '~> 1.117.2'
+gem 'aws-sdk-s3', '~> 1.118.0'
gem 'faraday_middleware-aws-sigv4', '~>0.3.0'
gem 'typhoeus', '~> 1.4.0' # Used with Elasticsearch to support http keep-alive connections
diff --git a/Gemfile.checksum b/Gemfile.checksum
index cfc3af02693..5eaded751b0 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -35,11 +35,11 @@
{"name":"awesome_print","version":"1.9.2","platform":"ruby","checksum":"e99b32b704acff16d768b3468680793ced40bfdc4537eb07e06a4be11133786e"},
{"name":"awrence","version":"1.1.1","platform":"ruby","checksum":"9be584c97408ed92d5e1ca11740853646fe270de675f2f8dd44e8233226dfc97"},
{"name":"aws-eventstream","version":"1.2.0","platform":"ruby","checksum":"ffa53482c92880b001ff2fb06919b9bb82fd847cbb0fa244985d2ebb6dd0d1df"},
-{"name":"aws-partitions","version":"1.674.0","platform":"ruby","checksum":"f96e70d85490bbabc2d4b911bad62412fa5e0a643701499e59f8e38d4ab69128"},
+{"name":"aws-partitions","version":"1.695.0","platform":"ruby","checksum":"f48ded613316522f5e44905af9c029dc62b43b7acaa917d9322831029ed45174"},
{"name":"aws-sdk-cloudformation","version":"1.41.0","platform":"ruby","checksum":"31e47539719734413671edf9b1a31f8673fbf9688549f50c41affabbcb1c6b26"},
-{"name":"aws-sdk-core","version":"3.168.4","platform":"ruby","checksum":"2c9bf6cb0c19f9d23fe2a9d5eca15381b0b904d19f2dd7801d094528f8632a8c"},
-{"name":"aws-sdk-kms","version":"1.61.0","platform":"ruby","checksum":"fe6f50aed34f38bd421e43fe997780c86beeecef2898573b30ad2467b73f572a"},
-{"name":"aws-sdk-s3","version":"1.117.2","platform":"ruby","checksum":"2159b3cbc45fc4a129f178ce54770023684fad078ce5c0577e8005fe1143ebf6"},
+{"name":"aws-sdk-core","version":"3.169.0","platform":"ruby","checksum":"81e75e70dfd4a17c55554b593ad2de5534b6cab9197cd8e278eb8b0a9ad4051b"},
+{"name":"aws-sdk-kms","version":"1.62.0","platform":"ruby","checksum":"b9111c698d783f3f092dcc6a8b9b7e3f53f00e6e501bdc5a4409afdcaf411a1c"},
+{"name":"aws-sdk-s3","version":"1.118.0","platform":"ruby","checksum":"85358b4e56a4b56bba0b8995127f1f6123929d9eb7007534925b359a4a0433db"},
{"name":"aws-sigv4","version":"1.5.1","platform":"ruby","checksum":"d68c87fff4ee843b4b92b23c7f31f957f254ec6eb064181f7119124aab8b8bb4"},
{"name":"azure-storage-blob","version":"2.0.3","platform":"ruby","checksum":"61b76118843c91776bd24bee22c74adafeb7c4bb3a858a325047dae3b59d0363"},
{"name":"azure-storage-common","version":"2.0.4","platform":"ruby","checksum":"608f4daab0e06b583b73dcffd3246ea39e78056de31630286b0cf97af7d6956b"},
@@ -59,7 +59,7 @@
{"name":"bindata","version":"2.4.11","platform":"ruby","checksum":"c38e0c99ffcd80c10a0a7ae6c8586d2fe26bf245cbefac90bec8764523220f6a"},
{"name":"binding_ninja","version":"0.2.3","platform":"java","checksum":"bbcf70b211d6e397493bf57c249bbec6aaf28fa7dafeb78e447b1b2f0610484f"},
{"name":"binding_ninja","version":"0.2.3","platform":"ruby","checksum":"4a85550a0066ee4721506b4e150857486808e50c9ddfeed04bdc896bb61eca9d"},
-{"name":"bootsnap","version":"1.15.0","platform":"ruby","checksum":"f246bb1152159098f5d5619b92e373c73db77769bf3e0c4b6336feeb934bc8d2"},
+{"name":"bootsnap","version":"1.16.0","platform":"ruby","checksum":"f87410c00f69cd84a6e72a6c4bdba733f800d80d934f4315849d18ca9f288fed"},
{"name":"bootstrap_form","version":"4.2.0","platform":"ruby","checksum":"f578b3c900d2cf15fab641064d357318b29e285bd5fdf090f903727912889710"},
{"name":"browser","version":"5.3.1","platform":"ruby","checksum":"62745301701ff2c6c5d32d077bb12532b20be261929dcb52c6781ed0d5658b3c"},
{"name":"builder","version":"3.2.4","platform":"ruby","checksum":"99caf08af60c8d7f3a6b004029c4c3c0bdaebced6c949165fe98f1db27fbbc10"},
diff --git a/Gemfile.lock b/Gemfile.lock
index a7bdfb7c00d..99649e7e36c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -200,19 +200,19 @@ GEM
awesome_print (1.9.2)
awrence (1.1.1)
aws-eventstream (1.2.0)
- aws-partitions (1.674.0)
+ aws-partitions (1.695.0)
aws-sdk-cloudformation (1.41.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
- aws-sdk-core (3.168.4)
+ aws-sdk-core (3.169.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
- aws-sdk-kms (1.61.0)
+ aws-sdk-kms (1.62.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
- aws-sdk-s3 (1.117.2)
+ aws-sdk-s3 (1.118.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
@@ -244,7 +244,7 @@ GEM
rack (>= 0.9.0)
bindata (2.4.11)
binding_ninja (0.2.3)
- bootsnap (1.15.0)
+ bootsnap (1.16.0)
msgpack (~> 1.2)
bootstrap_form (4.2.0)
actionpack (>= 5.0)
@@ -1599,8 +1599,8 @@ DEPENDENCIES
autoprefixer-rails (= 10.2.5.1)
awesome_print
aws-sdk-cloudformation (~> 1)
- aws-sdk-core (~> 3.168.4)
- aws-sdk-s3 (~> 1.117.2)
+ aws-sdk-core (~> 3.169.0)
+ aws-sdk-s3 (~> 1.118.0)
babosa (~> 1.0.4)
base32 (~> 0.3.0)
batch-loader (~> 2.0.1)
@@ -1608,7 +1608,7 @@ DEPENDENCIES
benchmark-ips (~> 2.3.0)
benchmark-memory (~> 0.1)
better_errors (~> 2.9.1)
- bootsnap (~> 1.15.0)
+ bootsnap (~> 1.16.0)
bootstrap_form (~> 4.2.0)
browser (~> 5.3.1)
bullet (~> 7.0.2)
diff --git a/app/assets/javascripts/environments/components/environment_form.vue b/app/assets/javascripts/environments/components/environment_form.vue
index 1bac0ef1359..ee5d95ae6f0 100644
--- a/app/assets/javascripts/environments/components/environment_form.vue
+++ b/app/assets/javascripts/environments/components/environment_form.vue
@@ -3,6 +3,10 @@ import { GlButton, GlForm, GlFormGroup, GlFormInput, GlLink, GlSprintf } from '@
import { helpPagePath } from '~/helpers/help_page_helper';
import { isAbsolute } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
+import {
+ ENVIRONMENT_NEW_HELP_TEXT,
+ ENVIRONMENT_EDIT_HELP_TEXT,
+} from 'ee_else_ce/environments/constants';
export default {
components: {
@@ -13,6 +17,7 @@ export default {
GlLink,
GlSprintf,
},
+ inject: ['protectedEnvironmentSettingsPath'],
props: {
environment: {
required: true,
@@ -34,9 +39,8 @@ export default {
},
i18n: {
header: __('Environments'),
- helpMessage: __(
- 'Environments allow you to track deployments of your application. %{linkStart}More information%{linkEnd}.',
- ),
+ helpNewMessage: ENVIRONMENT_NEW_HELP_TEXT,
+ helpEditMessage: ENVIRONMENT_EDIT_HELP_TEXT,
nameLabel: __('Name'),
nameFeedback: __('This field is required'),
nameDisabledHelp: __("You cannot rename an environment after it's created."),
@@ -62,6 +66,9 @@ export default {
isNameDisabled() {
return Boolean(this.environment.id);
},
+ showEditHelp() {
+ return this.isNameDisabled && Boolean(this.protectedEnvironmentSettingsPath);
+ },
valid() {
return {
name: this.visited.name && this.environment.name !== '',
@@ -89,9 +96,14 @@ export default {
{{ $options.i18n.header }}
</h4>
<p class="gl-w-full">
- <gl-sprintf :message="$options.i18n.helpMessage">
+ <gl-sprintf
+ :message="showEditHelp ? $options.i18n.helpEditMessage : $options.i18n.helpNewMessage"
+ >
<template #link="{ content }">
- <gl-link :href="$options.helpPagePath">{{ content }}</gl-link>
+ <gl-link
+ :href="showEditHelp ? protectedEnvironmentSettingsPath : $options.helpPagePath"
+ >{{ content }}</gl-link
+ >
</template>
</gl-sprintf>
</p>
diff --git a/app/assets/javascripts/environments/constants.js b/app/assets/javascripts/environments/constants.js
index f010898073c..28424322dd2 100644
--- a/app/assets/javascripts/environments/constants.js
+++ b/app/assets/javascripts/environments/constants.js
@@ -81,3 +81,9 @@ export const REVIEW_APP_MODAL_I18N = {
export const MIN_STALE_ENVIRONMENT_DATE = getDateInPast(new Date(), 3650); // 10 years ago
export const MAX_STALE_ENVIRONMENT_DATE = getDateInPast(new Date(), 7); // one week ago
+
+export const ENVIRONMENT_NEW_HELP_TEXT = __(
+ 'Environments allow you to track deployments of your application.%{linkStart} More information.%{linkEnd}',
+);
+
+export const ENVIRONMENT_EDIT_HELP_TEXT = ENVIRONMENT_NEW_HELP_TEXT;
diff --git a/app/assets/javascripts/environments/edit.js b/app/assets/javascripts/environments/edit.js
index dd6680f64bd..a128d2fb3c7 100644
--- a/app/assets/javascripts/environments/edit.js
+++ b/app/assets/javascripts/environments/edit.js
@@ -7,6 +7,7 @@ export default (el) =>
provide: {
projectEnvironmentsPath: el.dataset.projectEnvironmentsPath,
updateEnvironmentPath: el.dataset.updateEnvironmentPath,
+ protectedEnvironmentSettingsPath: el.dataset.protectedEnvironmentSettingsPath,
},
render(h) {
return h(EditEnvironment, {
diff --git a/app/assets/javascripts/pages/admin/jobs/index/components/cancel_jobs.vue b/app/assets/javascripts/pages/admin/jobs/index/components/cancel_jobs.vue
new file mode 100644
index 00000000000..72cfc005782
--- /dev/null
+++ b/app/assets/javascripts/pages/admin/jobs/index/components/cancel_jobs.vue
@@ -0,0 +1,37 @@
+<script>
+import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
+import CancelJobsModal from './cancel_jobs_modal.vue';
+import { CANCEL_JOBS_MODAL_ID, CANCEL_JOBS_BUTTON_TEXT, CANCEL_BUTTON_TOOLTIP } from './constants';
+
+export default {
+ name: 'CancelJobs',
+ components: {
+ GlButton,
+ CancelJobsModal,
+ },
+ directives: {
+ GlModal: GlModalDirective,
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ url: {
+ type: String,
+ required: true,
+ },
+ },
+ modalId: CANCEL_JOBS_MODAL_ID,
+ buttonText: CANCEL_JOBS_BUTTON_TEXT,
+ buttonTooltip: CANCEL_BUTTON_TOOLTIP,
+};
+</script>
+<template>
+ <div>
+ <gl-button
+ v-gl-modal="$options.modalId"
+ v-gl-tooltip="$options.buttonTooltip"
+ variant="danger"
+ >{{ $options.buttonText }}</gl-button
+ >
+ <cancel-jobs-modal :modal-id="$options.modalId" :url="url" @confirm="$emit('confirm')" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/pages/admin/jobs/index/components/stop_jobs_modal.vue b/app/assets/javascripts/pages/admin/jobs/index/components/cancel_jobs_modal.vue
index b608b3b9492..d5857294617 100644
--- a/app/assets/javascripts/pages/admin/jobs/index/components/stop_jobs_modal.vue
+++ b/app/assets/javascripts/pages/admin/jobs/index/components/cancel_jobs_modal.vue
@@ -5,10 +5,9 @@ import axios from '~/lib/utils/axios_utils';
import { redirectTo } from '~/lib/utils/url_utility';
import {
CANCEL_TEXT,
- STOP_JOBS_MODAL_ID,
- STOP_JOBS_FAILED_TEXT,
- STOP_JOBS_MODAL_TITLE,
- STOP_JOBS_WARNING,
+ CANCEL_JOBS_FAILED_TEXT,
+ CANCEL_JOBS_MODAL_TITLE,
+ CANCEL_JOBS_WARNING,
PRIMARY_ACTION_TEXT,
} from './constants';
@@ -21,6 +20,10 @@ export default {
type: String,
required: true,
},
+ modalId: {
+ type: String,
+ required: true,
+ },
},
methods: {
onSubmit() {
@@ -32,7 +35,7 @@ export default {
})
.catch((error) => {
createAlert({
- message: STOP_JOBS_FAILED_TEXT,
+ message: CANCEL_JOBS_FAILED_TEXT,
});
throw error;
});
@@ -45,20 +48,19 @@ export default {
cancelAction: {
text: CANCEL_TEXT,
},
- STOP_JOBS_WARNING,
- STOP_JOBS_MODAL_ID,
- STOP_JOBS_MODAL_TITLE,
+ CANCEL_JOBS_WARNING,
+ CANCEL_JOBS_MODAL_TITLE,
};
</script>
<template>
<gl-modal
- :modal-id="$options.STOP_JOBS_MODAL_ID"
+ :modal-id="modalId"
:action-primary="$options.primaryAction"
:action-cancel="$options.cancelAction"
+ :title="$options.CANCEL_JOBS_MODAL_TITLE"
@primary="onSubmit"
>
- <template #modal-title>{{ $options.STOP_JOBS_MODAL_TITLE }}</template>
- {{ $options.STOP_JOBS_WARNING }}
+ {{ $options.CANCEL_JOBS_WARNING }}
</gl-modal>
</template>
diff --git a/app/assets/javascripts/pages/admin/jobs/index/components/constants.js b/app/assets/javascripts/pages/admin/jobs/index/components/constants.js
index 9e2d464bc4d..cfde1fc0a2b 100644
--- a/app/assets/javascripts/pages/admin/jobs/index/components/constants.js
+++ b/app/assets/javascripts/pages/admin/jobs/index/components/constants.js
@@ -1,11 +1,12 @@
import { s__, __ } from '~/locale';
-export const STOP_JOBS_MODAL_ID = 'stop-jobs-modal';
-export const STOP_JOBS_MODAL_TITLE = s__('AdminArea|Stop all jobs?');
-export const STOP_JOBS_BUTTON_TEXT = s__('AdminArea|Stop all jobs');
+export const CANCEL_JOBS_MODAL_ID = 'cancel-jobs-modal';
+export const CANCEL_JOBS_MODAL_TITLE = s__('AdminArea|Are you sure?');
+export const CANCEL_JOBS_BUTTON_TEXT = s__('AdminArea|Cancel all jobs');
+export const CANCEL_BUTTON_TOOLTIP = s__('AdminArea|Cancel all running and pending jobs');
export const CANCEL_TEXT = __('Cancel');
-export const STOP_JOBS_FAILED_TEXT = s__('AdminArea|Stopping jobs failed');
-export const PRIMARY_ACTION_TEXT = s__('AdminArea|Stop jobs');
-export const STOP_JOBS_WARNING = s__(
- 'AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running.',
+export const CANCEL_JOBS_FAILED_TEXT = s__('AdminArea|Canceling jobs failed');
+export const PRIMARY_ACTION_TEXT = s__('AdminArea|Yes, proceed');
+export const CANCEL_JOBS_WARNING = s__(
+ "AdminArea|You're about to cancel all running and pending jobs across this instance. Do you want to proceed?",
);
diff --git a/app/assets/javascripts/pages/admin/jobs/index/index.js b/app/assets/javascripts/pages/admin/jobs/index/index.js
index c82b186f671..f9bc097da4c 100644
--- a/app/assets/javascripts/pages/admin/jobs/index/index.js
+++ b/app/assets/javascripts/pages/admin/jobs/index/index.js
@@ -1,31 +1,32 @@
import Vue from 'vue';
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import Translate from '~/vue_shared/translate';
-import { STOP_JOBS_MODAL_ID } from './components/constants';
-import StopJobsModal from './components/stop_jobs_modal.vue';
+import { CANCEL_JOBS_MODAL_ID } from './components/constants';
+import CancelJobsModal from './components/cancel_jobs_modal.vue';
Vue.use(Translate);
function initJobs() {
const buttonId = 'js-stop-jobs-button';
- const stopJobsButton = document.getElementById(buttonId);
- if (stopJobsButton) {
+ const cancelJobsButton = document.getElementById(buttonId);
+ if (cancelJobsButton) {
// eslint-disable-next-line no-new
new Vue({
- el: `#js-${STOP_JOBS_MODAL_ID}`,
+ el: `#js-${CANCEL_JOBS_MODAL_ID}`,
components: {
- StopJobsModal,
+ CancelJobsModal,
},
mounted() {
- stopJobsButton.classList.remove('disabled');
- stopJobsButton.addEventListener('click', () => {
- this.$root.$emit(BV_SHOW_MODAL, STOP_JOBS_MODAL_ID, `#${buttonId}`);
+ cancelJobsButton.classList.remove('disabled');
+ cancelJobsButton.addEventListener('click', () => {
+ this.$root.$emit(BV_SHOW_MODAL, CANCEL_JOBS_MODAL_ID, `#${buttonId}`);
});
},
render(createElement) {
- return createElement(STOP_JOBS_MODAL_ID, {
+ return createElement(CANCEL_JOBS_MODAL_ID, {
props: {
- url: stopJobsButton.dataset.url,
+ url: cancelJobsButton.dataset.url,
+ modalId: CANCEL_JOBS_MODAL_ID,
},
});
},
diff --git a/app/channels/awareness_channel.rb b/app/channels/awareness_channel.rb
index cf85e4b3d33..cf7ba0e5aaf 100644
--- a/app/channels/awareness_channel.rb
+++ b/app/channels/awareness_channel.rb
@@ -15,7 +15,7 @@ class AwarenessChannel < ApplicationCable::Channel # rubocop:disable Gitlab/Name
private_class_method :refresh_interval
# keep clients updated about session membership
- periodically every: self.refresh_interval do
+ periodically every: refresh_interval do
transmit payload
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 36aae42e21f..865cde1b641 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -69,7 +69,7 @@ class ApplicationController < ActionController::Base
:masked_page_url
def self.endpoint_id_for_action(action_name)
- "#{self.name}##{action_name}"
+ "#{name}##{action_name}"
end
rescue_from Encoding::CompatibilityError do |exception|
diff --git a/app/finders/security/jobs_finder.rb b/app/finders/security/jobs_finder.rb
index 6c2090e0509..ef5b63ccd1d 100644
--- a/app/finders/security/jobs_finder.rb
+++ b/app/finders/security/jobs_finder.rb
@@ -20,7 +20,7 @@ module Security
end
def initialize(pipeline:, job_types: [])
- if self.instance_of?(Security::JobsFinder)
+ if instance_of?(Security::JobsFinder)
raise NotImplementedError, 'This is an abstract class, please instantiate its descendants'
end
diff --git a/app/graphql/types/permission_types/base_permission_type.rb b/app/graphql/types/permission_types/base_permission_type.rb
index 0192af25d0f..d45c61f489b 100644
--- a/app/graphql/types/permission_types/base_permission_type.rb
+++ b/app/graphql/types/permission_types/base_permission_type.rb
@@ -28,7 +28,7 @@ module Types
end
def self.define_field_resolver_method(ability)
- unless self.respond_to?(ability)
+ unless respond_to?(ability)
define_method ability.to_sym do |*args|
Ability.allowed?(context[:current_user], ability, object, args.to_h)
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index e8fc6bc292f..129871ca3fd 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -113,7 +113,7 @@ module GroupsHelper
end
def render_setting_to_allow_project_access_token_creation?(group)
- group.root? && current_user.can?(:admin_setting_to_allow_project_access_token_creation, group)
+ group.root? && current_user.can?(:admin_setting_to_allow_resource_access_token_creation, group)
end
def show_thanks_for_purchase_alert?(quantity)
diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb
index be9d49ab4e2..dbcdfa5e946 100644
--- a/app/models/abuse_report.rb
+++ b/app/models/abuse_report.rb
@@ -72,9 +72,9 @@ class AbuseReport < ApplicationRecord
end
def notify
- return unless self.persisted?
+ return unless persisted?
- AbuseReportMailer.notify(self.id).deliver_later
+ AbuseReportMailer.notify(id).deliver_later
end
private
diff --git a/app/models/analytics/usage_trends/measurement.rb b/app/models/analytics/usage_trends/measurement.rb
index c1245d8dce7..ddadaf78c8f 100644
--- a/app/models/analytics/usage_trends/measurement.rb
+++ b/app/models/analytics/usage_trends/measurement.rb
@@ -24,8 +24,8 @@ module Analytics
scope :order_by_latest, -> { order(recorded_at: :desc) }
scope :with_identifier, ->(identifier) { where(identifier: identifier) }
- scope :recorded_after, ->(date) { where(self.model.arel_table[:recorded_at].gteq(date)) if date.present? }
- scope :recorded_before, ->(date) { where(self.model.arel_table[:recorded_at].lteq(date)) if date.present? }
+ scope :recorded_after, ->(date) { where(model.arel_table[:recorded_at].gteq(date)) if date.present? }
+ scope :recorded_before, ->(date) { where(model.arel_table[:recorded_at].lteq(date)) if date.present? }
def self.identifier_query_mapping
{
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index 198a3653cd3..291375f647c 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -36,7 +36,7 @@ class ApplicationRecord < ActiveRecord::Base
end
def self.pluck_primary_key
- where(nil).pluck(self.primary_key)
+ where(nil).pluck(primary_key)
end
def self.safe_ensure_unique(retries: 0)
@@ -95,7 +95,7 @@ class ApplicationRecord < ActiveRecord::Base
end
def self.underscore
- Gitlab::SafeRequestStore.fetch("model:#{self}:underscore") { self.to_s.underscore }
+ Gitlab::SafeRequestStore.fetch("model:#{self}:underscore") { to_s.underscore }
end
def self.where_exists(query)
@@ -111,7 +111,7 @@ class ApplicationRecord < ActiveRecord::Base
end
def self.cached_column_list
- self.column_names.map { |column_name| self.arel_table[column_name] }
+ column_names.map { |column_name| arel_table[column_name] }
end
def self.default_select_columns
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index f13b2143cd3..db2c053d12c 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -303,11 +303,11 @@ module ApplicationSettingImplementation
end
def domain_allowlist_raw
- array_to_string(self.domain_allowlist)
+ array_to_string(domain_allowlist)
end
def domain_denylist_raw
- array_to_string(self.domain_denylist)
+ array_to_string(domain_denylist)
end
def domain_allowlist_raw=(values)
@@ -323,7 +323,7 @@ module ApplicationSettingImplementation
end
def outbound_local_requests_allowlist_raw
- array_to_string(self.outbound_local_requests_whitelist)
+ array_to_string(outbound_local_requests_whitelist)
end
def outbound_local_requests_allowlist_raw=(values)
@@ -356,7 +356,7 @@ module ApplicationSettingImplementation
end
def protected_paths_raw
- array_to_string(self.protected_paths)
+ array_to_string(protected_paths)
end
def protected_paths_raw=(values)
@@ -364,7 +364,7 @@ module ApplicationSettingImplementation
end
def notes_create_limit_allowlist_raw
- array_to_string(self.notes_create_limit_allowlist)
+ array_to_string(notes_create_limit_allowlist)
end
def notes_create_limit_allowlist_raw=(values)
@@ -372,7 +372,7 @@ module ApplicationSettingImplementation
end
def users_get_by_id_limit_allowlist_raw
- array_to_string(self.users_get_by_id_limit_allowlist)
+ array_to_string(users_get_by_id_limit_allowlist)
end
def users_get_by_id_limit_allowlist_raw=(values)
@@ -536,7 +536,7 @@ module ApplicationSettingImplementation
def set_max_key_restriction!(key_type)
attr_name = "#{key_type}_key_restriction"
- current = self.attributes[attr_name].to_i
+ current = attributes[attr_name].to_i
return if current == KeyRestrictionValidator::FORBIDDEN
@@ -549,7 +549,7 @@ module ApplicationSettingImplementation
[min_size, current].max
end
- self.assign_attributes({ attr_name => new_value })
+ assign_attributes({ attr_name => new_value })
end
def separate_allowlists(string_array)
diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb
index 5cc87be388f..0c75f6e8b0b 100644
--- a/app/models/audit_event.rb
+++ b/app/models/audit_event.rb
@@ -55,7 +55,7 @@ class AuditEvent < ApplicationRecord
end
def initialize_details
- return unless self.has_attribute?(:details)
+ return unless has_attribute?(:details)
self.details = {} if details&.nil?
end
@@ -82,7 +82,7 @@ class AuditEvent < ApplicationRecord
def as_json(options = {})
super(options).tap do |json|
- json['ip_address'] = self.ip_address.to_s
+ json['ip_address'] = ip_address.to_s
end
end
@@ -114,10 +114,10 @@ class AuditEvent < ApplicationRecord
def parallel_persist
PARALLEL_PERSISTENCE_COLUMNS.each do |name|
- original = self[name] || self.details[name]
+ original = self[name] || details[name]
next unless original
- self[name] = self.details[name] = original
+ self[name] = details[name] = original
end
end
diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb
index f41f0a8be84..dbc5c7a584e 100644
--- a/app/models/award_emoji.rb
+++ b/app/models/award_emoji.rb
@@ -55,11 +55,11 @@ class AwardEmoji < ApplicationRecord
end
def downvote?
- self.name == DOWNVOTE_NAME
+ name == DOWNVOTE_NAME
end
def upvote?
- self.name == UPVOTE_NAME
+ name == UPVOTE_NAME
end
def url
diff --git a/app/models/board.rb b/app/models/board.rb
index 8a7330e7320..2181b2f0545 100644
--- a/app/models/board.rb
+++ b/app/models/board.rb
@@ -18,7 +18,7 @@ class Board < ApplicationRecord
# Sort by case-insensitive name, then ascending ids. This ensures that we will always
# get the same list/first board no matter how many other boards are named the same
scope :order_by_name_asc, -> { order(arel_table[:name].lower.asc).order(id: :asc) }
- scope :first_board, -> { where(id: self.order_by_name_asc.limit(1).select(:id)) }
+ scope :first_board, -> { where(id: order_by_name_asc.limit(1).select(:id)) }
def project_needed?
!group
diff --git a/app/models/ci/application_record.rb b/app/models/ci/application_record.rb
index ea7b1104e36..52f02bfb2fd 100644
--- a/app/models/ci/application_record.rb
+++ b/app/models/ci/application_record.rb
@@ -13,7 +13,7 @@ module Ci
end
def self.model_name
- @model_name ||= ActiveModel::Name.new(self, nil, self.name.demodulize)
+ @model_name ||= ActiveModel::Name.new(self, nil, name.demodulize)
end
end
end
diff --git a/app/models/ci/bridge.rb b/app/models/ci/bridge.rb
index 54daff7dbda..697f06fbffd 100644
--- a/app/models/ci/bridge.rb
+++ b/app/models/ci/bridge.rb
@@ -80,9 +80,9 @@ module Ci
def inherit_status_from_downstream!(pipeline)
case pipeline.status
when 'success'
- self.success!
+ success!
when 'failed', 'canceled', 'skipped'
- self.drop!
+ drop!
else
false
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index ec3aa9d70be..214880f5833 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -386,21 +386,21 @@ module Ci
def detailed_status(current_user)
Gitlab::Ci::Status::Build::Factory
- .new(self.present, current_user)
+ .new(present, current_user)
.fabricate!
end
def other_manual_actions
- pipeline.manual_actions.reject { |action| action.name == self.name }
+ pipeline.manual_actions.reject { |action| action.name == name }
end
def other_scheduled_actions
- pipeline.scheduled_actions.reject { |action| action.name == self.name }
+ pipeline.scheduled_actions.reject { |action| action.name == name }
end
def pages_generator?
Gitlab.config.pages.enabled &&
- self.name == 'pages'
+ name == 'pages'
end
def runnable?
@@ -456,7 +456,7 @@ module Ci
end
def retries_count
- pipeline.builds.retried.where(name: self.name).count
+ pipeline.builds.retried.where(name: name).count
end
override :all_met_to_become_pending?
@@ -529,19 +529,19 @@ module Ci
end
def deployment_job?
- has_environment_keyword? && self.environment_action == 'start'
+ has_environment_keyword? && environment_action == 'start'
end
def stops_environment?
- has_environment_keyword? && self.environment_action == 'stop'
+ has_environment_keyword? && environment_action == 'stop'
end
def environment_action
- self.options.fetch(:environment, {}).fetch(:action, 'start') if self.options
+ options.fetch(:environment, {}).fetch(:action, 'start') if options
end
def environment_tier_from_options
- self.options.dig(:environment, :deployment_tier) if self.options
+ options.dig(:environment, :deployment_tier) if options
end
def environment_tier
@@ -831,7 +831,7 @@ module Ci
end
def erased?
- !self.erased_at.nil?
+ !erased_at.nil?
end
def artifacts_expired?
@@ -864,8 +864,8 @@ module Ci
end
def keep_artifacts!
- self.update(artifacts_expire_at: nil)
- self.job_artifacts.update_all(expire_at: nil)
+ update(artifacts_expire_at: nil)
+ job_artifacts.update_all(expire_at: nil)
end
def artifacts_file_for_type(type)
@@ -1096,11 +1096,11 @@ module Ci
# without actually loading data.
#
def all_queuing_entries
- ::Ci::PendingBuild.where(build_id: self.id)
+ ::Ci::PendingBuild.where(build_id: id)
end
def all_runtime_metadata
- ::Ci::RunningBuild.where(build_id: self.id)
+ ::Ci::RunningBuild.where(build_id: id)
end
def shared_runner_build?
diff --git a/app/models/ci/build_metadata.rb b/app/models/ci/build_metadata.rb
index 5c8ac2adb8d..b294afd405d 100644
--- a/app/models/ci/build_metadata.rb
+++ b/app/models/ci/build_metadata.rb
@@ -68,7 +68,7 @@ module Ci
private
def set_build_project
- self.project_id ||= self.build.project_id
+ self.project_id ||= build.project_id
end
def timeout_with_highest_precedence
diff --git a/app/models/ci/build_runner_session.rb b/app/models/ci/build_runner_session.rb
index 20c0b04e228..5773b6132be 100644
--- a/app/models/ci/build_runner_session.rb
+++ b/app/models/ci/build_runner_session.rb
@@ -20,7 +20,7 @@ module Ci
validates :url, public_url: { schemes: %w(https) }
def terminal_specification
- wss_url = Gitlab::UrlHelpers.as_wss(Addressable::URI.escape(self.url))
+ wss_url = Gitlab::UrlHelpers.as_wss(Addressable::URI.escape(url))
return {} unless wss_url.present?
parsed_wss_url = URI.parse(wss_url)
@@ -33,7 +33,7 @@ module Ci
port = port.presence || DEFAULT_PORT_NAME
service = service.presence || DEFAULT_SERVICE_NAME
- parsed_url = URI.parse(Addressable::URI.escape(self.url))
+ parsed_url = URI.parse(Addressable::URI.escape(url))
parsed_url.path += "/proxy/#{service}/#{port}/#{path}"
subprotocols = subprotocols.presence || ::Ci::BuildRunnerSession::TERMINAL_SUBPROTOCOL
diff --git a/app/models/ci/build_trace_chunk.rb b/app/models/ci/build_trace_chunk.rb
index c5f6e54c336..541a8b5bffa 100644
--- a/app/models/ci/build_trace_chunk.rb
+++ b/app/models/ci/build_trace_chunk.rb
@@ -108,7 +108,7 @@ module Ci
raise ArgumentError, 'Offset is out of range' if offset > size || offset < 0
return if offset == size # Skip the following process as it doesn't affect anything
- self.append(+"", offset)
+ append(+"", offset)
end
def append(new_data, offset)
@@ -166,7 +166,7 @@ module Ci
raise FailedToPersistDataError, 'Modifed build trace chunk detected' if has_changes_to_save?
self.class.with_read_consistency(build) do
- self.reset.then(&:unsafe_persist_data!)
+ reset.then(&:unsafe_persist_data!)
end
end
rescue FailedToObtainLockError
@@ -205,9 +205,9 @@ module Ci
end
def <=>(other)
- return unless self.build_id == other.build_id
+ return unless build_id == other.build_id
- self.chunk_index <=> other.chunk_index
+ chunk_index <=> other.chunk_index
end
protected
diff --git a/app/models/ci/deleted_object.rb b/app/models/ci/deleted_object.rb
index d36646aba66..2b5452c803a 100644
--- a/app/models/ci/deleted_object.rb
+++ b/app/models/ci/deleted_object.rb
@@ -21,7 +21,7 @@ module Ci
accumulator << record if record[:store_dir] && record[:file]
end
- self.insert_all(attributes) if attributes.any?
+ insert_all(attributes) if attributes.any?
end
def delete_file_from_storage
diff --git a/app/models/clusters/applications/cert_manager.rb b/app/models/clusters/applications/cert_manager.rb
deleted file mode 100644
index 11f84940c38..00000000000
--- a/app/models/clusters/applications/cert_manager.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-# frozen_string_literal: true
-
-module Clusters
- module Applications
- # DEPRECATED for removal in %14.0
- # See https://gitlab.com/groups/gitlab-org/-/epics/4280
- class CertManager < ApplicationRecord
- VERSION = 'v0.10.1'
- CRD_VERSION = '0.10'
-
- self.table_name = 'clusters_applications_cert_managers'
-
- include ::Clusters::Concerns::ApplicationCore
- include ::Clusters::Concerns::ApplicationStatus
- include ::Clusters::Concerns::ApplicationVersion
- include ::Clusters::Concerns::ApplicationData
-
- attribute :version, default: VERSION
- after_initialize :set_default_email, if: :new_record?
-
- validates :email, presence: true
-
- def chart
- 'certmanager/cert-manager'
- end
-
- def repository
- 'https://charts.jetstack.io'
- end
-
- def install_command
- helm_command_module::InstallCommand.new(
- name: 'certmanager',
- repository: repository,
- version: VERSION,
- rbac: cluster.platform_kubernetes_rbac?,
- chart: chart,
- files: files.merge(cluster_issuer_file),
- preinstall: pre_install_script,
- postinstall: post_install_script
- )
- end
-
- def uninstall_command
- helm_command_module::DeleteCommand.new(
- name: 'certmanager',
- rbac: cluster.platform_kubernetes_rbac?,
- files: files,
- postdelete: post_delete_script
- )
- end
-
- private
-
- def set_default_email
- self.email ||= self.cluster&.user&.email
- end
-
- def pre_install_script
- [
- apply_file("https://raw.githubusercontent.com/jetstack/cert-manager/release-#{CRD_VERSION}/deploy/manifests/00-crds.yaml"),
- "kubectl label --overwrite namespace #{Gitlab::Kubernetes::Helm::NAMESPACE} certmanager.k8s.io/disable-validation=true"
- ]
- end
-
- def post_install_script
- [retry_command(apply_file('/data/helm/certmanager/config/cluster_issuer.yaml'))]
- end
-
- def retry_command(command)
- Gitlab::Kubernetes::PodCmd.retry_command(command, times: 90)
- end
-
- def post_delete_script
- [
- delete_private_key,
- delete_crd('certificates.certmanager.k8s.io'),
- delete_crd('certificaterequests.certmanager.k8s.io'),
- delete_crd('challenges.certmanager.k8s.io'),
- delete_crd('clusterissuers.certmanager.k8s.io'),
- delete_crd('issuers.certmanager.k8s.io'),
- delete_crd('orders.certmanager.k8s.io')
- ].compact
- end
-
- def private_key_name
- @private_key_name ||= cluster_issuer_content.dig('spec', 'acme', 'privateKeySecretRef', 'name')
- end
-
- def delete_private_key
- return unless private_key_name.present?
-
- args = %W(secret -n #{Gitlab::Kubernetes::Helm::NAMESPACE} #{private_key_name} --ignore-not-found)
-
- Gitlab::Kubernetes::KubectlCmd.delete(*args)
- end
-
- def delete_crd(definition)
- Gitlab::Kubernetes::KubectlCmd.delete("crd", definition, "--ignore-not-found")
- end
-
- def apply_file(filename)
- Gitlab::Kubernetes::KubectlCmd.apply_file(filename)
- end
-
- def cluster_issuer_file
- {
- 'cluster_issuer.yaml': cluster_issuer_yaml_content
- }
- end
-
- def cluster_issuer_yaml_content
- YAML.dump(cluster_issuer_content.deep_merge(cluster_issue_overlay))
- end
-
- def cluster_issuer_content
- YAML.safe_load(File.read(cluster_issuer_file_path))
- end
-
- def cluster_issue_overlay
- { "spec" => { "acme" => { "email" => self.email } } }
- end
-
- def cluster_issuer_file_path
- Rails.root.join('vendor', 'cert_manager', 'cluster_issuer.yaml')
- end
- end
- end
-end
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index 55dbaf9c6b7..a35ea6ddb46 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -14,7 +14,6 @@ module Clusters
APPLICATIONS = {
Clusters::Applications::Helm.application_name => Clusters::Applications::Helm,
Clusters::Applications::Ingress.application_name => Clusters::Applications::Ingress,
- Clusters::Applications::CertManager.application_name => Clusters::Applications::CertManager,
Clusters::Applications::Crossplane.application_name => Clusters::Applications::Crossplane,
Clusters::Applications::Prometheus.application_name => Clusters::Applications::Prometheus,
Clusters::Applications::Runner.application_name => Clusters::Applications::Runner,
@@ -57,7 +56,6 @@ module Clusters
has_one_cluster_application :helm
has_one_cluster_application :ingress
- has_one_cluster_application :cert_manager
has_one_cluster_application :crossplane
has_one_cluster_application :prometheus
has_one_cluster_application :runner
diff --git a/app/models/ml/experiment.rb b/app/models/ml/experiment.rb
index 0a326b0e005..7bb80a170c5 100644
--- a/app/models/ml/experiment.rb
+++ b/app/models/ml/experiment.rb
@@ -12,6 +12,12 @@ module Ml
has_many :candidates, class_name: 'Ml::Candidate'
has_many :metadata, class_name: 'Ml::ExperimentMetadata'
+ scope :with_candidate_count, -> {
+ left_outer_joins(:candidates)
+ .select("ml_experiments.*, count(ml_candidates.id) as candidate_count")
+ .group(:id)
+ }
+
has_internal_id :iid, scope: :project
class << self
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index b2325b7acac..1dae2682772 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -76,6 +76,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
with_scope :subject
condition(:resource_access_token_feature_available) { resource_access_token_feature_available? }
condition(:resource_access_token_creation_allowed) { resource_access_token_creation_allowed? }
+ condition(:resource_access_token_create_feature_available) { resource_access_token_create_feature_available? }
with_scope :subject
condition(:has_project_with_service_desk_enabled) { @subject.has_project_with_service_desk_enabled? }
@@ -277,8 +278,8 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :destroy_resource_access_tokens
end
- rule { can?(:admin_group) & resource_access_token_creation_allowed }.policy do
- enable :admin_setting_to_allow_project_access_token_creation
+ rule { can?(:admin_group) & resource_access_token_create_feature_available }.policy do
+ enable :admin_setting_to_allow_resource_access_token_creation
end
rule { resource_access_token_creation_allowed & can?(:read_resource_access_tokens) }.policy do
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index f2d0cfc42fd..8d858ad72d2 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -4,7 +4,7 @@
- add_page_specific_style 'page_bundles/issuable_list'
.top-area
- = render 'shared/issuable/nav', type: :merge_requests
+ = render 'shared/issuable/nav', type: :merge_requests, display_count: !@search_timeout_occurred
- if current_user
.nav-controls
- if @can_bulk_update
@@ -16,4 +16,7 @@
- if @can_bulk_update
= render_if_exists 'shared/issuable/group_bulk_update_sidebar', group: @group, type: :merge_requests
-= render 'shared/merge_requests'
+- if @search_timeout_occurred
+ = render 'shared/dashboard/search_timeout_occurred'
+- else
+ = render 'shared/merge_requests'
diff --git a/app/views/projects/environments/edit.html.haml b/app/views/projects/environments/edit.html.haml
index dcd5fb2574e..7a275b51c74 100644
--- a/app/views/projects/environments/edit.html.haml
+++ b/app/views/projects/environments/edit.html.haml
@@ -3,4 +3,5 @@
#js-edit-environment{ data: { project_environments_path: project_environments_path(@project),
update_environment_path: project_environment_path(@project, @environment),
+ protected_environment_settings_path: (project_settings_ci_cd_path(@project, anchor: 'js-protected-environments-settings') if @project.licensed_feature_available?(:protected_environments)),
environment: environment_data(@environment)} }
diff --git a/db/docs/clusters_applications_cert_managers.yml b/db/docs/clusters_applications_cert_managers.yml
index 36bc15e045c..78ef851a2c0 100644
--- a/db/docs/clusters_applications_cert_managers.yml
+++ b/db/docs/clusters_applications_cert_managers.yml
@@ -1,7 +1,5 @@
---
table_name: clusters_applications_cert_managers
-classes:
-- Clusters::Applications::CertManager
feature_categories:
- kubernetes_management
description: "(Deprecated) A GitLab managed cert-manager installation in a Kubernetes cluster"
diff --git a/doc/administration/clusters/kas.md b/doc/administration/clusters/kas.md
index 9f0f7e836f7..a7f8f8e712b 100644
--- a/doc/administration/clusters/kas.md
+++ b/doc/administration/clusters/kas.md
@@ -62,7 +62,7 @@ To enable the agent server on multiple nodes:
gitlab_rails['gitlab_kas_enabled'] = true
gitlab_rails['gitlab_kas_external_url'] = 'wss://gitlab.example.com/-/kubernetes-agent/'
gitlab_rails['gitlab_kas_internal_url'] = 'grpc://kas.internal.gitlab.example.com'
- gitlab_rails['gitlab_kas_external_k8s_proxy_url'] = 'https://gitlab.example.com/-/kubernetes-agent/'
+ gitlab_rails['gitlab_kas_external_k8s_proxy_url'] = 'https://gitlab.example.com/-/kubernetes-agent/k8s-proxy/'
```
In this configuration:
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index be4ba2b7f99..740a90257bb 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -105,7 +105,13 @@ When the consolidated form is:
See the section on [ETag mismatch errors](#etag-mismatch) for more details.
-**In Omnibus installations:**
+#### Use AWS S3
+
+The following example uses AWS S3 to enable object storage for all supported services:
+
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
1. Edit `/etc/gitlab/gitlab.rb` and add the following lines, substituting
the values you want:
@@ -116,7 +122,7 @@ See the section on [ETag mismatch errors](#etag-mismatch) for more details.
gitlab_rails['object_store']['proxy_download'] = true
gitlab_rails['object_store']['connection'] = {
'provider' => 'AWS',
- 'region' => '<eu-central-1>',
+ 'region' => 'eu-central-1',
'aws_access_key_id' => '<AWS_ACCESS_KEY_ID>',
'aws_secret_access_key' => '<AWS_SECRET_ACCESS_KEY>'
}
@@ -125,62 +131,231 @@ See the section on [ETag mismatch errors](#etag-mismatch) for more details.
'server_side_encryption' => '<AES256 or aws:kms>',
'server_side_encryption_kms_key_id' => '<arn:aws:kms:xxx>'
}
- gitlab_rails['object_store']['objects']['artifacts']['bucket'] = '<artifacts>'
- gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = '<external-diffs>'
- gitlab_rails['object_store']['objects']['lfs']['bucket'] = '<lfs-objects>'
- gitlab_rails['object_store']['objects']['uploads']['bucket'] = '<uploads>'
- gitlab_rails['object_store']['objects']['packages']['bucket'] = '<packages>'
- gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = '<dependency-proxy>'
- gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = '<terraform-state>'
- gitlab_rails['object_store']['objects']['pages']['bucket'] = '<pages>'
+ gitlab_rails['object_store']['objects']['artifacts']['bucket'] = 'gitlab-artifacts'
+ gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = 'gitlab-mr-diffs'
+ gitlab_rails['object_store']['objects']['lfs']['bucket'] = 'gitlab-lfs'
+ gitlab_rails['object_store']['objects']['uploads']['bucket'] = 'gitlab-uploads'
+ gitlab_rails['object_store']['objects']['packages']['bucket'] = 'gitlab-packages'
+ gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = 'gitlab-dependency-proxy'
+ gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = 'gitlab-terraform-state'
+ gitlab_rails['object_store']['objects']['ci_secure_files']['bucket'] = 'gitlab-ci-secure-files'
+ gitlab_rails['object_store']['objects']['pages']['bucket'] = 'gitlab-pages'
+ ```
+
+ If you’re using [AWS IAM profiles](#using-amazon-instance-profiles), omit
+ the AWS access key and secret access key/value pairs. For example:
+
+ ```ruby
+ gitlab_rails['object_store']['connection'] = {
+ 'provider' => 'AWS',
+ 'region' => 'eu-central-1',
+ 'use_iam_profile' => true
+ }
```
- If you're using AWS IAM profiles, omit the AWS access key and secret access
- key/value pairs. For example:
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `object_storage.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#connection):
+
+ ```yaml
+ provider: AWS
+ region: us-east-1
+ aws_access_key_id: <AWS_ACCESS_KEY_ID>
+ aws_secret_access_key: <AWS_SECRET_ACCESS_KEY>
+ ```
+
+ If you’re using [AWS IAM profiles](#using-amazon-instance-profiles), omit
+ the AWS access key and secret access key/value pairs. For example:
+
+ ```yaml
+ provider: AWS
+ region: us-east-1
+ use_iam_profile: true
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-object-storage --from-file=connection=object_storage.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ object_store:
+ enabled: false
+ proxy_download: true
+ storage_options: {}
+ # server_side_encryption:
+ # server_side_encryption_kms_key_id
+ connection:
+ secret: gitlab-object-storage
+ lfs:
+ enabled: true
+ proxy_download: true
+ bucket: gitlab-lfs
+ connection: {}
+ # secret:
+ # key:
+ artifacts:
+ enabled: true
+ proxy_download: true
+ bucket: gitlab-artifacts
+ connection: {}
+ # secret:
+ # key:
+ uploads:
+ enabled: true
+ proxy_download: true
+ bucket: gitlab-uploads
+ connection: {}
+ # secret:
+ # key:
+ packages:
+ enabled: true
+ proxy_download: true
+ bucket: gitlab-packages
+ connection: {}
+ externalDiffs:
+ enabled: true
+ when:
+ proxy_download: true
+ bucket: gitlab-mr-diffs
+ connection: {}
+ terraformState:
+ enabled: true
+ bucket: gitlab-terraform-state
+ connection: {}
+ ciSecureFiles:
+ enabled: true
+ bucket: gitlab-ci-secure-files
+ connection: {}
+ dependencyProxy:
+ enabled: true
+ proxy_download: true
+ bucket: gitlab-dependency-proxy
+ connection: {}
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ # Consolidated object storage configuration
+ gitlab_rails['object_store']['enabled'] = true
+ gitlab_rails['object_store']['proxy_download'] = true
+ gitlab_rails['object_store']['connection'] = {
+ 'provider' => 'AWS',
+ 'region' => 'eu-central-1',
+ 'aws_access_key_id' => '<AWS_ACCESS_KEY_ID>',
+ 'aws_secret_access_key' => '<AWS_SECRET_ACCESS_KEY>'
+ }
+ # OPTIONAL: The following lines are only needed if server side encryption is required
+ gitlab_rails['object_store']['storage_options'] = {
+ 'server_side_encryption' => '<AES256 or aws:kms>',
+ 'server_side_encryption_kms_key_id' => '<arn:aws:kms:xxx>'
+ }
+ gitlab_rails['object_store']['objects']['artifacts']['bucket'] = 'gitlab-artifacts'
+ gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = 'gitlab-mr-diffs'
+ gitlab_rails['object_store']['objects']['lfs']['bucket'] = 'gitlab-lfs'
+ gitlab_rails['object_store']['objects']['uploads']['bucket'] = 'gitlab-uploads'
+ gitlab_rails['object_store']['objects']['packages']['bucket'] = 'gitlab-packages'
+ gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = 'gitlab-dependency-proxy'
+ gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = 'gitlab-terraform-state'
+ gitlab_rails['object_store']['objects']['ci_secure_files']['bucket'] = 'gitlab-ci-secure-files'
+ gitlab_rails['object_store']['objects']['pages']['bucket'] = 'gitlab-pages'
+ ```
+
+ If you’re using [AWS IAM profiles](#using-amazon-instance-profiles), omit
+ the AWS access key and secret access key/value pairs. For example:
```ruby
gitlab_rails['object_store']['connection'] = {
'provider' => 'AWS',
- 'region' => '<eu-central-1>',
+ 'region' => 'eu-central-1',
'use_iam_profile' => true
}
```
-1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+1. Save the file and restart GitLab:
-**In installations from source:**
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
1. Edit `/home/git/gitlab/config/gitlab.yml` and add or amend the following lines:
```yaml
- object_store:
- enabled: true
- proxy_download: true
- connection:
- provider: AWS
- aws_access_key_id: <AWS_ACCESS_KEY_ID>
- aws_secret_access_key: <AWS_SECRET_ACCESS_KEY>
- region: <eu-central-1>
- storage_options:
- server_side_encryption: <AES256 or aws:kms>
- server_side_encryption_key_kms_id: <arn:aws:kms:xxx>
- objects:
- artifacts:
- bucket: <artifacts>
- external_diffs:
- bucket: <external-diffs>
- lfs:
- bucket: <lfs-objects>
- uploads:
- bucket: <uploads>
- packages:
- bucket: <packages>
- dependency_proxy:
- bucket: <dependency_proxy>
- terraform_state:
- bucket: <terraform>
- pages:
- bucket: <pages>
+ production: &base
+ object_store:
+ enabled: true
+ proxy_download: true
+ connection:
+ provider: AWS
+ aws_access_key_id: <AWS_ACCESS_KEY_ID>
+ aws_secret_access_key: <AWS_SECRET_ACCESS_KEY>
+ region: eu-central-1
+ storage_options:
+ server_side_encryption: <AES256 or aws:kms>
+ server_side_encryption_key_kms_id: <arn:aws:kms:xxx>
+ objects:
+ artifacts:
+ bucket: gitlab-artifacts
+ external_diffs:
+ bucket: gitlab-mr-diffs
+ lfs:
+ bucket: gitlab-lfs
+ uploads:
+ bucket: gitlab-uploads
+ packages:
+ bucket: gitlab-packages
+ dependency_proxy:
+ bucket: gitlab-dependency-proxy
+ terraform_state:
+ bucket: gitlab-terraform-state
+ ci_secure_files:
+ bucket: gitlab-ci-secure-files
+ pages:
+ bucket: gitlab-pages
+ ```
+
+ If you’re using [AWS IAM profiles](#using-amazon-instance-profiles), omit
+ the AWS access key and secret access key/value pairs. For example:
+
+ ```yaml
+ connection:
+ provider: AWS
+ region: eu-central-1
+ use_iam_profile: true
```
1. Edit `/home/git/gitlab-workhorse/config.toml` and add or amend the following lines:
@@ -194,7 +369,25 @@ See the section on [ETag mismatch errors](#etag-mismatch) for more details.
aws_secret_access_key = "<AWS_SECRET_ACCESS_KEY>"
```
-1. Save the file and [restart GitLab](restart_gitlab.md#installations-from-source) for the changes to take effect.
+ If you’re using [AWS IAM profiles](#using-amazon-instance-profiles), omit
+ the AWS access key and secret access key/value pairs. For example:
+
+ ```yaml
+ [object_storage.s3]
+ use_iam_profile = true
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
#### Common parameters
diff --git a/doc/development/documentation/topic_types/task.md b/doc/development/documentation/topic_types/task.md
index 0dba3e079b6..cd55fa0b897 100644
--- a/doc/development/documentation/topic_types/task.md
+++ b/doc/development/documentation/topic_types/task.md
@@ -57,8 +57,70 @@ The issue is created. You can view it by going to **Issues > List**.
For the title text, use the structure `active verb` + `noun`.
For example, `Create an issue`.
-If you have several tasks on a page that share prerequisites, you can use the title
-`Prerequisites` and link to it.
+If several tasks on a page share prerequisites, you can create a separate
+topic with the title `Prerequisites`.
+
+### When more than one way exists to perform a task
+
+If more than one way exists to perform a task in the UI, you should
+document the primary way only.
+
+However, sometimes you must document multiple ways to perform a task.
+When this situation occurs:
+
+- Introduce the task as usual. Then, for each way of performing the task, add a topic title.
+- Nest the topic titles one level below the task topic title.
+- List the tasks in descending order, with the most likely method first.
+- Make the task titles as brief as possible. When possible,
+ use `infinitive` + `noun`.
+
+Here is an example.
+
+```markdown
+# Change the default branch name
+
+You can change the default branch name for the instance or group.
+If the name is set for the instance, you can override it for a group.
+
+## For the instance
+
+Prerequisites:
+
+- You must have at least the Maintainer role for the instance.
+
+To change the default branch name for an instance:
+
+1. Step.
+1. Step.
+
+## For the group
+
+Prerequisites:
+
+- You must have at least the Developer role for the group.
+
+To change the default branch name for a group:
+
+1. Step.
+1. Step.
+```
+
+### To perform the task in the UI and API
+
+Usually an API exists to perform the same task that you perform in the UI.
+
+When this situation occurs:
+
+- Do not use a separate heading for a one-sentence link to the API.
+- Do not include API examples in the **Use GitLab** documentation. API examples
+ belong in the API documentation. If you have GraphQL examples, put them on
+ their own page, because the API documentation might move some day.
+- Do not mention the API if you do not need to. Users can search for
+ the API documentation, and extra linking adds clutter.
+- If someone feels strongly that you mention the API, at the end
+ of the UI task, add this sentence:
+
+ `To create an issue, you can also [use the API](link).`
## Task introductions
diff --git a/doc/integration/arkose.md b/doc/integration/arkose.md
index 9c8f6cdfb6a..36c0784cb94 100644
--- a/doc/integration/arkose.md
+++ b/doc/integration/arkose.md
@@ -93,17 +93,25 @@ To check if a user failed to sign in because the ArkoseLabs challenge was not so
KQL: json.message:"Challenge was not solved" AND json.username:replace_username_here`
```
-## QA tests caveat
+## Allowlists
-Several GitLab QA test suites need to sign in to the app to test its features. This can conflict
-with Arkose Protect as it would identify QA users as being malicious because they are being run with
-a headless browser. To work around this, ArkoseLabs has allowlisted the unique token
-that serves as QA session's User Agent. While this doesn't guarantee that the session is not
-flagged as malicious, the Arkose API returns a specific telltale when we verify the sign in
-attempt's token. We are leveraging this telltale to bypass the verification step entirely so that the
-test suite doesn't fail. This bypass is done in the `UserVerificationService` class.
+To ensure end-to-end QA test suites can pass during staging and production, we've [allowlisted](https://developer.arkoselabs.com/docs/verify-api-v4#creating-allowlists-and-denylists) the [GITLAB_QA_USER_AGENT](https://start.1password.com/open/i?a=LKATQYUATRBRDHRRABEBH4RJ5Y&v=6gq44ckmq23vqk5poqunurdgay&i=u2wvs63affaxzi22gnfbjjw2zm&h=gitlab.1password.com). Each QA user receives an `ALLOWLIST` [risk category](https://developer.arkoselabs.com/docs/risk-score).
+
+You can find the usage of the allowlist telltale in our [Arkose::VerifyResponse](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/arkose/verify_response.rb#L38) class.
## Feedback Job
To help Arkose improve their protection service, we created a daily background job to send them the list of blocked users by us.
This job is performed by the `Arkose::BlockedUsersReportWorker` class.
+
+## Additional resources
+
+<!-- markdownlint-disable MD044 -->
+The [Anti-abuse team](https://about.gitlab.com/handbook/engineering/development/data-science/anti-abuse/#team-members) owns the ArkoseLabs Protect feature. You can join our ArkoseLabs/GitLab collaboration channel on Slack: [#ext-gitlab-arkose](https://gitlab.slack.com/archives/C02SGF6RLPQ).
+<!-- markdownlint-enable MD044 -->
+
+ArkoseLabs also maintains the following resources:
+
+- [ArkoseLabs portal](https://portal.arkoselabs.com/)
+- [ArkoseLabs Zendesk](https://support.arkoselabs.com/)
+- [ArkoseLabs documentation](https://developer.arkoselabs.com/docs/documentation-guide)
diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md
index 07dbe46691b..1dfd9c95a73 100644
--- a/doc/integration/omniauth.md
+++ b/doc/integration/omniauth.md
@@ -43,7 +43,7 @@ GitLab supports the following OmniAuth providers.
Before you configure the OmniAuth provider,
configure the settings that are common for all providers.
-Omnibus, Docker, and source | Helm chart | Description | Default value
+Linux package, Docker, and self-compiled | Helm chart | Description | Default value
----------------------------|------------|-------------|-----------
`allow_single_sign_on` | `allowSingleSignOn` | List of providers that automatically create a GitLab account. The provider names are available in the **OmniAuth provider name** column in the [supported providers table](#supported-providers). | `false`, which means that signing in using your OmniAuth provider account without a pre-existing GitLab account is not allowed. You must create a GitLab account first, and then connect it to your OmniAuth provider account through your profile settings.
`auto_link_ldap_user` | `autoLinkLdapUser` | Creates an LDAP identity in GitLab for users that are created through an OmniAuth provider. You can enable this setting if you have [LDAP integration](../administration/auth/ldap/index.md) enabled. Requires the `uid` of the user to be the same in both LDAP and the OmniAuth provider. | `false`
@@ -104,6 +104,27 @@ To change the OmniAuth settings:
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
```
+ :::TabTitle Docker
+
+ 1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_allow_single_sign_on'] = ['saml', 'twitter']
+ gitlab_rails['omniauth_auto_link_ldap_user'] = true
+ gitlab_rails['omniauth_block_auto_created_users'] = true
+ ```
+
+ 1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
:::TabTitle Self-compiled (source)
1. Edit `/home/git/gitlab/config/gitlab.yml`:
diff --git a/doc/integration/saml.md b/doc/integration/saml.md
index b210a9b9888..24b5e6152a5 100644
--- a/doc/integration/saml.md
+++ b/doc/integration/saml.md
@@ -23,62 +23,29 @@ For more information on:
## Configure SAML support in GitLab
-1. Make sure GitLab is [configured with HTTPS](../install/installation.md#using-https).
-
-1. On your GitLab server, open the configuration file.
-
- For Omnibus installations:
-
- ```shell
- sudo editor /etc/gitlab/gitlab.rb
- ```
-
- For installations from source:
-
- ```shell
- cd /home/git/gitlab
+::Tabs
- sudo -u git -H editor config/gitlab.yml
- ```
+:::TabTitle Linux package (Omnibus)
+1. Make sure GitLab is [configured with HTTPS](https://docs.gitlab.com/omnibus/settings/ssl/).
1. Edit the [common configuration file settings](omniauth.md#configure-common-settings)
to add `saml` as a single sign-on provider. This enables Just-In-Time
account provisioning for users who do not have an existing GitLab account.
-
1. To allow your users to use SAML to sign up without having to manually create
- an account first, add the following values to your configuration.
-
- For Omnibus installations:
+ an account first, edit `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
gitlab_rails['omniauth_block_auto_created_users'] = false
```
- For installations from source:
-
- ```yaml
- omniauth:
- enabled: true
- allow_single_sign_on: ["saml"]
- block_auto_created_users: false
- ```
-
1. Optional. You can automatically link SAML users with existing GitLab users if their
- email addresses match by adding the following setting.
-
- For Omnibus installations:
+ email addresses match by adding the following setting in `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_rails['omniauth_auto_link_saml_user'] = true
```
- For installations from source:
-
- ```yaml
- auto_link_saml_user: true
- ```
-
Alternatively, a user can manually link their SAML identity to an existing GitLab
account by [enabling OmniAuth for an existing user](omniauth.md#enable-omniauth-for-an-existing-user).
@@ -91,9 +58,7 @@ For more information on:
See your SAML IdP documentation for information on how to make these attributes
unchangeable.
-1. Add the provider configuration.
-
- For Omnibus installations:
+1. Edit `/etc/gitlab/gitlab.rb` and add the provider configuration:
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -111,7 +76,244 @@ For more information on:
]
```
- For installations from source:
+ Where:
+
+ - `assertion_consumer_service_url`: The GitLab HTTPS endpoint
+ (append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation).
+ - `idp_cert_fingerprint`: Your IdP value. It must be a SHA1 fingerprint.
+ For more information on these values, see the
+ [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
+ For more information on other configuration settings, see
+ [configuring SAML on your IdP](#configure-saml-on-your-idp).
+ - `idp_sso_target_url`: Your IdP value.
+ - `issuer`: Change to a unique name, which identifies the application to the IdP.
+ - `name_identifier_format`: Your IdP value.
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Make sure GitLab is [configured with HTTPS](https://docs.gitlab.com/charts/installation/tls.html).
+1. Edit the [common configuration file settings](omniauth.md#configure-common-settings)
+ to add `saml` as a single sign-on provider. This enables Just-In-Time
+ account provisioning for users who do not have an existing GitLab account.
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. To allow your users to use SAML to sign up without having to manually create
+ an account first, edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ enabled: true
+ allowSingleSignOn: ['saml']
+ blockAutoCreatedUsers: true
+ ```
+
+1. Optional. You can automatically link SAML users with existing GitLab users if their
+ email addresses match by adding the following setting in `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ autoLinkSamlUser: true
+ ```
+
+ Alternatively, a user can manually link their SAML identity to an existing GitLab
+ account by [enabling OmniAuth for an existing user](omniauth.md#enable-omniauth-for-an-existing-user).
+
+1. Configure the following attributes so your SAML users cannot change them:
+
+ - [`NameID`](../user/group/saml_sso/index.md#nameid).
+ - `Email` when used with `omniauth_auto_link_saml_user`.
+
+ If users can change these attributes, they can sign in as other authorized users.
+ See your SAML IdP documentation for information on how to make these attributes
+ unchangeable.
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Provider name' # optional label for login button, defaults to "Saml"
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ ```
+
+ Where:
+
+ - `assertion_consumer_service_url`: The GitLab HTTPS endpoint
+ (append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation).
+ - `idp_cert_fingerprint`: Your IdP value. It must be a SHA1 fingerprint.
+ For more information on these values, see the
+ [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
+ For more information on other configuration settings, see
+ [configuring SAML on your IdP](#configure-saml-on-your-idp).
+ - `idp_sso_target_url`: Your IdP value.
+ - `issuer`: Change to a unique name, which identifies the application to the IdP.
+ - `name_identifier_format`: Your IdP value.
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Edit `gitlab_values.yaml` and add the provider configuration:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Make sure GitLab is [configured with HTTPS](https://docs.gitlab.com/omnibus/settings/ssl/).
+1. Edit the [common configuration file settings](omniauth.md#configure-common-settings)
+ to add `saml` as a single sign-on provider. This enables Just-In-Time
+ account provisioning for users who do not have an existing GitLab account.
+1. To allow your users to use SAML to sign up without having to manually create
+ an account first, edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
+ gitlab_rails['omniauth_block_auto_created_users'] = false
+ ```
+
+1. Optional. You can automatically link SAML users with existing GitLab users if their
+ email addresses match by adding the following setting in `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_auto_link_saml_user'] = true
+ ```
+
+ Alternatively, a user can manually link their SAML identity to an existing GitLab
+ account by [enabling OmniAuth for an existing user](omniauth.md#enable-omniauth-for-an-existing-user).
+
+1. Configure the following attributes so your SAML users cannot change them:
+
+ - [`NameID`](../user/group/saml_sso/index.md#nameid).
+ - `Email` when used with `omniauth_auto_link_saml_user`.
+
+ If users can change these attributes, they can sign in as other authorized users.
+ See your SAML IdP documentation for information on how to make these attributes
+ unchangeable.
+
+1. Edit `docker-compose.yml` and add the provider configuration:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ {
+ name: "saml",
+ label: "Provider name", # optional label for login button, defaults to "Saml"
+ args: {
+ assertion_consumer_service_url: "https://gitlab.example.com/users/auth/saml/callback",
+ idp_cert_fingerprint: "43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8",
+ idp_sso_target_url: "https://login.example.com/idp",
+ issuer: "https://gitlab.example.com",
+ name_identifier_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
+ }
+ }
+ ]
+ ```
+
+ Where:
+
+ - `assertion_consumer_service_url`: The GitLab HTTPS endpoint
+ (append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation).
+ - `idp_cert_fingerprint`: Your IdP value. It must be a SHA1 fingerprint.
+ For more information on these values, see the
+ [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
+ For more information on other configuration settings, see
+ [configuring SAML on your IdP](#configure-saml-on-your-idp).
+ - `idp_sso_target_url`: Your IdP value.
+ - `issuer`: Change to a unique name, which identifies the application to the IdP.
+ - `name_identifier_format`: Your IdP value.
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Make sure GitLab is [configured with HTTPS](../install/installation.md#using-https).
+1. Edit the [common configuration file settings](omniauth.md#configure-common-settings)
+ to add `saml` as a single sign-on provider. This enables Just-In-Time
+ account provisioning for users who do not have an existing GitLab account.
+1. To allow your users to use SAML to sign up without having to manually create
+ an account first, edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ enabled: true
+ allow_single_sign_on: ["saml"]
+ block_auto_created_users: false
+ ```
+
+1. Optional. You can automatically link SAML users with existing GitLab users if their
+ email addresses match by adding the following setting in `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ auto_link_saml_user: true
+ ```
+
+ Alternatively, a user can manually link their SAML identity to an existing GitLab
+ account by [enabling OmniAuth for an existing user](omniauth.md#enable-omniauth-for-an-existing-user).
+
+1. Configure the following attributes so your SAML users cannot change them:
+
+ - [`NameID`](../user/group/saml_sso/index.md#nameid).
+ - `Email` when used with `omniauth_auto_link_saml_user`.
+
+ If users can change these attributes, they can sign in as other authorized users.
+ See your SAML IdP documentation for information on how to make these attributes
+ unchangeable.
+
+1. Edit `/home/git/gitlab/config/gitlab.yml` and add the provider configuration:
```yaml
omniauth:
@@ -129,26 +331,30 @@ For more information on:
}
```
-1. Match the value for `assertion_consumer_service_url` to the HTTPS endpoint
- of GitLab. To generate the correct value, append `users/auth/saml/callback` to the
- HTTPS URL of your GitLab installation.
+ Where:
+
+ - `assertion_consumer_service_url`: The GitLab HTTPS endpoint
+ (append `/users/auth/saml/callback` to the HTTPS URL of your GitLab installation).
+ - `idp_cert_fingerprint`: Your IdP value. It must be a SHA1 fingerprint.
+ For more information on these values, see the
+ [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
+ For more information on other configuration settings, see
+ [configuring SAML on your IdP](#configure-saml-on-your-idp).
+ - `idp_sso_target_url`: Your IdP value.
+ - `issuer`: Change to a unique name, which identifies the application to the IdP.
+ - `name_identifier_format`: Your IdP value.
-1. Change the following values to match your IdP:
- - `idp_cert_fingerprint`.
- - `idp_sso_target_url`.
- - `name_identifier_format`.
- If you use a `idp_cert_fingerprint`, it must be a SHA1 fingerprint. For more
- information on these values, see the
- [OmniAuth SAML documentation](https://github.com/omniauth/omniauth-saml).
- For more information on other configuration settings, see
- [configuring SAML on your IdP](#configure-saml-on-your-idp).
+1. Save the file and restart GitLab:
-1. Change the value of `issuer` to a unique name, which identifies the application
- to the IdP.
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
-1. For the changes to take effect, if you installed:
- - Using Omnibus, [reconfigure GitLab](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure).
- - From source, [restart GitLab](../administration/restart_gitlab.md#installations-from-source).
+::EndTabs
### Register GitLab in your SAML IdP
@@ -204,65 +410,229 @@ You can configure GitLab to use multiple SAML IdPs if:
[SAML group memberships](#configure-users-based-on-saml-group-membership) and [Group Sync](../user/group/saml_sso/group_sync.md) do not support multiple IdPs. For more information, see [issue 386605](https://gitlab.com/gitlab-org/gitlab/-/issues/386605).
-Example provider's configuration for installations from source:
-
-```yaml
-omniauth:
- providers:
- - {
- name: 'saml', # This must match the following name configuration parameter
- args: {
- name: 'saml', # This is mandatory and must match the provider name
- strategy_class: 'OmniAuth::Strategies::SAML',
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_1/callback', # URL must match the name of the provider
- ... # Put here all the required arguments similar to a single provider
- },
- label: 'Provider 1' # Differentiate the two buttons and providers in the UI
- }
- - {
- name: 'saml1', # This must match the following name configuration parameter
- args: {
- name: 'saml1', # This is mandatory and must match the provider name
- strategy_class: 'OmniAuth::Strategies::SAML',
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_2/callback', # URL must match the name of the provider
- ... # Put here all the required arguments similar to a single provider
- },
- label: 'Provider 2' # Differentiate the two buttons and providers in the UI
- }
-```
-
-Example provider's configuration for Omnibus GitLab installations:
-
-To allow your users to use SAML to sign up without having to manually create an account from either of the providers, add the following values to your configuration.
-
-```ruby
-gitlab_rails['omniauth_allow_single_sign_on'] = ['saml', 'saml1']
-```
-
-```ruby
-gitlab_rails['omniauth_providers'] = [
- {
- name: 'saml', # This must match the following name configuration parameter
- args: {
- name: 'saml', # This is mandatory and must match the provider name
- strategy_class: 'OmniAuth::Strategies::SAML',
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_1/callback', # URL must match the name of the provider
- ... # Put here all the required arguments similar to a single provider
- },
- label: 'Provider 1' # Differentiate the two buttons and providers in the UI
- },
- {
- name: 'saml1', # This must match the following name configuration parameter
- args: {
- name: 'saml1', # This is mandatory and must match the provider name
- strategy_class: 'OmniAuth::Strategies::SAML',
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_2/callback', # URL must match the name of the provider
- ... # Put here all the required arguments similar to a single provider
- },
- label: 'Provider 2' # Differentiate the two buttons and providers in the UI
- }
-]
-```
+To set up multiple SAML IdPs:
+
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ {
+ name: 'saml', # This must match the following name configuration parameter
+ label: 'Provider 1' # Differentiate the two buttons and providers in the UI
+ args: {
+ name: 'saml', # This is mandatory and must match the provider name
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback', # URL must match the name of the provider
+ strategy_class: 'OmniAuth::Strategies::SAML',
+ ... # Put here all the required arguments similar to a single provider
+ },
+ },
+ {
+ name: 'saml_2', # This must match the following name configuration parameter
+ label: 'Provider 2' # Differentiate the two buttons and providers in the UI
+ args: {
+ name: 'saml_2', # This is mandatory and must match the provider name
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_2/callback', # URL must match the name of the provider
+ strategy_class: 'OmniAuth::Strategies::SAML',
+ ... # Put here all the required arguments similar to a single provider
+ },
+ }
+ ]
+ ```
+
+ To allow your users to use SAML to sign up without having to manually create an
+ account from either of the providers, add the following values to your configuration:
+
+ ```ruby
+ gitlab_rails['omniauth_allow_single_sign_on'] = ['saml', 'saml_2']
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers)
+ for the first SAML provider:
+
+ ```yaml
+ name: 'saml' # At least one provider must be named 'saml'
+ label: 'Provider 1' # Differentiate the two buttons and providers in the UI
+ args:
+ name: 'saml' # This is mandatory and must match the provider name
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback' # URL must match the name of the provider
+ strategy_class: 'OmniAuth::Strategies::SAML' # Mandatory
+ ... # Put here all the required arguments similar to a single provider
+ ```
+
+1. Put the following content in a file named `saml_2.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers)
+ for the second SAML provider:
+
+ ```yaml
+ name: 'saml_2'
+ label: 'Provider 2' # Differentiate the two buttons and providers in the UI
+ args:
+ name: 'saml_2' # This is mandatory and must match the provider name
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_2/callback' # URL must match the name of the provider
+ strategy_class: 'OmniAuth::Strategies::SAML' # Mandatory
+ ... # Put here all the required arguments similar to a single provider
+ ```
+
+1. Optional. Set additional SAML providers by following the same steps.
+1. Create the Kubernetes Secrets:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml \
+ --from-file=saml=saml.yaml \
+ --from-file=saml_2=saml_2.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ - key: saml
+ - secret: gitlab-saml
+ - key: saml_2
+ ```
+
+ To allow your users to use SAML to sign up without having to manually create an
+ account from either of the providers, add the following values to your configuration:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ allowSingleSignOn: ['saml', 'saml_2']
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_allow_single_sign_on'] = ['saml', 'saml1']
+ gitlab_rails['omniauth_providers'] = [
+ {
+ name: 'saml', # This must match the following name configuration parameter
+ label: 'Provider 1' # Differentiate the two buttons and providers in the UI
+ args: {
+ name: 'saml', # This is mandatory and must match the provider name
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback', # URL must match the name of the provider
+ strategy_class: 'OmniAuth::Strategies::SAML',
+ ... # Put here all the required arguments similar to a single provider
+ },
+ },
+ {
+ name: 'saml_2', # This must match the following name configuration parameter
+ label: 'Provider 2' # Differentiate the two buttons and providers in the UI
+ args: {
+ name: 'saml_2', # This is mandatory and must match the provider name
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_2/callback', # URL must match the name of the provider
+ strategy_class: 'OmniAuth::Strategies::SAML',
+ ... # Put here all the required arguments similar to a single provider
+ },
+ }
+ ]
+ ```
+
+ To allow your users to use SAML to sign up without having to manually create an
+ account from either of the providers, add the following values to your configuration:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_allow_single_sign_on'] = ['saml', 'saml_2']
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - {
+ name: 'saml', # This must match the following name configuration parameter
+ label: 'Provider 1' # Differentiate the two buttons and providers in the UI
+ args: {
+ name: 'saml', # This is mandatory and must match the provider name
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback', # URL must match the name of the provider
+ strategy_class: 'OmniAuth::Strategies::SAML',
+ ... # Put here all the required arguments similar to a single provider
+ },
+ }
+ - {
+ name: 'saml_2', # This must match the following name configuration parameter
+ label: 'Provider 2' # Differentiate the two buttons and providers in the UI
+ args: {
+ name: 'saml_2', # This is mandatory and must match the provider name
+ strategy_class: 'OmniAuth::Strategies::SAML',
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml_2/callback', # URL must match the name of the provider
+ ... # Put here all the required arguments similar to a single provider
+ },
+ }
+ ```
+
+ To allow your users to use SAML to sign up without having to manually create an
+ account from either of the providers, add the following values to your configuration:
+
+ ```yaml
+ production: &base
+ omniauth:
+ allow_single_sign_on: ["saml", "saml_2"]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
## Set up identity providers
@@ -388,26 +758,26 @@ Support for these groups depends on:
| [Admin](#administrator-groups) | **(FREE SELF)** | Yes |
| [Auditor](#auditor-groups) | **(PREMIUM SELF)** | Yes |
-### Prerequisites
-
-You must tell GitLab where to look for group information. To do this, make sure
-that your IdP server sends a specific `AttributeStatement` along with the regular
-SAML response. For example:
-
-```xml
-<saml:AttributeStatement>
- <saml:Attribute Name="Groups">
- <saml:AttributeValue xsi:type="xs:string">Developers</saml:AttributeValue>
- <saml:AttributeValue xsi:type="xs:string">Freelancers</saml:AttributeValue>
- <saml:AttributeValue xsi:type="xs:string">Admins</saml:AttributeValue>
- <saml:AttributeValue xsi:type="xs:string">Auditors</saml:AttributeValue>
- </saml:Attribute>
-</saml:AttributeStatement>
-```
+Prerequisites:
-The name of the attribute must contain the groups that a user belongs to.
-To tell GitLab where to find these groups, add a `groups_attribute:`
-element to your SAML settings.
+- You must tell GitLab where to look for group information. To do this, make sure
+ that your IdP server sends a specific `AttributeStatement` along with the regular
+ SAML response. For example:
+
+ ```xml
+ <saml:AttributeStatement>
+ <saml:Attribute Name="Groups">
+ <saml:AttributeValue xsi:type="xs:string">Developers</saml:AttributeValue>
+ <saml:AttributeValue xsi:type="xs:string">Freelancers</saml:AttributeValue>
+ <saml:AttributeValue xsi:type="xs:string">Admins</saml:AttributeValue>
+ <saml:AttributeValue xsi:type="xs:string">Auditors</saml:AttributeValue>
+ </saml:Attribute>
+ </saml:AttributeStatement>
+ ```
+
+ The name of the attribute must contain the groups that a user belongs to.
+ To tell GitLab where to find these groups, add a `groups_attribute:`
+ element to your SAML settings.
### Required groups
@@ -423,21 +793,146 @@ membership is required to sign in.
If you do not set `required_groups` or leave the setting empty, anyone with proper
authentication can use the service.
-Example configuration:
+::Tabs
-```yaml
-{ name: 'saml',
- label: 'Our SAML Provider',
- groups_attribute: 'Groups',
- required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
- args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
- } }
-```
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ groups_attribute: 'Groups'
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors']
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
### External groups
@@ -453,19 +948,147 @@ setting.
Example configuration:
-```yaml
-{ name: 'saml',
- label: 'Our SAML Provider',
- groups_attribute: 'Groups',
- external_groups: ['Freelancers'],
- args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
- } }
-```
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ external_groups: ['Freelancers'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ groups_attribute: 'Groups'
+ external_groups: ['Freelancers']
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ external_groups: ['Freelancers'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ external_groups: ['Freelancers'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
### Administrator groups
@@ -480,19 +1103,146 @@ the user administrator access.
Example configuration:
-```yaml
-{ name: 'saml',
- label: 'Our SAML Provider',
- groups_attribute: 'Groups',
- admin_groups: ['Admins'],
- args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
- } }
-```
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ admin_groups: ['Admins'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ groups_attribute: 'Groups'
+ admin_groups: ['Admins']
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ admin_groups: ['Admins'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ admin_groups: ['Admins'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
### Auditor groups **(PREMIUM SELF)**
@@ -509,19 +1259,146 @@ users with [auditor access](../administration/auditor_users.md).
Example configuration:
-```yaml
-{ name: 'saml',
- label: 'Our SAML Provider',
- groups_attribute: 'Groups',
- auditor_groups: ['Auditors'],
- args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
- } }
-```
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ auditor_groups: ['Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ groups_attribute: 'Groups'
+ auditor_groups: ['Auditors']
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ auditor_groups: ['Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ auditor_groups: ['Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
## Automatically manage SAML Group Sync
@@ -535,110 +1412,464 @@ list.
1. Make sure that your IdP is returning the `AuthnContext`. For example:
-```xml
-<saml:AuthnStatement>
- <saml:AuthnContext>
- <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:MediumStrongCertificateProtectedTransport</saml:AuthnContextClassRef>
- </saml:AuthnContext>
-</saml:AuthnStatement>
-```
+ ```xml
+ <saml:AuthnStatement>
+ <saml:AuthnContext>
+ <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:MediumStrongCertificateProtectedTransport</saml:AuthnContextClassRef>
+ </saml:AuthnContext>
+ </saml:AuthnStatement>
+ ```
1. Edit your installation configuration to register the SAML authentication method
- in the `upstream_two_factor_authn_contexts` list. How you edit your configuration
- differs depending on your installation type.
+ in the `upstream_two_factor_authn_contexts` list.
+
+ ::Tabs
+
+ :::TabTitle Linux package (Omnibus)
+
+ 1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ upstream_two_factor_authn_contexts:
+ %w(
+ urn:oasis:names:tc:SAML:2.0:ac:classes:CertificateProtectedTransport
+ urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorOTPSMS
+ urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorIGTOKEN
+ ),
+ }
+ }
+ ]
+ ```
+
+ 1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+ :::TabTitle Helm chart (Kubernetes)
+
+ 1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ upstream_two_factor_authn_contexts:
+ - 'urn:oasis:names:tc:SAML:2.0:ac:classes:CertificateProtectedTransport'
+ - 'urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorOTPSMS'
+ - 'urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorIGTOKEN'
+ ```
+
+ 1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+ 1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+ 1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+ 1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+ :::TabTitle Docker
+
+ 1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ upstream_two_factor_authn_contexts:
+ %w(
+ urn:oasis:names:tc:SAML:2.0:ac:classes:CertificateProtectedTransport
+ urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorOTPSMS
+ urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorIGTOKEN
+ )
+ }
+ }
+ ]
+ ```
+
+ 1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+ :::TabTitle Self-compiled (source)
+
+ 1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ upstream_two_factor_authn_contexts:
+ [
+ 'urn:oasis:names:tc:SAML:2.0:ac:classes:CertificateProtectedTransport',
+ 'urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorOTPSMS',
+ 'urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorIGTOKEN'
+ ]
+ }
+ }
+ ```
+
+ 1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+ ::EndTabs
+
+## Validate response signatures
+
+IdPs must sign SAML responses to ensure that the assertions are not tampered with.
+
+This prevents user impersonation and privilege escalation when specific group
+membership is required.
-### Omnibus GitLab installations
+### Using `idp_cert_fingerprint`
+
+You configure the response signature validation using `idp_cert_fingerprint`.
+An example configuration:
+
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
1. Edit `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_rails['omniauth_providers'] = [
- {
- name: "saml",
+ { name: 'saml',
+ label: 'Our SAML Provider',
args: {
- assertion_consumer_service_url: "https://gitlab.example.com/users/auth/saml/callback",
- idp_cert_fingerprint: "43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8",
- idp_sso_target_url: "https://login.example.com/idp",
- issuer: "https://gitlab.example.com",
- name_identifier_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
- upstream_two_factor_authn_contexts:
- %w(
- urn:oasis:names:tc:SAML:2.0:ac:classes:CertificateProtectedTransport
- urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorOTPSMS
- urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorIGTOKEN
- )
- },
- label: "Company Login" # optional label for SAML login button, defaults to "Saml"
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
}
]
```
-1. Save the file and [reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
- GitLab for the changes to take effect.
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
-### Installations from source
+:::TabTitle Helm chart (Kubernetes)
-1. Edit `config/gitlab.yml`:
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
```yaml
- omniauth:
- providers:
- - {
- name: 'saml',
- args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
- upstream_two_factor_authn_contexts:
- [
- 'urn:oasis:names:tc:SAML:2.0:ac:classes:CertificateProtectedTransport',
- 'urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorOTPSMS',
- 'urn:oasis:names:tc:SAML:2.0:ac:classes:SecondFactorIGTOKEN'
- ]
- },
- label: 'Company Login' # optional label for SAML login button, defaults to "Saml"
- }
+ name: 'saml'
+ label: 'Our SAML Provider'
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
```
-1. Save the file and [restart GitLab](../administration/restart_gitlab.md#installations-from-source)
- for the changes to take effect.
+1. Create the Kubernetes Secret:
-## Validate response signatures
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
-IdPs must sign SAML responses to ensure that the assertions are not tampered with.
+1. Export the Helm values:
-This prevents user impersonation and privilege escalation when specific group
-membership is required.
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
-You configure the response signature validation using `idp_cert_fingerprint`.
-An example configuration:
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
-```yaml
-args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
-}
-```
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
+
+### Using `idp_cert`
If your IdP does not support configuring this using `idp_cert_fingerprint`, you
-can instead configure GitLab directly using `idp_cert`. An example configuration:
-
-```yaml
-args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert: '-----BEGIN CERTIFICATE-----
- <redacted>
- -----END CERTIFICATE-----',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
-}
-```
+can instead configure GitLab directly using `idp_cert`.
+An example configuration:
+
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert: '-----BEGIN CERTIFICATE-----
+ <redacted>
+ -----END CERTIFICATE-----',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert: |
+ -----BEGIN CERTIFICATE-----
+ <redacted>
+ -----END CERTIFICATE-----
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert: '-----BEGIN CERTIFICATE-----
+ <redacted>
+ -----END CERTIFICATE-----',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert: '-----BEGIN CERTIFICATE-----
+ <redacted>
+ -----END CERTIFICATE-----',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
If you have configured the response signature validation incorrectly, you might see
error messages such as:
@@ -657,24 +1888,92 @@ You can add the `auto_sign_in_with_provider` setting to your GitLab configuratio
to automatically redirect you to your SAML server for authentication. This removes
the requirement to select an element before actually signing in.
-For Omnibus GitLab installations:
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml'
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Export the Helm values:
-```ruby
-gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml'
-```
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
-For installations from source:
+1. Edit `gitlab_values.yaml`:
-```yaml
-omniauth:
- auto_sign_in_with_provider: saml
-```
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ autoSignInWithProvider: 'saml'
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml'
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ auto_sign_in_with_provider: 'saml'
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
Every sign in attempt redirects to the SAML server, so you cannot sign in using
local credentials. Make sure at least one of the SAML users has administrator access.
-You can also bypass the auto sign-in feature by
-`https://gitlab.example.com/users/sign_in?auto_sign_in=false`.
+NOTE:
+To bypass the auto sign-in setting, append `?auto_sign_in=false` in the sign in
+URL, for example: `https://gitlab.example.com/users/sign_in?auto_sign_in=false`.
### Map SAML response attribute names **(FREE SELF)**
@@ -690,19 +1989,146 @@ corresponding key in the `info` hash. URI-named Attributes are also supported, f
`{ email: ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'] }`.
Use this setting to tell GitLab where to look for certain attributes required
-to create an account. If your IdP sends the user's email address as `EmailAddress`
+to create an account. For example, if your IdP sends the user's email address as `EmailAddress`
instead of `email`, let GitLab know by setting it on your configuration:
-```yaml
-args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
- attribute_statements: { email: ['EmailAddress'] }
-}
-```
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ attribute_statements: { email: ['EmailAddress'] }
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ attribute_statements:
+ email: ['EmailAddress']
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ attribute_statements: { email: ['EmailAddress'] }
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ attribute_statements: { email: ['EmailAddress'] }
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
#### Set a username
@@ -711,16 +2137,147 @@ generate the user's GitLab username.
Configure `nickname` in `attribute_statements` to specify one or more attributes that contain a user's desired username:
-```yaml
-args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
- attribute_statements: { nickname: ['username'] }
-}
-```
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ attribute_statements: { nickname: ['username'] }
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ attribute_statements:
+ nickname: ['username']
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ attribute_statements: { nickname: ['username'] }
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ attribute_statements: { nickname: ['username'] }
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
This also sets the `username` attribute in your SAML Response to the username in GitLab.
@@ -731,34 +2288,152 @@ To allow for a small amount of clock drift, use `allowed_clock_drift` in
your settings. You must enter the parameter's value in a number and fraction of seconds.
The value given is added to the current time at which the response is validated.
-```yaml
-args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
- attribute_statements: { email: ['EmailAddress'] },
- allowed_clock_drift: 1 # for one second clock drift
-}
-```
+::Tabs
-### Designate a unique attribute for the `uid`
+:::TabTitle Linux package (Omnibus)
-By default, the `uid` is set as the `name_id` in the SAML response. To designate
-a unique attribute for the `uid`, you can set the `uid_attribute`. In the following
-example, the value of `uid` attribute in the SAML response is set as the `uid_attribute`.
+1. Edit `/etc/gitlab/gitlab.rb`:
-```yaml
-args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
- uid_attribute: 'uid'
-}
-```
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ allowed_clock_drift: 1 # for one second clock drift
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ groups_attribute: 'Groups'
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors']
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ allowed_clock_drift: 1 # for one second clock drift
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ allowed_clock_drift: 1 # for one second clock drift
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ allowed_clock_drift: 1 # for one second clock drift
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
+
+### Designate a unique attribute for the `uid`
Before setting the `uid` to a unique attribute, make sure that you have configured
the following attributes so your SAML users cannot change them:
@@ -770,6 +2445,153 @@ If users can change these attributes, they can sign in as other authorized users
See your SAML IdP documentation for information on how to make these attributes
unchangeable.
+By default, the `uid` is set as the `name_id` in the SAML response. To designate
+a unique attribute for the `uid`, you can set the `uid_attribute`. In the following
+example, the value of `uid` attribute in the SAML response is set as the `uid_attribute`.
+
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ uid_attribute: 'uid'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ groups_attribute: 'Groups'
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors']
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ uid_attribute: 'uid'
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ uid_attribute: 'uid'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ uid_attribute: 'uid'
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
+
## Assertion encryption (optional)
GitLab requires the use of TLS encryption with SAML 2.0. Sometimes, GitLab needs
@@ -780,6 +2602,13 @@ additional assertion encryption. For example, if you:
Most organizations should not need additional encryption at this layer.
+Your IdP encrypts the assertion with the public certificate of GitLab.
+GitLab decrypts the `EncryptedAssertion` with its private key.
+
+NOTE:
+This integration uses the `certificate` and `private_key` settings for both
+assertion encryption and request signing.
+
The SAML integration supports `EncryptedAssertion`. To encrypt your assertions,
define the private key and the public certificate of your GitLab instance in the
SAML settings.
@@ -787,24 +2616,154 @@ SAML settings.
When you define the key and certificate, replace all line feeds in the key file with `\n`.
This makes the key file one long string with no line feeds.
-```yaml
-args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
- certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----',
- private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----'
-}
-```
+::Tabs
-Your IdP encrypts the assertion with the public certificate of GitLab.
-GitLab decrypts the `EncryptedAssertion` with its private key.
+:::TabTitle Linux package (Omnibus)
-NOTE:
-This integration uses the `certificate` and `private_key` settings for both
-assertion encryption and request signing.
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----',
+ private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ groups_attribute: 'Groups'
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors']
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----'
+ private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----'
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----',
+ private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----'
+ }
+ }
+ ]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ groups_attribute: 'Groups',
+ required_groups: ['Developers', 'Freelancers', 'Admins', 'Auditors'],
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----',
+ private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----'
+ }
+ }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+::EndTabs
## Sign SAML authentication requests (optional)
@@ -818,24 +2777,173 @@ To implement signing:
1. Configure the signing settings in the `security` section of the configuration.
For example:
-```yaml
-args: {
- assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
- idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
- idp_sso_target_url: 'https://login.example.com/idp',
- issuer: 'https://gitlab.example.com',
- name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
- certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----',
- private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----',
- security: {
- authn_requests_signed: true, # enable signature on AuthNRequest
- want_assertions_signed: true, # enable the requirement of signed assertion
- metadata_signed: false, # enable signature on Metadata
- signature_method: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
- digest_method: 'http://www.w3.org/2001/04/xmlenc#sha256',
- }
-}
-```
+ ::Tabs
+
+ :::TabTitle Linux package (Omnibus)
+
+ 1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----',
+ private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----',
+ security: {
+ authn_requests_signed: true, # enable signature on AuthNRequest
+ want_assertions_signed: true, # enable the requirement of signed assertion
+ metadata_signed: false, # enable signature on Metadata
+ signature_method: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
+ digest_method: 'http://www.w3.org/2001/04/xmlenc#sha256',
+ }
+ }
+ }
+ ]
+ ```
+
+ 1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+ :::TabTitle Helm chart (Kubernetes)
+
+ 1. Put the following content in a file named `saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'saml'
+ label: 'Our SAML Provider'
+ args:
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback'
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8'
+ idp_sso_target_url: 'https://login.example.com/idp'
+ issuer: 'https://gitlab.example.com'
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
+ certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----'
+ private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----'
+ security:
+ authn_requests_signed: true # enable signature on AuthNRequest
+ want_assertions_signed: true # enable the requirement of signed assertion
+ metadata_signed: false # enable signature on Metadata
+ signature_method: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
+ digest_method: 'http://www.w3.org/2001/04/xmlenc#sha256'
+ ```
+
+ 1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-saml --from-file=provider=saml.yaml
+ ```
+
+ 1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+ 1. Edit `gitlab_values.yaml`:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ providers:
+ - secret: gitlab-saml
+ ```
+
+ 1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+ :::TabTitle Docker
+
+ 1. Edit `docker-compose.yml`:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_providers'] = [
+ { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----',
+ private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----',
+ security: {
+ authn_requests_signed: true, # enable signature on AuthNRequest
+ want_assertions_signed: true, # enable the requirement of signed assertion
+ metadata_signed: false, # enable signature on Metadata
+ signature_method: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
+ digest_method: 'http://www.w3.org/2001/04/xmlenc#sha256',
+ }
+ }
+ }
+ ]
+ ```
+
+ 1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+ :::TabTitle Self-compiled (source)
+
+ 1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ production: &base
+ omniauth:
+ providers:
+ - { name: 'saml',
+ label: 'Our SAML Provider',
+ args: {
+ assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
+ idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
+ idp_sso_target_url: 'https://login.example.com/idp',
+ issuer: 'https://gitlab.example.com',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
+ certificate: '-----BEGIN CERTIFICATE-----\n<redacted>\n-----END CERTIFICATE-----',
+ private_key: '-----BEGIN PRIVATE KEY-----\n<redacted>\n-----END PRIVATE KEY-----',
+ security: {
+ authn_requests_signed: true, # enable signature on AuthNRequest
+ want_assertions_signed: true, # enable the requirement of signed assertion
+ metadata_signed: false, # enable signature on Metadata
+ signature_method: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
+ digest_method: 'http://www.w3.org/2001/04/xmlenc#sha256',
+ }
+ }
+ }
+ ```
+
+ 1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
+
+ ::EndTabs
GitLab then:
@@ -877,24 +2985,108 @@ self-managed instance.
To configure group SAML SSO:
-1. [Configure GitLab with HTTPS](../install/installation.md#using-https).
-1. Enable OmniAuth and the `group_saml` provider.
+::Tabs
- To do this for Omnibus GitLab installations, edit `gitlab.rb`:
+:::TabTitle Linux package (Omnibus)
+
+1. Make sure GitLab is [configured with HTTPS](https://docs.gitlab.com/omnibus/settings/ssl/).
+1. Edit `/etc/gitlab/gitlab.rb` to enable OmniAuth and the `group_saml` provider:
```ruby
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_providers'] = [{ name: 'group_saml' }]
```
- For installations from source, edit `gitlab/config/gitlab.yml`:
+1. Save the file and reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+:::TabTitle Helm chart (Kubernetes)
+
+1. Make sure GitLab is [configured with HTTPS](https://docs.gitlab.com/charts/installation/tls.html).
+1. Put the following content in a file named `group_saml.yaml` to be used as a
+ [Kubernetes Secret](https://docs.gitlab.com/charts/charts/globals.html#providers):
+
+ ```yaml
+ name: 'group_saml'
+ ```
+
+1. Create the Kubernetes Secret:
+
+ ```shell
+ kubectl create secret generic -n <namespace> gitlab-group-saml --from-file=provider=group_saml.yaml
+ ```
+
+1. Export the Helm values:
+
+ ```shell
+ helm get values gitlab > gitlab_values.yaml
+ ```
+
+1. Edit `gitlab_values.yaml` to enable OmniAuth and the `group_saml` provider:
+
+ ```yaml
+ global:
+ appConfig:
+ omniauth:
+ enabled: true
+ providers:
+ - secret: gitlab-group-saml
+ ```
+
+1. Save the file and apply the new values:
+
+ ```shell
+ helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
+ ```
+
+:::TabTitle Docker
+
+1. Make sure GitLab is [configured with HTTPS](https://docs.gitlab.com/omnibus/settings/ssl/).
+1. Edit `docker-compose.yml` to enable OmniAuth and the `group_saml` provider:
+
+ ```yaml
+ version: "3.6"
+ services:
+ gitlab:
+ environment:
+ GITLAB_OMNIBUS_CONFIG: |
+ gitlab_rails['omniauth_enabled'] = true
+ gitlab_rails['omniauth_providers'] = [{ name: 'group_saml' }]
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ docker compose up -d
+ ```
+
+:::TabTitle Self-compiled (source)
+
+1. Make sure GitLab is [configured with HTTPS](../install/installation.md#using-https).
+1. Edit `/home/git/gitlab/config/gitlab.yml` to enable OmniAuth and the `group_saml` provider:
+
+ ```yaml
+ production: &base
+ omniauth:
+ enabled: true
+ providers:
+ - { name: 'group_saml' }
+ ```
+
+1. Save the file and restart GitLab:
+
+ ```shell
+ # For systems running systemd
+ sudo systemctl restart gitlab.target
+
+ # For systems running SysV init
+ sudo service gitlab restart
+ ```
- ```yaml
- omniauth:
- enabled: true
- providers:
- - { name: 'group_saml' }
- ```
+::EndTabs
As a multi-tenant solution, group SAML on a self-managed instance is limited compared
to the recommended [instance-wide SAML](../user/group/saml_sso/index.md). Use
diff --git a/doc/raketasks/backup_gitlab.md b/doc/raketasks/backup_gitlab.md
index 9bf811371fc..d63ef61a99f 100644
--- a/doc/raketasks/backup_gitlab.md
+++ b/doc/raketasks/backup_gitlab.md
@@ -241,8 +241,6 @@ You can exclude specific directories from the backup by adding the environment v
- `repositories` (Git repositories data)
- `packages` (Packages)
-All wikis are backed up as part of the `repositories` group. Non-existent wikis are skipped during a backup.
-
NOTE:
When [backing up and restoring Helm Charts](https://docs.gitlab.com/charts/architecture/backup-restore.html), there is an additional option `packages`, which refers to any packages managed by the GitLab [package registry](../user/packages/package_registry/index.md).
For more information see [command line arguments](https://docs.gitlab.com/charts/architecture/backup-restore.html#command-line-arguments).
diff --git a/doc/user/packages/nuget_repository/index.md b/doc/user/packages/nuget_repository/index.md
index bc19acde6f7..6710c147c87 100644
--- a/doc/user/packages/nuget_repository/index.md
+++ b/doc/user/packages/nuget_repository/index.md
@@ -461,9 +461,15 @@ for more details on what other GitLab CI patterns are demonstrated.
## Troubleshooting
+### Clear NuGet cache
+
To improve performance, NuGet caches files related to a package. If you encounter issues, clear the
cache with this command:
```shell
nuget locals all -clear
```
+
+### `Error publishing` or `Invalid Package: Failed metadata extraction error` messages when trying to publish NuGet packages in a Docker-based GitLab installation
+
+Webhook requests to local network addresses are blocked to prevent the exploitation of internal web services. If you get `Error publishing` or `Invalid Package` messages when you try to publish NuGet packages, change your network settings to [allow webhook and service requests to the local network](../../../security/webhooks.md#allow-webhook-and-service-requests-to-local-network).
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index a3a5f0ca06a..d4a445edfe2 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -624,8 +624,9 @@ module API
merge_request = find_project_merge_request(params[:merge_request_iid])
- # Merge request can not be merged
- # because user dont have permissions to push into target branch
+ # Merge request can not be merged because the user doesn't have
+ # permissions to push into target branch
+ #
unauthorized! unless merge_request.can_be_merged_by?(current_user)
merge_when_pipeline_succeeds = to_boolean(params[:merge_when_pipeline_succeeds])
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index f2765a5af91..5d1e2ae5499 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2584,6 +2584,9 @@ msgstr ""
msgid "AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}."
msgstr ""
+msgid "AdminArea|Are you sure?"
+msgstr ""
+
msgid "AdminArea|Blocked users"
msgstr ""
@@ -2596,6 +2599,15 @@ msgstr ""
msgid "AdminArea|Breakdown of Non-Billable users"
msgstr ""
+msgid "AdminArea|Cancel all jobs"
+msgstr ""
+
+msgid "AdminArea|Cancel all running and pending jobs"
+msgstr ""
+
+msgid "AdminArea|Canceling jobs failed"
+msgstr ""
+
msgid "AdminArea|Components"
msgstr ""
@@ -2668,15 +2680,6 @@ msgstr ""
msgid "AdminArea|Stop all jobs"
msgstr ""
-msgid "AdminArea|Stop all jobs?"
-msgstr ""
-
-msgid "AdminArea|Stop jobs"
-msgstr ""
-
-msgid "AdminArea|Stopping jobs failed"
-msgstr ""
-
msgid "AdminArea|Total Billable users"
msgstr ""
@@ -2713,7 +2716,10 @@ msgstr ""
msgid "AdminArea|View latest users"
msgstr ""
-msgid "AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running."
+msgid "AdminArea|Yes, proceed"
+msgstr ""
+
+msgid "AdminArea|You're about to cancel all running and pending jobs across this instance. Do you want to proceed?"
msgstr ""
msgid "AdminArea|active users + blocked users"
@@ -15698,7 +15704,10 @@ msgstr ""
msgid "Environments Dashboard"
msgstr ""
-msgid "Environments allow you to track deployments of your application. %{linkStart}More information%{linkEnd}."
+msgid "Environments allow you to track deployments of your application. To protect this environment, go to the CI/CD settings %{linkStart}Protected environments%{linkEnd} section."
+msgstr ""
+
+msgid "Environments allow you to track deployments of your application.%{linkStart} More information.%{linkEnd}"
msgstr ""
msgid "Environments in %{name}"
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index 22a406b3197..6b71d5595c5 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -552,6 +552,53 @@ RSpec.describe GroupsController, factory_default: :keep do
expect(assigns(:merge_requests)).to eq [merge_request_2, merge_request_1]
end
end
+
+ context 'rendering views' do
+ render_views
+
+ it 'displays MR counts in nav' do
+ get :merge_requests, params: { id: group.to_param }
+
+ expect(response.body).to have_content('Open 2 Merged 0 Closed 0 All 2')
+ expect(response.body).not_to have_content('Open Merged Closed All')
+ end
+ end
+
+ context 'when an ActiveRecord::QueryCanceled is raised' do
+ before do
+ allow_next_instance_of(Gitlab::IssuableMetadata) do |instance|
+ allow(instance).to receive(:data).and_raise(ActiveRecord::QueryCanceled)
+ end
+ end
+
+ it 'sets :search_timeout_occurred' do
+ get :merge_requests, params: { id: group.to_param }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(assigns(:search_timeout_occurred)).to eq(true)
+ end
+
+ it 'logs the exception' do
+ get :merge_requests, params: { id: group.to_param }
+ end
+
+ context 'rendering views' do
+ render_views
+
+ it 'shows error message' do
+ get :merge_requests, params: { id: group.to_param }
+
+ expect(response.body).to have_content('Too many results to display. Edit your search or add a filter.')
+ end
+
+ it 'does not display MR counts in nav' do
+ get :merge_requests, params: { id: group.to_param }
+
+ expect(response.body).to have_content('Open Merged Closed All')
+ expect(response.body).not_to have_content('Open 0 Merged 0 Closed 0 All 0')
+ end
+ end
+ end
end
describe 'DELETE #destroy' do
diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb
index 078450ef1e8..0647058d63a 100644
--- a/spec/factories/clusters/applications/helm.rb
+++ b/spec/factories/clusters/applications/helm.rb
@@ -98,11 +98,6 @@ FactoryBot.define do
cluster factory: %i(cluster with_installed_helm provided_by_gcp)
end
- factory :clusters_applications_cert_manager, class: 'Clusters::Applications::CertManager' do
- email { 'admin@example.com' }
- cluster factory: %i(cluster with_installed_helm provided_by_gcp)
- end
-
factory :clusters_applications_crossplane, class: 'Clusters::Applications::Crossplane' do
stack { 'gcp' }
cluster factory: %i(cluster with_installed_helm provided_by_gcp)
diff --git a/spec/factories/clusters/clusters.rb b/spec/factories/clusters/clusters.rb
index f6af9d04ea5..32cd6beb7ea 100644
--- a/spec/factories/clusters/clusters.rb
+++ b/spec/factories/clusters/clusters.rb
@@ -94,7 +94,6 @@ FactoryBot.define do
trait :with_all_applications do
application_helm factory: %i(clusters_applications_helm installed)
application_ingress factory: %i(clusters_applications_ingress installed)
- application_cert_manager factory: %i(clusters_applications_cert_manager installed)
application_crossplane factory: %i(clusters_applications_crossplane installed)
application_prometheus factory: %i(clusters_applications_prometheus installed)
application_runner factory: %i(clusters_applications_runner installed)
diff --git a/spec/features/admin/admin_jobs_spec.rb b/spec/features/admin/admin_jobs_spec.rb
index f0eaa83f05e..626605868cb 100644
--- a/spec/features/admin/admin_jobs_spec.rb
+++ b/spec/features/admin/admin_jobs_spec.rb
@@ -28,8 +28,8 @@ RSpec.describe 'Admin Jobs', feature_category: :continuous_integration do
expect(page).to have_button 'Stop all jobs'
click_button 'Stop all jobs'
- expect(page).to have_button 'Stop jobs'
- expect(page).to have_content 'Stop all jobs?'
+ expect(page).to have_button 'Yes, proceed'
+ expect(page).to have_content 'Are you sure?'
end
end
diff --git a/spec/frontend/environments/edit_environment_spec.js b/spec/frontend/environments/edit_environment_spec.js
index 5ea23af4c16..ba4b4db54ff 100644
--- a/spec/frontend/environments/edit_environment_spec.js
+++ b/spec/frontend/environments/edit_environment_spec.js
@@ -14,6 +14,7 @@ const DEFAULT_OPTS = {
provide: {
projectEnvironmentsPath: '/projects/environments',
updateEnvironmentPath: '/proejcts/environments/1',
+ protectedEnvironmentSettingsPath: '/projects/1/settings/ci_cd',
},
propsData: { environment: { id: '0', name: 'foo', external_url: 'https://foo.example.com' } },
};
diff --git a/spec/frontend/environments/environment_form_spec.js b/spec/frontend/environments/environment_form_spec.js
index f1af08bcf32..b9b34bee80f 100644
--- a/spec/frontend/environments/environment_form_spec.js
+++ b/spec/frontend/environments/environment_form_spec.js
@@ -10,11 +10,14 @@ const DEFAULT_PROPS = {
cancelPath: '/cancel',
};
+const PROVIDE = { protectedEnvironmentSettingsPath: '/projects/not_real/settings/ci_cd' };
+
describe('~/environments/components/form.vue', () => {
let wrapper;
const createWrapper = (propsData = {}) =>
mountExtended(EnvironmentForm, {
+ provide: PROVIDE,
propsData: {
...DEFAULT_PROPS,
...propsData,
@@ -31,7 +34,7 @@ describe('~/environments/components/form.vue', () => {
});
it('links to documentation regarding environments', () => {
- const link = wrapper.findByRole('link', { name: 'More information' });
+ const link = wrapper.findByRole('link', { name: 'More information.' });
expect(link.attributes('href')).toBe('/help/ci/environments/index.md');
});
@@ -124,6 +127,10 @@ describe('~/environments/components/form.vue', () => {
expect(urlInput.element.value).toBe('');
});
+
+ it('does not show protected environment documentation', () => {
+ expect(wrapper.findByRole('link', { name: 'Protected environments' }).exists()).toBe(false);
+ });
});
describe('when an existing environment is being edited', () => {
diff --git a/spec/frontend/environments/new_environment_spec.js b/spec/frontend/environments/new_environment_spec.js
index 6dd4eea7437..5dd77759391 100644
--- a/spec/frontend/environments/new_environment_spec.js
+++ b/spec/frontend/environments/new_environment_spec.js
@@ -11,7 +11,10 @@ jest.mock('~/lib/utils/url_utility');
jest.mock('~/flash');
const DEFAULT_OPTS = {
- provide: { projectEnvironmentsPath: '/projects/environments' },
+ provide: {
+ projectEnvironmentsPath: '/projects/environments',
+ protectedEnvironmentSettingsPath: '/projects/not_real/settings/ci_cd',
+ },
};
describe('~/environments/components/new.vue', () => {
diff --git a/spec/frontend/pages/admin/jobs/index/components/stop_jobs_modal_spec.js b/spec/frontend/pages/admin/jobs/index/components/cancel_jobs_modal_spec.js
index 17669331370..366d148a608 100644
--- a/spec/frontend/pages/admin/jobs/index/components/stop_jobs_modal_spec.js
+++ b/spec/frontend/pages/admin/jobs/index/components/cancel_jobs_modal_spec.js
@@ -4,30 +4,27 @@ import { GlModal } from '@gitlab/ui';
import { TEST_HOST } from 'helpers/test_constants';
import axios from '~/lib/utils/axios_utils';
import { redirectTo } from '~/lib/utils/url_utility';
-import StopJobsModal from '~/pages/admin/jobs/index/components/stop_jobs_modal.vue';
+import CancelJobsModal from '~/pages/admin/jobs/index/components/cancel_jobs_modal.vue';
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
redirectTo: jest.fn(),
}));
-describe('stop_jobs_modal.vue', () => {
+describe('Cancel jobs modal', () => {
const props = {
- url: `${TEST_HOST}/stop_jobs_modal.vue/stopAll`,
+ url: `${TEST_HOST}/cancel_jobs_modal.vue/cancelAll`,
+ modalId: 'cancel-jobs-modal',
};
let wrapper;
beforeEach(() => {
- wrapper = mount(StopJobsModal, { propsData: props });
- });
-
- afterEach(() => {
- wrapper.destroy();
+ wrapper = mount(CancelJobsModal, { propsData: props });
});
describe('on submit', () => {
- it('stops jobs and redirects to overview page', async () => {
- const responseURL = `${TEST_HOST}/stop_jobs_modal.vue/jobs`;
+ it('cancels jobs and redirects to overview page', async () => {
+ const responseURL = `${TEST_HOST}/cancel_jobs_modal.vue/jobs`;
// TODO: We can't use axios-mock-adapter because our current version
// does not support responseURL
//
@@ -47,10 +44,10 @@ describe('stop_jobs_modal.vue', () => {
expect(redirectTo).toHaveBeenCalledWith(responseURL);
});
- it('displays error if stopping jobs failed', async () => {
+ it('displays error if canceling jobs failed', async () => {
Vue.config.errorHandler = () => {}; // silencing thrown error
- const dummyError = new Error('stopping jobs failed');
+ const dummyError = new Error('canceling jobs failed');
// TODO: We can't use axios-mock-adapter because our current version
// does not support responseURL
//
diff --git a/spec/frontend/pages/admin/jobs/index/components/cancel_jobs_spec.js b/spec/frontend/pages/admin/jobs/index/components/cancel_jobs_spec.js
new file mode 100644
index 00000000000..ec6369e7119
--- /dev/null
+++ b/spec/frontend/pages/admin/jobs/index/components/cancel_jobs_spec.js
@@ -0,0 +1,57 @@
+import { GlButton } from '@gitlab/ui';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { TEST_HOST } from 'helpers/test_constants';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import CancelJobs from '~/pages/admin/jobs/index/components/cancel_jobs.vue';
+import CancelJobsModal from '~/pages/admin/jobs/index/components/cancel_jobs_modal.vue';
+import {
+ CANCEL_JOBS_MODAL_ID,
+ CANCEL_BUTTON_TOOLTIP,
+} from '~/pages/admin/jobs/index/components/constants';
+
+describe('CancelJobs component', () => {
+ let wrapper;
+
+ const findCancelJobs = () => wrapper.findComponent(CancelJobs);
+ const findButton = () => wrapper.findComponent(GlButton);
+ const findModal = () => wrapper.findComponent(CancelJobsModal);
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMountExtended(CancelJobs, {
+ directives: {
+ GlModal: createMockDirective(),
+ GlTooltip: createMockDirective(),
+ },
+ propsData: {
+ url: `${TEST_HOST}/cancel_jobs_modal.vue/cancelAll`,
+ ...props,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('has correct inputs', () => {
+ expect(findCancelJobs().props().url).toBe(`${TEST_HOST}/cancel_jobs_modal.vue/cancelAll`);
+ });
+
+ it('has correct button variant', () => {
+ expect(findButton().props().variant).toBe('danger');
+ });
+
+ it('checks that button and modal are connected', () => {
+ const buttonModalDirective = getBinding(findButton().element, 'gl-modal');
+ const modalId = findModal().props('modalId');
+
+ expect(buttonModalDirective.value).toBe(CANCEL_JOBS_MODAL_ID);
+ expect(modalId).toBe(CANCEL_JOBS_MODAL_ID);
+ });
+
+ it('checks that tooltip is displayed', () => {
+ const buttonTooltipDirective = getBinding(findButton().element, 'gl-tooltip');
+
+ expect(buttonTooltipDirective.value).toBe(CANCEL_BUTTON_TOOLTIP);
+ });
+});
diff --git a/spec/graphql/types/ci/runner_architecture_type_spec.rb b/spec/graphql/types/ci/runner_architecture_type_spec.rb
index 60709acfd53..58ec73323c6 100644
--- a/spec/graphql/types/ci/runner_architecture_type_spec.rb
+++ b/spec/graphql/types/ci/runner_architecture_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerArchitectureType do
+RSpec.describe Types::Ci::RunnerArchitectureType, feature_category: :runner do
specify { expect(described_class.graphql_name).to eq('RunnerArchitecture') }
it 'exposes the expected fields' do
diff --git a/spec/graphql/types/ci/runner_platform_type_spec.rb b/spec/graphql/types/ci/runner_platform_type_spec.rb
index 29b8e885183..1b0f5a5ec71 100644
--- a/spec/graphql/types/ci/runner_platform_type_spec.rb
+++ b/spec/graphql/types/ci/runner_platform_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerPlatformType do
+RSpec.describe Types::Ci::RunnerPlatformType, feature_category: :runner_fleet do
specify { expect(described_class.graphql_name).to eq('RunnerPlatform') }
it 'exposes the expected fields' do
diff --git a/spec/graphql/types/ci/runner_setup_type_spec.rb b/spec/graphql/types/ci/runner_setup_type_spec.rb
index 197e717e964..d3e47b52a80 100644
--- a/spec/graphql/types/ci/runner_setup_type_spec.rb
+++ b/spec/graphql/types/ci/runner_setup_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerSetupType do
+RSpec.describe Types::Ci::RunnerSetupType, feature_category: :runner_fleet do
specify { expect(described_class.graphql_name).to eq('RunnerSetup') }
it 'exposes the expected fields' do
diff --git a/spec/graphql/types/ci/runner_type_spec.rb b/spec/graphql/types/ci/runner_type_spec.rb
index b078d7f5fac..2296d1bea30 100644
--- a/spec/graphql/types/ci/runner_type_spec.rb
+++ b/spec/graphql/types/ci/runner_type_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe GitlabSchema.types['CiRunner'] do
+RSpec.describe GitlabSchema.types['CiRunner'], feature_category: :runner do
specify { expect(described_class.graphql_name).to eq('CiRunner') }
specify { expect(described_class).to require_graphql_authorizations(:read_runner) }
diff --git a/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb b/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb
index ef378f3fc5a..ec53e5bd508 100644
--- a/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb
+++ b/spec/graphql/types/ci/runner_upgrade_status_enum_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerUpgradeStatusEnum do
+RSpec.describe Types::Ci::RunnerUpgradeStatusEnum, feature_category: :runner_fleet do
let(:model_only_enum_values) { %w[not_processed] }
let(:expected_graphql_source_values) do
Ci::RunnerVersion.statuses.keys - model_only_enum_values
diff --git a/spec/graphql/types/ci/runner_web_url_edge_spec.rb b/spec/graphql/types/ci/runner_web_url_edge_spec.rb
index 08718df0a5b..07a9655b3e1 100644
--- a/spec/graphql/types/ci/runner_web_url_edge_spec.rb
+++ b/spec/graphql/types/ci/runner_web_url_edge_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerWebUrlEdge do
+RSpec.describe Types::Ci::RunnerWebUrlEdge, feature_category: :runner_fleet do
specify { expect(described_class.graphql_name).to eq('RunnerWebUrlEdge') }
it 'contains URL attributes' do
diff --git a/spec/lib/gitlab/ci/runner_instructions_spec.rb b/spec/lib/gitlab/ci/runner_instructions_spec.rb
index dd547a0161a..31c53d4a030 100644
--- a/spec/lib/gitlab/ci/runner_instructions_spec.rb
+++ b/spec/lib/gitlab/ci/runner_instructions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::RunnerInstructions do
+RSpec.describe Gitlab::Ci::RunnerInstructions, feature_category: :runner_fleet do
using RSpec::Parameterized::TableSyntax
let(:params) { {} }
diff --git a/spec/lib/gitlab/ci/runner_releases_spec.rb b/spec/lib/gitlab/ci/runner_releases_spec.rb
index ad1e9b12b8a..14f3c95ec79 100644
--- a/spec/lib/gitlab/ci/runner_releases_spec.rb
+++ b/spec/lib/gitlab/ci/runner_releases_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::RunnerReleases do
+RSpec.describe Gitlab::Ci::RunnerReleases, feature_category: :runner_fleet do
subject { described_class.instance }
let(:runner_releases_url) { 'http://testurl.com/runner_public_releases' }
diff --git a/spec/lib/gitlab/ci/runner_upgrade_check_spec.rb b/spec/lib/gitlab/ci/runner_upgrade_check_spec.rb
index 55c3834bfa7..a07e95151d6 100644
--- a/spec/lib/gitlab/ci/runner_upgrade_check_spec.rb
+++ b/spec/lib/gitlab/ci/runner_upgrade_check_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::RunnerUpgradeCheck do
+RSpec.describe Gitlab::Ci::RunnerUpgradeCheck, feature_category: :runner_fleet do
using RSpec::Parameterized::TableSyntax
subject(:instance) { described_class.new(gitlab_version, runner_releases) }
diff --git a/spec/models/clusters/applications/cert_manager_spec.rb b/spec/models/clusters/applications/cert_manager_spec.rb
deleted file mode 100644
index 427a99efadd..00000000000
--- a/spec/models/clusters/applications/cert_manager_spec.rb
+++ /dev/null
@@ -1,157 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::CertManager do
- let(:cert_manager) { create(:clusters_applications_cert_manager) }
-
- include_examples 'cluster application core specs', :clusters_applications_cert_manager
- include_examples 'cluster application status specs', :clusters_applications_cert_manager
- include_examples 'cluster application version specs', :clusters_applications_cert_manager
- include_examples 'cluster application initial status specs'
-
- describe 'default values' do
- it { expect(cert_manager.version).to eq(described_class::VERSION) }
- it { expect(cert_manager.email).to eq("admin@example.com") }
- end
-
- describe '#can_uninstall?' do
- subject { cert_manager.can_uninstall? }
-
- it { is_expected.to be_truthy }
- end
-
- describe '#install_command' do
- let(:cert_email) { 'admin@example.com' }
-
- let(:cluster_issuer_file) do
- file_contents = <<~EOF
- ---
- apiVersion: certmanager.k8s.io/v1alpha1
- kind: ClusterIssuer
- metadata:
- name: letsencrypt-prod
- spec:
- acme:
- server: https://acme-v02.api.letsencrypt.org/directory
- email: #{cert_email}
- privateKeySecretRef:
- name: letsencrypt-prod
- http01: {}
- EOF
-
- { "cluster_issuer.yaml": file_contents }
- end
-
- subject { cert_manager.install_command }
-
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
-
- it 'is initialized with cert_manager arguments' do
- expect(subject.name).to eq('certmanager')
- expect(subject.chart).to eq('certmanager/cert-manager')
- expect(subject.repository).to eq('https://charts.jetstack.io')
- expect(subject.version).to eq('v0.10.1')
- expect(subject).to be_rbac
- expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file))
- expect(subject.preinstall).to eq(
- [
- 'kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.10/deploy/manifests/00-crds.yaml',
- 'kubectl label --overwrite namespace gitlab-managed-apps certmanager.k8s.io/disable-validation=true'
- ])
- expect(subject.postinstall).to eq(
- [
- "for i in $(seq 1 90); do kubectl apply -f /data/helm/certmanager/config/cluster_issuer.yaml && s=0 && break || s=$?; sleep 1s; echo \"Retrying ($i)...\"; done; (exit $s)"
- ])
- end
-
- context 'for a specific user' do
- let(:cert_email) { 'abc@xyz.com' }
-
- before do
- cert_manager.email = cert_email
- end
-
- it 'uses their email to register issuer with certificate provider' do
- expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file))
- end
- end
-
- context 'on a non rbac enabled cluster' do
- before do
- cert_manager.cluster.platform_kubernetes.abac!
- end
-
- it { is_expected.not_to be_rbac }
- end
-
- context 'application failed to install previously' do
- let(:cert_manager) { create(:clusters_applications_cert_manager, :errored, version: '0.0.1') }
-
- it 'is initialized with the locked version' do
- expect(subject.version).to eq('v0.10.1')
- end
- end
- end
-
- describe '#uninstall_command' do
- subject { cert_manager.uninstall_command }
-
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
-
- it 'is initialized with cert_manager arguments' do
- expect(subject.name).to eq('certmanager')
- expect(subject).to be_rbac
- expect(subject.files).to eq(cert_manager.files)
- end
-
- it 'specifies a post delete command to remove custom resource definitions' do
- expect(subject.postdelete).to eq(
- [
- 'kubectl delete secret -n gitlab-managed-apps letsencrypt-prod --ignore-not-found',
- 'kubectl delete crd certificates.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd certificaterequests.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd challenges.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd clusterissuers.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd issuers.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd orders.certmanager.k8s.io --ignore-not-found'
- ])
- end
-
- context 'secret key name is not found' do
- before do
- allow(File).to receive(:read).and_call_original
- expect(File).to receive(:read)
- .with(Rails.root.join('vendor', 'cert_manager', 'cluster_issuer.yaml'))
- .and_return('key: value')
- end
-
- it 'does not try and delete the secret' do
- expect(subject.postdelete).to eq(
- [
- 'kubectl delete crd certificates.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd certificaterequests.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd challenges.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd clusterissuers.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd issuers.certmanager.k8s.io --ignore-not-found',
- 'kubectl delete crd orders.certmanager.k8s.io --ignore-not-found'
- ])
- end
- end
- end
-
- describe '#files' do
- let(:application) { cert_manager }
- let(:values) { subject[:'values.yaml'] }
-
- subject { application.files }
-
- it 'includes cert_manager specific keys in the values.yaml file' do
- expect(values).to include('ingressShim')
- end
- end
-
- describe 'validations' do
- it { is_expected.to validate_presence_of(:email) }
- end
-end
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 58a986fd099..2a2e2899d24 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -714,14 +714,13 @@ feature_category: :kubernetes_management do
context 'when all applications are created' do
let!(:helm) { create(:clusters_applications_helm, cluster: cluster) }
let!(:ingress) { create(:clusters_applications_ingress, cluster: cluster) }
- let!(:cert_manager) { create(:clusters_applications_cert_manager, cluster: cluster) }
let!(:prometheus) { create(:clusters_applications_prometheus, cluster: cluster) }
let!(:runner) { create(:clusters_applications_runner, cluster: cluster) }
let!(:jupyter) { create(:clusters_applications_jupyter, cluster: cluster) }
let!(:knative) { create(:clusters_applications_knative, cluster: cluster) }
it 'returns a list of created applications' do
- is_expected.to contain_exactly(helm, ingress, cert_manager, prometheus, runner, jupyter, knative)
+ is_expected.to contain_exactly(helm, ingress, prometheus, runner, jupyter, knative)
end
end
diff --git a/spec/models/ml/experiment_spec.rb b/spec/models/ml/experiment_spec.rb
index 52e9f9217f5..c75331a2ab5 100644
--- a/spec/models/ml/experiment_spec.rb
+++ b/spec/models/ml/experiment_spec.rb
@@ -57,4 +57,21 @@ RSpec.describe Ml::Experiment do
it { is_expected.to be_empty }
end
end
+
+ describe '#with_candidate_count' do
+ let_it_be(:exp3) do
+ create(:ml_experiments, project: exp.project).tap do |e|
+ create_list(:ml_candidates, 3, experiment: e, user: nil)
+ create(:ml_candidates, experiment: exp2, user: nil)
+ end
+ end
+
+ subject { described_class.with_candidate_count.to_h { |e| [e.id, e.candidate_count] } }
+
+ it 'fetches the candidate count', :aggregate_failures do
+ expect(subject[exp.id]).to eq(0)
+ expect(subject[exp2.id]).to eq(1)
+ expect(subject[exp3.id]).to eq(3)
+ end
+ end
end
diff --git a/spec/views/admin/application_settings/_jira_connect.html.haml_spec.rb b/spec/views/admin/application_settings/_jira_connect.html.haml_spec.rb
index 7cfc2db5a41..1739fb3d8b9 100644
--- a/spec/views/admin/application_settings/_jira_connect.html.haml_spec.rb
+++ b/spec/views/admin/application_settings/_jira_connect.html.haml_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'admin/application_settings/_jira_connect.html.haml' do
+RSpec.describe 'admin/application_settings/_jira_connect.html.haml', feature_category: :integrations do
let_it_be(:admin) { create(:admin) }
let(:application_setting) { build(:application_setting) }
diff --git a/workhorse/go.mod b/workhorse/go.mod
index 582903f9721..9c740e0fe82 100644
--- a/workhorse/go.mod
+++ b/workhorse/go.mod
@@ -7,7 +7,7 @@ require (
github.com/BurntSushi/toml v1.2.1
github.com/FZambia/sentinel v1.1.1
github.com/alecthomas/chroma/v2 v2.4.0
- github.com/aws/aws-sdk-go v1.44.184
+ github.com/aws/aws-sdk-go v1.44.189
github.com/disintegration/imaging v1.6.2
github.com/getsentry/raven-go v0.2.0
github.com/golang-jwt/jwt/v4 v4.4.3
diff --git a/workhorse/go.sum b/workhorse/go.sum
index f8b510b88fa..bb1dd5c2b99 100644
--- a/workhorse/go.sum
+++ b/workhorse/go.sum
@@ -542,8 +542,8 @@ github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4
github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.128/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.151/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
-github.com/aws/aws-sdk-go v1.44.184 h1:/MggyE66rOImXJKl1HqhLQITvWvqIV7w1Q4MaG6FHUo=
-github.com/aws/aws-sdk-go v1.44.184/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
+github.com/aws/aws-sdk-go v1.44.189 h1:9PBrjndH1uL5AN8818qI3duhQ4hgkMuLvqkJlg9MRyk=
+github.com/aws/aws-sdk-go v1.44.189/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/aws/aws-sdk-go-v2 v1.17.1 h1:02c72fDJr87N8RAC2s3Qu0YuvMRZKNZJ9F+lAehCazk=
github.com/aws/aws-sdk-go-v2 v1.17.1/go.mod h1:JLnGeGONAyi2lWXI1p0PCIOIy333JMVK1U7Hf0aRFLw=