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/global.gitlab-ci.yml20
-rw-r--r--.gitlab/ci/rails.gitlab-ci.yml99
-rw-r--r--app/assets/javascripts/clusters/forms/components/integration_form.vue17
-rw-r--r--app/assets/javascripts/clusters/forms/stores/state.js1
-rw-r--r--app/assets/javascripts/pages/users/activity_calendar.js67
-rw-r--r--app/assets/stylesheets/framework/calendar.scss10
-rw-r--r--app/assets/stylesheets/framework/variables.scss12
-rw-r--r--app/finders/ci/auth_job_finder.rb4
-rw-r--r--app/models/ci/job_token/project_scope_link.rb33
-rw-r--r--app/models/ci/job_token/scope.rb40
-rw-r--r--app/models/hooks/web_hook_log_archived.rb12
-rw-r--r--app/models/user.rb18
-rw-r--r--app/policies/concerns/policy_actor.rb4
-rw-r--r--app/policies/project_policy.rb7
-rw-r--r--app/views/clusters/clusters/show.html.haml12
-rw-r--r--config/feature_flags/development/ci_scoped_job_token.yml8
-rw-r--r--db/migrate/20210527194558_create_ci_job_token_project_scope_links.rb24
-rw-r--r--db/post_migrate/20210609125005_drop_non_partitioned_web_hook_logs.rb43
-rw-r--r--db/schema_migrations/202105271945581
-rw-r--r--db/schema_migrations/202106091250051
-rw-r--r--db/structure.sql121
-rw-r--r--doc/ci/runners/configure_runners.md5
-rw-r--r--doc/development/architecture.md2
-rw-r--r--doc/development/pipelines.md9
-rw-r--r--doc/operations/index.md2
-rw-r--r--doc/operations/metrics/dashboards/index.md42
-rw-r--r--doc/operations/metrics/index.md32
-rw-r--r--doc/topics/autodevops/requirements.md3
-rw-r--r--doc/user/clusters/applications.md591
-rw-r--r--doc/user/clusters/crossplane.md2
-rw-r--r--doc/user/clusters/integrations.md23
-rw-r--r--doc/user/clusters/management_project.md2
-rw-r--r--doc/user/clusters/management_project_template.md86
-rw-r--r--doc/user/clusters/migrating_from_gma_to_project_template.md95
-rw-r--r--doc/user/project/clusters/kubernetes_pod_logs.md11
-rw-r--r--doc/user/project/clusters/protect/container_host_security/quick_start_guide.md1
-rw-r--r--doc/user/project/clusters/protect/container_network_security/quick_start_guide.md1
-rw-r--r--doc/user/project/integrations/prometheus.md140
-rw-r--r--doc/user/project/integrations/prometheus_library/kubernetes.md2
-rw-r--r--locale/gitlab.pot33
-rw-r--r--package.json1
-rw-r--r--spec/factories/ci/job_token/project_scope_links.rb9
-rw-r--r--spec/factories_spec.rb1
-rw-r--r--spec/features/admin/clusters/applications_spec.rb22
-rw-r--r--spec/features/calendar_spec.rb13
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb24
-rw-r--r--spec/features/clusters/cluster_health_dashboard_spec.rb8
-rw-r--r--spec/features/clusters/installing_applications_shared_examples.rb252
-rw-r--r--spec/features/groups/clusters/applications_spec.rb23
-rw-r--r--spec/features/projects/clusters/applications_spec.rb23
-rw-r--r--spec/finders/ci/auth_job_finder_spec.rb30
-rw-r--r--spec/frontend/clusters/forms/components/integration_form_spec.js13
-rw-r--r--spec/frontend/pages/users/activity_calendar_spec.js16
-rw-r--r--spec/lib/gitlab/auth/auth_finders_spec.rb8
-rw-r--r--spec/models/ci/job_token/project_scope_link_spec.rb68
-rw-r--r--spec/models/ci/job_token/scope_spec.rb55
-rw-r--r--spec/models/hooks/web_hook_log_archived_spec.rb52
-rw-r--r--spec/policies/project_policy_spec.rb49
-rw-r--r--spec/requests/api/generic_packages_spec.rb2
-rw-r--r--spec/requests/api/go_proxy_spec.rb2
-rw-r--r--spec/requests/api/maven_packages_spec.rb2
-rw-r--r--spec/requests/api/npm_project_packages_spec.rb2
-rw-r--r--spec/requests/api/nuget_project_packages_spec.rb4
-rw-r--r--spec/requests/api/pypi_packages_spec.rb2
-rw-r--r--spec/requests/api/releases_spec.rb2
-rw-r--r--spec/requests/api/rubygem_packages_spec.rb2
-rw-r--r--spec/requests/api/terraform/modules/v1/packages_spec.rb2
-rw-r--r--spec/requests/git_http_spec.rb4
-rw-r--r--spec/requests/lfs_http_spec.rb4
-rw-r--r--spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb4
-rw-r--r--spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb2
-rw-r--r--yarn.lock2
72 files changed, 829 insertions, 1510 deletions
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml
index 5d2be0f03ae..3ae7e961aa5 100644
--- a/.gitlab/ci/global.gitlab-ci.yml
+++ b/.gitlab/ci/global.gitlab-ci.yml
@@ -158,15 +158,6 @@
- *node-modules-cache-push
- *assets-cache-push
-.use-pg11:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
- services:
- - name: postgres:11.6
- command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- - name: redis:5.0-alpine
- variables:
- POSTGRES_HOST_AUTH_METHOD: trust
-
.use-pg12:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36"
services:
@@ -176,17 +167,6 @@
variables:
POSTGRES_HOST_AUTH_METHOD: trust
-.use-pg11-ee:
- image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36"
- services:
- - name: postgres:11.6
- command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- - name: redis:5.0-alpine
- - name: elasticsearch:7.11.1
- command: ["elasticsearch", "-E", "discovery.type=single-node"]
- variables:
- POSTGRES_HOST_AUTH_METHOD: trust
-
.use-pg12-ee:
image: "registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2.patched-golang-1.16-git-2.31-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36"
services:
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index 3cca098a5c5..a30c4ebd413 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -58,11 +58,6 @@
- !reference [.base-script, script]
- rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag level:migration"
-.rspec-base-pg11:
- extends:
- - .rspec-base
- - .use-pg11
-
.rspec-base-pg12:
extends:
- .rspec-base
@@ -75,11 +70,6 @@
- .use-pg12
needs: ["setup-test-env", "retrieve-tests-metadata", "compile-test-assets as-if-foss", "detect-tests"]
-.rspec-ee-base-pg11:
- extends:
- - .rspec-base
- - .use-pg11-ee
-
.rspec-ee-base-pg12:
extends:
- .rspec-base
@@ -91,11 +81,6 @@
- !reference [.base-script, script]
- rspec_paralellized_job "--tag ~quarantine --tag geo"
-.rspec-ee-base-geo-pg11:
- extends:
- - .rspec-ee-base-geo
- - .use-pg11-ee
-
.rspec-ee-base-geo-pg12:
extends:
- .rspec-ee-base-geo
@@ -298,16 +283,6 @@ rspec system pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-system:minimal
-# Dedicated job to test DB library code against PG11.
-# Note that these are already tested against PG12 in the `rspec unit pg12` / `rspec-ee unit pg12` jobs.
-rspec db-library-code pg11:
- extends:
- - .rspec-base-pg11
- - .rails:rules:ee-and-foss-db-library-code
- script:
- - !reference [.base-script, script]
- - rspec_db_library_code
-
rspec fast_spec_helper:
extends:
- .rspec-base-pg12
@@ -668,80 +643,6 @@ db:rollback geo:
# EE: default refs (MRs, default branch, schedules) jobs #
##################################################
-##########################################
-# EE/FOSS: default branch nightly scheduled jobs #
-rspec migration pg11:
- extends:
- - .rspec-base-pg11
- - .rspec-base-migration
- - .rails:rules:default-branch-schedule-nightly--code-backstage
- - .rspec-migration-parallel
-
-rspec unit pg11:
- extends:
- - .rspec-base-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage
- - .rspec-unit-parallel
-
-rspec integration pg11:
- extends:
- - .rspec-base-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage
- - .rspec-integration-parallel
-
-rspec system pg11:
- extends:
- - .rspec-base-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage
- - .rspec-system-parallel
-# EE/FOSS: default branch nightly scheduled jobs #
-##########################################
-
-#####################################
-# EE: default branch nightly scheduled jobs #
-rspec-ee migration pg11:
- extends:
- - .rspec-ee-base-pg11
- - .rspec-base-migration
- - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
- - .rspec-ee-migration-parallel
-
-rspec-ee unit pg11:
- extends:
- - .rspec-ee-base-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
- - .rspec-ee-unit-parallel
-
-rspec-ee integration pg11:
- extends:
- - .rspec-ee-base-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
- - .rspec-ee-integration-parallel
-
-rspec-ee system pg11:
- extends:
- - .rspec-ee-base-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
- - .rspec-ee-system-parallel
-
-rspec-ee unit pg11 geo:
- extends:
- - .rspec-ee-base-geo-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
- - .rspec-ee-unit-geo-parallel
-
-rspec-ee integration pg11 geo:
- extends:
- - .rspec-ee-base-geo-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
-
-rspec-ee system pg11 geo:
- extends:
- - .rspec-ee-base-geo-pg11
- - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
-# EE: default branch nightly scheduled jobs #
-#####################################
-
##################################################
# EE: Canonical MR pipelines
rspec fail-fast:
diff --git a/app/assets/javascripts/clusters/forms/components/integration_form.vue b/app/assets/javascripts/clusters/forms/components/integration_form.vue
index a344f9578fd..3f61a1b18a7 100644
--- a/app/assets/javascripts/clusters/forms/components/integration_form.vue
+++ b/app/assets/javascripts/clusters/forms/components/integration_form.vue
@@ -41,17 +41,10 @@ export default {
toggleEnabled: true,
envScope: '*',
baseDomainField: '',
- externalIp: '',
};
},
computed: {
- ...mapState([
- 'enabled',
- 'editable',
- 'environmentScope',
- 'baseDomain',
- 'applicationIngressExternalIp',
- ]),
+ ...mapState(['enabled', 'editable', 'environmentScope', 'baseDomain']),
canSubmit() {
return (
this.enabled !== this.toggleEnabled ||
@@ -64,7 +57,6 @@ export default {
this.toggleEnabled = this.enabled;
this.envScope = this.environmentScope;
this.baseDomainField = this.baseDomain;
- this.externalIp = this.applicationIngressExternalIp;
},
};
</script>
@@ -135,13 +127,6 @@ export default {
<gl-link :href="autoDevopsHelpPath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
- <div v-if="applicationIngressExternalIp" class="js-ingress-domain-help-text inline">
- {{ s__('ClusterIntegration|Alternatively, ') }}
- <gl-sprintf :message="s__('ClusterIntegration|%{externalIp}.nip.io')">
- <template #externalIp>{{ externalIp }}</template>
- </gl-sprintf>
- {{ s__('ClusterIntegration|can be used instead of a custom domain. ') }}
- </div>
<gl-sprintf
class="inline"
:message="s__('ClusterIntegration|%{linkStart}More information%{linkEnd}')"
diff --git a/app/assets/javascripts/clusters/forms/stores/state.js b/app/assets/javascripts/clusters/forms/stores/state.js
index 2a96590b5e7..74a00b97603 100644
--- a/app/assets/javascripts/clusters/forms/stores/state.js
+++ b/app/assets/javascripts/clusters/forms/stores/state.js
@@ -6,7 +6,6 @@ export default (initialState = {}) => {
editable: parseBoolean(initialState.editable),
environmentScope: initialState.environmentScope,
baseDomain: initialState.baseDomain,
- applicationIngressExternalIp: initialState.applicationIngressExternalIp,
autoDevopsHelpPath: initialState.autoDevopsHelpPath,
externalEndpointHelpPath: initialState.externalEndpointHelpPath,
};
diff --git a/app/assets/javascripts/pages/users/activity_calendar.js b/app/assets/javascripts/pages/users/activity_calendar.js
index c416106fdd8..03dba699461 100644
--- a/app/assets/javascripts/pages/users/activity_calendar.js
+++ b/app/assets/javascripts/pages/users/activity_calendar.js
@@ -1,4 +1,3 @@
-import { scaleLinear, scaleThreshold } from 'd3-scale';
import { select } from 'd3-selection';
import dateFormat from 'dateformat';
import $ from 'jquery';
@@ -8,7 +7,7 @@ import axios from '~/lib/utils/axios_utils';
import { getDayName, getDayDifference } from '~/lib/utils/datetime_utility';
import { n__, s__, __ } from '~/locale';
-const d3 = { select, scaleLinear, scaleThreshold };
+const d3 = { select };
const firstDayOfWeekChoices = Object.freeze({
sunday: 0,
@@ -16,6 +15,14 @@ const firstDayOfWeekChoices = Object.freeze({
saturday: 6,
});
+const CONTRIB_LEGENDS = [
+ { title: __('No contributions'), min: 0 },
+ { title: __('1-9 contributions'), min: 1 },
+ { title: __('10-19 contributions'), min: 10 },
+ { title: __('20-29 contributions'), min: 20 },
+ { title: __('30+ contributions'), min: 30 },
+];
+
const LOADING_HTML = `
<div class="text-center">
<div class="spinner spinner-md"></div>
@@ -42,7 +49,17 @@ function formatTooltipText({ date, count }) {
return `${contribText}<br /><span class="gl-text-gray-300">${dateDayName} ${dateText}</span>`;
}
-const initColorKey = () => d3.scaleLinear().range(['#acd5f2', '#254e77']).domain([0, 3]);
+// Return the contribution level from the number of contributions
+export const getLevelFromContributions = (count) => {
+ if (count <= 0) {
+ return 0;
+ }
+
+ const nextLevel = CONTRIB_LEGENDS.findIndex(({ min }) => count < min);
+
+ // If there is no higher level, we are at the end
+ return nextLevel >= 0 ? nextLevel - 1 : CONTRIB_LEGENDS.length - 1;
+};
export default class ActivityCalendar {
constructor(
@@ -111,10 +128,6 @@ export default class ActivityCalendar {
innerArray.push({ count, date, day });
}
- // Init color functions
- this.colorKey = initColorKey();
- this.color = this.initColor();
-
// Init the svg element
this.svg = this.renderSvg(container, group);
this.renderDays();
@@ -180,9 +193,7 @@ export default class ActivityCalendar {
.attr('y', (stamp) => this.dayYPos(stamp.day))
.attr('width', this.daySize)
.attr('height', this.daySize)
- .attr('fill', (stamp) =>
- stamp.count !== 0 ? this.color(Math.min(stamp.count, 40)) : '#ededed',
- )
+ .attr('data-level', (stamp) => getLevelFromContributions(stamp.count))
.attr('title', (stamp) => formatTooltipText(stamp))
.attr('class', 'user-contrib-cell has-tooltip')
.attr('data-html', true)
@@ -246,50 +257,24 @@ export default class ActivityCalendar {
}
renderKey() {
- const keyValues = [
- __('No contributions'),
- __('1-9 contributions'),
- __('10-19 contributions'),
- __('20-29 contributions'),
- __('30+ contributions'),
- ];
- const keyColors = [
- '#ededed',
- this.colorKey(0),
- this.colorKey(1),
- this.colorKey(2),
- this.colorKey(3),
- ];
-
this.svg
.append('g')
.attr('transform', `translate(18, ${this.daySizeWithSpace * 8 + 16})`)
.selectAll('rect')
- .data(keyColors)
+ .data(CONTRIB_LEGENDS)
.enter()
.append('rect')
.attr('width', this.daySize)
.attr('height', this.daySize)
- .attr('x', (color, i) => this.daySizeWithSpace * i)
+ .attr('x', (_, i) => this.daySizeWithSpace * i)
.attr('y', 0)
- .attr('fill', (color) => color)
- .attr('class', 'has-tooltip')
- .attr('title', (color, i) => keyValues[i])
+ .attr('data-level', (_, i) => i)
+ .attr('class', 'user-contrib-cell has-tooltip contrib-legend')
+ .attr('title', (x) => x.title)
.attr('data-container', 'body')
.attr('data-html', true);
}
- initColor() {
- const colorRange = [
- '#ededed',
- this.colorKey(0),
- this.colorKey(1),
- this.colorKey(2),
- this.colorKey(3),
- ];
- return d3.scaleThreshold().domain([0, 10, 20, 30]).range(colorRange);
- }
-
clickDay(stamp) {
if (this.currentSelectedDate !== stamp.date) {
this.currentSelectedDate = stamp.date;
diff --git a/app/assets/stylesheets/framework/calendar.scss b/app/assets/stylesheets/framework/calendar.scss
index 5b7f1a3f38b..1fa03d66f32 100644
--- a/app/assets/stylesheets/framework/calendar.scss
+++ b/app/assets/stylesheets/framework/calendar.scss
@@ -30,6 +30,16 @@
cursor: pointer;
stroke: $black;
}
+
+ // `app/assets/javascripts/pages/users/activity_calendar.js` sets this attribute
+ @for $i from 1 through length($calendar-activity-colors) {
+ $color: nth($calendar-activity-colors, $i);
+ $level: $i - 1;
+
+ &[data-level='#{$level}'] {
+ fill: $color;
+ }
+ }
}
.user-contrib-text {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index eb5cb19facd..d3976cfa8c7 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -717,6 +717,18 @@ $job-line-number-margin: 43px;
$job-arrow-margin: 55px;
/*
+ * Calendar
+ */
+// See https://gitlab.com/gitlab-org/gitlab/-/issues/332150 to align with Pajamas Design System
+$calendar-activity-colors: (
+ #ededed,
+ #acd5f2,
+ #7fa8c9,
+ #527ba0,
+ #254e77,
+);
+
+/*
* Commit Page
*/
$commit-max-width-marker-color: rgba(0, 0, 0, 0);
diff --git a/app/finders/ci/auth_job_finder.rb b/app/finders/ci/auth_job_finder.rb
index aee7dd16341..d207a522aa8 100644
--- a/app/finders/ci/auth_job_finder.rb
+++ b/app/finders/ci/auth_job_finder.rb
@@ -15,6 +15,10 @@ module Ci
next unless job
validate_job!(job)
+
+ if job.user && Feature.enabled?(:ci_scoped_job_token, job.project, default_enabled: :yaml)
+ job.user.set_ci_job_token_scope!(job)
+ end
end
end
diff --git a/app/models/ci/job_token/project_scope_link.rb b/app/models/ci/job_token/project_scope_link.rb
new file mode 100644
index 00000000000..283ad4a190d
--- /dev/null
+++ b/app/models/ci/job_token/project_scope_link.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+# The connection between a source project (which defines the job token scope)
+# and a target project which is the one allowed to be accessed by the job token.
+
+module Ci
+ module JobToken
+ class ProjectScopeLink < ApplicationRecord
+ self.table_name = 'ci_job_token_project_scope_links'
+
+ belongs_to :source_project, class_name: 'Project'
+ belongs_to :target_project, class_name: 'Project'
+ belongs_to :added_by, class_name: 'User'
+
+ scope :from_project, ->(project) { where(source_project: project) }
+ scope :to_project, ->(project) { where(target_project: project) }
+
+ validates :source_project, presence: true
+ validates :target_project, presence: true
+ validate :not_self_referential_link
+
+ private
+
+ def not_self_referential_link
+ return unless source_project && target_project
+
+ if source_project == target_project
+ self.errors.add(:target_project, _("can't be the same as the source project"))
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/ci/job_token/scope.rb b/app/models/ci/job_token/scope.rb
new file mode 100644
index 00000000000..fb1d5952a4c
--- /dev/null
+++ b/app/models/ci/job_token/scope.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+# This model represents the surface where a CI_JOB_TOKEN can be used.
+# A Scope is initialized with the project that the job token belongs to,
+# and indicates what are all the other projects that the token could access.
+#
+# By default a job token can only access its own project, which is the same
+# project that defines the scope.
+# By adding ScopeLinks to the scope we can allow other projects to be accessed
+# by the job token. This works as an allowlist of projects for a job token.
+#
+# If a project is not included in the scope we should not allow the job user
+# to access it since operations using CI_JOB_TOKEN should be considered untrusted.
+
+module Ci
+ module JobToken
+ class Scope
+ attr_reader :source_project
+
+ def initialize(project)
+ @source_project = project
+ end
+
+ def includes?(target_project)
+ target_project.id == source_project.id ||
+ Ci::JobToken::ProjectScopeLink.from_project(source_project).to_project(target_project).exists?
+ end
+
+ def all_projects
+ Project.from_union([
+ Project.id_in(source_project),
+ Project.where_exists(
+ Ci::JobToken::ProjectScopeLink
+ .from_project(source_project)
+ .where('projects.id = ci_job_token_project_scope_links.target_project_id'))
+ ], remove_duplicates: false)
+ end
+ end
+ end
+end
diff --git a/app/models/hooks/web_hook_log_archived.rb b/app/models/hooks/web_hook_log_archived.rb
deleted file mode 100644
index a1c8a44f5ba..00000000000
--- a/app/models/hooks/web_hook_log_archived.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-# This model is not intended to be used.
-# It is a temporary reference to the old non-partitioned
-# web_hook_logs table.
-# Please refer to https://gitlab.com/groups/gitlab-org/-/epics/5558
-# for details.
-# rubocop:disable Gitlab/NamespacedClass: This is a temporary class with no relevant namespace
-# WebHook, WebHookLog and all hooks are defined outside of a namespace
-class WebHookLogArchived < ApplicationRecord
- self.table_name = 'web_hook_logs_archived'
-end
diff --git a/app/models/user.rb b/app/models/user.rb
index 7a6bc50639c..8ee0421e45f 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1923,6 +1923,20 @@ class User < ApplicationRecord
confirmed? && !blocked? && !ghost?
end
+ # This attribute hosts a Ci::JobToken::Scope object which is set when
+ # the user is authenticated successfully via CI_JOB_TOKEN.
+ def ci_job_token_scope
+ Gitlab::SafeRequestStore[ci_job_token_scope_cache_key]
+ end
+
+ def set_ci_job_token_scope!(job)
+ Gitlab::SafeRequestStore[ci_job_token_scope_cache_key] = Ci::JobToken::Scope.new(job.project)
+ end
+
+ def from_ci_job_token?
+ ci_job_token_scope.present?
+ end
+
protected
# override, from Devise::Validatable
@@ -2086,6 +2100,10 @@ class User < ApplicationRecord
def update_highest_role_attribute
id
end
+
+ def ci_job_token_scope_cache_key
+ "users:#{id}:ci:job_token_scope"
+ end
end
User.prepend_mod_with('User')
diff --git a/app/policies/concerns/policy_actor.rb b/app/policies/concerns/policy_actor.rb
index 08a26da6673..cbc34bdeed3 100644
--- a/app/policies/concerns/policy_actor.rb
+++ b/app/policies/concerns/policy_actor.rb
@@ -84,6 +84,10 @@ module PolicyActor
def password_expired?
false
end
+
+ def from_ci_job_token?
+ false
+ end
end
PolicyActor.prepend_mod_with('PolicyActor')
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index df06f0a95fe..164d73fe332 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -75,6 +75,11 @@ class ProjectPolicy < BasePolicy
user.is_a?(DeployToken) && user.has_access_to?(project) && user.write_package_registry
end
+ desc "If user is authenticated via CI job token then the target project should be in scope"
+ condition(:project_allowed_for_job_token) do
+ !@user&.from_ci_job_token? || @user.ci_job_token_scope.includes?(project)
+ end
+
with_scope :subject
condition(:forking_allowed) do
@subject.feature_available?(:forking, @user)
@@ -508,6 +513,8 @@ class ProjectPolicy < BasePolicy
enable :read_project_for_iids
end
+ rule { ~project_allowed_for_job_token }.prevent_all
+
rule { can?(:public_access) }.policy do
enable :read_package
enable :read_project
diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml
index 8e27b6e5c75..654fcab8bf1 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -27,9 +27,6 @@
provider_type: @cluster.provider_type,
pre_installed_knative: @cluster.knative_pre_installed? ? 'true': 'false',
help_path: help_page_path('user/project/clusters/index.md'),
- helm_help_path: help_page_path('user/clusters/applications.md', anchor: 'helm'),
- ingress_help_path: help_page_path('user/clusters/applications.md', anchor: 'determining-the-external-endpoint-automatically'),
- ingress_dns_help_path: help_page_path('user/clusters/applications.md', anchor: 'pointing-your-dns-at-the-external-endpoint'),
environments_help_path: help_page_path('ci/environments/index.md', anchor: 'create-a-static-environment'),
clusters_help_path: help_page_path('user/project/clusters/index.md', anchor: 'deploying-to-a-kubernetes-cluster'),
deploy_boards_help_path: help_page_path('user/project/deploy_boards.md', anchor: 'enabling-deploy-boards'),
@@ -51,13 +48,20 @@
= render 'banner'
+ .gl-alert.gl-alert-warning{ role: 'alert' }
+ = sprite_icon('warning', css_class: "gl-alert-icon gl-alert-icon-no-title gl-icon")
+ %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss'), data: { testid: 'dismiss-one-click-application-removal' } }
+ = sprite_icon('close', css_class: 'gl-icon')
+ .gl-alert-body
+ = s_('ClusterApplicationsRemoved|One-click application management was removed in GitLab 14.0. Your applications are still installed in your cluster, and integrations continue working.')
+ = link_to _('More information.'), help_page_path("user/clusters/applications"), target: '_blank'
+
- if cluster_created?(@cluster)
.js-toggle-container
%ul.nav-links.mobile-separator.nav.nav-tabs{ role: 'tablist' }
= render 'details_tab'
= render_if_exists 'clusters/clusters/environments_tab'
= render 'clusters/clusters/health_tab'
- = render 'applications_tab'
= render 'integrations_tab'
= render 'advanced_settings_tab'
diff --git a/config/feature_flags/development/ci_scoped_job_token.yml b/config/feature_flags/development/ci_scoped_job_token.yml
new file mode 100644
index 00000000000..a7fa0244839
--- /dev/null
+++ b/config/feature_flags/development/ci_scoped_job_token.yml
@@ -0,0 +1,8 @@
+---
+name: ci_scoped_job_token
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62733
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332272
+milestone: '14.0'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/db/migrate/20210527194558_create_ci_job_token_project_scope_links.rb b/db/migrate/20210527194558_create_ci_job_token_project_scope_links.rb
new file mode 100644
index 00000000000..aaa94b9a231
--- /dev/null
+++ b/db/migrate/20210527194558_create_ci_job_token_project_scope_links.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class CreateCiJobTokenProjectScopeLinks < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ def up
+ with_lock_retries do
+ create_table :ci_job_token_project_scope_links, if_not_exists: true do |t|
+ t.belongs_to :source_project, index: false, null: false, foreign_key: { to_table: :projects, on_delete: :cascade }
+ t.belongs_to :target_project, null: false, foreign_key: { to_table: :projects, on_delete: :cascade }
+ t.belongs_to :added_by, foreign_key: { to_table: :users, on_delete: :nullify }
+ t.datetime_with_timezone :created_at, null: false
+
+ t.index [:source_project_id, :target_project_id], unique: true, name: 'i_ci_job_token_project_scope_links_on_source_and_target_project'
+ end
+ end
+ end
+
+ def down
+ with_lock_retries do
+ drop_table :ci_job_token_project_scope_links, if_exists: true
+ end
+ end
+end
diff --git a/db/post_migrate/20210609125005_drop_non_partitioned_web_hook_logs.rb b/db/post_migrate/20210609125005_drop_non_partitioned_web_hook_logs.rb
new file mode 100644
index 00000000000..596b643e079
--- /dev/null
+++ b/db/post_migrate/20210609125005_drop_non_partitioned_web_hook_logs.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+class DropNonPartitionedWebHookLogs < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+
+ DOWNTIME = false
+
+ def up
+ drop_nonpartitioned_archive_table(:web_hook_logs)
+ end
+
+ def down
+ execute(<<~SQL)
+ CREATE TABLE web_hook_logs_archived (
+ id integer NOT NULL,
+ web_hook_id integer NOT NULL,
+ trigger character varying,
+ url character varying,
+ request_headers text,
+ request_data text,
+ response_headers text,
+ response_body text,
+ response_status character varying,
+ execution_duration double precision,
+ internal_error_message character varying,
+ created_at timestamp without time zone NOT NULL,
+ updated_at timestamp without time zone NOT NULL
+ );
+
+ ALTER TABLE ONLY web_hook_logs_archived ADD CONSTRAINT web_hook_logs_archived_pkey PRIMARY KEY (id);
+
+ CREATE INDEX index_web_hook_logs_on_created_at_and_web_hook_id ON web_hook_logs_archived USING btree (created_at, web_hook_id);
+ CREATE INDEX index_web_hook_logs_on_web_hook_id ON web_hook_logs_archived USING btree (web_hook_id);
+
+ ALTER TABLE ONLY web_hook_logs_archived ADD CONSTRAINT fk_rails_666826e111 FOREIGN KEY (web_hook_id) REFERENCES web_hooks(id) ON DELETE CASCADE;
+ SQL
+
+ with_lock_retries do
+ create_trigger_to_sync_tables(:web_hook_logs, :web_hook_logs_archived, 'id')
+ end
+ end
+end
diff --git a/db/schema_migrations/20210527194558 b/db/schema_migrations/20210527194558
new file mode 100644
index 00000000000..089b97aa90e
--- /dev/null
+++ b/db/schema_migrations/20210527194558
@@ -0,0 +1 @@
+8c0661a42edbdb79be283df0e88879707ef34ba3fe21b6756b21cd99ea9f05de \ No newline at end of file
diff --git a/db/schema_migrations/20210609125005 b/db/schema_migrations/20210609125005
new file mode 100644
index 00000000000..3e26956bdb8
--- /dev/null
+++ b/db/schema_migrations/20210609125005
@@ -0,0 +1 @@
+de8468173d8a7499d03b84913cf071af8842a2f47d5f85908af20bf7c71dc96b \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 93b8c8029a8..49563bdb895 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -41,62 +41,6 @@ RETURN NULL;
END
$$;
-CREATE FUNCTION table_sync_function_29bc99d6db() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
-IF (TG_OP = 'DELETE') THEN
- DELETE FROM web_hook_logs_archived where id = OLD.id;
-ELSIF (TG_OP = 'UPDATE') THEN
- UPDATE web_hook_logs_archived
- SET web_hook_id = NEW.web_hook_id,
- trigger = NEW.trigger,
- url = NEW.url,
- request_headers = NEW.request_headers,
- request_data = NEW.request_data,
- response_headers = NEW.response_headers,
- response_body = NEW.response_body,
- response_status = NEW.response_status,
- execution_duration = NEW.execution_duration,
- internal_error_message = NEW.internal_error_message,
- created_at = NEW.created_at,
- updated_at = NEW.updated_at
- WHERE web_hook_logs_archived.id = NEW.id;
-ELSIF (TG_OP = 'INSERT') THEN
- INSERT INTO web_hook_logs_archived (id,
- web_hook_id,
- trigger,
- url,
- request_headers,
- request_data,
- response_headers,
- response_body,
- response_status,
- execution_duration,
- internal_error_message,
- created_at,
- updated_at)
- VALUES (NEW.id,
- NEW.web_hook_id,
- NEW.trigger,
- NEW.url,
- NEW.request_headers,
- NEW.request_data,
- NEW.response_headers,
- NEW.response_body,
- NEW.response_status,
- NEW.execution_duration,
- NEW.internal_error_message,
- NEW.created_at,
- NEW.updated_at);
-END IF;
-RETURN NULL;
-
-END
-$$;
-
-COMMENT ON FUNCTION table_sync_function_29bc99d6db() IS 'Partitioning migration: table sync for web_hook_logs table';
-
CREATE FUNCTION trigger_07c94931164e() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -10777,6 +10721,23 @@ CREATE SEQUENCE ci_job_artifacts_id_seq
ALTER SEQUENCE ci_job_artifacts_id_seq OWNED BY ci_job_artifacts.id;
+CREATE TABLE ci_job_token_project_scope_links (
+ id bigint NOT NULL,
+ source_project_id bigint NOT NULL,
+ target_project_id bigint NOT NULL,
+ added_by_id bigint,
+ created_at timestamp with time zone NOT NULL
+);
+
+CREATE SEQUENCE ci_job_token_project_scope_links_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE ci_job_token_project_scope_links_id_seq OWNED BY ci_job_token_project_scope_links.id;
+
CREATE TABLE ci_job_variables (
id bigint NOT NULL,
key character varying NOT NULL,
@@ -19351,22 +19312,6 @@ CREATE SEQUENCE vulnerability_user_mentions_id_seq
ALTER SEQUENCE vulnerability_user_mentions_id_seq OWNED BY vulnerability_user_mentions.id;
-CREATE TABLE web_hook_logs_archived (
- id integer NOT NULL,
- web_hook_id integer NOT NULL,
- trigger character varying,
- url character varying,
- request_headers text,
- request_data text,
- response_headers text,
- response_body text,
- response_status character varying,
- execution_duration double precision,
- internal_error_message character varying,
- created_at timestamp without time zone NOT NULL,
- updated_at timestamp without time zone NOT NULL
-);
-
CREATE SEQUENCE web_hook_logs_id_seq
START WITH 1
INCREMENT BY 1
@@ -19699,6 +19644,8 @@ ALTER TABLE ONLY ci_instance_variables ALTER COLUMN id SET DEFAULT nextval('ci_i
ALTER TABLE ONLY ci_job_artifacts ALTER COLUMN id SET DEFAULT nextval('ci_job_artifacts_id_seq'::regclass);
+ALTER TABLE ONLY ci_job_token_project_scope_links ALTER COLUMN id SET DEFAULT nextval('ci_job_token_project_scope_links_id_seq'::regclass);
+
ALTER TABLE ONLY ci_job_variables ALTER COLUMN id SET DEFAULT nextval('ci_job_variables_id_seq'::regclass);
ALTER TABLE ONLY ci_minutes_additional_packs ALTER COLUMN id SET DEFAULT nextval('ci_minutes_additional_packs_id_seq'::regclass);
@@ -20881,6 +20828,9 @@ ALTER TABLE ONLY ci_instance_variables
ALTER TABLE ONLY ci_job_artifacts
ADD CONSTRAINT ci_job_artifacts_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY ci_job_token_project_scope_links
+ ADD CONSTRAINT ci_job_token_project_scope_links_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY ci_job_variables
ADD CONSTRAINT ci_job_variables_pkey PRIMARY KEY (id);
@@ -22129,9 +22079,6 @@ ALTER TABLE ONLY vulnerability_statistics
ALTER TABLE ONLY vulnerability_user_mentions
ADD CONSTRAINT vulnerability_user_mentions_pkey PRIMARY KEY (id);
-ALTER TABLE ONLY web_hook_logs_archived
- ADD CONSTRAINT web_hook_logs_archived_pkey PRIMARY KEY (id);
-
ALTER TABLE ONLY web_hook_logs
ADD CONSTRAINT web_hook_logs_pkey PRIMARY KEY (id, created_at);
@@ -22335,6 +22282,8 @@ CREATE INDEX finding_evidences_on_vulnerability_occurrence_id ON vulnerability_f
CREATE INDEX finding_links_on_vulnerability_occurrence_id ON vulnerability_finding_links USING btree (vulnerability_occurrence_id);
+CREATE UNIQUE INDEX i_ci_job_token_project_scope_links_on_source_and_target_project ON ci_job_token_project_scope_links USING btree (source_project_id, target_project_id);
+
CREATE INDEX idx_analytics_devops_adoption_segments_on_namespace_id ON analytics_devops_adoption_segments USING btree (namespace_id);
CREATE INDEX idx_audit_events_part_on_entity_id_desc_author_id_created_at ON ONLY audit_events USING btree (entity_id, entity_type, id DESC, author_id, created_at);
@@ -22815,6 +22764,10 @@ CREATE INDEX index_ci_job_artifacts_on_project_id ON ci_job_artifacts USING btre
CREATE INDEX index_ci_job_artifacts_on_project_id_for_security_reports ON ci_job_artifacts USING btree (project_id) WHERE (file_type = ANY (ARRAY[5, 6, 7, 8]));
+CREATE INDEX index_ci_job_token_project_scope_links_on_added_by_id ON ci_job_token_project_scope_links USING btree (added_by_id);
+
+CREATE INDEX index_ci_job_token_project_scope_links_on_target_project_id ON ci_job_token_project_scope_links USING btree (target_project_id);
+
CREATE INDEX index_ci_job_variables_on_job_id ON ci_job_variables USING btree (job_id);
CREATE UNIQUE INDEX index_ci_job_variables_on_key_and_job_id ON ci_job_variables USING btree (key, job_id);
@@ -24973,10 +24926,6 @@ CREATE UNIQUE INDEX index_vulns_user_mentions_on_vulnerability_id ON vulnerabili
CREATE UNIQUE INDEX index_vulns_user_mentions_on_vulnerability_id_and_note_id ON vulnerability_user_mentions USING btree (vulnerability_id, note_id);
-CREATE INDEX index_web_hook_logs_on_created_at_and_web_hook_id ON web_hook_logs_archived USING btree (created_at, web_hook_id);
-
-CREATE INDEX index_web_hook_logs_on_web_hook_id ON web_hook_logs_archived USING btree (web_hook_id);
-
CREATE INDEX index_web_hook_logs_part_on_created_at_and_web_hook_id ON ONLY web_hook_logs USING btree (created_at, web_hook_id);
CREATE INDEX index_web_hook_logs_part_on_web_hook_id ON ONLY web_hook_logs USING btree (web_hook_id);
@@ -25359,8 +25308,6 @@ ALTER INDEX product_analytics_events_experimental_pkey ATTACH PARTITION gitlab_p
ALTER INDEX product_analytics_events_experimental_pkey ATTACH PARTITION gitlab_partitions_static.product_analytics_events_experimental_63_pkey;
-CREATE TRIGGER table_sync_trigger_b99eb6998c AFTER INSERT OR DELETE OR UPDATE ON web_hook_logs FOR EACH ROW EXECUTE FUNCTION table_sync_function_29bc99d6db();
-
CREATE TRIGGER trigger_07c94931164e BEFORE INSERT OR UPDATE ON push_event_payloads FOR EACH ROW EXECUTE FUNCTION trigger_07c94931164e();
CREATE TRIGGER trigger_21e7a2602957 BEFORE INSERT OR UPDATE ON ci_build_needs FOR EACH ROW EXECUTE FUNCTION trigger_21e7a2602957();
@@ -26493,6 +26440,9 @@ ALTER TABLE ONLY metrics_dashboard_annotations
ALTER TABLE ONLY wiki_page_slugs
ADD CONSTRAINT fk_rails_358b46be14 FOREIGN KEY (wiki_page_meta_id) REFERENCES wiki_page_meta(id) ON DELETE CASCADE;
+ALTER TABLE ONLY ci_job_token_project_scope_links
+ ADD CONSTRAINT fk_rails_35f7f506ce FOREIGN KEY (added_by_id) REFERENCES users(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY board_labels
ADD CONSTRAINT fk_rails_362b0600a3 FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
@@ -26628,6 +26578,9 @@ ALTER TABLE ONLY upcoming_reconciliations
ALTER TABLE ONLY ci_pipeline_artifacts
ADD CONSTRAINT fk_rails_4a70390ca6 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY ci_job_token_project_scope_links
+ ADD CONSTRAINT fk_rails_4b2ee3290b FOREIGN KEY (source_project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY group_deletion_schedules
ADD CONSTRAINT fk_rails_4b8c694a6c FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -26823,9 +26776,6 @@ ALTER TABLE ONLY operations_feature_flags_clients
ALTER TABLE ONLY namespace_admin_notes
ADD CONSTRAINT fk_rails_666166ea7b FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
-ALTER TABLE ONLY web_hook_logs_archived
- ADD CONSTRAINT fk_rails_666826e111 FOREIGN KEY (web_hook_id) REFERENCES web_hooks(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams
ADD CONSTRAINT fk_rails_669f4ba293 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -26844,6 +26794,9 @@ ALTER TABLE ONLY vulnerability_finding_evidence_headers
ALTER TABLE ONLY geo_hashed_storage_migrated_events
ADD CONSTRAINT fk_rails_687ed7d7c5 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+ALTER TABLE ONLY ci_job_token_project_scope_links
+ ADD CONSTRAINT fk_rails_6904b38465 FOREIGN KEY (target_project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY plan_limits
ADD CONSTRAINT fk_rails_69f8b6184f FOREIGN KEY (plan_id) REFERENCES plans(id) ON DELETE CASCADE;
diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md
index f0fd4aba8b8..775de26b772 100644
--- a/doc/ci/runners/configure_runners.md
+++ b/doc/ci/runners/configure_runners.md
@@ -142,8 +142,9 @@ different places.
To view the IP address of a shared runner you must have admin access to
the GitLab instance. To determine this:
-1. Visit **Admin Area > Overview > Runners**.
-1. Look for the runner in the table and you should see a column for **IP Address**.
+1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the left sidebar, select **Overview > Runners**.
+1. Find the runner in the table and view the **IP Address** column.
![shared runner IP address](img/shared_runner_ip_address.png)
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 215b8fad92b..67d5c02799b 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -215,7 +215,7 @@ click NodeExporter "./architecture.html#node-exporter"
### Component legend
- ✅ - Installed by default
-- ⚙ - Requires additional configuration, or GitLab Managed Apps
+- ⚙ - Requires additional configuration
- ⤓ - Manual installation required
- ❌ - Not supported or no instructions available
- N/A - Not applicable
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index a3c9d77f573..367fa659150 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -480,11 +480,7 @@ because of 2 reasons:
### PostgreSQL versions testing
Our test suite runs against PG12 as GitLab.com runs on PG12 and
-[Omnibus defaults to PG12 for new installs and upgrades](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html),
-Our test suite is currently running against PG11, since GitLab.com still runs on PG11.
-
-We do run our test suite against PG11 on nightly scheduled pipelines as well as upon specific
-database library changes in MRs and `master` pipelines (with the `rspec db-library-code pg11` job).
+[Omnibus defaults to PG12 for new installs and upgrades](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html).
#### Current versions testing
@@ -502,7 +498,6 @@ We follow the [PostgreSQL versions shipped with Omnibus GitLab](https://docs.git
| PostgreSQL version | 13.11 (April 2021) | 13.12 (May 2021) | 14.0 (June 2021?) |
| -------------------| ---------------------- | ---------------------- | ---------------------- |
| PG12 | `nightly` | MRs/`2-hour`/`nightly` | MRs/`2-hour`/`nightly` |
-| PG11 | MRs/`2-hour`/`nightly` | `nightly` | `nightly` |
### Test jobs
@@ -730,8 +725,6 @@ that are scoped to a single [configuration keyword](../ci/yaml/README.md#job-key
| `.qa-cache` | Allows a job to use a default `cache` definition suitable for QA tasks. |
| `.yarn-cache` | Allows a job to use a default `cache` definition suitable for frontend jobs that do a `yarn install`. |
| `.assets-compile-cache` | Allows a job to use a default `cache` definition suitable for frontend jobs that compile assets. |
-| `.use-pg11` | Allows a job to run the `postgres` 11 and `redis` services (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific versions of the services). |
-| `.use-pg11-ee` | Same as `.use-pg11` but also use an `elasticsearch` service (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific version of the service). |
| `.use-pg12` | Allows a job to use the `postgres` 12 and `redis` services (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific versions of the services). |
| `.use-pg12-ee` | Same as `.use-pg12` but also use an `elasticsearch` service (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific version of the service). |
| `.use-kaniko` | Allows a job to use the `kaniko` tool to build Docker images. |
diff --git a/doc/operations/index.md b/doc/operations/index.md
index c2f3ce0a427..d170e82dd7f 100644
--- a/doc/operations/index.md
+++ b/doc/operations/index.md
@@ -73,7 +73,7 @@ production services. GitLab provides centralized, aggregated log storage for you
distributed application, enabling you to collect logs across multiple services and
infrastructure.
-- [View logs of pods or managed applications](../user/project/clusters/kubernetes_pod_logs.md)
+- [View logs of pods](../user/project/clusters/kubernetes_pod_logs.md)
in connected Kubernetes clusters.
## Manage your infrastructure in code
diff --git a/doc/operations/metrics/dashboards/index.md b/doc/operations/metrics/dashboards/index.md
index 7b056020a99..95075e2b0e4 100644
--- a/doc/operations/metrics/dashboards/index.md
+++ b/doc/operations/metrics/dashboards/index.md
@@ -217,8 +217,46 @@ links:
## Troubleshooting
-When troubleshooting issues with a managed Prometheus app, it is often useful to
-[view the Prometheus UI](../../../user/project/integrations/prometheus.md#access-the-ui-of-a-prometheus-managed-application-in-kubernetes).
+### Accessing the UI of Prometheus in Kubernetes
+
+When troubleshooting issues with an in-cluster Prometheus, it can help to
+view the Prometheus UI. In the example below, we assume the Prometheus
+server to be the pod `prometheus-prometheus-server` in the `gitlab-managed-apps`
+namespace:
+
+1. Find the name of the Prometheus pod in the user interface of your Kubernetes
+ provider, such as GKE, or by running the following `kubectl` command in your
+ terminal. For example:
+
+ ```shell
+ kubectl get pods -n gitlab-managed-apps | grep 'prometheus-prometheus-server'
+ ```
+
+ The command should return a result like the following example, where
+ `prometheus-prometheus-server-55b4bd64c9-dpc6b` is the name of the Prometheus pod:
+
+ ```plaintext
+ gitlab-managed-apps prometheus-prometheus-server-55b4bd64c9-dpc6b 2/2 Running 0 71d
+ ```
+
+1. Run a `kubectl port-forward` command. In the following example, `9090` is the
+ Prometheus server's listening port:
+
+ ```shell
+ kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 9090:9090 -n gitlab-managed-apps
+ ```
+
+ The `port-forward` command forwards all requests sent to your system's `9090` port
+ to the `9090` port of the Prometheus pod. If the `9090` port on your system is used
+ by another application, you can change the port number before the colon to your
+ desired port. For example, to forward port `8080` of your local system, change the
+ command to:
+
+ ```shell
+ kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 8080:9090 -n gitlab-managed-apps
+ ```
+
+1. Open `localhost:9090` in your browser to display the Prometheus user interface.
### "No data found" error on Metrics dashboard page
diff --git a/doc/operations/metrics/index.md b/doc/operations/metrics/index.md
index 8ff45ac4015..8151bf97bd9 100644
--- a/doc/operations/metrics/index.md
+++ b/doc/operations/metrics/index.md
@@ -16,10 +16,10 @@ critical. For GitLab to display your information in charts, you must:
For an overview, see [How to instrument Prometheus metrics in GitLab](https://www.youtube.com/watch?v=tuI2oJ3TTB4).
1. **Expose metrics for capture** - Make logs, metrics, and traces available for capture.
1. [**Configure Prometheus to gather metrics**](#configure-prometheus-to-gather-metrics) -
- Deploy managed applications like Elasticsearch, Prometheus, and Jaeger to gather
+ Use applications like Elasticsearch, Prometheus, and Jaeger to gather
the data you've exposed.
1. **GitLab collects metrics** - GitLab uses Prometheus to scrape the data you've
- captured in your managed apps, and prepares the data for display. To learn more, read
+ captured in your applications, and prepares the data for display. To learn more, read
[Collect and process metrics](#collect-and-process-metrics).
1. **Display charts in the GitLab user interface** - GitLab converts your metrics
into easy-to-read charts on a default dashboard. You can create as many custom charts
@@ -34,30 +34,10 @@ your Prometheus integration depends on where your apps are running:
- **For manually-configured Prometheus** -
[Specify your Prometheus server](../../user/project/integrations/prometheus.md#manual-configuration-of-prometheus),
and define at least one environment.
-- **For GitLab-managed Prometheus** - GitLab can
- [deploy and manage Prometheus](../../user/project/integrations/prometheus.md#managed-prometheus-on-kubernetes) for you.
- You must also complete a code deployment, as described in
- [Deploy code with GitLab-managed Prometheus](#deploy-code-with-gitlab-managed-prometheus),
- for the **Operations > Metrics** page to contain data.
-
-### Deploy code with GitLab-managed Prometheus
-
-For GitLab-managed Prometheus, you can set up [Auto DevOps](../../topics/autodevops/index.md)
-to quickly create a deployment:
-
-1. Navigate to your project's **Operations > Kubernetes** page.
-1. Ensure that, in addition to Prometheus, you also have GitLab Runner and Ingress
- installed.
-1. After installing Ingress, copy its endpoint.
-1. Navigate to your project's **Settings > CI/CD** page. In the
- **Auto DevOps** section, select a deployment strategy and save your changes.
-1. On the same page, in the **Variables** section, add a variable named
- `KUBE_INGRESS_BASE_DOMAIN` with the value of the Ingress endpoint you
- copied previously. Leave the type as **Variable**.
-1. Navigate to your project's **{rocket}** **CI/CD > Pipelines** page, and run a
- pipeline on any branch.
-1. When the pipeline has run successfully, graphs are available on the
- **Operations > Metrics** page.
+- **For a cluster integrated Prometheus** - GitLab can query
+ [an in-cluster Prometheus](../../user/clusters/integrations.md#prometheus-cluster-integration).
+ You must also complete a code deployment to your cluster for the **Operations > Metrics**
+ page to contain data. You can do this using [Auto DevOps](../../topics/autodevops/quick_start_guide.md).
![Monitoring Dashboard](img/prometheus_monitoring_dashboard_v13_3.png)
diff --git a/doc/topics/autodevops/requirements.md b/doc/topics/autodevops/requirements.md
index f39f33c7730..ccffb5913f5 100644
--- a/doc/topics/autodevops/requirements.md
+++ b/doc/topics/autodevops/requirements.md
@@ -66,8 +66,7 @@ To make full use of Auto DevOps with Kubernetes, you need:
Runners should be registered as [shared runners](../../ci/runners/runners_scope.md#shared-runners)
for the entire GitLab instance, or [specific runners](../../ci/runners/runners_scope.md#specific-runners)
- that are assigned to specific projects (the default if you've installed the
- GitLab Runner managed application).
+ that are assigned to specific projects.
- **Prometheus** (for [Auto Monitoring](stages.md#auto-monitoring))
diff --git a/doc/user/clusters/applications.md b/doc/user/clusters/applications.md
index 495767cea69..f712dcace73 100644
--- a/doc/user/clusters/applications.md
+++ b/doc/user/clusters/applications.md
@@ -6,12 +6,15 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Managed Apps (DEPRECATED) **(FREE)**
+NOTE:
+The new recommended way to manage cluster applications is to use the [cluster management project template](management_project_template.md).
+If you want to migrate your GitLab managed apps management to this template, reference to [migrating from GitLab managed apps to project template](migrating_from_gma_to_project_template.md).
+
**GitLab Managed Apps** was created to help you configure applications in your
cluster directly from GitLab. You could use this feature through two different
methods: "one-click install" and "CI/CD template". Both methods are **deprecated**:
-- The **one-click install** method was deprecated in GitLab 13.9 and **will be
- removed** in GitLab 14.0.
+- The **one-click install** method was [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63348) in GitLab 14.0.
- The **CI/CD template method** was deprecated in GitLab 13.12 and is scheduled
to be removed in GitLab 15.0.
@@ -19,15 +22,6 @@ Both methods were limiting as you couldn't fully customize your third-party apps
through GitLab Managed Apps. Therefore, we decided to deprecate this feature and provide
better [GitOps-driven alternatives](https://about.gitlab.com/direction/configure/kubernetes_management/#gitlab-managed-applications) to our users, such as [cluster integrations](integrations.md#cluster-integrations) and [cluster management project](management_project.md).
-Read the sections below according to the installation method you chose to
-learn how to proceed to keep your apps up and running:
-
-- [One-click install method](#install-with-one-click-deprecated)
-- [CI/CD template method](#install-using-gitlab-cicd-deprecated)
-
-NOTE:
-Despite being deprecated, the recommended way for installing GitLab integrated applications is by the GitLab CI/CD method presented below. We are working on a [cluster management project template](https://gitlab.com/gitlab-org/gitlab/-/issues/327908) with a simple upgrade path from the CI/CD based method.
-
## Install using GitLab CI/CD (DEPRECATED)
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20822) in GitLab 12.6.
@@ -37,8 +31,8 @@ WARNING:
The GitLab Managed Apps CI/CD installation method was [deprecated in 13.12](https://gitlab.com/gitlab-org/gitlab/-/issues/327908).
Your applications continue to work. However, we no longer support and maintain the GitLab CI/CD template for
Managed Apps (`Managed-Cluster-Applications.gitlab-ci.yml`).
-As a replacement, we are working on a [cluster management project template](https://gitlab.com/gitlab-org/gitlab/-/issues/327908),
-still to be released.
+The new recommended way to manage cluster applications is to use the [cluster management project template](management_project_template.md).
+If you want to migrate your GitLab managed apps management to this template, reference to [migrating from GitLab managed apps to project template](migrating_from_gma_to_project_template.md).
The CI/CD template was the primary method for installing applications to clusters via GitLab Managed Apps
and customize them through Helm.
@@ -821,11 +815,6 @@ management project. Refer to the
[chart](https://gitlab.com/gitlab-org/charts/elastic-stack) for all
available configuration options.
-NOTE:
-In this alpha implementation of installing Elastic Stack through CI, reading the
-environment logs through Elasticsearch is unsupported. This is supported if
-[installed with the UI](#elastic-stack).
-
Support for installing the Elastic Stack managed application is provided by the
GitLab APM group. If you run into unknown issues,
[open a new issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new), and ping at
@@ -1033,565 +1022,29 @@ GitLab Container Security group. If you run into unknown issues,
at least 2 people from the
[Container Security group](https://about.gitlab.com/handbook/product/categories/#container-security-group).
-## Browse applications logs
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36769) in GitLab 13.2.
-
-Logs produced by pods running **GitLab Managed Apps** can be browsed using
-[**Log Explorer**](../project/clusters/kubernetes_pod_logs.md).
+## Install with one click (REMOVED)
-## Install with one click (DEPRECATED)
+> [Removed](https://gitlab.com/groups/gitlab-org/-/epics/4280) in GitLab 14.0.
-WARNING:
-The one-click installation method was deprecated in GitLab 13.9 and will be removed in [GitLab 14.0](https://gitlab.com/groups/gitlab-org/-/epics/4280).
-The removal does not break nor uninstall any apps you have installed but removes the GitLab UI page
-for installing and updating your GitLab Managed Apps.
+The one-click installation method was deprecated in GitLab 13.9 and removed in [GitLab 14.0](https://gitlab.com/groups/gitlab-org/-/epics/4280).
+The removal does not break nor uninstall any apps you have installed, it only
+removes the "Applications" tab from the cluster page.
Follow the process to [take ownership of your GitLab Managed Apps](#take-ownership-of-your-gitlab-managed-apps).
-Applications managed by GitLab are installed onto the `gitlab-managed-apps`
-namespace. This namespace:
-
-- Is different from the namespace used for project deployments.
-- Is created once.
-- Has a non-configurable name.
-
-To view a list of available applications to install for a:
-
-- [Project-level cluster](../project/clusters/index.md), navigate to your project's
- **Operations > Kubernetes**.
-- [Group-level cluster](../group/clusters/index.md), navigate to your group's
- **Kubernetes** page.
-
-You can install the following applications with one click:
-
-- [Helm](#helm)
-- [Ingress](#ingress)
-- [cert-manager](#cert-manager)
-- [Prometheus](#prometheus)
-- [GitLab Runner](#gitlab-runner)
-- [JupyterHub](#jupyterhub)
-- [Knative](#knative)
-- [Crossplane](#crossplane)
-- [Elastic Stack](#elastic-stack)
-
-With the exception of Knative, the applications are installed in a dedicated
-namespace called `gitlab-managed-apps`.
-
-Some applications are installable only for a project-level cluster.
-Support for installing these applications in a group-level cluster is
-planned for future releases.
-For updates, see the [issue tracking progress](https://gitlab.com/gitlab-org/gitlab/-/issues/24411).
-
-WARNING:
-If you have an existing Kubernetes cluster with Helm already installed,
-you should be careful as GitLab cannot detect it. In this case, installing
-Helm with the applications results in the cluster having it twice, which
-can lead to confusion during deployments.
-
-In GitLab versions 11.6 and greater, Helm is upgraded to the latest version
-supported by GitLab before installing any of the applications.
-
-### Helm
-
-> - Introduced in GitLab 10.2 for project-level clusters.
-> - Introduced in GitLab 11.6 for group-level clusters.
-> - [Uses a local Tiller](https://gitlab.com/gitlab-org/gitlab/-/issues/209736) in GitLab 13.2 and later.
-> - [Uses Helm 3](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46267) for clusters created with GitLab 13.6 and later.
-> - [Offers legacy Tiller removal](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47457) in GitLab 13.7 and later.
-
-[Helm](https://helm.sh/docs/) is a package manager for Kubernetes and is
-used to install the GitLab-managed apps. GitLab runs each `helm` command
-in a pod in the `gitlab-managed-apps` namespace inside the cluster.
-
-- For clusters created in GitLab 13.6 and newer, GitLab uses Helm 3 to manage
- applications.
-- For clusters created on versions of GitLab prior to 13.6, GitLab uses Helm 2
- with a local [Tiller](https://v2.helm.sh/docs/glossary/#tiller) server. Prior
- to [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/209736), GitLab
- used an in-cluster Tiller server in the `gitlab-managed-apps` namespace. You
- can safely uninstall the server from the GitLab application page if you have
- previously installed it. This doesn't affect your other applications.
-
-The GitLab Helm integration does not support installing applications behind a proxy,
-but a [workaround](../../topics/autodevops/index.md#install-applications-behind-a-proxy)
-is available.
-
-#### Upgrade a cluster to Helm 3
-
-GitLab does not offer a way to migrate existing application management
-on existing clusters from Helm 2 to Helm 3. To migrate a cluster to Helm 3:
-
-1. Uninstall all applications on your cluster.
-1. [Remove the cluster integration](../project/clusters/add_remove_clusters.md#removing-integration).
-1. [Re-add the cluster](../project/clusters/add_remove_clusters.md#existing-kubernetes-cluster) as
- an existing cluster.
-
-### cert-manager
-
-> Introduced in GitLab 11.6 for project- and group-level clusters.
-
-[cert-manager](https://cert-manager.io/docs/) is a native Kubernetes certificate
-management controller that helps with issuing certificates. Installing
-cert-manager on your cluster issues a certificate by [Let's Encrypt](https://letsencrypt.org/)
-and ensures that certificates are valid and up-to-date.
-
-The chart used to install this application depends on the version of GitLab used. In:
-
-- GitLab 12.3 and newer, the [`jetstack/cert-manager`](https://github.com/jetstack/cert-manager)
- chart is used with a
- [`values.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/cert_manager/values.yaml)
- file.
-- GitLab 12.2 and older, the
- [`stable/cert-manager`](https://github.com/helm/charts/tree/master/stable/cert-manager)
- chart was used.
-
-If you installed cert-manager prior to GitLab 12.3, Let's Encrypt
-[blocks requests](https://community.letsencrypt.org/t/blocking-old-cert-manager-versions/98753)
-from older versions of `cert-manager`. To resolve this:
-
-1. [Back up any additional configuration](https://cert-manager.io/docs/tutorials/backup/).
-1. Uninstall cert-manager.
-1. Install cert-manager again.
-
-### GitLab Runner
-
-> - Introduced in GitLab 10.6 for project-level clusters.
-> - Introduced in GitLab 11.10 for group-level clusters.
-
-[GitLab Runner](https://docs.gitlab.com/runner/) is the open source project that
-is used to run your jobs and send the results back to GitLab. It's used in
-conjunction with [GitLab CI/CD](../../ci/README.md), the open-source continuous
-integration service included with GitLab that coordinates the jobs.
-
-If the project is on GitLab.com, [shared runners](../gitlab_com/index.md#shared-runners)
-are available. You don't have to deploy one if they are enough for your
-needs. If a project-specific runner is desired, or there are no shared runners,
-you can deploy one.
-
-The deployed runner is set as **privileged**. Root access to the underlying
-server is required to build Docker images, so it's the default. Be sure to read
-the [security implications](../project/clusters/index.md#security-implications)
-before deploying one.
-
-The [`runner/gitlab-runner`](https://gitlab.com/gitlab-org/charts/gitlab-runner)
-chart is used to install this application, using
-[a preconfigured `values.yaml`](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/blob/main/values.yaml)
-file. Customizing the installation by modifying this file is not supported. This
-also means you cannot modify `config.toml` file for this Runner. If you want to
-have that possibility and still deploy Runner in Kubernetes, consider using the
-[Cluster management project](management_project.md) or installing Runner manually
-via [GitLab Runner Helm Chart](https://docs.gitlab.com/runner/install/kubernetes.html).
-
-### Ingress
-
-> - Introduced in GitLab 10.2 for project-level clusters.
-> - Introduced in GitLab 11.6 for group-level clusters.
-
-[Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
-provides load balancing, SSL termination, and name-based virtual hosting
-out of the box. It acts as a web proxy for your applications and is useful
-if you want to use [Auto DevOps](../../topics/autodevops/index.md) or deploy your own web apps.
-
-The Ingress Controller installed is
-[Ingress-NGINX](https://kubernetes.io/docs/concepts/services-networking/ingress/),
-which is supported by the Kubernetes community.
-
-With the following procedure, a load balancer must be installed in your cluster
-to obtain the endpoint. You can use either
-Ingress, or Knative's own load balancer ([Istio](https://istio.io)) if using Knative.
-
-To publish your web application, you first need to find the endpoint, which is either an IP
-address or a hostname associated with your load balancer.
-
-To install it, click on the **Install** button for Ingress. GitLab attempts
-to determine the external endpoint and it should be available in a few minutes.
-
-#### Determining the external endpoint automatically
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17052) in GitLab 10.6.
-
-After you install Ingress, the external endpoint should be available in a few minutes.
-
-NOTE:
-This endpoint can be used for the
-[Auto DevOps base domain](../../topics/autodevops/index.md#auto-devops-base-domain)
-using the `KUBE_INGRESS_BASE_DOMAIN` environment variable.
-
-If the endpoint doesn't appear and your cluster runs on Google Kubernetes Engine:
-
-1. [Examine your Kubernetes cluster](https://console.cloud.google.com/kubernetes)
- on Google Kubernetes Engine to ensure there are no errors on its nodes.
-1. Ensure you have enough [Quotas](https://console.cloud.google.com/iam-admin/quotas)
- on Google Kubernetes Engine. For more information, see
- [Resource Quotas](https://cloud.google.com/compute/quotas).
-1. Review [Google Cloud's Status](https://status.cloud.google.com/) for service
- disruptions.
-
-The [`stable/nginx-ingress`](https://github.com/helm/charts/tree/master/stable/nginx-ingress)
-chart is used to install this application with a
-[`values.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/ingress/values.yaml)
-file.
-
-After installing, you may see a `?` for **Ingress IP Address** depending on the
-cloud provider. For EKS specifically, this is because the ELB is created
-with a DNS name, not an IP address. If GitLab is still unable to
-determine the endpoint of your Ingress or Knative application, you can
-[determine it manually](#determining-the-external-endpoint-manually).
-
-#### Determining the external endpoint manually
-
-See the [Base domain section](../project/clusters/index.md#base-domain) for a
-guide on how to determine the external endpoint manually.
-
-#### Using a static IP
-
-By default, an ephemeral external IP address is associated to the cluster's load
-balancer. If you associate the ephemeral IP with your DNS and the IP changes,
-your apps aren't reachable, and you'd have to change the DNS record again.
-To avoid that, change it into a static reserved IP.
-
-Read how to [promote an ephemeral external IP address in GKE](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address#promote_ephemeral_ip).
-
-#### Pointing your DNS at the external endpoint
-
-After you have set up the external endpoint, associate it with a
-[wildcard DNS record](https://en.wikipedia.org/wiki/Wildcard_DNS_record) (such
-as `*.example.com.`) to reach your apps. If your external endpoint is an IP
-address, use an A record. If your external endpoint is a hostname, use a CNAME
-record.
-
-### JupyterHub
-
-> - Introduced in GitLab 11.0 for project-level clusters.
-> - Introduced in GitLab 12.3 for group and instance-level clusters.
-
-[JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) is a multi-user service
-for managing notebooks across a team. [Jupyter Notebooks](https://jupyter-notebook.readthedocs.io/en/latest/)
-provide a web-based interactive programming environment used for data analysis,
-visualization, and machine learning.
-
-The [`jupyter/jupyterhub`](https://jupyterhub.github.io/helm-chart/)
-chart is used to install this application with a
-[`values.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/jupyter/values.yaml)
-file.
-
-Authentication is enabled only for [project members](../project/members/index.md)
-for project-level clusters and group members for group-level clusters with
-[Developer or higher](../permissions.md) access to the associated project or group.
-
-GitLab uses a [custom Jupyter image](https://gitlab.com/gitlab-org/jupyterhub-user-image/blob/master/Dockerfile)
-that installs additional relevant packages on top of the base Jupyter. Ready-to-use
-DevOps Runbooks built with Nurtch's [Rubix library](https://github.com/Nurtch/rubix)
-are also available.
-
-More information on creating executable runbooks can be found in
-[our Runbooks documentation](../project/clusters/runbooks/index.md#configure-an-executable-runbook-with-gitlab).
-Ingress must be installed and have an IP address assigned before
-JupyterHub can be installed.
-
-#### Jupyter Git Integration
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/28783) in GitLab 12.0 for project-level clusters.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/32512) in GitLab 12.3 for group and instance-level clusters.
-
-When installing JupyterHub onto your Kubernetes cluster,
-[JupyterLab's Git extension](https://github.com/jupyterlab/jupyterlab-git)
-is provisioned and configured using the authenticated user's:
-
-- Name.
-- Email.
-- Newly created access token.
-
-JupyterLab's Git extension enables full version control of your notebooks, and
-issuance of Git commands in Jupyter. You can issue Git commands through the
-**Git** tab on the left panel, or through Jupyter's command-line prompt.
-
-JupyterLab's Git extension stores the user token in the JupyterHub DB in encrypted
-format, and in the single user Jupyter instance as plain text, because
-[Git requires storing credentials as plain text](https://git-scm.com/docs/git-credential-store)
-Potentially, if a nefarious user finds a way to read from the file system in the
-single-user Jupyter instance, they could retrieve the token.
-
-![Jupyter's Git Extension](img/jupyter-git-extension.gif)
-
-You can clone repositories from the files tab in Jupyter:
-
-![Jupyter clone repository](img/jupyter-gitclone.png)
-
-### Knative
-
-> - Introduced in GitLab 11.5 for project-level clusters.
-> - Introduced in GitLab 12.3 for group- and instance-level clusters.
-
-[Knative](https://cloud.google.com/knative/) provides a platform to
-create, deploy, and manage serverless workloads from a Kubernetes
-cluster. It's used in conjunction with, and includes
-[Istio](https://istio.io) to provide an external IP address for all
-programs hosted by Knative.
-
-The [`knative/knative`](https://storage.googleapis.com/triggermesh-charts)
-chart is used to install this application.
-
-During installation, you must enter a wildcard domain where your applications
-are exposed. Configure your DNS server to use the external IP address for that
-domain. Applications created and installed are accessible as
-`<program_name>.<kubernetes_namespace>.<domain_name>`, which requires
-your Kubernetes cluster to have
-[RBAC enabled](../project/clusters/add_remove_clusters.md#rbac-cluster-resources).
-
-### Prometheus
-
-> - Introduced in GitLab 10.4 for project-level clusters.
-> - Introduced in GitLab 11.11 for group-level clusters.
+If you are not yet on GitLab 14.0 or later, you can refer to [an older version of this document](https://docs.gitlab.com/13.12/ee/user/clusters/applications.html#install-with-one-click-deprecated).
-[Prometheus](https://prometheus.io/docs/introduction/overview/) is an
-open-source monitoring and alerting system you can use to supervise your
-deployed applications.
-
-GitLab is able to monitor applications by using the
-[Prometheus integration](../project/integrations/prometheus.md). Kubernetes container CPU and
-memory metrics are collected, and response metrics are also retrieved
-from NGINX Ingress.
-
-The [`stable/prometheus`](https://github.com/helm/charts/tree/master/stable/prometheus)
-chart is used to install this application with a
-[`values.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/prometheus/values.yaml)
-file.
-
-To enable monitoring, install Prometheus into the cluster with the **Install**
-button.
-
-### Crossplane
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34702) in GitLab 12.5 for project-level clusters.
-
-[Crossplane](https://crossplane.github.io/docs/v0.9/) is a multi-cloud control plane
-to help you manage applications and infrastructure across multiple clouds. It extends the
-Kubernetes API using:
-
-- Custom resources.
-- Controllers that watch those custom resources.
-
-Crossplane allows provisioning and lifecycle management of infrastructure components
-across cloud providers in a uniform manner by abstracting cloud provider-specific
-configurations.
-
-The Crossplane GitLab-managed application:
-
-- Installs Crossplane with a provider of choice on a Kubernetes cluster attached to the
- project repository.
-- Can then be used to provision infrastructure or managed applications such as
- PostgreSQL (for example, CloudSQL from GCP or RDS from AWS) and other services
- required by the application with the Auto DevOps pipeline.
-
-[`alpha/crossplane`](https://github.com/crossplane/crossplane/tree/v0.4.1/cluster/charts/crossplane) chart v0.4.1 is used to
-install Crossplane using the
-[`values.yaml`](https://github.com/crossplane/crossplane/blob/master/cluster/charts/crossplane/values.yaml.tmpl)
-file.
-
-For information about configuring Crossplane installed on the cluster, see
-[Crossplane configuration](crossplane.md).
-
-### Elastic Stack
-
-> Introduced in GitLab 12.7 for project- and group-level clusters.
-
-[Elastic Stack](https://www.elastic.co/elastic-stack) is a complete end-to-end
-log analysis solution which helps in deep searching, analyzing and visualizing the logs
-generated from different machines.
-
-GitLab can gather logs from pods in your cluster. Filebeat runs as a DaemonSet
-on each node in your cluster, and ships container logs to Elasticsearch for
-querying. GitLab then connects to Elasticsearch for logs, instead of the
-Kubernetes API, giving you access to more advanced querying capabilities. Log
-data is deleted after 30 days, using [Curator](https://www.elastic.co/guide/en/elasticsearch/client/curator/5.5/about.html).
-
-The Elastic Stack cluster application is intended as a log aggregation solution
-and is not related to our [Advanced Search](../search/advanced_search.md)
-functionality, which uses a separate Elasticsearch cluster.
-
-To enable log shipping:
-
-1. Ensure your cluster contains at least three nodes of instance types larger
- than `f1-micro`, `g1-small`, or `n1-standard-1`.
-1. Navigate to **Operations > Kubernetes**.
-1. In **Kubernetes Cluster**, select a cluster.
-1. In the **Applications** section, find **Elastic Stack**, and then select
- **Install**.
-
-The [`gitlab/elastic-stack`](https://gitlab.com/gitlab-org/charts/elastic-stack)
-chart is used to install this application with a
-[`values.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/elastic_stack/values.yaml)
-file. The chart deploys three identical Elasticsearch pods which can't be
-colocated, and each requires one CPU and 2 GB of RAM, making them
-incompatible with clusters containing fewer than three nodes, or consisting of
-`f1-micro`, `g1-small`, `n1-standard-1`, or `*-highcpu-2` instance types.
-
-#### Optional: deploy Kibana to perform advanced queries
-
-If you are an advanced user and have direct access to your Kubernetes cluster
-using `kubectl` and `helm`, you can deploy Kibana manually. The following assumes
-that `helm` has been [initialized](https://v2.helm.sh/docs/helm/) with `helm init`.
-
-Save the following to `kibana.yml`:
-
-```yaml
-elasticsearch:
- enabled: false
-
-filebeat:
- enabled: false
-
-kibana:
- enabled: true
- elasticsearchHosts: http://elastic-stack-elasticsearch-master.gitlab-managed-apps.svc.cluster.local:9200
-```
-
-Then install it on your cluster:
-
-```shell
-helm repo add gitlab https://charts.gitlab.io
-helm install --name kibana gitlab/elastic-stack --values kibana.yml
-```
-
-To access Kibana, forward the port to your local machine:
-
-```shell
-kubectl port-forward svc/kibana-kibana 5601:5601
-```
-
-Then, you can visit Kibana at `http://localhost:5601`.
-
-## Upgrading applications
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24789) in GitLab 11.8.
-
-The applications below can be upgraded.
-
-| Application | GitLab version |
-| ----------- | -------------- |
-| GitLab Runner | 11.8+ |
-
-To upgrade an application:
-
-1. For a:
- - [Project-level cluster](../project/clusters/index.md),
- navigate to your project's **Operations > Kubernetes**.
- - [Group-level cluster](../group/clusters/index.md),
- navigate to your group's **Kubernetes** page.
-1. Select your cluster.
-1. If an upgrade is available, the **Upgrade** button is displayed. Click the button to upgrade.
-
-Upgrades reset values back to the values built into the `runner` chart, plus the values set by
-[`values.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/runner/values.yaml)
-
-## Uninstalling applications
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/60665) in GitLab 11.11.
-
-The applications below can be uninstalled.
-
-| Application | GitLab version | Notes |
-| ----------- | -------------- | ----- |
-| cert-manager | 12.2+ | The associated private key is deleted and cannot be restored. Deployed applications continue to use HTTPS, but certificates aren't renewed. Before uninstalling, you may want to [back up your configuration](https://cert-manager.io/docs/tutorials/backup/) or [revoke your certificates](https://letsencrypt.org/docs/revoking/). |
-| GitLab Runner | 12.2+ | Any running pipelines are canceled. |
-| Helm | 12.2+ | The associated Tiller pod, the `gitlab-managed-apps` namespace, and all of its resources are deleted and cannot be restored. |
-| Ingress | 12.1+ | The associated load balancer and IP are deleted and cannot be restored. Furthermore, it can only be uninstalled if JupyterHub is not installed. |
-| JupyterHub | 12.1+ | All data not committed to GitLab are deleted and cannot be restored. |
-| Knative | 12.1+ | The associated IP are deleted and cannot be restored. |
-| Prometheus | 11.11+ | All data are deleted and cannot be restored. |
-| Crossplane | 12.5+ | All data are deleted and cannot be restored. |
-| Elastic Stack | 12.7+ | All data are deleted and cannot be restored. |
-| Sentry | 12.6+ | The PostgreSQL persistent volume remains and should be manually removed for complete uninstall. |
-
-To uninstall an application:
-
-1. For a:
- - [Project-level cluster](../project/clusters/index.md),
- navigate to your project's **Operations > Kubernetes**.
- - [Group-level cluster](../group/clusters/index.md),
- navigate to your group's **Kubernetes** page.
-1. Select your cluster.
-1. Click the **Uninstall** button for the application.
-
-Support for uninstalling all applications is planned for progressive rollout.
-To follow progress, see the [relevant epic](https://gitlab.com/groups/gitlab-org/-/epics/1201).
-
-## Troubleshooting applications
-
-Applications can fail with the following error:
-
-```plaintext
-Error: remote error: tls: bad certificate
-```
-
-To avoid installation errors:
-
-- Before starting the installation of applications, make sure that time is synchronized
- between your GitLab server and your Kubernetes cluster.
-- Ensure certificates are not out of sync. When installing applications, GitLab
- expects a new cluster with no previous installation of Helm.
-
- You can confirm that the certificates match by using `kubectl`:
-
- ```shell
- kubectl get configmaps/values-content-configuration-ingress -n gitlab-managed-apps -o \
- "jsonpath={.data['cert\.pem']}" | base64 -d > a.pem
- kubectl get secrets/tiller-secret -n gitlab-managed-apps -o "jsonpath={.data['ca\.crt']}" | base64 -d > b.pem
- diff a.pem b.pem
- ```
-
-### Error installing managed apps on EKS cluster
-
-If you're using a managed cluster on AWS EKS, and you are not able to install some of the managed
-apps, consider checking the logs.
-
-You can check the logs by running the following commands:
-
-```shell
-kubectl get pods --all-namespaces
-kubectl get services --all-namespaces
-```
-
-If you are getting the `Failed to assign an IP address to container` error, it's probably due to the
-instance type you've specified in the AWS configuration.
-The number and size of nodes might not have enough IP addresses to run or install those pods.
-
-For reference, all the AWS instance IP limits are found
-[in this AWS repository on GitHub](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/pkg/awsutils/vpc_ip_resource_limit.go) (search for `InstanceENIsAvailable`).
-
-### Unable to install Prometheus
-
-Installing Prometheus is failing with the following error:
-
-```shell
-# kubectl -n gitlab-managed-apps logs install-prometheus
-...
-Error: Could not get apiVersions from Kubernetes: unable to retrieve the complete list of server APIs: admission.certmanager.k8s.io/v1beta1: the server is currently unable to handle the request
-```
-
-This is a bug that was introduced in Helm `2.15` and fixed in `3.0.2`. As a workaround,
-ensure [`cert-manager`](#cert-manager) is installed successfully prior to installing Prometheus.
-
-### Unable to create a Persistent Volume Claim with DigitalOcean
-
-Trying to create additional block storage volumes might lead to the following error when using DigitalOcean:
+## Browse applications logs
-```plaintext
-Server requested
-[Warning] pod has unbound immediate PersistentVolumeClaims (repeated 2 times)
-[Normal] pod didn't trigger scale-up (it wouldn't fit if a new node is added):
-Spawn failed: Timeout
-```
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36769) in GitLab 13.2.
-This is due to DigitalOcean imposing a few limits with regards to creating additional block storage volumes.
-[Learn more about DigitalOcean Block Storage Volumes limits.](https://www.digitalocean.com/docs/volumes/#limits)
+Logs produced by pods running **GitLab Managed Apps** can be browsed using
+[**Log Explorer**](../project/clusters/kubernetes_pod_logs.md).
## Take ownership of your GitLab Managed Apps
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327803) in GitLab 13.12.
-With the removal of the [One-click install method](#install-with-one-click-deprecated) in GitLab 14.0,
+With the removal of the One-click install method in GitLab 14.0,
the **Applications** tab (under your project's **Operations > Kubernetes**)
will no longer be displayed:
@@ -1664,10 +1117,10 @@ If you choose to keep using Helm v2 (B), follow the steps below to manage your a
### Cluster integrations
-Some applications were not only installed in your cluster by GitLab through Managed Apps but were also
-directly integrated with GitLab so that you could benefit from seeing, controlling, or getting notified
-about them through GitLab.
-To keep them integrated, read the documentation for:
+Some applications were not only installed in your cluster by GitLab through
+Managed Apps but were also directly integrated with GitLab. If you had one of
+these applications installed before GitLab 14.0, then a corresponding [cluster
+integration](integrations.md) has been automatically enabled:
- [Prometheus cluster integration](integrations.md#prometheus-cluster-integration)
- [Elastic Stack cluster integration](integrations.md#elastic-stack-cluster-integration)
diff --git a/doc/user/clusters/crossplane.md b/doc/user/clusters/crossplane.md
index bdf9d582b93..8906d1224b1 100644
--- a/doc/user/clusters/crossplane.md
+++ b/doc/user/clusters/crossplane.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Crossplane configuration **(FREE)**
-After [installing](applications.md#crossplane) Crossplane, you must configure it for use.
+After [installing](applications.md#install-crossplane-using-gitlab-cicd) Crossplane, you must configure it for use.
The process of configuring Crossplane includes:
1. [Configure RBAC permissions](#configure-rbac-permissions).
diff --git a/doc/user/clusters/integrations.md b/doc/user/clusters/integrations.md
index a8b181f8726..8abdfdeb7fd 100644
--- a/doc/user/clusters/integrations.md
+++ b/doc/user/clusters/integrations.md
@@ -14,6 +14,17 @@ To enable cluster integrations, first add a Kubernetes cluster to a GitLab
[group](../group/clusters/index.md#group-level-kubernetes-clusters) or
[instance](../instance/clusters/index.md).
+You can install your applications manually as shown in the following sections, or use the
+[Cluster management project template](management_project_template.md) that automates the
+installation.
+
+Although, the [Cluster management project template](management_project_template.md) still
+requires that you manually do the last steps of these sections,
+[Enable Prometheus integration for your cluster](#enable-prometheus-integration-for-your-cluster)
+or [Enable Elastic Stack integration for your cluster](#enable-elastic-stack-integration-for-your-cluster)
+depending on which application you are installing. We plan to also automate this step in the future,
+see the [opened issue](https://gitlab.com/gitlab-org/gitlab/-/issues/326565).
+
## Prometheus cluster integration
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55244) in GitLab 13.11.
@@ -43,10 +54,8 @@ it up using [Helm](https://helm.sh/) as follows:
kubectl create ns gitlab-managed-apps
# Download Helm chart values that is compatible with the requirements above.
-# You should substitute the tag that corresponds to the GitLab version in the URL
-# - https://gitlab.com/gitlab-org/gitlab/-/raw/<tag>/vendor/prometheus/values.yaml
-#
-wget https://gitlab.com/gitlab-org/gitlab/-/raw/v13.9.0-ee/vendor/prometheus/values.yaml
+# These are included in the Cluster Management project template.
+wget https://gitlab.com/gitlab-org/project-templates/cluster-management/-/raw/master/applications/prometheus/values.yaml
# Add the Prometheus community Helm chart repository
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
@@ -103,10 +112,8 @@ running:
kubectl create namespace gitlab-managed-apps
# Download Helm chart values that is compatible with the requirements above.
-# You should substitute the tag that corresponds to the GitLab version in the URL
-# - https://gitlab.com/gitlab-org/gitlab/-/raw/<tag>/vendor/elastic_stack/values.yaml
-#
-wget https://gitlab.com/gitlab-org/gitlab/-/raw/v13.9.0-ee/vendor/elastic_stack/values.yaml
+# These are included in the Cluster Management project template.
+wget https://gitlab.com/gitlab-org/project-templates/cluster-management/-/raw/master/applications/elastic-stack/values.yaml
# Add the GitLab Helm chart repository
helm repo add gitlab https://charts.gitlab.io
diff --git a/doc/user/clusters/management_project.md b/doc/user/clusters/management_project.md
index 0a24bca67a5..eca9721796d 100644
--- a/doc/user/clusters/management_project.md
+++ b/doc/user/clusters/management_project.md
@@ -16,7 +16,7 @@ privileges.
This can be useful for:
-- Creating pipelines to install cluster-wide applications into your cluster, see [Install using GitLab CI/CD (beta)](applications.md#install-using-gitlab-cicd-deprecated) for details.
+- Creating pipelines to install cluster-wide applications into your cluster, see [management project template](management_project_template.md) for details.
- Any jobs that require `cluster-admin` privileges.
## Permissions
diff --git a/doc/user/clusters/management_project_template.md b/doc/user/clusters/management_project_template.md
new file mode 100644
index 00000000000..52390cb18b0
--- /dev/null
+++ b/doc/user/clusters/management_project_template.md
@@ -0,0 +1,86 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Cluster Management Project Template **(FREE)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25318) in GitLab 12.10 with Helmfile support via Helm v2.
+> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63577) in GitLab 14.0 with Helmfile support via Helm v3 instead, and a much more flexible usage of Helmfile. This introduces breaking changes that are detailed below.
+
+This [GitLab built-in project template](../project/working_with_projects.md#built-in-templates)
+provides a quicker start for users interested in managing cluster
+applications via [Helm v3](https://helm.sh/) charts. More specifically, taking advantage of the
+[Helmfile](https://github.com/roboll/helmfile) utility client. The template consists of some pre-configured apps that
+should help you get started quickly using various GitLab features. Still, you have all the flexibility to remove the ones you do not
+need, or even add new ones that are not built-in.
+
+## How to use this template
+
+1. Create a new project, choosing "GitLab Cluster Management" from the list of [built-in project templates](../project/working_with_projects.md#built-in-templates).
+1. Make this project a [cluster management project](management_project.md).
+1. If you used the [GitLab Managed Apps](applications.md), refer to
+ [Migrating from GitLab Manged Apps](migrating_from_gma_to_project_template.md).
+
+### Components
+
+In the repository of the newly-created project, you will find:
+
+- A predefined [`.gitlab-ci.yml`](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/blob/master/.gitlab-ci.yml)
+ file, with a CI pipeline already configured.
+- A main [`helmfile.yaml`](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/blob/master/helmfile.yaml) to toggle which applications you would like to manage.
+- An `applications` directory with a `helmfile.yaml` configured for each application GitLab provides.
+
+#### The `.gitlab-ci.yml` file
+
+The base image used in your pipeline is built by the [cluster-applications](https://gitlab.com/gitlab-org/cluster-integration/cluster-applications)
+project. This image consists of a set of Bash utility scripts to support [Helm v3 releases](https://helm.sh/docs/intro/using_helm/#three-big-concepts):
+
+- `gl-fail-if-helm2-releases-exist {namespace}`: It tries to detect whether you have apps deployed through Helm v2
+ releases for a given namespace. If so, it will fail the pipeline and ask you to manually
+ [migrate your Helm v2 releases to Helm v3](https://helm.sh/docs/topics/v2_v3_migration/).
+- `gl-ensure-namespace {namespace}`: It creates the given namespace if it does not exist and adds the necessary label
+ for the [Cilium](https://github.com/cilium/cilium/) app network policies to work.
+- `gl-adopt-resource-with-helm-v3 {arguments}`: Used only internally in the [cert-manager's](https://cert-manager.io/) Helmfile to
+ facilitate the GitLab Managed Apps adoption.
+- `gl-adopt-crds-with-helm-v3 {arguments}`: Used only internally in the [cert-manager's](https://cert-manager.io/) Helmfile to
+ facilitate the GitLab Managed Apps adoption.
+- `gl-helmfile {arguments}`: A thin wrapper that triggers the [Helmfile](https://github.com/roboll/helmfile) command.
+
+#### The main `helmfile.yml` file
+
+This file has a list of paths to other Helmfiles for each app. They're all commented out by default, so you must uncomment
+the paths for the apps that you would like to manage.
+
+By default, each `helmfile.yaml` in these sub-paths will have the attribute `installed: true`, which signifies that everytime
+the pipeline runs, Helmfile will try to either install or update your apps according to the current state of your
+cluster and Helm releases. If you change this attribute to `installed: false`, Helmfile will try to uninstall this app
+from your cluster. [Read more](https://github.com/roboll/helmfile) about how Helmfile works.
+
+Furthermore, each app has an `applications/{app}/values.yaml` file. This is the
+place where you can define some default values for your app's Helm chart. Some apps will already have defaults
+pre-defined by GitLab.
+
+#### Built-in applications
+
+The built-in applications are intended to provide an easy way to get started with various Kubernetes oriented GitLab features.
+
+The [built-in supported applications](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/tree/master/applications) are:
+
+- Apparmor
+- Cert-manager
+- Cilium
+- Elastic Stack
+- Falco
+- Fluentd
+- GitLab Runner
+- Ingress
+- Prometheus
+- Sentry
+- Vault
+
+### Migrating from GitLab Managed Apps
+
+If you had GitLab Managed Apps, either One-Click or CI/CD install, read the docs on how to
+[migrate from GitLab Managed Apps to project template](migrating_from_gma_to_project_template.md)
diff --git a/doc/user/clusters/migrating_from_gma_to_project_template.md b/doc/user/clusters/migrating_from_gma_to_project_template.md
new file mode 100644
index 00000000000..7fa6ccea433
--- /dev/null
+++ b/doc/user/clusters/migrating_from_gma_to_project_template.md
@@ -0,0 +1,95 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Migrating from GitLab Managed Apps to a management project template
+
+The [GitLab Managed Apps](applications.md) are deprecated in GitLab 14.0. To migrate to the new way of managing them:
+
+1. Read how the [management project template](management_project_template.md) works, and
+ create a new project based on the "GitLab Cluster Management" template.
+1. Create a new project as explained in the [management project template](management_project_template.md).
+1. Detect apps deployed through Helm v2 releases by using the pre-configured [`.gitlab-ci.yml`](management_project_template.md#the-gitlab-ciyml-file) file:
+ - In case you had overwritten the default GitLab Managed Apps namespace, edit `.gitlab-ci.yml`,
+ and make sure the script is receiving the correct namespace as an argument:
+
+ ```yaml
+ script:
+ - gl-fail-if-helm2-releases-exist <your_custom_namespace>
+ ```
+
+ - If you kept the default name (`gitlab-managed-apps`), then the script is already
+ set up.
+
+ Either way, [run a pipeline manually](../../ci/pipelines/index.md#run-a-pipeline-manually) and read the logs of the
+ `detect-helm2-releases` job to know if you have any Helm v2 releases and which are they.
+
+1. If you have no Helm v2 releases, skip this step. Otherwise, follow the official Helm docs on
+ [how to migrate from Helm v2 to Helm v3](https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/),
+ and clean up the Helm v2 releases after you are confident that they have been successfully migrated.
+
+1. In this step you should already have only Helm v3 releases.
+ Uncomment from the main [`./helmfile.yaml`](management_project_template.md#the-main-helmfileyml-file) the paths for the
+ applications that you would like to manage with this project. Although you could uncomment all the ones you want to
+ managed at once, we recommend you repeat the following steps separately for each app, so you do not get lost during
+ the process.
+1. Edit the associated `applications/{app}/helmfiles.yaml` to match the chart version currently deployed
+ for your app. Take a GitLab Runner Helm v3 release as an example:
+
+ The following command lists the releases and their versions:
+
+ ```shell
+ helm ls -n gitlab-managed-apps
+
+ NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
+ runner gitlab-managed-apps 1 2021-06-09 19:36:55.739141644 +0000 UTC deployed gitlab-runner-0.28.0 13.11.0
+ ```
+
+ Take the version from the `CHART` column which is in the format `{release}-v{chart_version}`,
+ then edit the `version:` attribute in the `./applications/gitlab-runner/helmfile.yaml`, so that it matches the version
+ you have currently deployed. This is a safe step to avoid upgrading versions during this migration.
+ Make sure you replace `gitlab-managed-apps` from the above command if you have your apps deployed to a different
+ namespace.
+
+1. Edit the `applications/{app}/values.yaml` associated with your app to match the currently
+ deployed values. For example, for GitLab Runner:
+
+ 1. Copy the output of the following command (it might be big):
+
+ ```shell
+ helm get values runner -n gitlab-managed-apps -a --output yaml
+ ```
+
+ 1. Overwrite `applications/gitlab-runner/values.yaml` with the output of the previous command.
+
+ This safe step will guarantee that no unexpected default values overwrite your currently deployed values.
+ For instance, your GitLab Runner could have its `gitlabUrl` or `runnerRegistrationToken` overwritten by mistake.
+
+1. Some apps require special attention:
+
+ - Ingress: Due to an existing [chart issue](https://github.com/helm/charts/pull/13646), you might see
+ `spec.clusterIP: Invalid value` when trying to run the [`./gl-helmfile`](management_project_template.md#the-gitlab-ciyml-file)
+ command. To work around this, after overwriting the release values in `applications/ingress/values.yaml`,
+ you might need to overwrite all the occurrences of `omitClusterIP: false`, setting it to `omitClusterIP: true`.
+ Another approach,could be to collect these IPs by running `kubectl get services -n gitlab-managed-apps`
+ and then overwriting each `ClusterIP` that it complains about with the value you got from that command.
+
+ - Vault: This application introduces a breaking change from the chart we used in Helm v2 to the chart
+ used in Helm v3. So, the only way to integrate it with this Cluster Management Project is to actually uninstall this app and accept the
+ chart version proposed in `applications/vault/values.yaml`.
+
+1. After following all the previous steps, [run a pipeline manually](../../ci/pipelines/index.md#run-a-pipeline-manually)
+ and watch the `apply` job logs to see if any of your applications were successfully detected, installed, and whether they got any
+ unexpected updates.
+
+ Some annotation checksums are expected to be updated, as well as this attribute:
+
+ ```diff
+ --- heritage: Tiller
+ +++ heritage: Tiller
+ ```
+
+After getting a successful pipeline, repeat these steps for any other deployed apps
+you want to manage with the Cluster Management Project.
diff --git a/doc/user/project/clusters/kubernetes_pod_logs.md b/doc/user/project/clusters/kubernetes_pod_logs.md
index 0ad32adffb1..b14412eb1d6 100644
--- a/doc/user/project/clusters/kubernetes_pod_logs.md
+++ b/doc/user/project/clusters/kubernetes_pod_logs.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4752) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.0.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26383) to [GitLab Free](https://about.gitlab.com/pricing/) 12.9.
-GitLab makes it easy to view the logs of running pods or managed applications in
+GitLab makes it easy to view the logs of running pods in
[connected Kubernetes clusters](index.md). By displaying the logs directly in GitLab
in the **Log Explorer**, developers can avoid managing console tools or jumping
to a different interface. The **Log Explorer** interface provides a set of filters
@@ -18,10 +18,11 @@ above the log file data, depending on your configuration:
![Pod logs](img/kubernetes_pod_logs_v12_10.png)
- **Namespace** - Select the environment to display. Users with Maintainer or
- greater [permissions](../../permissions.md) can also select Managed Apps.
-- **Search** - Only available if the Elastic Stack managed application is installed.
-- **Select time range** - Select the range of time to display. Only available if the
- Elastic Stack managed application is installed.
+ greater [permissions](../../permissions.md) can also see pods in the
+ `gitlab-managed-apps` namespace.
+- **Search** - Only available if the [Elastic Stack integration](../../clusters/integrations.md#elastic-stack-cluster-integration) is enabled.
+- **Select time range** - Select the range of time to display.
+ Only available if the [Elastic Stack integration](../../clusters/integrations.md#elastic-stack-cluster-integration) is enabled.
- **Scroll to bottom** **{scroll_down}** - Scroll to the end of the displayed logs.
- **Refresh** **{retry}** - Reload the displayed logs.
diff --git a/doc/user/project/clusters/protect/container_host_security/quick_start_guide.md b/doc/user/project/clusters/protect/container_host_security/quick_start_guide.md
index b999ae5b933..ebcd56078ae 100644
--- a/doc/user/project/clusters/protect/container_host_security/quick_start_guide.md
+++ b/doc/user/project/clusters/protect/container_host_security/quick_start_guide.md
@@ -20,7 +20,6 @@ The following steps are recommended to install and use Container Host Security t
1. Install and configure an Ingress node:
- [Install the Ingress node via CI/CD (Cluster Management Project)](../../../../clusters/applications.md#install-ingress-using-gitlab-cicd).
- - [Determine the external endpoint via the manual method](../../../../clusters/applications.md#determining-the-external-endpoint-manually).
- Navigate to the Kubernetes page and enter the [DNS address for the external endpoint](../../index.md#base-domain)
into the **Base domain** field on the **Details** tab. Save the changes to the Kubernetes
cluster.
diff --git a/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md b/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
index 3acb44c61ac..33aefec224a 100644
--- a/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
+++ b/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
@@ -20,7 +20,6 @@ The following steps are recommended to install and use Container Network Securit
1. Install and configure an Ingress node:
- [Install the Ingress node via CI/CD (Cluster Management Project)](../../../../clusters/applications.md#install-ingress-using-gitlab-cicd).
- - [Determine the external endpoint via the manual method](../../../../clusters/applications.md#determining-the-external-endpoint-manually).
- Navigate to the Kubernetes page and enter the [DNS address for the external endpoint](../../index.md#base-domain)
into the **Base domain** field on the **Details** tab. Save the changes to the Kubernetes
cluster.
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index 2b4c6c6ca87..adc98151ce4 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -17,7 +17,7 @@ in the GitLab interface.
There are two ways to set up Prometheus integration, depending on where your apps are running:
-- For deployments on Kubernetes, GitLab can automatically [deploy and manage Prometheus](#managed-prometheus-on-kubernetes).
+- For deployments on Kubernetes, GitLab can be [integrated with an in-cluster Prometheus](#prometheus-cluster-integration)
- For other deployment targets, [specify the Prometheus server](#manual-configuration-of-prometheus).
Once enabled, GitLab detects metrics from known services in the
@@ -27,137 +27,13 @@ Once enabled, GitLab detects metrics from known services in the
## Enabling Prometheus Integration
-### Managed Prometheus on Kubernetes
+### Prometheus cluster integration
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/28916) in GitLab 10.5.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55244) in GitLab 13.11.
+> - [Replaced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62725) the Prometheus cluster applications in GitLab 14.0.
-**Deprecated:** Managed Prometheus on Kubernetes is deprecated, and
-scheduled for removal in [GitLab
-14.0](https://gitlab.com/groups/gitlab-org/-/epics/4280).
-
-GitLab can seamlessly deploy and manage Prometheus on a
-[connected Kubernetes cluster](../clusters/index.md), to help you monitor your apps.
-
-#### Requirements
-
-- A [connected Kubernetes cluster](../clusters/index.md)
-
-#### Getting started
-
-After you have a connected Kubernetes cluster, you can deploy a managed Prometheus with a single click.
-
-1. Go to the **Operations > Kubernetes** page to view your connected clusters
-1. Select the cluster you would like to deploy Prometheus to
-1. Click the **Install** button to deploy Prometheus to the cluster
-
-![Managed Prometheus Deploy](img/prometheus_deploy.png)
-
-#### About managed Prometheus deployments
-
-Prometheus is deployed into the `gitlab-managed-apps` namespace, using the
-[official Helm chart](https://github.com/helm/charts/tree/master/stable/prometheus).
-Prometheus is only accessible in the cluster, with GitLab communicating through the
-[Kubernetes API](https://kubernetes.io/docs/concepts/overview/kubernetes-api/).
-
-The Prometheus server
-[automatically detects and monitors](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config)
-nodes, pods, and endpoints. To configure a resource to be monitored by Prometheus,
-set the following [Kubernetes annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/):
-
-- `prometheus.io/scrape` to `true` to enable monitoring of the resource.
-- `prometheus.io/port` to define the port of the metrics endpoint.
-- `prometheus.io/path` to define the path of the metrics endpoint. Defaults to `/metrics`.
-
-CPU and Memory consumption is monitored, but requires
-[naming conventions](prometheus_library/kubernetes.md#specifying-the-environment)
-to determine the environment. If you are using
-[Auto DevOps](../../../topics/autodevops/index.md), this is handled automatically.
-
-##### Example of Kubernetes service annotations and labels
-
-As an example, to activate Prometheus monitoring of a service:
-
-1. Add at least this annotation: `prometheus.io/scrape: 'true'`.
-1. Add two labels so GitLab can retrieve metrics dynamically for any environment:
- - `application: ${CI_ENVIRONMENT_SLUG}`
- - `release: ${CI_ENVIRONMENT_SLUG}`
-1. Create a dynamic PromQL query. For example, a query like
- `temperature{application="{{ci_environment_slug}}",release="{{ci_environment_slug}}"}` to either:
- - Add [custom metrics](../../../operations/metrics/index.md#adding-custom-metrics).
- - Add [custom dashboards](../../../operations/metrics/dashboards/index.md).
-
-The following is a service definition to accomplish this:
-
-```yaml
----
-# Service
-apiVersion: v1
-kind: Service
-metadata:
- name: service-${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}
- # === Prometheus annotations ===
- annotations:
- prometheus.io/scrape: 'true'
- labels:
- application: ${CI_ENVIRONMENT_SLUG}
- release: ${CI_ENVIRONMENT_SLUG}
- # === End of Prometheus ===
-spec:
- selector:
- app: ${CI_PROJECT_NAME}
- ports:
- - port: ${EXPOSED_PORT}
- targetPort: ${CONTAINER_PORT}
-```
-
-#### Access the UI of a Prometheus managed application in Kubernetes
-
-You can connect directly to Prometheus, and view the Prometheus user interface, when
-using a Prometheus managed application in Kubernetes:
-
-1. Find the name of the Prometheus pod in the user interface of your Kubernetes
- provider, such as GKE, or by running the following `kubectl` command in your
- terminal:
-
- ```shell
- kubectl get pods -n gitlab-managed-apps | grep 'prometheus-prometheus-server'
- ```
-
- The command should return a result like the following example, where
- `prometheus-prometheus-server-55b4bd64c9-dpc6b` is the name of the Prometheus pod:
-
- ```plaintext
- gitlab-managed-apps prometheus-prometheus-server-55b4bd64c9-dpc6b 2/2 Running 0 71d
- ```
-
-1. Run a `kubectl port-forward` command. In the following example, `9090` is the
- Prometheus server's listening port:
-
- ```shell
- kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 9090:9090 -n gitlab-managed-apps
- ```
-
- The `port-forward` command forwards all requests sent to your system's `9090` port
- to the `9090` port of the Prometheus pod. If the `9090` port on your system is used
- by another application, you can change the port number before the colon to your
- desired port. For example, to forward port `8080` of your local system, change the
- command to:
-
- ```shell
- kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 8080:9090 -n gitlab-managed-apps
- ```
-
-1. Open `localhost:9090` in your browser to display the Prometheus user interface.
-
-#### Script access to Prometheus
-
-You can script the access to Prometheus, extracting the name of the pod automatically like this:
-
-```shell
-POD_INFORMATION=$(kubectl get pods -n gitlab-managed-apps | grep 'prometheus-prometheus-server')
-POD_NAME=$(echo $POD_INFORMATION | awk '{print $1;}')
-kubectl port-forward $POD_NAME 9090:9090 -n gitlab-managed-apps
-```
+GitLab can query an in-cluster Prometheus for your metrics.
+See [Prometheus cluster integration](../../clusters/integrations.md#prometheus-cluster-integration) for details.
### Manual configuration of Prometheus
@@ -219,12 +95,12 @@ to integrate with.
### Precedence with multiple Prometheus configurations
Although you can enable both a [manual configuration](#manual-configuration-of-prometheus)
-and [auto configuration](#managed-prometheus-on-kubernetes) of Prometheus, you
+and [cluster integration](#prometheus-cluster-integration) of Prometheus, you
can use only one:
- If you have enabled a
[Prometheus manual configuration](#manual-configuration-of-prometheus)
- and a [managed Prometheus on Kubernetes](#managed-prometheus-on-kubernetes),
+ and a [Prometheus cluster integration](#prometheus-cluster-integration),
the manual configuration takes precedence and is used to run queries from
[custom dashboards](../../../operations/metrics/dashboards/index.md) and
[custom metrics](../../../operations/metrics/index.md#adding-custom-metrics).
diff --git a/doc/user/project/integrations/prometheus_library/kubernetes.md b/doc/user/project/integrations/prometheus_library/kubernetes.md
index e14c1c0f6fd..1bafa4938af 100644
--- a/doc/user/project/integrations/prometheus_library/kubernetes.md
+++ b/doc/user/project/integrations/prometheus_library/kubernetes.md
@@ -33,7 +33,7 @@ integration services must be enabled.
Prometheus needs to be deployed into the cluster and configured properly in order to gather Kubernetes metrics. GitLab supports two methods for doing so:
-- GitLab [integrates with Kubernetes](../../clusters/index.md), and can [deploy Prometheus into a connected cluster](../prometheus.md#managed-prometheus-on-kubernetes). It is automatically configured to collect Kubernetes metrics.
+- GitLab [integrates with Kubernetes](../../clusters/index.md), and can [query a Prometheus in a connected cluster](../../../clusters/integrations.md#prometheus-cluster-integration). The in-cluster Prometheus can be configured to automatically collect application metrics from your cluster.
- To configure your own Prometheus server, you can follow the [Prometheus documentation](https://prometheus.io/docs/introduction/overview/).
## Specifying the Environment
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 18c548d1400..2967ca71c83 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -6901,13 +6901,13 @@ msgstr ""
msgid "ClusterAgent|You have insufficient permissions to delete this cluster agent"
msgstr ""
-msgid "ClusterIntegration|%{appList} was successfully installed on your Kubernetes cluster"
+msgid "ClusterApplicationsRemoved|One-click application management was removed in GitLab 14.0. Your applications are still installed in your cluster, and integrations continue working."
msgstr ""
-msgid "ClusterIntegration|%{boldStart}Note:%{boldEnd} Requires Ingress to be installed."
+msgid "ClusterIntegration|%{appList} was successfully installed on your Kubernetes cluster"
msgstr ""
-msgid "ClusterIntegration|%{externalIp}.nip.io"
+msgid "ClusterIntegration|%{boldStart}Note:%{boldEnd} Requires Ingress to be installed."
msgstr ""
msgid "ClusterIntegration|%{linkStart}More information%{linkEnd}"
@@ -6973,9 +6973,6 @@ msgstr ""
msgid "ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics."
msgstr ""
-msgid "ClusterIntegration|Alternatively, "
-msgstr ""
-
msgid "ClusterIntegration|Amazon EKS"
msgstr ""
@@ -7861,9 +7858,6 @@ msgstr ""
msgid "ClusterIntegration|access to Google Kubernetes Engine"
msgstr ""
-msgid "ClusterIntegration|can be used instead of a custom domain. "
-msgstr ""
-
msgid "ClusterIntegration|installed via %{linkStart}Cloud Run%{linkEnd}"
msgstr ""
@@ -25487,9 +25481,6 @@ msgstr ""
msgid "Project path"
msgstr ""
-msgid "Project scanning help page"
-msgstr ""
-
msgid "Project security status"
msgstr ""
@@ -34818,21 +34809,6 @@ msgstr ""
msgid "UnscannedProjects|60 or more days"
msgstr ""
-msgid "UnscannedProjects|Default branch scanning by project"
-msgstr ""
-
-msgid "UnscannedProjects|Out of date"
-msgstr ""
-
-msgid "UnscannedProjects|Project scanning"
-msgstr ""
-
-msgid "UnscannedProjects|Untested"
-msgstr ""
-
-msgid "UnscannedProjects|Your projects are up do date! Nice job!"
-msgstr ""
-
msgid "Unschedule job"
msgstr ""
@@ -38000,6 +37976,9 @@ msgstr ""
msgid "can't be enabled because signed commits are required for this project"
msgstr ""
+msgid "can't be the same as the source project"
+msgstr ""
+
msgid "can't include: %{invalid_storages}"
msgstr ""
diff --git a/package.json b/package.json
index d5de6a60924..e251ac6122d 100644
--- a/package.json
+++ b/package.json
@@ -110,7 +110,6 @@
"css-loader": "^2.1.1",
"d3": "^5.16.0",
"d3-sankey": "^0.12.3",
- "d3-scale": "^2.2.2",
"d3-selection": "^1.2.0",
"dateformat": "^4.5.1",
"deckar01-task_list": "^2.3.1",
diff --git a/spec/factories/ci/job_token/project_scope_links.rb b/spec/factories/ci/job_token/project_scope_links.rb
new file mode 100644
index 00000000000..a11edd87e4e
--- /dev/null
+++ b/spec/factories/ci/job_token/project_scope_links.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_job_token_project_scope_link, class: 'Ci::JobToken::ProjectScopeLink' do
+ association :source_project, factory: :project
+ association :target_project, factory: :project
+ association :added_by, factory: :user
+ end
+end
diff --git a/spec/factories_spec.rb b/spec/factories_spec.rb
index 994bf066cf0..80e94fa1628 100644
--- a/spec/factories_spec.rb
+++ b/spec/factories_spec.rb
@@ -66,6 +66,7 @@ RSpec.describe 'factories' do
# associations must be unique and cannot be reused, or the factory default
# is being mutated.
skip_factory_defaults = %i[
+ ci_job_token_project_scope_link
evidence
exported_protected_branch
fork_network_member
diff --git a/spec/features/admin/clusters/applications_spec.rb b/spec/features/admin/clusters/applications_spec.rb
deleted file mode 100644
index e083e4fee4c..00000000000
--- a/spec/features/admin/clusters/applications_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Instance-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:user) { create(:admin) }
-
- before do
- sign_in(user)
- gitlab_enable_admin_mode_sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { admin_cluster_path(cluster) }
- let(:cluster_factory_args) { [:instance] }
- end
- end
-end
diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb
index 1281d890ef7..21da92c9f43 100644
--- a/spec/features/calendar_spec.rb
+++ b/spec/features/calendar_spec.rb
@@ -15,10 +15,9 @@ RSpec.describe 'Contributions Calendar', :js do
issue_title = 'Bug in old browser'
issue_params = { title: issue_title }
- def get_cell_color_selector(contributions)
- activity_colors = ["#ededed", "rgb(172, 213, 242)", "rgb(127, 168, 201)", "rgb(82, 123, 160)", "rgb(37, 78, 119)"]
+ def get_cell_level_selector(contributions)
# We currently don't actually test the cases with contributions >= 20
- activity_colors_index =
+ activity_level_index =
if contributions > 0 && contributions < 10
1
elsif contributions >= 10 && contributions < 20
@@ -31,7 +30,7 @@ RSpec.describe 'Contributions Calendar', :js do
0
end
- ".user-contrib-cell[fill='#{activity_colors[activity_colors_index]}']"
+ ".user-contrib-cell:not(.contrib-legend)[data-level='#{activity_level_index}']"
end
def get_cell_date_selector(contributions, date)
@@ -42,7 +41,7 @@ RSpec.describe 'Contributions Calendar', :js do
"#{contributions} #{'contribution'.pluralize(contributions)}"
end
- "#{get_cell_color_selector(contributions)}[title='#{contribution_text}<br /><span class=\"gl-text-gray-300\">#{date}</span>']"
+ "#{get_cell_level_selector(contributions)}[title='#{contribution_text}<br /><span class=\"gl-text-gray-300\">#{date}</span>']"
end
def push_code_contribution
@@ -137,7 +136,7 @@ RSpec.describe 'Contributions Calendar', :js do
include_context 'visit user page'
it 'displays calendar activity square for 1 contribution', :sidekiq_might_not_need_inline do
- expect(find('#js-overview')).to have_selector(get_cell_color_selector(contribution_count), count: 1)
+ expect(find('#js-overview')).to have_selector(get_cell_level_selector(contribution_count), count: 1)
today = Date.today.strftime(date_format)
expect(find('#js-overview')).to have_selector(get_cell_date_selector(contribution_count, today), count: 1)
@@ -187,7 +186,7 @@ RSpec.describe 'Contributions Calendar', :js do
include_context 'visit user page'
it 'displays calendar activity squares for both days', :sidekiq_might_not_need_inline do
- expect(find('#js-overview')).to have_selector(get_cell_color_selector(1), count: 2)
+ expect(find('#js-overview')).to have_selector(get_cell_level_selector(1), count: 2)
end
it 'displays calendar activity square for yesterday', :sidekiq_might_not_need_inline do
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index 84a18a45d35..cba8aaef1ef 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -31,30 +31,6 @@ RSpec.describe 'Clusterable > Show page' do
expect(page).to have_content('Kubernetes cluster was successfully updated.')
end
- context 'when there is a cluster with ingress and external ip', :js do
- before do
- cluster.create_application_ingress!(external_ip: '192.168.1.100')
-
- visit cluster_path
- end
-
- it 'shows help text with the domain as an alternative to custom domain', :js do
- within '.js-cluster-details-form' do
- expect(find(cluster_ingress_help_text_selector).text).to include('192.168.1.100')
- end
- end
- end
-
- context 'when there is no ingress' do
- it 'alternative to custom domain is not shown' do
- visit cluster_path
-
- within '.js-cluster-details-form' do
- expect(page).not_to have_selector(cluster_ingress_help_text_selector)
- end
- end
- end
-
it 'does not show the environments tab' do
visit cluster_path
diff --git a/spec/features/clusters/cluster_health_dashboard_spec.rb b/spec/features/clusters/cluster_health_dashboard_spec.rb
index 0e2739a45b1..20c07f4d6ac 100644
--- a/spec/features/clusters/cluster_health_dashboard_spec.rb
+++ b/spec/features/clusters/cluster_health_dashboard_spec.rb
@@ -27,8 +27,8 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
expect(page).to have_css('.cluster-health-graphs')
end
- context 'no prometheus enabled' do
- it 'shows install prometheus message' do
+ context 'no prometheus available' do
+ it 'shows enable Prometheus message' do
visit cluster_path
click_link 'Health'
@@ -82,12 +82,12 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
def stub_empty_response
stub_prometheus_request(/prometheus-prometheus-server/, status: 204, body: {})
- stub_prometheus_request(/prometheus\/api\/v1/, status: 204, body: {})
+ stub_prometheus_request(%r{prometheus/api/v1}, status: 204, body: {})
end
def stub_connected
stub_prometheus_request(/prometheus-prometheus-server/, body: prometheus_values_body)
- stub_prometheus_request(/prometheus\/api\/v1/, body: prometheus_values_body)
+ stub_prometheus_request(%r{prometheus/api/v1}, body: prometheus_values_body)
end
end
end
diff --git a/spec/features/clusters/installing_applications_shared_examples.rb b/spec/features/clusters/installing_applications_shared_examples.rb
deleted file mode 100644
index c422aa2be72..00000000000
--- a/spec/features/clusters/installing_applications_shared_examples.rb
+++ /dev/null
@@ -1,252 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples "installing applications for a cluster" do
- before do
- # Reduce interval from 10 seconds which is too long for an automated test
- stub_const("#{Clusters::ClustersController}::STATUS_POLLING_INTERVAL", 500)
-
- visit cluster_path
- end
-
- context 'when cluster is being created' do
- let(:cluster) { create(:cluster, :providing_by_gcp, *cluster_factory_args) }
-
- it 'user is unable to install applications' do
- expect(page).not_to have_text('Helm')
- expect(page).not_to have_text('Install')
- end
- end
-
- context 'when cluster is created' do
- let(:cluster) { create(:cluster, :provided_by_gcp, *cluster_factory_args) }
-
- before do
- page.within('.js-edit-cluster-form') do
- click_link 'Applications'
- end
- end
-
- it 'user can install applications' do
- wait_for_requests
-
- application_row = '.js-cluster-application-row-ingress'
-
- page.within(application_row) do
- expect(page).not_to have_css('.js-cluster-application-install-button[disabled]')
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Install')
- end
- end
-
- it 'does not show the Helm application' do
- expect(page).not_to have_selector(:css, '.js-cluster-application-row-helm')
- end
-
- context 'when user installs Knative' do
- context 'on an abac cluster' do
- let(:cluster) { create(:cluster, :provided_by_gcp, :rbac_disabled, *cluster_factory_args) }
-
- it 'shows info block and not be installable' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_css('.rbac-notice')
- expect(page.find(:css, '.js-cluster-application-install-button')['disabled']).to eq('true')
- end
- end
- end
-
- context 'on an rbac cluster' do
- let(:cluster) { create(:cluster, :provided_by_gcp, *cluster_factory_args) }
-
- it 'does not show callout block and be installable' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).not_to have_css('p', text: 'You must have an RBAC-enabled cluster', visible: :all)
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
- end
- end
-
- describe 'when user clicks install button' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
-
- page.find('.js-knative-domainname').set("domain.example.org")
-
- click_button 'Install'
-
- wait_for_requests
-
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_knative.make_installing!
- Clusters::Cluster.last.application_knative.make_installed!
- Clusters::Cluster.last.application_knative.update_attribute(:external_ip, '127.0.0.1')
- end
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_field('Knative Domain Name:', with: 'domain.example.org')
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Knative was successfully installed on your Kubernetes cluster')
- expect(page).to have_css('.js-knative-save-domain-button'), exact_text: 'Save changes'
- end
-
- it 'can then update the domain' do
- page.within('.js-cluster-application-row-knative') do
- expect(ClusterPatchAppWorker).to receive(:perform_async)
-
- expect(page).to have_field('Knative Domain Name:', with: 'domain.example.org')
-
- page.find('.js-knative-domainname').set("new.domain.example.org")
-
- click_button 'Save changes'
-
- wait_for_requests
-
- expect(page).to have_field('Knative Domain Name:', with: 'new.domain.example.org')
- end
- end
- end
- end
- end
-
- context 'when user installs Cert Manager' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-cert_manager') do
- click_button 'Install'
- wait_for_requests
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installing!
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installed!
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Cert-Manager was successfully installed on your Kubernetes cluster')
- end
-
- it 'installs with custom email' do
- custom_email = 'new_email@example.org'
-
- page.within('.js-cluster-application-row-cert_manager') do
- # Wait for the polling to finish
- wait_for_requests
-
- page.find('.js-email').set(custom_email)
- click_button 'Install'
- wait_for_requests
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installing!
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installed!
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
- end
- end
-
- context 'when user installs Elastic Stack' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-elastic_stack') do
- click_button 'Install'
- end
-
- wait_for_requests
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-elastic_stack') do
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_elastic_stack.make_installing!
-
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_elastic_stack.make_installed!
-
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Elastic Stack was successfully installed on your Kubernetes cluster')
- end
- end
-
- context 'when user installs Ingress' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-ingress') do
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
- page.find(:css, '.js-cluster-application-install-button').click
-
- wait_for_requests
- end
- end
-
- it 'shows the status transition' do
- page.within('.js-cluster-application-row-ingress') do
- # FE sends request and gets the response, then the buttons is "Installing"
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_ingress.make_installing!
-
- # FE starts polling and update the buttons to "Installing"
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installing')
-
- # The application becomes installed but we keep waiting for external IP address
- Clusters::Cluster.last.application_ingress.make_installed!
-
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installed')
- expect(page).to have_selector('.js-no-endpoint-message')
- expect(page).to have_selector('.js-ingress-ip-loading-icon')
-
- # We receive the external IP address and display
- Clusters::Cluster.last.application_ingress.update!(external_ip: '192.168.1.100')
-
- expect(page).not_to have_css('button', exact_text: 'Install', visible: :all)
- expect(page).not_to have_css('button', exact_text: 'Installing', visible: :all)
- expect(page).to have_css('.js-cluster-application-uninstall-button:not([disabled])', exact_text: 'Uninstall')
- expect(page).not_to have_css('p', text: 'The endpoint is in the process of being assigned', visible: :all)
- expect(page.find('.js-endpoint').value).to eq('192.168.1.100')
- end
-
- expect(page).to have_content('Ingress was successfully installed on your Kubernetes cluster')
- end
- end
- end
-end
-
-RSpec.shared_examples "installing applications on a cluster" do
- it_behaves_like "installing applications for a cluster", false
- it_behaves_like "installing applications for a cluster", true
-end
diff --git a/spec/features/groups/clusters/applications_spec.rb b/spec/features/groups/clusters/applications_spec.rb
deleted file mode 100644
index 324ef24efc4..00000000000
--- a/spec/features/groups/clusters/applications_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Group-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:group) { create(:group) }
- let(:user) { create(:user) }
-
- before do
- group.add_maintainer(user)
- sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { group_cluster_path(group, cluster) }
- let(:cluster_factory_args) { [:group, groups: [group]] }
- end
- end
-end
diff --git a/spec/features/projects/clusters/applications_spec.rb b/spec/features/projects/clusters/applications_spec.rb
deleted file mode 100644
index 74b477dd85d..00000000000
--- a/spec/features/projects/clusters/applications_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Project-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:project) { create(:project) }
- let(:user) { create(:user) }
-
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { project_cluster_path(project, cluster) }
- let(:cluster_factory_args) { [projects: [project]] }
- end
- end
-end
diff --git a/spec/finders/ci/auth_job_finder_spec.rb b/spec/finders/ci/auth_job_finder_spec.rb
index 6cd58f5cd01..78827c9ddee 100644
--- a/spec/finders/ci/auth_job_finder_spec.rb
+++ b/spec/finders/ci/auth_job_finder_spec.rb
@@ -2,7 +2,8 @@
require 'spec_helper'
RSpec.describe Ci::AuthJobFinder do
- let_it_be(:job, reload: true) { create(:ci_build, status: :running) }
+ let_it_be(:user, reload: true) { create(:user) }
+ let_it_be(:job, reload: true) { create(:ci_build, status: :running, user: user) }
let(:token) { job.token }
@@ -55,10 +56,31 @@ RSpec.describe Ci::AuthJobFinder do
describe '#execute' do
subject(:execute) { finder.execute }
- before do
- job.success!
+ context 'when job is not running' do
+ before do
+ job.success!
+ end
+
+ it { is_expected.to be_nil }
end
- it { is_expected.to be_nil }
+ context 'when job is running', :request_store do
+ it 'sets ci_job_token_scope on the job user', :aggregate_failures do
+ expect(subject).to eq(job)
+ expect(subject.user).to be_from_ci_job_token
+ expect(subject.user.ci_job_token_scope.source_project).to eq(job.project)
+ end
+
+ context 'when feature flag ci_scoped_job_token is disabled' do
+ before do
+ stub_feature_flags(ci_scoped_job_token: false)
+ end
+
+ it 'does not set ci_job_token_scope on the job user' do
+ expect(subject).to eq(job)
+ expect(subject.user).not_to be_from_ci_job_token
+ end
+ end
+ end
end
end
diff --git a/spec/frontend/clusters/forms/components/integration_form_spec.js b/spec/frontend/clusters/forms/components/integration_form_spec.js
index c5cec4c4fdb..b129baa2d83 100644
--- a/spec/frontend/clusters/forms/components/integration_form_spec.js
+++ b/spec/frontend/clusters/forms/components/integration_form_spec.js
@@ -15,7 +15,6 @@ describe('ClusterIntegrationForm', () => {
editable: true,
environmentScope: '*',
baseDomain: 'testDomain',
- applicationIngressExternalIp: null,
};
const createWrapper = (storeValues = defaultStoreValues) => {
@@ -72,18 +71,6 @@ describe('ClusterIntegrationForm', () => {
expect(findSubmitButton().exists()).toBe(false);
});
});
-
- it('does not render external IP block if applicationIngressExternalIp was not passed', () => {
- createWrapper({ ...defaultStoreValues });
-
- expect(wrapper.find('.js-ingress-domain-help-text').exists()).toBe(false);
- });
-
- it('renders external IP block if applicationIngressExternalIp was passed', () => {
- createWrapper({ ...defaultStoreValues, applicationIngressExternalIp: '127.0.0.1' });
-
- expect(wrapper.find('.js-ingress-domain-help-text').exists()).toBe(true);
- });
});
describe('reactivity', () => {
diff --git a/spec/frontend/pages/users/activity_calendar_spec.js b/spec/frontend/pages/users/activity_calendar_spec.js
new file mode 100644
index 00000000000..b33e92e14b2
--- /dev/null
+++ b/spec/frontend/pages/users/activity_calendar_spec.js
@@ -0,0 +1,16 @@
+import { getLevelFromContributions } from '~/pages/users/activity_calendar';
+
+describe('getLevelFromContributions', () => {
+ it.each([
+ [0, 0],
+ [1, 1],
+ [9, 1],
+ [10, 2],
+ [19, 2],
+ [20, 3],
+ [30, 4],
+ [99, 4],
+ ])('.getLevelFromContributions(%i, %i)', (count, expected) => {
+ expect(getLevelFromContributions(count)).toBe(expected);
+ });
+});
diff --git a/spec/lib/gitlab/auth/auth_finders_spec.rb b/spec/lib/gitlab/auth/auth_finders_spec.rb
index cddcaf09b74..7475ed2796f 100644
--- a/spec/lib/gitlab/auth/auth_finders_spec.rb
+++ b/spec/lib/gitlab/auth/auth_finders_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
shared_examples 'find user from job token' do |without_job_token_allowed|
- context 'when route is allowed to be authenticated' do
+ context 'when route is allowed to be authenticated', :request_store do
let(:route_authentication_setting) { { job_token_allowed: true } }
context 'for an invalid token' do
@@ -68,6 +68,8 @@ RSpec.describe Gitlab::Auth::AuthFinders do
it 'return user' do
expect(subject).to eq(user)
expect(@current_authenticated_job).to eq job
+ expect(subject).to be_from_ci_job_token
+ expect(subject.ci_job_token_scope.source_project).to eq(job.project)
end
end
@@ -81,7 +83,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
end
- context 'when route is not allowed to be authenticated' do
+ context 'when route is not allowed to be authenticated', :request_store do
let(:route_authentication_setting) { { job_token_allowed: false } }
context 'with a running job' do
@@ -96,6 +98,8 @@ RSpec.describe Gitlab::Auth::AuthFinders do
it 'returns the user' do
expect(subject).to eq(user)
expect(@current_authenticated_job).to eq job
+ expect(subject).to be_from_ci_job_token
+ expect(subject.ci_job_token_scope.source_project).to eq(job.project)
end
else
it 'returns nil' do
diff --git a/spec/models/ci/job_token/project_scope_link_spec.rb b/spec/models/ci/job_token/project_scope_link_spec.rb
new file mode 100644
index 00000000000..d18495b9312
--- /dev/null
+++ b/spec/models/ci/job_token/project_scope_link_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobToken::ProjectScopeLink do
+ it { is_expected.to belong_to(:source_project) }
+ it { is_expected.to belong_to(:target_project) }
+ it { is_expected.to belong_to(:added_by) }
+
+ let_it_be(:project) { create(:project) }
+
+ describe 'unique index' do
+ let!(:link) { create(:ci_job_token_project_scope_link) }
+
+ it 'raises an error' do
+ expect do
+ create(:ci_job_token_project_scope_link,
+ source_project: link.source_project,
+ target_project: link.target_project)
+ end.to raise_error(ActiveRecord::RecordNotUnique)
+ end
+ end
+
+ describe 'validations' do
+ it 'must have a source project', :aggregate_failures do
+ link = build(:ci_job_token_project_scope_link, source_project: nil)
+
+ expect(link).not_to be_valid
+ expect(link.errors[:source_project]).to contain_exactly("can't be blank")
+ end
+
+ it 'must have a target project', :aggregate_failures do
+ link = build(:ci_job_token_project_scope_link, target_project: nil)
+
+ expect(link).not_to be_valid
+ expect(link.errors[:target_project]).to contain_exactly("can't be blank")
+ end
+
+ it 'must have a target project different than source project', :aggregate_failures do
+ link = build(:ci_job_token_project_scope_link, target_project: project, source_project: project)
+
+ expect(link).not_to be_valid
+ expect(link.errors[:target_project]).to contain_exactly("can't be the same as the source project")
+ end
+ end
+
+ describe '.from_project' do
+ subject { described_class.from_project(project) }
+
+ let!(:source_link) { create(:ci_job_token_project_scope_link, source_project: project) }
+ let!(:target_link) { create(:ci_job_token_project_scope_link, target_project: project) }
+
+ it 'returns only the links having the given source project' do
+ expect(subject).to contain_exactly(source_link)
+ end
+ end
+
+ describe '.to_project' do
+ subject { described_class.to_project(project) }
+
+ let!(:source_link) { create(:ci_job_token_project_scope_link, source_project: project) }
+ let!(:target_link) { create(:ci_job_token_project_scope_link, target_project: project) }
+
+ it 'returns only the links having the given target project' do
+ expect(subject).to contain_exactly(target_link)
+ end
+ end
+end
diff --git a/spec/models/ci/job_token/scope_spec.rb b/spec/models/ci/job_token/scope_spec.rb
new file mode 100644
index 00000000000..2fbfbac64f8
--- /dev/null
+++ b/spec/models/ci/job_token/scope_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobToken::Scope do
+ let_it_be(:project) { create(:project) }
+
+ let(:scope) { described_class.new(project) }
+
+ describe '#all_projects' do
+ subject(:all_projects) { scope.all_projects }
+
+ context 'when no projects are added to the scope' do
+ it 'returns the project defining the scope' do
+ expect(all_projects).to contain_exactly(project)
+ end
+ end
+
+ context 'when other projects are added to the scope' do
+ let_it_be(:scoped_project) { create(:project) }
+ let_it_be(:unscoped_project) { create(:project) }
+
+ let!(:link_in_scope) { create(:ci_job_token_project_scope_link, source_project: project, target_project: scoped_project) }
+ let!(:link_out_of_scope) { create(:ci_job_token_project_scope_link, target_project: unscoped_project) }
+
+ it 'returns all projects that can be accessed from a given scope' do
+ expect(subject).to contain_exactly(project, scoped_project)
+ end
+ end
+ end
+
+ describe 'includes?' do
+ subject { scope.includes?(target_project) }
+
+ context 'when param is the project defining the scope' do
+ let(:target_project) { project }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when param is a project in scope' do
+ let(:target_link) { create(:ci_job_token_project_scope_link, source_project: project) }
+ let(:target_project) { target_link.target_project }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when param is a project in another scope' do
+ let(:scope_link) { create(:ci_job_token_project_scope_link) }
+ let(:target_project) { scope_link.target_project }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+end
diff --git a/spec/models/hooks/web_hook_log_archived_spec.rb b/spec/models/hooks/web_hook_log_archived_spec.rb
deleted file mode 100644
index ac726dbaf4f..00000000000
--- a/spec/models/hooks/web_hook_log_archived_spec.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe WebHookLogArchived do
- let(:source_table) { WebHookLog }
- let(:destination_table) { described_class }
-
- it 'has the same columns as the source table' do
- column_names_from_source_table = column_names(source_table)
- column_names_from_destination_table = column_names(destination_table)
-
- expect(column_names_from_destination_table).to match_array(column_names_from_source_table)
- end
-
- it 'has the same null constraints as the source table' do
- constraints_from_source_table = null_constraints(source_table)
- constraints_from_destination_table = null_constraints(destination_table)
-
- expect(constraints_from_destination_table.to_a).to match_array(constraints_from_source_table.to_a)
- end
-
- it 'inserts the same record as the one in the source table', :aggregate_failures do
- expect { create(:web_hook_log) }.to change { destination_table.count }.by(1)
-
- event_from_source_table = source_table.connection.select_one(
- "SELECT * FROM #{source_table.table_name} ORDER BY created_at desc LIMIT 1"
- )
- event_from_destination_table = destination_table.connection.select_one(
- "SELECT * FROM #{destination_table.table_name} ORDER BY created_at desc LIMIT 1"
- )
-
- expect(event_from_destination_table).to eq(event_from_source_table)
- end
-
- def column_names(table)
- table.connection.select_all(<<~SQL)
- SELECT c.column_name
- FROM information_schema.columns c
- WHERE c.table_name = '#{table.table_name}'
- SQL
- end
-
- def null_constraints(table)
- table.connection.select_all(<<~SQL)
- SELECT c.column_name, c.is_nullable
- FROM information_schema.columns c
- WHERE c.table_name = '#{table.table_name}'
- AND c.column_name != 'created_at'
- SQL
- end
-end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index d0abcfbd091..53d9bdb01a3 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -1385,4 +1385,53 @@ RSpec.describe ProjectPolicy do
end
end
end
+
+ describe 'when user is authenticated via CI_JOB_TOKEN', :request_store do
+ let(:current_user) { developer }
+ let(:job) { build_stubbed(:ci_build, project: scope_project, user: current_user) }
+
+ before do
+ current_user.set_ci_job_token_scope!(job)
+ end
+
+ context 'when accessing a private project' do
+ let(:project) { private_project }
+
+ context 'when the job token comes from the same project' do
+ let(:scope_project) { project }
+
+ it { is_expected.to be_allowed(:developer_access) }
+ end
+
+ context 'when the job token comes from another project' do
+ let(:scope_project) { create(:project, :private) }
+
+ before do
+ scope_project.add_developer(current_user)
+ end
+
+ it { is_expected.to be_disallowed(:guest_access) }
+ end
+ end
+
+ context 'when accessing a public project' do
+ let(:project) { public_project }
+
+ context 'when the job token comes from the same project' do
+ let(:scope_project) { project }
+
+ it { is_expected.to be_allowed(:developer_access) }
+ end
+
+ context 'when the job token comes from another project' do
+ let(:scope_project) { create(:project, :private) }
+
+ before do
+ scope_project.add_developer(current_user)
+ end
+
+ it { is_expected.to be_disallowed(:public_access) }
+ end
+ end
+ end
end
diff --git a/spec/requests/api/generic_packages_spec.rb b/spec/requests/api/generic_packages_spec.rb
index a5e40eec919..6886fff2282 100644
--- a/spec/requests/api/generic_packages_spec.rb
+++ b/spec/requests/api/generic_packages_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe API::GenericPackages do
let_it_be(:project_deploy_token_wo) { create(:project_deploy_token, deploy_token: deploy_token_wo, project: project) }
let(:user) { personal_access_token.user }
- let(:ci_build) { create(:ci_build, :running, user: user) }
+ let(:ci_build) { create(:ci_build, :running, user: user, project: project) }
def auth_header
return {} if user_role == :anonymous
diff --git a/spec/requests/api/go_proxy_spec.rb b/spec/requests/api/go_proxy_spec.rb
index e678b6cf1c8..0143340de11 100644
--- a/spec/requests/api/go_proxy_spec.rb
+++ b/spec/requests/api/go_proxy_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe API::GoProxy do
let_it_be(:base) { "#{Settings.build_gitlab_go_url}/#{project.full_path}" }
let_it_be(:oauth) { create :oauth_access_token, scopes: 'api', resource_owner: user }
- let_it_be(:job) { create :ci_build, user: user, status: :running }
+ let_it_be(:job) { create :ci_build, user: user, status: :running, project: project }
let_it_be(:pa_token) { create :personal_access_token, user: user }
let_it_be(:modules) do
diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb
index 2bb6d05f54b..d9f11b19e6e 100644
--- a/spec/requests/api/maven_packages_spec.rb
+++ b/spec/requests/api/maven_packages_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe API::MavenPackages do
let_it_be(:package_file) { package.package_files.with_file_name_like('%.xml').first }
let_it_be(:jar_file) { package.package_files.with_file_name_like('%.jar').first }
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
- let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
+ let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let_it_be(:deploy_token_for_group) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
diff --git a/spec/requests/api/npm_project_packages_spec.rb b/spec/requests/api/npm_project_packages_spec.rb
index 8230061546f..ab74da4bda4 100644
--- a/spec/requests/api/npm_project_packages_spec.rb
+++ b/spec/requests/api/npm_project_packages_spec.rb
@@ -78,7 +78,7 @@ RSpec.describe API::NpmProjectPackages do
context 'with a job token for a different user' do
let_it_be(:other_user) { create(:user) }
- let_it_be_with_reload(:other_job) { create(:ci_build, :running, user: other_user) }
+ let_it_be_with_reload(:other_job) { create(:ci_build, :running, user: other_user, project: project) }
let(:headers) { build_token_auth_header(other_job.token) }
diff --git a/spec/requests/api/nuget_project_packages_spec.rb b/spec/requests/api/nuget_project_packages_spec.rb
index 98458cb8dfa..572736cfc86 100644
--- a/spec/requests/api/nuget_project_packages_spec.rb
+++ b/spec/requests/api/nuget_project_packages_spec.rb
@@ -192,7 +192,7 @@ RSpec.describe API::NugetProjectPackages do
it_behaves_like 'deploy token for package uploads'
it_behaves_like 'job token for package uploads', authorize_endpoint: true do
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
end
it_behaves_like 'rejects nuget access with unknown target id'
@@ -260,7 +260,7 @@ RSpec.describe API::NugetProjectPackages do
it_behaves_like 'deploy token for package uploads'
it_behaves_like 'job token for package uploads' do
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
end
it_behaves_like 'rejects nuget access with unknown target id'
diff --git a/spec/requests/api/pypi_packages_spec.rb b/spec/requests/api/pypi_packages_spec.rb
index 552ef2b2120..86925e6a0ba 100644
--- a/spec/requests/api/pypi_packages_spec.rb
+++ b/spec/requests/api/pypi_packages_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe API::PypiPackages do
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let(:headers) { {} }
context 'simple API endpoint' do
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index dad3e34404b..81a4fcdbcac 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -775,7 +775,7 @@ RSpec.describe API::Releases do
end
context 'when using JOB-TOKEN auth' do
- let(:job) { create(:ci_build, user: maintainer) }
+ let(:job) { create(:ci_build, user: maintainer, project: project) }
let(:params) do
{
name: 'Another release',
diff --git a/spec/requests/api/rubygem_packages_spec.rb b/spec/requests/api/rubygem_packages_spec.rb
index 09b63139e54..7d863b55bbe 100644
--- a/spec/requests/api/rubygem_packages_spec.rb
+++ b/spec/requests/api/rubygem_packages_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe API::RubygemPackages do
let_it_be_with_reload(:project) { create(:project) }
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let_it_be(:headers) { {} }
diff --git a/spec/requests/api/terraform/modules/v1/packages_spec.rb b/spec/requests/api/terraform/modules/v1/packages_spec.rb
index 6803c09b8c2..b04f5ad9a94 100644
--- a/spec/requests/api/terraform/modules/v1/packages_spec.rb
+++ b/spec/requests/api/terraform/modules/v1/packages_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
let_it_be(:package) { create(:terraform_module_package, project: project) }
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
+ let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 279c65fc2f4..7cf46f6adc6 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -883,10 +883,10 @@ RSpec.describe 'Git HTTP requests' do
context 'when admin mode is enabled', :enable_admin_mode do
it_behaves_like 'can download code only'
- it 'downloads from other project get status 403' do
+ it 'downloads from other project get status 404' do
clone_get "#{other_project.full_path}.git", user: 'gitlab-ci-token', password: build.token
- expect(response).to have_gitlab_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb
index 0e3a0252638..fda8b2ecec6 100644
--- a/spec/requests/lfs_http_spec.rb
+++ b/spec/requests/lfs_http_spec.rb
@@ -569,7 +569,7 @@ RSpec.describe 'Git LFS API and storage' do
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
# I'm not sure what this tests that is different from the previous test
- it_behaves_like 'LFS http 403 response'
+ it_behaves_like 'LFS http 404 response'
end
end
@@ -1043,7 +1043,7 @@ RSpec.describe 'Git LFS API and storage' do
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
# I'm not sure what this tests that is different from the previous test
- it_behaves_like 'LFS http 403 response'
+ it_behaves_like 'LFS http 404 response'
end
end
diff --git a/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb b/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb
index ac53be1a1cb..c69a987c00d 100644
--- a/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb
+++ b/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb
@@ -8,11 +8,11 @@ RSpec.shared_context 'conan api setup' do
let_it_be(:personal_access_token) { create(:personal_access_token) }
let_it_be(:user) { personal_access_token.user }
let_it_be(:base_secret) { SecureRandom.base64(64) }
- let_it_be(:job) { create(:ci_build, :running, user: user) }
- let_it_be(:job_token) { job.token }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let(:project) { package.project }
+ let(:job) { create(:ci_build, :running, user: user, project: project) }
+ let(:job_token) { job.token }
let(:auth_token) { personal_access_token.token }
let(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
diff --git a/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb b/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
index 815108be447..c737091df48 100644
--- a/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
+++ b/spec/support/shared_contexts/requests/api/npm_packages_shared_context.rb
@@ -11,7 +11,7 @@ RSpec.shared_context 'npm api setup' do
let_it_be(:package, reload: true) { create(:npm_package, project: project, name: "@#{group.path}/scoped_package") }
let_it_be(:token) { create(:oauth_access_token, scopes: 'api', resource_owner: user) }
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
- let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
+ let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
diff --git a/yarn.lock b/yarn.lock
index 2100dad5b9a..f9a1e6161f8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4014,7 +4014,7 @@ d3-scale-chromatic@1:
d3-color "1"
d3-interpolate "1"
-d3-scale@2, d3-scale@^2.2.2:
+d3-scale@2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f"
integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==