Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-29 21:09:23 +00:00
parent 860efb35e2
commit ab593c8ded
61 changed files with 506 additions and 529 deletions

View File

@ -1,4 +1,3 @@
import $ from 'jquery';
import Vue from 'vue';
import { highCountTrim } from '~/lib/utils/text_utility';
import Tracking from '~/tracking';
@ -12,12 +11,18 @@ import Translate from '~/vue_shared/translate';
* @param {String} count
*/
export default function initTodoToggle() {
$(document).on('todo:toggle', (e, count) => {
const updatedCount = count || e?.detail?.count || 0;
const $todoPendingCount = $('.js-todos-count');
document.addEventListener('todo:toggle', (e) => {
const updatedCount = e.detail.count || 0;
const todoPendingCount = document.querySelector('.js-todos-count');
$todoPendingCount.text(highCountTrim(updatedCount));
$todoPendingCount.toggleClass('hidden', updatedCount === 0);
if (todoPendingCount) {
todoPendingCount.textContent = highCountTrim(updatedCount);
if (updatedCount === 0) {
todoPendingCount.classList.add('hidden');
} else {
todoPendingCount.classList.remove('hidden');
}
}
});
}
@ -85,7 +90,7 @@ function initStatusTriggers() {
function trackShowUserDropdownLink(trackEvent, elToTrack, el) {
const { trackLabel, trackProperty } = elToTrack.dataset;
$(el).on('shown.bs.dropdown', () => {
el.addEventListener('shown.bs.dropdown', () => {
Tracking.event(document.body.dataset.page, trackEvent, {
label: trackLabel,
property: trackProperty,

View File

@ -28,20 +28,32 @@ export default class Todos {
}
unbindEvents() {
$('.js-done-todo, .js-undo-todo, .js-add-todo').off('click', this.updateRowStateClickedWrapper);
$('.js-todos-mark-all', '.js-todos-undo-all').off('click', this.updateallStateClickedWrapper);
$('.todo').off('click', this.goToTodoUrl);
$('.todo').off('auxclick', this.goToTodoUrl);
document.querySelectorAll('.js-done-todo, .js-undo-todo, .js-add-todo').forEach((el) => {
el.removeEventListener('click', this.updateRowStateClickedWrapper);
});
document.querySelectorAll('.js-todos-mark-all, .js-todos-undo-all').forEach((el) => {
el.removeEventListener('click', this.updateallStateClickedWrapper);
});
document.querySelectorAll('.todo').forEach((el) => {
el.removeEventListener('click', this.goToTodoUrl);
el.removeEventListener('auxclick', this.goToTodoUrl);
});
}
bindEvents() {
this.updateRowStateClickedWrapper = this.updateRowStateClicked.bind(this);
this.updateAllStateClickedWrapper = this.updateAllStateClicked.bind(this);
$('.js-done-todo, .js-undo-todo, .js-add-todo').on('click', this.updateRowStateClickedWrapper);
$('.js-todos-mark-all, .js-todos-undo-all').on('click', this.updateAllStateClickedWrapper);
$('.todo').on('click', this.goToTodoUrl);
$('.todo').on('auxclick', this.goToTodoUrl);
document.querySelectorAll('.js-done-todo, .js-undo-todo, .js-add-todo').forEach((el) => {
el.addEventListener('click', this.updateRowStateClickedWrapper);
});
document.querySelectorAll('.js-todos-mark-all, .js-todos-undo-all').forEach((el) => {
el.addEventListener('click', this.updateAllStateClickedWrapper);
});
document.querySelectorAll('.todo').forEach((el) => {
el.addEventListener('click', this.goToTodoUrl);
el.addEventListener('auxclick', this.goToTodoUrl);
});
}
initFilters() {
@ -181,7 +193,13 @@ export default class Todos {
}
updateBadges(data) {
$(document).trigger('todo:toggle', data.count);
const event = new CustomEvent('todo:toggle', {
detail: {
count: data.count,
},
});
document.dispatchEvent(event);
document.querySelector('.js-todos-pending .js-todos-badge').innerHTML = addDelimiter(
data.count,
);

View File

@ -61,7 +61,7 @@ export default {
},
});
return document.dispatchEvent(headerTodoEvent);
document.dispatchEvent(headerTodoEvent);
},
addToDo() {
this.isUpdating = true;
@ -75,9 +75,10 @@ export default {
})
.then(({ data: { errors = [] } }) => {
if (errors[0]) {
return this.throwError(errors[0]);
this.throwError(errors[0]);
return;
}
return this.updateToDoCount(true);
this.updateToDoCount(true);
})
.catch(() => {
this.throwError();
@ -98,9 +99,10 @@ export default {
})
.then(({ data: { errors = [] } }) => {
if (errors[0]) {
return this.throwError(errors[0]);
this.throwError(errors[0]);
return;
}
return this.updateToDoCount(false);
this.updateToDoCount(false);
})
.catch(() => {
this.throwError();

View File

@ -12,7 +12,10 @@ class Admin::SystemInfoController < Admin::ApplicationController
EXCLUDED_MOUNT_TYPES = [
'autofs',
'binfmt_misc',
'bpf',
'cgroup',
'cgroup2',
'configfs',
'debugfs',
'devfs',
'devpts',

View File

@ -7,7 +7,8 @@ module Pages
'type' => 'object',
'properties' => {
'project_id' => { 'type' => 'integer' },
'namespace_id' => { 'type' => 'integer' }
'namespace_id' => { 'type' => 'integer' },
'root_namespace_id' => { 'type' => 'integer' }
},
'required' => %w[project_id namespace_id]
}

View File

@ -27,7 +27,7 @@ module StorageHelper
def storage_enforcement_banner_info(namespace)
root_ancestor = namespace.root_ancestor
return unless can?(current_user, :admin_namespace, root_ancestor)
return unless can?(current_user, :maintain_namespace, root_ancestor)
return if root_ancestor.paid?
return unless future_enforcement_date?(root_ancestor)
return if user_dismissed_storage_enforcement_banner?(root_ancestor)

View File

@ -327,11 +327,7 @@ module Ci
build.run_after_commit do
build.run_status_commit_hooks!
if Feature.enabled?(:ci_build_finished_worker_namespace_changed, build.project)
Ci::BuildFinishedWorker.perform_async(id)
else
::BuildFinishedWorker.perform_async(id)
end
Ci::BuildFinishedWorker.perform_async(id)
end
end

View File

@ -4,6 +4,9 @@ module Ci
class Trigger < Ci::ApplicationRecord
include Presentable
include Limitable
include IgnorableColumns
ignore_column :ref, remove_with: '15.4', remove_after: '2022-08-22'
self.limit_name = 'pipeline_triggers'
self.limit_scope = :project

View File

@ -179,6 +179,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :read_deploy_token
enable :create_jira_connect_subscription
enable :maintainer_access
enable :maintain_namespace
end
rule { owner }.policy do

View File

@ -57,13 +57,7 @@ class IssuePolicy < IssuablePolicy
enable :update_subscription
end
# admin can set metadata on new issues
rule { ~persisted & admin }.policy do
enable :set_issue_metadata
end
# support bot needs to be able to set metadata on new issues when service desk is enabled
rule { ~persisted & support_bot & can?(:guest_access) }.policy do
rule { can?(:admin_issue) }.policy do
enable :set_issue_metadata
end
@ -72,10 +66,6 @@ class IssuePolicy < IssuablePolicy
enable :set_issue_metadata
end
rule { persisted & can?(:admin_issue) }.policy do
enable :set_issue_metadata
end
rule { can?(:set_issue_metadata) }.policy do
enable :set_confidentiality
end

View File

@ -11,6 +11,7 @@ module Namespaces
enable :owner_access
enable :create_projects
enable :admin_namespace
enable :maintain_namespace
enable :read_namespace
enable :read_statistics
enable :create_jira_connect_subscription

View File

@ -52,16 +52,6 @@ module Clusters
end
end
def gitlab_managed_apps_logs_path
return unless logs_project && can_read_cluster?
if cluster.elastic_stack_adapter&.available?
elasticsearch_project_logs_path(logs_project, cluster_id: cluster.id, format: :json)
else
k8s_project_logs_path(logs_project, cluster_id: cluster.id, format: :json)
end
end
def read_only_kubernetes_platform_fields?
!cluster.provided_by_user?
end

View File

@ -19,21 +19,7 @@ class ClusterEntity < Grape::Entity
Clusters::ClusterPresenter.new(cluster).show_path # rubocop: disable CodeReuse/Presenter
end
expose :gitlab_managed_apps_logs_path, if: -> (*) { logging_enabled? } do |cluster|
Clusters::ClusterPresenter.new(cluster, current_user: request.current_user).gitlab_managed_apps_logs_path # rubocop: disable CodeReuse/Presenter
end
expose :kubernetes_errors do |cluster|
Clusters::KubernetesErrorEntity.new(cluster)
end
expose :enable_advanced_logs_querying, if: -> (*) { logging_enabled? } do |cluster|
cluster.elastic_stack_available?
end
private
def logging_enabled?
Feature.enabled?(:monitor_logging, object.project)
end
end

View File

@ -10,8 +10,6 @@ class ClusterSerializer < BaseSerializer
:cluster_type,
:enabled,
:environment_scope,
:gitlab_managed_apps_logs_path,
:enable_advanced_logs_querying,
:id,
:kubernetes_errors,
:name,

View File

@ -21,7 +21,8 @@ module Pages
def publish_deleted_event
event = Pages::PageDeletedEvent.new(data: {
project_id: project.id,
namespace_id: project.namespace_id
namespace_id: project.namespace_id,
root_namespace_id: project.root_namespace.id
})
Gitlab::EventStore.publish(event)

View File

@ -4,7 +4,7 @@
%section.settings.as-email.no-animate#js-email-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'email_content' } }
.settings-header
%h4
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Email')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? _('Collapse') : _('Expand')
@ -15,7 +15,7 @@
%section.settings.as-whats-new-page.no-animate#js-whats-new-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _("What's new")
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? _('Collapse') : _('Expand')
@ -26,7 +26,7 @@
%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Sign-in and Help page')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? _('Collapse') : _('Expand')
@ -38,7 +38,7 @@
%section.settings.as-pages.no-animate#js-pages-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Pages')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? _('Collapse') : _('Expand')
@ -49,7 +49,7 @@
%section.settings.as-realtime.no-animate#js-realtime-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Polling interval multiplier')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? _('Collapse') : _('Expand')
@ -61,7 +61,7 @@
%section.settings.as-gitaly.no-animate#js-gitaly-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Gitaly timeouts')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? _('Collapse') : _('Expand')
@ -74,7 +74,7 @@
%section.settings.as-localization.no-animate#js-localization-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Localization')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? _('Collapse') : _('Expand')
@ -85,7 +85,7 @@
%section.settings.as-sidekiq-job-limits.no-animate#js-sidekiq-job-limits-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
= _('Sidekiq job size limits')
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
= expanded_by_default? ? _('Collapse') : _('Expand')

View File

@ -57,15 +57,7 @@ module Ci
# See https://gitlab.com/gitlab-org/gitlab/-/issues/267112 for more
# details.
#
archive_trace_worker_class(build).perform_in(ARCHIVE_TRACES_IN, build.id)
end
def archive_trace_worker_class(build)
if Feature.enabled?(:ci_build_finished_worker_namespace_changed, build.project)
Ci::ArchiveTraceWorker
else
::ArchiveTraceWorker
end
Ci::ArchiveTraceWorker.perform_in(ARCHIVE_TRACES_IN, build.id)
end
end
end

View File

@ -1,8 +0,0 @@
---
name: ci_build_finished_worker_namespace_changed
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64934
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335499
milestone: '14.1'
type: development
group: group::pipeline execution
default_enabled: false

View File

@ -1266,24 +1266,29 @@ production: &base
ip_whitelist:
- 127.0.0.0/8
# Sidekiq exporter is webserver built in to Sidekiq to expose Prometheus metrics
# Sidekiq exporter is a dedicated Prometheus metrics server optionally running alongside Sidekiq.
sidekiq_exporter:
# enabled: true
# log_enabled: false
# address: localhost
# port: 8082
# tls_enabled: false
# tls_cert_path: /path/to/cert.pem
# tls_key_path: /path/to/key.pem
sidekiq_health_checks:
# enabled: true
# address: localhost
# port: 8092
# Web exporter is a dedicated Rack server running alongside Puma to expose Prometheus metrics
# It runs alongside the `/metrics` endpoints to ease the publish of metrics
# Web exporter is a dedicated Prometheus metrics server optionally running alongside Puma.
web_exporter:
# enabled: true
# address: localhost
# port: 8083
# tls_enabled: false
# tls_cert_path: /path/to/cert.pem
# tls_key_path: /path/to/key.pem
## Prometheus settings
# Do not modify these settings here. They should be modified in /etc/gitlab/gitlab.rb

View File

@ -971,6 +971,9 @@ Settings.monitoring.sidekiq_exporter['enabled'] ||= false
Settings.monitoring.sidekiq_exporter['log_enabled'] ||= false
Settings.monitoring.sidekiq_exporter['address'] ||= 'localhost'
Settings.monitoring.sidekiq_exporter['port'] ||= 8082
Settings.monitoring.sidekiq_exporter['tls_enabled'] ||= false
Settings.monitoring.sidekiq_exporter['tls_cert_path'] ||= nil
Settings.monitoring.sidekiq_exporter['tls_key_path'] ||= nil
Settings.monitoring['sidekiq_health_checks'] ||= Settingslogic.new({})
Settings.monitoring.sidekiq_health_checks['enabled'] ||= false
@ -981,6 +984,9 @@ Settings.monitoring['web_exporter'] ||= Settingslogic.new({})
Settings.monitoring.web_exporter['enabled'] ||= false
Settings.monitoring.web_exporter['address'] ||= 'localhost'
Settings.monitoring.web_exporter['port'] ||= 8083
Settings.monitoring.web_exporter['tls_enabled'] ||= false
Settings.monitoring.web_exporter['tls_cert_path'] ||= nil
Settings.monitoring.web_exporter['tls_key_path'] ||= nil
#
# Prometheus settings

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddAppliesToAllProtectedBranchesToApprovalProjectRule < Gitlab::Database::Migration[2.0]
def change
add_column :approval_project_rules, :applies_to_all_protected_branches, :boolean, default: false, null: false
end
end

View File

@ -0,0 +1 @@
2c0c801506c47adb74c4a91a5fcf37b02355b35570ffbdd18c8aa6a11a8397ac

View File

@ -11496,7 +11496,8 @@ CREATE TABLE approval_project_rules (
severity_levels text[] DEFAULT '{}'::text[] NOT NULL,
report_type smallint,
vulnerability_states text[] DEFAULT '{newly_detected}'::text[] NOT NULL,
orchestration_policy_idx smallint
orchestration_policy_idx smallint,
applies_to_all_protected_branches boolean DEFAULT false NOT NULL
);
CREATE TABLE approval_project_rules_groups (

View File

@ -14,12 +14,12 @@ GitLab can read settings for certain features from encrypted settings files. The
- [LDAP `bind_dn` and `password`](auth/ldap/index.md#use-encrypted-credentials).
- [SMTP `user_name` and `password`](raketasks/smtp.md#secrets).
In order to enable the encrypted configuration settings, a new base key needs to be generated for
To enable the encrypted configuration settings, a new base key must be generated for
`encrypted_settings_key_base`. The secret can be generated in the following ways:
**Omnibus Installation**
Starting with 13.7 the new secret is automatically generated for you, but you need to ensure your
Starting with 13.7 the new secret is automatically generated for you, but you must ensure your
`/etc/gitlab/gitlab-secrets.json` contains the same values on all nodes.
**GitLab Cloud Native Helm Chart**

View File

@ -64,7 +64,7 @@ the status of the flag and the command to enable or disable it.
### Start the GitLab Rails console
The first thing you need to enable or disable a feature behind a flag is to
The first thing you must do to enable or disable a feature behind a flag is to
start a session on GitLab Rails console.
For Omnibus installations:
@ -83,7 +83,7 @@ For details, see [starting a Rails console session](operations/rails_console.md#
### Enable or disable the feature
Once the Rails console session has started, run the `Feature.enable` or
After the Rails console session has started, run the `Feature.enable` or
`Feature.disable` commands accordingly. The specific flag can be found
in the feature's documentation itself.
@ -159,7 +159,7 @@ Feature.all
### Unset feature flag
You can unset a feature flag so that GitLab will fall back to the current defaults for that flag:
You can unset a feature flag so that GitLab falls back to the current defaults for that flag:
```ruby
Feature.remove(:my_awesome_feature)

View File

@ -184,7 +184,11 @@ Verify `objectstg` below (where `store=2`) has count of all LFS objects:
```shell
gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM lfs_objects;
```
**Example Output**
```shell
total | filesystem | objectstg
------+------------+-----------
2409 | 0 | 2409

View File

@ -12,7 +12,7 @@ GitLab by default supports the [Gravatar](https://gravatar.com) avatar service.
Libravatar is another service that delivers your avatar (profile picture) to
other websites. The Libravatar API is
[heavily based on gravatar](https://wiki.libravatar.org/api/), so you can
easily switch to the Libravatar avatar service or even your own Libravatar
switch to the Libravatar avatar service or even your own Libravatar
server.
## Configuration
@ -45,7 +45,7 @@ the URL is different in the configuration, but you must provide the same
placeholders so GitLab can parse the URL correctly.
For example, you host a service on `http://libravatar.example.com` and the
`plain_url` you need to supply in `gitlab.yml` is
`plain_url` you must supply in `gitlab.yml` is
`http://libravatar.example.com/avatar/%{hash}?s=%{size}&d=identicon`

View File

@ -51,3 +51,21 @@ To enable the dedicated server:
for the changes to take effect.
Metrics can now be served and scraped from `localhost:8083/metrics`.
## Enable HTTPS
To serve metrics via HTTPS instead of HTTP, enable TLS in the exporter settings:
1. Edit `/etc/gitlab/gitlab.rb` to add (or find and uncomment) the following lines:
```ruby
puma['exporter_tls_enabled'] = true
puma['exporter_tls_cert_path'] = "/path/to/certificate.pem"
puma['exporter_tls_key_path'] = "/path/to/private-key.pem"
```
1. Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect.
When TLS is enabled, the same `port` and `address` will be used as described above.
The metrics server cannot serve both HTTP and HTTPS at the same time.

View File

@ -191,6 +191,24 @@ To configure the metrics server:
sudo gitlab-ctl reconfigure
```
### Enable HTTPS
To serve metrics via HTTPS instead of HTTP, enable TLS in the exporter settings:
1. Edit `/etc/gitlab/gitlab.rb` to add (or find and uncomment) the following lines:
```ruby
sidekiq['exporter_tls_enabled'] = true
sidekiq['exporter_tls_cert_path'] = "/path/to/certificate.pem"
sidekiq['exporter_tls_key_path'] = "/path/to/private-key.pem"
```
1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect.
When TLS is enabled, the same `port` and `address` will be used as described above.
The metrics server cannot serve both HTTP and HTTPS at the same time.
## Configure health checks
If you use health check probes to observe Sidekiq, enable the Sidekiq health check server.

View File

@ -44,7 +44,7 @@ third parties.
1. Save the file and [reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
The key needs to be readable by the GitLab system user (`git` by default).
The key must be readable by the GitLab system user (`git` by default).
**For installations from source:**
@ -67,7 +67,7 @@ The key needs to be readable by the GitLab system user (`git` by default).
1. Save the file and [restart GitLab](restart_gitlab.md#installations-from-source) for the changes to take effect.
The key needs to be readable by the GitLab system user (`git` by default).
The key must be readable by the GitLab system user (`git` by default).
### How to convert S/MIME PKCS #12 format to PEM encoding

View File

@ -48,4 +48,4 @@ Read how to [use the GitLab Runner Helm Chart](https://docs.gitlab.com/runner/in
## Runner Cache
Since the EKS Quick Start provides for EFS provisioning, the best approach is to use EFS for runner caching. Eventually we will publish information on using an S3 bucket for runner caching here.
Because the EKS Quick Start provides for EFS provisioning, the best approach is to use EFS for runner caching. Eventually we will publish information on using an S3 bucket for runner caching here.

View File

@ -32,23 +32,23 @@ For the Cloud Native Hybrid architectures there are two Infrastructure as Code o
## Introduction
For the most part, we'll make use of Omnibus GitLab in our setup, but we'll also leverage native AWS services. Instead of using the Omnibus bundled PostgreSQL and Redis, we will use Amazon RDS and ElastiCache.
For the most part, we make use of Omnibus GitLab in our setup, but we also leverage native AWS services. Instead of using the Omnibus bundled PostgreSQL and Redis, we use Amazon RDS and ElastiCache.
In this guide, we'll go through a multi-node setup where we'll start by
In this guide, we go through a multi-node setup where we start by
configuring our Virtual Private Cloud and subnets to later integrate
services such as RDS for our database server and ElastiCache as a Redis
cluster to finally manage them within an auto scaling group with custom
cluster to finally manage them in an auto scaling group with custom
scaling policies.
## Requirements
In addition to having a basic familiarity with [AWS](https://docs.aws.amazon.com/) and [Amazon EC2](https://docs.aws.amazon.com/ec2/), you will need:
In addition to having a basic familiarity with [AWS](https://docs.aws.amazon.com/) and [Amazon EC2](https://docs.aws.amazon.com/ec2/), you need:
- [An AWS account](https://console.aws.amazon.com/console/home)
- [To create or upload an SSH key](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html)
to connect to the instance via SSH
- A domain name for the GitLab instance
- An SSL/TLS certificate to secure your domain. If you do not already own one, you can provision a free public SSL/TLS certificate through [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/)(ACM) for use with the [Elastic Load Balancer](#load-balancer) we'll create.
- An SSL/TLS certificate to secure your domain. If you do not already own one, you can provision a free public SSL/TLS certificate through [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/)(ACM) for use with the [Elastic Load Balancer](#load-balancer) we create.
NOTE:
It can take a few hours to validate a certificate provisioned through ACM. To avoid delays later, request your certificate as soon as possible.
@ -79,11 +79,11 @@ GitLab uses the following AWS services, with links to pricing information:
## Create an IAM EC2 instance role and profile
As we'll be using [Amazon S3 object storage](#amazon-s3-object-storage), our EC2 instances need to have read, write, and list permissions for our S3 buckets. To avoid embedding AWS keys in our GitLab configuration, we'll make use of an [IAM Role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) to allow our GitLab instance with this access. We'll need to create an IAM policy to attach to our IAM role:
As we are using [Amazon S3 object storage](#amazon-s3-object-storage), our EC2 instances must have read, write, and list permissions for our S3 buckets. To avoid embedding AWS keys in our GitLab configuration, we make use of an [IAM Role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) to allow our GitLab instance with this access. We must create an IAM policy to attach to our IAM role:
### Create an IAM Policy
1. Navigate to the IAM dashboard and select **Policies** in the left menu.
1. Go to the IAM dashboard and select **Policies** in the left menu.
1. Select **Create policy**, select the `JSON` tab, and add a policy. We want to [follow security best practices and grant _least privilege_](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege), giving our role only the permissions needed to perform the required actions.
1. Assuming you prefix the S3 bucket names with `gl-` as shown in the diagram, add the following policy:
@ -114,7 +114,7 @@ As we'll be using [Amazon S3 object storage](#amazon-s3-object-storage), our EC2
}
```
1. Select **Review policy**, give your policy a name (we'll use `gl-s3-policy`), and select **Create policy**.
1. Select **Review policy**, give your policy a name (we use `gl-s3-policy`), and select **Create policy**.
### Create an IAM Role
@ -124,20 +124,20 @@ As we'll be using [Amazon S3 object storage](#amazon-s3-object-storage), our EC2
**Next: Permissions**.
1. In the policy filter, search for the `gl-s3-policy` we created above, select it, and select **Tags**.
1. Add tags if needed and select **Review**.
1. Give the role a name (we'll use `GitLabS3Access`) and select **Create Role**.
1. Give the role a name (we use `GitLabS3Access`) and select **Create Role**.
We'll use this role when we [create a launch configuration](#create-a-launch-configuration) later on.
We use this role when we [create a launch configuration](#create-a-launch-configuration) later on.
## Configuring the network
We'll start by creating a VPC for our GitLab cloud infrastructure, then
We start by creating a VPC for our GitLab cloud infrastructure, then
we can create subnets to have public and private instances in at least
two [Availability Zones (AZs)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). Public subnets will require a Route Table keep and an associated
two [Availability Zones (AZs)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). Public subnets require a Route Table keep and an associated
Internet Gateway.
### Creating the Virtual Private Cloud (VPC)
We'll now create a VPC, a virtual networking environment that you'll control:
We now create a VPC, a virtual networking environment that you control:
1. Sign in to [Amazon Web Services](https://console.aws.amazon.com/vpc/home).
1. Select **Your VPCs** from the left menu and then select **Create VPC**.
@ -153,15 +153,15 @@ We'll now create a VPC, a virtual networking environment that you'll control:
Now, let's create some subnets in different Availability Zones. Make sure
that each subnet is associated to the VPC we just created and
that CIDR blocks don't overlap. This will also
allow us to enable multi AZ for redundancy.
that CIDR blocks don't overlap. This also
allows us to enable multi AZ for redundancy.
We will create private and public subnets to match load balancers and
We create private and public subnets to match load balancers and
RDS instances as well:
1. Select **Subnets** from the left menu.
1. Select **Create subnet**. Give it a descriptive name tag based on the IP,
for example `gitlab-public-10.0.0.0`, select the VPC we created previously, select an availability zone (we'll use `us-west-2a`),
for example `gitlab-public-10.0.0.0`, select the VPC we created previously, select an availability zone (we use `us-west-2a`),
and at the IPv4 CIDR block let's give it a 24 subnet `10.0.0.0/24`:
![Create subnet](img/create_subnet.png)
@ -186,7 +186,7 @@ create a new one:
1. Select **Internet Gateways** from the left menu.
1. Select **Create internet gateway**, give it the name `gitlab-gateway` and
select **Create**.
1. Select it from the table, and then under the **Actions** dropdown choose
1. Select it from the table, and then under the **Actions** dropdown list choose
"Attach to VPC".
![Create gateway](img/create_gateway.png)
@ -195,11 +195,11 @@ create a new one:
### Create NAT Gateways
Instances deployed in our private subnets need to connect to the internet for updates, but should not be reachable from the public internet. To achieve this, we'll make use of [NAT Gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) deployed in each of our public subnets:
Instances deployed in our private subnets must connect to the internet for updates, but should not be reachable from the public internet. To achieve this, we make use of [NAT Gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) deployed in each of our public subnets:
1. Navigate to the VPC dashboard and select **NAT Gateways** in the left menu bar.
1. Go to the VPC dashboard and select **NAT Gateways** in the left menu bar.
1. Select **Create NAT Gateway** and complete the following:
1. **Subnet**: Select `gitlab-public-10.0.0.0` from the dropdown.
1. **Subnet**: Select `gitlab-public-10.0.0.0` from the dropdown list.
1. **Elastic IP Allocation ID**: Enter an existing Elastic IP or select **Allocate Elastic IP address** to allocate a new IP to your NAT gateway.
1. Add tags if needed.
1. Select **Create NAT Gateway**.
@ -210,7 +210,7 @@ Create a second NAT gateway but this time place it in the second public subnet,
#### Public Route Table
We need to create a route table for our public subnets to reach the internet via the internet gateway we created in the previous step.
We must create a route table for our public subnets to reach the internet via the internet gateway we created in the previous step.
On the VPC dashboard:
@ -219,7 +219,7 @@ On the VPC dashboard:
1. At the "Name tag" enter `gitlab-public` and choose `gitlab-vpc` under "VPC".
1. Select **Create**.
We now need to add our internet gateway as a new target and have
We now must add our internet gateway as a new target and have
it receive traffic from any destination.
1. Select **Route Tables** from the left menu and select the `gitlab-public`
@ -235,7 +235,7 @@ Next, we must associate the **public** subnets to the route table:
#### Private Route Tables
We also need to create two private route tables so that instances in each private subnet can reach the internet via the NAT gateway in the corresponding public subnet in the same availability zone.
We also must create two private route tables so that instances in each private subnet can reach the internet via the NAT gateway in the corresponding public subnet in the same availability zone.
1. Follow the same steps as above to create two private route tables. Name them `gitlab-private-a` and `gitlab-private-b` respectively.
1. Next, add a new route to each of the private route tables where the destination is `0.0.0.0/0` and the target is one of the NAT gateways we created earlier.
@ -247,30 +247,30 @@ We also need to create two private route tables so that instances in each privat
## Load Balancer
We'll create a load balancer to evenly distribute inbound traffic on ports `80` and `443` across our GitLab application servers. Based the on the [scaling policies](#create-an-auto-scaling-group) we'll create later, instances will be added to or removed from our load balancer as needed. Additionally, the load balance will perform health checks on our instances.
We create a load balancer to evenly distribute inbound traffic on ports `80` and `443` across our GitLab application servers. Based on the [scaling policies](#create-an-auto-scaling-group) we create later, instances are added to or removed from our load balancer as needed. Additionally, the load balancer performs health checks on our instances.
On the EC2 dashboard, look for Load Balancer in the left navigation bar:
1. Select **Create Load Balancer**.
1. Choose the **Classic Load Balancer**.
1. Give it a name (we'll use `gitlab-loadbalancer`) and for the **Create LB Inside** option, select `gitlab-vpc` from the dropdown menu.
1. Give it a name (we use `gitlab-loadbalancer`) and for the **Create LB Inside** option, select `gitlab-vpc` from the dropdown list.
1. In the **Listeners** section, set the following listeners:
- HTTP port 80 for both load balancer and instance protocol and ports
- TCP port 22 for both load balancer and instance protocols and ports
- HTTPS port 443 for load balancer protocol and ports, forwarding to HTTP port 80 on the instance (we will configure GitLab to listen on port 80 [later in the guide](#add-support-for-proxied-ssl))
- HTTPS port 443 for load balancer protocol and ports, forwarding to HTTP port 80 on the instance (we configure GitLab to listen on port 80 [later in the guide](#add-support-for-proxied-ssl))
1. In the **Select Subnets** section, select both public subnets from the list so that the load balancer can route traffic to both availability zones.
1. We'll add a security group for our load balancer to act as a firewall to control what traffic is allowed through. Select **Assign Security Groups** and select **Create a new security group**, give it a name
(we'll use `gitlab-loadbalancer-sec-group`) and description, and allow both HTTP and HTTPS traffic
from anywhere (`0.0.0.0/0, ::/0`). Also allow SSH traffic, select a custom source, and add a single trusted IP address or an IP address range in CIDR notation. This will allow users to perform Git actions over SSH.
1. We add a security group for our load balancer to act as a firewall to control what traffic is allowed through. Select **Assign Security Groups** and select **Create a new security group**, give it a name
(we use `gitlab-loadbalancer-sec-group`) and description, and allow both HTTP and HTTPS traffic
from anywhere (`0.0.0.0/0, ::/0`). Also allow SSH traffic, select a custom source, and add a single trusted IP address or an IP address range in CIDR notation. This allows users to perform Git actions over SSH.
1. Select **Configure Security Settings** and set the following:
1. Select an SSL/TLS certificate from ACM or upload a certificate to IAM.
1. Under **Select a Cipher**, pick a predefined security policy from the dropdown. You can see a breakdown of [Predefined SSL Security Policies for Classic Load Balancers](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html) in the AWS docs. Check the GitLab codebase for a list of [supported SSL ciphers and protocols](https://gitlab.com/gitlab-org/gitlab/-/blob/9ee7ad433269b37251e0dd5b5e00a0f00d8126b4/lib/support/nginx/gitlab-ssl#L97-99).
1. Under **Select a Cipher**, pick a predefined security policy from the dropdown list. You can see a breakdown of [Predefined SSL Security Policies for Classic Load Balancers](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html) in the AWS documentation. Check the GitLab codebase for a list of [supported SSL ciphers and protocols](https://gitlab.com/gitlab-org/gitlab/-/blob/9ee7ad433269b37251e0dd5b5e00a0f00d8126b4/lib/support/nginx/gitlab-ssl#L97-99).
1. Select **Configure Health Check** and set up a health check for your EC2 instances.
1. For **Ping Protocol**, select HTTP.
1. For **Ping Port**, enter 80.
1. For **Ping Path** - we recommend that you [use the Readiness check endpoint](../../administration/load_balancer.md#readiness-check). You'll need to add [the VPC IP Address Range (CIDR)](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-groups.html#elb-vpc-nacl) to the [IP allowlist](../../administration/monitoring/ip_whitelist.md) for the [Health Check endpoints](../../user/admin_area/monitoring/health_check.md)
1. For **Ping Path** - we recommend that you [use the Readiness check endpoint](../../administration/load_balancer.md#readiness-check). You must add [the VPC IP Address Range (CIDR)](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-groups.html#elb-vpc-nacl) to the [IP allowlist](../../administration/monitoring/ip_whitelist.md) for the [Health Check endpoints](../../user/admin_area/monitoring/health_check.md)
1. Keep the default **Advanced Details** or adjust them according to your needs.
1. Select **Add EC2 Instances** - don't add anything as we will create an Auto Scaling Group later to manage instances for us.
1. Select **Add EC2 Instances** - don't add anything as we create an Auto Scaling Group later to manage instances for us.
1. Select **Add Tags** and add any tags you need.
1. Select **Review and Create**, review all your settings, and select **Create** if you're happy.
@ -288,28 +288,28 @@ On the Route 53 dashboard, select **Hosted zones** in the left navigation bar:
1. **Type:** Select **A - IPv4 address**.
1. **Alias:** Defaults to **No**. Select **Yes**.
1. **Alias Target:** Find the **ELB Classic Load Balancers** section and select the classic load balancer we created earlier.
1. **Routing Policy:** We'll use **Simple** but you can choose a different policy based on your use case.
1. **Evaluate Target Health:** We'll set this to **No** but you can choose to have the load balancer route traffic based on target health.
1. **Routing Policy:** We use **Simple** but you can choose a different policy based on your use case.
1. **Evaluate Target Health:** We set this to **No** but you can choose to have the load balancer route traffic based on target health.
1. Select **Create**.
1. If you registered your domain through Route 53, you're done. If you used a different domain registrar, you need to update your DNS records with your domain registrar. You'll need to:
1. If you registered your domain through Route 53, you're done. If you used a different domain registrar, you must update your DNS records with your domain registrar. You must:
1. Select **Hosted zones** and select the domain you added above.
1. You'll see a list of `NS` records. From your domain registrar's administrator panel, add each of these as `NS` records to your domain's DNS records. These steps may vary between domain registrars. If you're stuck, Google **"name of your registrar" add DNS records** and you should find a help article specific to your domain registrar.
1. You see a list of `NS` records. From your domain registrar's administrator panel, add each of these as `NS` records to your domain's DNS records. These steps may vary between domain registrars. If you're stuck, Google **"name of your registrar" add DNS records** and you should find a help article specific to your domain registrar.
The steps for doing this vary depending on which registrar you use and is beyond the scope of this guide.
## PostgreSQL with RDS
For our database server we will use Amazon RDS for PostgreSQL which offers Multi AZ
for redundancy (Aurora is **not** supported). First we'll create a security group and subnet group, then we'll
For our database server we use Amazon RDS for PostgreSQL which offers Multi AZ
for redundancy (Aurora is **not** supported). First we create a security group and subnet group, then we
create the actual RDS instance.
### RDS Security Group
We need a security group for our database that will allow inbound traffic from the instances we'll deploy in our `gitlab-loadbalancer-sec-group` later on:
We need a security group for our database that allows inbound traffic from the instances we deploy in our `gitlab-loadbalancer-sec-group` later on:
1. From the EC2 dashboard, select **Security Groups** from the left menu bar.
1. Select **Create security group**.
1. Give it a name (we'll use `gitlab-rds-sec-group`), a description, and select the `gitlab-vpc` from the **VPC** dropdown.
1. Give it a name (we use `gitlab-rds-sec-group`), a description, and select the `gitlab-vpc` from the **VPC** dropdown list.
1. In the **Inbound rules** section, select **Add rule** and set the following:
1. **Type:** search for and select the **PostgreSQL** rule.
1. **Source type:** set as "Custom".
@ -318,11 +318,11 @@ We need a security group for our database that will allow inbound traffic from t
### RDS Subnet Group
1. Navigate to the RDS dashboard and select **Subnet Groups** from the left menu.
1. Go to the RDS dashboard and select **Subnet Groups** from the left menu.
1. Select **Create DB Subnet Group**.
1. Under **Subnet group details**, enter a name (we'll use `gitlab-rds-group`), a description, and choose the `gitlab-vpc` from the VPC dropdown.
1. From the **Availability Zones** dropdown, select the Availability Zones that include the subnets you've configured. In our case, we'll add `eu-west-2a` and `eu-west-2b`.
1. From the **Subnets** dropdown, select the two private subnets (`10.0.1.0/24` and `10.0.3.0/24`) as we defined them in the [subnets section](#subnets).
1. Under **Subnet group details**, enter a name (we use `gitlab-rds-group`), a description, and choose the `gitlab-vpc` from the VPC dropdown list.
1. From the **Availability Zones** dropdown list, select the Availability Zones that include the subnets you've configured. In our case, we add `eu-west-2a` and `eu-west-2b`.
1. From the **Subnets** dropdown list, select the two private subnets (`10.0.1.0/24` and `10.0.3.0/24`) as we defined them in the [subnets section](#subnets).
1. Select **Create** when ready.
### Create the database
@ -332,30 +332,30 @@ Avoid using burstable instances (t class instances) for the database as this cou
Now, it's time to create the database:
1. Navigate to the RDS dashboard, select **Databases** from the left menu, and select **Create database**.
1. Go to the RDS dashboard, select **Databases** from the left menu, and select **Create database**.
1. Select **Standard Create** for the database creation method.
1. Select **PostgreSQL** as the database engine and select the minimum PostgreSQL version as defined for your GitLab version in our [database requirements](../../install/requirements.md#postgresql-requirements).
1. Since this is a production server, let's choose **Production** from the **Templates** section.
1. Under **Settings**, set a DB instance identifier, a master username, and a master password. We'll use `gitlab-db-ha`, `gitlab`, and a very secure password respectively. Make a note of these as we'll need them later.
1. For the DB instance size, select **Standard classes** and select an instance size that meets your requirements from the dropdown menu. We'll use a `db.m4.large` instance.
1. Because this is a production server, let's choose **Production** from the **Templates** section.
1. Under **Settings**, set a DB instance identifier, a master username, and a master password. We use `gitlab-db-ha`, `gitlab`, and a very secure password respectively. Make a note of these as we need them later.
1. For the DB instance size, select **Standard classes** and select an instance size that meets your requirements from the dropdown list. We use a `db.m4.large` instance.
1. Under **Storage**, configure the following:
1. Select **Provisioned IOPS (SSD)** from the storage type dropdown menu. Provisioned IOPS (SSD) storage is best suited for this use (though you can choose General Purpose (SSD) to reduce the costs). Read more about it at [Storage for Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html).
1. Allocate storage and set provisioned IOPS. We'll use the minimum values, `100` and `1000`, respectively.
1. Select **Provisioned IOPS (SSD)** from the storage type dropdown list. Provisioned IOPS (SSD) storage is best suited for this use (though you can choose General Purpose (SSD) to reduce the costs). Read more about it at [Storage for Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html).
1. Allocate storage and set provisioned IOPS. We use the minimum values, `100` and `1000`, respectively.
1. Enable storage autoscaling (optional) and set a maximum storage threshold.
1. Under **Availability & durability**, select **Create a standby instance** to have a standby RDS instance provisioned in a different [Availability Zone](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html).
1. Under **Connectivity**, configure the following:
1. Select the VPC we created earlier (`gitlab-vpc`) from the **Virtual Private Cloud (VPC)** dropdown menu.
1. Select the VPC we created earlier (`gitlab-vpc`) from the **Virtual Private Cloud (VPC)** dropdown list.
1. Expand the **Additional connectivity configuration** section and select the subnet group (`gitlab-rds-group`) we created earlier.
1. Set public accessibility to **No**.
1. Under **VPC security group**, select **Choose existing** and select the `gitlab-rds-sec-group` we create above from the dropdown.
1. Under **VPC security group**, select **Choose existing** and select the `gitlab-rds-sec-group` we create above from the dropdown list.
1. Leave the database port as the default `5432`.
1. For **Database authentication**, select **Password authentication**.
1. Expand the **Additional configuration** section and complete the following:
1. The initial database name. We'll use `gitlabhq_production`.
1. The initial database name. We use `gitlabhq_production`.
1. Configure your preferred backup settings.
1. The only other change we'll make here is to disable auto minor version updates under **Maintenance**.
1. The only other change we make here is to disable auto minor version updates under **Maintenance**.
1. Leave all the other settings as is or tweak according to your needs.
1. Once you're happy, select **Create database**.
1. If you're happy, select **Create database**.
Now that the database is created, let's move on to setting up Redis with ElastiCache.
@ -366,17 +366,17 @@ persistence and is used to store session data, temporary cache information, and
### Create a Redis Security Group
1. Navigate to the EC2 dashboard.
1. Go to the EC2 dashboard.
1. Select **Security Groups** from the left menu.
1. Select **Create security group** and fill in the details. Give it a name (we'll use `gitlab-redis-sec-group`),
1. Select **Create security group** and fill in the details. Give it a name (we use `gitlab-redis-sec-group`),
add a description, and choose the VPC we created previously
1. In the **Inbound rules** section, select **Add rule** and add a **Custom TCP** rule, set port `6379`, and set the "Custom" source as the `gitlab-loadbalancer-sec-group` we created earlier.
1. When done, select **Create security group**.
### Redis Subnet Group
1. Navigate to the ElastiCache dashboard from your AWS console.
1. Go to **Subnet Groups** in the left menu, and create a new subnet group (we'll name ours `gitlab-redis-group`).
1. Go to the ElastiCache dashboard from your AWS console.
1. Go to **Subnet Groups** in the left menu, and create a new subnet group (we name ours `gitlab-redis-group`).
Make sure to select our VPC and its [private subnets](#subnets).
1. Select **Create** when ready.
@ -384,14 +384,14 @@ persistence and is used to store session data, temporary cache information, and
### Create the Redis Cluster
1. Navigate back to the ElastiCache dashboard.
1. Go back to the ElastiCache dashboard.
1. Select **Redis** on the left menu and select **Create** to create a new
Redis cluster. Do not enable **Cluster Mode** as it is [not supported](../../administration/redis/replication_and_failover_external.md#requirements). Even without cluster mode on, you still get the
chance to deploy Redis in multiple availability zones.
1. In the settings section:
1. Give the cluster a name (`gitlab-redis`) and a description.
1. For the version, select the latest.
1. Leave the port as `6379` since this is what we used in our Redis security group above.
1. Leave the port as `6379` because this is what we used in our Redis security group above.
1. Select the node type (at least `cache.t3.medium`, but adjust to your needs) and the number of replicas.
1. In the advanced settings section:
1. Select the multi-AZ auto-failover option.
@ -418,20 +418,20 @@ If you do not want to maintain bastion hosts, you can set up [AWS Systems Manage
### Create Bastion Host A
1. Navigate to the EC2 Dashboard and select **Launch instance**.
1. Go to the EC2 Dashboard and select **Launch instance**.
1. Select the **Ubuntu Server 18.04 LTS (HVM)** AMI.
1. Choose an instance type. We'll use a `t2.micro` as we'll only use the bastion host to SSH into our other instances.
1. Choose an instance type. We use a `t2.micro` as we only use the bastion host to SSH into our other instances.
1. Select **Configure Instance Details**.
1. Under **Network**, select the `gitlab-vpc` from the dropdown menu.
1. Under **Network**, select the `gitlab-vpc` from the dropdown list.
1. Under **Subnet**, select the public subnet we created earlier (`gitlab-public-10.0.0.0`).
1. Double check that under **Auto-assign Public IP** you have **Use subnet setting (Enable)** selected.
1. Leave everything else as default and select **Add Storage**.
1. For storage, we'll leave everything as default and only add an 8GB root volume. We won't store anything on this instance.
1. For storage, we leave everything as default and only add an 8GB root volume. We do not store anything on this instance.
1. Select **Add Tags** and on the next screen select **Add Tag**.
1. We'll only set `Key: Name` and `Value: Bastion Host A`.
1. We only set `Key: Name` and `Value: Bastion Host A`.
1. Select **Configure Security Group**.
1. Select **Create a new security group**, enter a **Security group name** (we'll use `bastion-sec-group`), and add a description.
1. We'll enable SSH access from anywhere (`0.0.0.0/0`). If you want stricter security, specify a single IP address or an IP address range in CIDR notation.
1. Select **Create a new security group**, enter a **Security group name** (we use `bastion-sec-group`), and add a description.
1. We enable SSH access from anywhere (`0.0.0.0/0`). If you want stricter security, specify a single IP address or an IP address range in CIDR notation.
1. Select **Review and Launch**
1. Review all your settings and, if you're happy, select **Launch**.
1. Acknowledge that you have access to an existing key pair or create a new one. Select **Launch Instance**.
@ -447,18 +447,18 @@ Confirm that you can SSH into the instance:
1. Create an EC2 instance following the same steps as above with the following changes:
1. For the **Subnet**, select the second public subnet we created earlier (`gitlab-public-10.0.2.0`).
1. Under the **Add Tags** section, we'll set `Key: Name` and `Value: Bastion Host B` so that we can easily identify our two instances.
1. Under the **Add Tags** section, we set `Key: Name` and `Value: Bastion Host B` so that we can easily identify our two instances.
1. For the security group, select the existing `bastion-sec-group` we created above.
### Use SSH Agent Forwarding
EC2 instances running Linux use private key files for SSH authentication. You'll connect to your bastion host using an SSH client and the private key file stored on your client. Since the private key file is not present on the bastion host, you will not be able to connect to your instances in private subnets.
EC2 instances running Linux use private key files for SSH authentication. You connect to your bastion host using an SSH client and the private key file stored on your client. Because the private key file is not present on the bastion host, you are not able to connect to your instances in private subnets.
Storing private key files on your bastion host is a bad idea. To get around this, use SSH agent forwarding on your client. See [Securely Connect to Linux Instances Running in a Private Amazon VPC](https://aws.amazon.com/blogs/security/securely-connect-to-linux-instances-running-in-a-private-amazon-vpc/) for a step-by-step guide on how to use SSH agent forwarding.
## Install GitLab and create custom AMI
We will need a preconfigured, custom GitLab AMI to use in our launch configuration later. As a starting point, we will use the official GitLab AMI to create a GitLab instance. Then, we'll add our custom configuration for PostgreSQL, Redis, and Gitaly. If you prefer, instead of using the official GitLab AMI, you can also spin up an EC2 instance of your choosing and [manually install GitLab](https://about.gitlab.com/install/).
We need a preconfigured, custom GitLab AMI to use in our launch configuration later. As a starting point, we use the official GitLab AMI to create a GitLab instance. Then, we add our custom configuration for PostgreSQL, Redis, and Gitaly. If you prefer, instead of using the official GitLab AMI, you can also spin up an EC2 instance of your choosing and [manually install GitLab](https://about.gitlab.com/install/).
### Install GitLab
@ -467,12 +467,12 @@ From the EC2 dashboard:
1. Use the section below titled "[Find official GitLab-created AMI IDs on AWS](#find-official-gitlab-created-ami-ids-on-aws)" to find the correct AMI to launch.
1. After clicking **Launch** on the desired AMI, select an instance type based on your workload. Consult the [hardware requirements](../../install/requirements.md#hardware-requirements) to choose one that fits your needs (at least `c5.xlarge`, which is sufficient to accommodate 100 users).
1. Select **Configure Instance Details**:
1. In the **Network** dropdown, select `gitlab-vpc`, the VPC we created earlier.
1. In the **Subnet** dropdown, select `gitlab-private-10.0.1.0` from the list of subnets we created earlier.
1. In the **Network** dropdown list, select `gitlab-vpc`, the VPC we created earlier.
1. In the **Subnet** dropdown list, select `gitlab-private-10.0.1.0` from the list of subnets we created earlier.
1. Double check that **Auto-assign Public IP** is set to `Use subnet setting (Disable)`.
1. Select **Add Storage**.
1. The root volume is 8GiB by default and should be enough given that we won't store any data there.
1. Select **Add Tags** and add any tags you may need. In our case, we'll only set `Key: Name` and `Value: GitLab`.
1. The root volume is 8GiB by default and should be enough given that we do not store any data there.
1. Select **Add Tags** and add any tags you may need. In our case, we only set `Key: Name` and `Value: GitLab`.
1. Select **Configure Security Group**. Check **Select an existing security group** and select the `gitlab-loadbalancer-sec-group` we created earlier.
1. Select **Review and launch** followed by **Launch** if you're happy with your settings.
1. Finally, acknowledge that you have access to the selected private key file or create a new one. Select **Launch Instances**.
@ -483,7 +483,7 @@ Connect to your GitLab instance via **Bastion Host A** using [SSH Agent Forwardi
#### Disable Let's Encrypt
Since we're adding our SSL certificate at the load balancer, we do not need the GitLab built-in support for Let's Encrypt. Let's Encrypt [is enabled by default](https://docs.gitlab.com/omnibus/settings/ssl.html#lets-encrypt-integration) when using an `https` domain in GitLab 10.7 and later, so we need to explicitly disable it:
Because we're adding our SSL certificate at the load balancer, we do not need the GitLab built-in support for Let's Encrypt. Let's Encrypt [is enabled by default](https://docs.gitlab.com/omnibus/settings/ssl.html#lets-encrypt-integration) when using an `https` domain in GitLab 10.7 and later, so we must explicitly disable it:
1. Open `/etc/gitlab/gitlab.rb` and disable it:
@ -501,7 +501,7 @@ Since we're adding our SSL certificate at the load balancer, we do not need the
From your GitLab instance, connect to the RDS instance to verify access and to install the required `pg_trgm` and `btree_gist` extensions.
To find the host or endpoint, navigate to **Amazon RDS > Databases** and select the database you created earlier. Look for the endpoint under the **Connectivity & security** tab.
To find the host or endpoint, go to **Amazon RDS > Databases** and select the database you created earlier. Look for the endpoint under the **Connectivity & security** tab.
Do not to include the colon and port number:
@ -523,10 +523,10 @@ gitlab=# \q
#### Configure GitLab to connect to PostgreSQL and Redis
1. Edit `/etc/gitlab/gitlab.rb`, find the `external_url 'http://<domain>'` option
and change it to the `https` domain you will be using.
and change it to the `https` domain you are using.
1. Look for the GitLab database settings and uncomment as necessary. In
our current case we'll specify the database adapter, encoding, host, name,
our current case we specify the database adapter, encoding, host, name,
username, and password:
```ruby
@ -542,7 +542,7 @@ gitlab=# \q
gitlab_rails['db_host'] = "<rds-endpoint>"
```
1. Next, we need to configure the Redis section by adding the host and
1. Next, we must configure the Redis section by adding the host and
uncommenting the port:
```ruby
@ -560,7 +560,7 @@ gitlab=# \q
sudo gitlab-ctl reconfigure
```
1. You might also find it useful to run a check and a service status to make sure
1. You can also run a check and a service status to make sure
everything has been setup correctly:
```shell
@ -578,21 +578,21 @@ Gitaly is a service that provides high-level RPC access to Git repositories.
It should be enabled and configured on a separate EC2 instance in one of the
[private subnets](#subnets) we configured previously.
Let's create an EC2 instance where we'll install Gitaly:
Let's create an EC2 instance where we install Gitaly:
1. From the EC2 dashboard, select **Launch instance**.
1. Choose an AMI. In this example, we'll select the **Ubuntu Server 18.04 LTS (HVM), SSD Volume Type**.
1. Choose an instance type. We'll pick a `c5.xlarge`.
1. Choose an AMI. In this example, we select the **Ubuntu Server 18.04 LTS (HVM), SSD Volume Type**.
1. Choose an instance type. We pick a `c5.xlarge`.
1. Select **Configure Instance Details**.
1. In the **Network** dropdown, select `gitlab-vpc`, the VPC we created earlier.
1. In the **Subnet** dropdown, select `gitlab-private-10.0.1.0` from the list of subnets we created earlier.
1. In the **Network** dropdown list, select `gitlab-vpc`, the VPC we created earlier.
1. In the **Subnet** dropdown list, select `gitlab-private-10.0.1.0` from the list of subnets we created earlier.
1. Double check that **Auto-assign Public IP** is set to `Use subnet setting (Disable)`.
1. Select **Add Storage**.
1. Increase the Root volume size to `20 GiB` and change the **Volume Type** to `Provisioned IOPS SSD (io1)`. (This is an arbitrary size. Create a volume big enough for your repository storage requirements.)
1. For **IOPS** set `1000` (20 GiB x 50 IOPS). You can provision up to 50 IOPS per GiB. If you select a larger volume, increase the IOPS accordingly. Workloads where many small files are written in a serialized manner, like `git`, requires performant storage, hence the choice of `Provisioned IOPS SSD (io1)`.
1. Select **Add Tags** and add your tags. In our case, we'll only set `Key: Name` and `Value: Gitaly`.
1. Select **Add Tags** and add your tags. In our case, we only set `Key: Name` and `Value: Gitaly`.
1. Select **Configure Security Group** and let's **Create a new security group**.
1. Give your security group a name and description. We'll use `gitlab-gitaly-sec-group` for both.
1. Give your security group a name and description. We use `gitlab-gitaly-sec-group` for both.
1. Create a **Custom TCP** rule and add port `8075` to the **Port Range**. For the **Source**, select the `gitlab-loadbalancer-sec-group`.
1. Also add an inbound rule for SSH from the `bastion-sec-group` so that we can connect using [SSH Agent Forwarding](#use-ssh-agent-forwarding) from the Bastion hosts.
1. Select **Review and launch** followed by **Launch** if you're happy with your settings.
@ -611,11 +611,11 @@ Remember to run `sudo gitlab-ctl reconfigure` after saving the changes to the `g
#### Fast lookup of authorized SSH keys
The public SSH keys for users allowed to access GitLab are stored in `/var/opt/gitlab/.ssh/authorized_keys`. Typically we'd use shared storage so that all the instances are able to access this file when a user performs a Git action over SSH. Since we do not have shared storage in our setup, we'll update our configuration to authorize SSH users via indexed lookup in the GitLab database.
The public SSH keys for users allowed to access GitLab are stored in `/var/opt/gitlab/.ssh/authorized_keys`. Typically we'd use shared storage so that all the instances are able to access this file when a user performs a Git action over SSH. Because we do not have shared storage in our setup, we update our configuration to authorize SSH users via indexed lookup in the GitLab database.
Follow the instructions at [Setting up fast lookup via GitLab Shell](../../administration/operations/fast_ssh_key_lookup.md#setting-up-fast-lookup-via-gitlab-shell) to switch from using the `authorized_keys` file to the database.
If you do not configure fast lookup, Git actions over SSH will result in the following error:
If you do not configure fast lookup, Git actions over SSH results in the following error:
```shell
Permission denied (publickey).
@ -629,7 +629,7 @@ and the repository exists.
Ordinarily we would manually copy the contents (primary and public keys) of `/etc/ssh/` on the primary application server to `/etc/ssh` on all secondary servers. This prevents false man-in-the-middle-attack alerts when accessing servers in your cluster behind a load balancer.
We'll automate this by creating static host keys as part of our custom AMI. As these host keys are also rotated every time an EC2 instance boots up, "hard coding" them into our custom AMI serves as a handy workaround.
We automate this by creating static host keys as part of our custom AMI. As these host keys are also rotated every time an EC2 instance boots up, "hard coding" them into our custom AMI serves as a workaround.
On your GitLab instance run the following:
@ -650,16 +650,16 @@ HostKey /etc/ssh_static/ssh_host_ed25519_key
#### Amazon S3 object storage
Since we're not using NFS for shared storage, we will use [Amazon S3](https://aws.amazon.com/s3/) buckets to store backups, artifacts, LFS objects, uploads, merge request diffs, container registry images, and more. Our documentation includes [instructions on how to configure object storage](../../administration/object_storage.md) for each of these data types, and other information about using object storage with GitLab.
Because we're not using NFS for shared storage, we use [Amazon S3](https://aws.amazon.com/s3/) buckets to store backups, artifacts, LFS objects, uploads, merge request diffs, container registry images, and more. Our documentation includes [instructions on how to configure object storage](../../administration/object_storage.md) for each of these data types, and other information about using object storage with GitLab.
NOTE:
Since we are using the [AWS IAM profile](#create-an-iam-role) we created earlier, be sure to omit the AWS access key and secret access key/value pairs when configuring object storage. Instead, use `'use_iam_profile' => true` in your configuration as shown in the object storage documentation linked above.
Because we are using the [AWS IAM profile](#create-an-iam-role) we created earlier, be sure to omit the AWS access key and secret access key/value pairs when configuring object storage. Instead, use `'use_iam_profile' => true` in your configuration as shown in the object storage documentation linked above.
Remember to run `sudo gitlab-ctl reconfigure` after saving the changes to the `gitlab.rb` file.
---
That concludes the configuration changes for our GitLab instance. Next, we'll create a custom AMI based on this instance to use for our launch configuration and auto scaling group.
That concludes the configuration changes for our GitLab instance. Next, we create a custom AMI based on this instance to use for our launch configuration and auto scaling group.
### Log in for the first time
@ -672,7 +672,7 @@ Depending on how you installed GitLab and if you did not change the password by
To change the default password, log in as the `root` user with the default password and [change it in the user profile](../../user/profile#change-your-password).
When our [auto scaling group](#create-an-auto-scaling-group) spins up new instances, we'll be able to log in with username `root` and the newly created password.
When our [auto scaling group](#create-an-auto-scaling-group) spins up new instances, we are able to log in with username `root` and the newly created password.
### Create custom AMI
@ -680,10 +680,10 @@ On the EC2 dashboard:
1. Select the `GitLab` instance we [created earlier](#install-gitlab).
1. Select **Actions**, scroll down to **Image** and select **Create Image**.
1. Give your image a name and description (we'll use `GitLab-Source` for both).
1. Give your image a name and description (we use `GitLab-Source` for both).
1. Leave everything else as default and select **Create Image**
Now we have a custom AMI that we'll use to create our launch configuration the next step.
Now we have a custom AMI that we use to create our launch configuration the next step.
## Deploy GitLab inside an auto scaling group
@ -694,11 +694,11 @@ From the EC2 dashboard:
1. Select **Launch Configurations** from the left menu and select **Create launch configuration**.
1. Select **My AMIs** from the left menu and select the `GitLab` custom AMI we created above.
1. Select an instance type best suited for your needs (at least a `c5.xlarge`) and select **Configure details**.
1. Enter a name for your launch configuration (we'll use `gitlab-ha-launch-config`).
1. Enter a name for your launch configuration (we use `gitlab-ha-launch-config`).
1. **Do not** check **Request Spot Instance**.
1. From the **IAM Role** dropdown, pick the `GitLabAdmin` instance role we [created earlier](#create-an-iam-ec2-instance-role-and-profile).
1. From the **IAM Role** dropdown list, pick the `GitLabAdmin` instance role we [created earlier](#create-an-iam-ec2-instance-role-and-profile).
1. Leave the rest as defaults and select **Add Storage**.
1. The root volume is 8GiB by default and should be enough given that we won't store any data there. Select **Configure Security Group**.
1. The root volume is 8GiB by default and should be enough given that we do not store any data there. Select **Configure Security Group**.
1. Check **Select and existing security group** and select the `gitlab-loadbalancer-sec-group` we created earlier.
1. Select **Review**, review your changes, and select **Create launch configuration**.
1. Acknowledge that you have access to the private key or create a new one. Select **Create launch configuration**.
@ -706,16 +706,16 @@ From the EC2 dashboard:
### Create an auto scaling group
1. After the launch configuration is created, select **Create an Auto Scaling group using this launch configuration** to start creating the auto scaling group.
1. Enter a **Group name** (we'll use `gitlab-auto-scaling-group`).
1. For **Group size**, enter the number of instances you want to start with (we'll enter `2`).
1. Select the `gitlab-vpc` from the **Network** dropdown.
1. Enter a **Group name** (we use `gitlab-auto-scaling-group`).
1. For **Group size**, enter the number of instances you want to start with (we enter `2`).
1. Select the `gitlab-vpc` from the **Network** dropdown list.
1. Add both the private [subnets we created earlier](#subnets).
1. Expand the **Advanced Details** section and check the **Receive traffic from one or more load balancers** option.
1. From the **Classic Load Balancers** dropdown, select the load balancer we created earlier.
1. From the **Classic Load Balancers** dropdown list, select the load balancer we created earlier.
1. For **Health Check Type**, select **ELB**.
1. We'll leave our **Health Check Grace Period** as the default `300` seconds. Select **Configure scaling policies**.
1. We leave our **Health Check Grace Period** as the default `300` seconds. Select **Configure scaling policies**.
1. Check **Use scaling policies to adjust the capacity of this group**.
1. For this group we'll scale between 2 and 4 instances where one instance will be added if CPU
1. For this group we scale between 2 and 4 instances where one instance is added if CPU
utilization is greater than 60% and one instance is removed if it falls
to less than 45%.
@ -724,9 +724,9 @@ to less than 45%.
1. Finally, configure notifications and tags as you see fit, review your changes, and create the
auto scaling group.
As the auto scaling group is created, you'll see your new instances spinning up in your EC2 dashboard. You'll also see the new instances added to your load balancer. Once the instances pass the heath check, they are ready to start receiving traffic from the load balancer.
As the auto scaling group is created, you see your new instances spinning up in your EC2 dashboard. You also see the new instances added to your load balancer. After the instances pass the heath check, they are ready to start receiving traffic from the load balancer.
Since our instances are created by the auto scaling group, go back to your instances and terminate the [instance we created manually above](#install-gitlab). We only needed this instance to create our custom AMI.
Because our instances are created by the auto scaling group, go back to your instances and terminate the [instance we created manually above](#install-gitlab). We only needed this instance to create our custom AMI.
## Health check and monitoring with Prometheus
@ -753,8 +753,8 @@ and restore its Git data, database, attachments, LFS objects, and so on.
Some important things to know:
- The backup/restore tool **does not** store some configuration files, like secrets; you'll
need to [configure this yourself](../../raketasks/backup_restore.md#storing-configuration-files).
- The backup/restore tool **does not** store some configuration files, like secrets; you
must [configure this yourself](../../raketasks/backup_restore.md#storing-configuration-files).
- By default, the backup files are stored locally, but you can
[backup GitLab using S3](../../raketasks/backup_restore.md#using-amazon-s3).
- You can [exclude specific directories form the backup](../../raketasks/backup_restore.md#excluding-specific-directories-from-the-backup).
@ -825,7 +825,7 @@ to request additional material:
GitLab supports several different types of clustering.
- [Geo replication](../../administration/geo/index.md):
Geo is the solution for widely distributed development teams.
- [Omnibus GitLab](https://docs.gitlab.com/omnibus/) - Everything you need to know
- [Omnibus GitLab](https://docs.gitlab.com/omnibus/) - Everything you must know
about administering your GitLab instance.
- [Add a license](../../user/admin_area/license.md):
Activate all GitLab Enterprise Edition functionality with a license.
@ -835,9 +835,9 @@ to request additional material:
### Instances are failing health checks
If your instances are failing the load balancer's health checks, verify that they are returning a status `200` from the health check endpoint we configured earlier. Any other status, including redirects like status `302`, will cause the health check to fail.
If your instances are failing the load balancer's health checks, verify that they are returning a status `200` from the health check endpoint we configured earlier. Any other status, including redirects like status `302`, causes the health check to fail.
You may have to set a password on the `root` user to prevent automatic redirects on the sign-in endpoint before health checks will pass.
You may have to set a password on the `root` user to prevent automatic redirects on the sign-in endpoint before health checks pass.
### "The change you requested was rejected (422)"

View File

@ -32,7 +32,7 @@ Characteristics of beta features:
- Features and functions are not likely to change.
- Data loss is not likely.
Your Support Contract provides **commercially-reasonable effort** support for Beta features, with the expectation that issues will require extra time and assistance from development to troubleshoot.
Your Support Contract provides **commercially-reasonable effort** support for Beta features, with the expectation that issues require extra time and assistance from development to troubleshoot.
## Limited Availability (LA)

View File

@ -43,12 +43,12 @@ The following table describes the version types and their release cadence:
## Upgrade recommendations
We encourage everyone to run the [latest stable release](https://about.gitlab.com/releases/categories/releases/)
to ensure that you can easily upgrade to the most secure and feature-rich GitLab experience.
To make sure you can easily run the most recent stable release, we are working
to ensure that you can upgrade to the most secure and feature-rich GitLab experience.
To make sure you can run the most recent stable release, we are working
hard to keep the update process simple and reliable.
If you are unable to follow our monthly release cycle, there are a couple of
cases you need to consider. Follow the
cases you must consider. Follow the
[upgrade paths guide](../update/index.md#upgrade-paths) to safely upgrade
between versions.
@ -106,7 +106,7 @@ Backporting to more than one stable release is normally reserved for [security r
In some cases, however, we may need to backport *a bug fix* to more than one stable
release, depending on the severity of the bug.
The decision on whether backporting a change will be performed is done at the discretion of the
The decision on whether backporting a change is performed is done at the discretion of the
[current release managers](https://about.gitlab.com/community/release-managers/), similar to what is
described in the [managing bugs](https://gitlab.com/gitlab-org/gitlab/-/blob/master/PROCESS.md#managing-bugs) process,
based on *all* of the following:
@ -124,7 +124,7 @@ For instance, if we release `13.2.1` with a fix for a severe bug introduced in
`13.0.0`, we could backport the fix to a new `13.0.x`, and `13.1.x` patch release.
Note that [severity](../development/contributing/issue_workflow.md#severity-labels) 3 and lower
requests will be automatically turned down.
requests are automatically turned down.
To request backporting to more than one stable release for consideration, raise an issue in the
[release/tasks](https://gitlab.com/gitlab-org/release/tasks/-/issues/new?issuable_template=Backporting-request) issue tracker.

View File

@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Rake tasks are available to import bare repositories into a GitLab instance.
When migrating from an existing GitLab instance,
and to preserve ownership by users and their namespaces,
please use [our project-based import/export](../user/project/settings/import_export.md).
use [our project-based import/export](../user/project/settings/import_export.md).
Note that:
@ -39,7 +39,7 @@ To import bare repositories into a GitLab instance:
- Groups are created as needed, these could be nested folders.
For example, if we copy the repositories to `/var/opt/gitlab/git-data/repository-import-2020-08-22`,
and repository `A` needs to be under the groups `G1` and `G2`, it must be created under those folders:
and repository `A` must be under the groups `G1` and `G2`, it must be created under those folders:
`/var/opt/gitlab/git-data/repository-import-2020-08-22/G1/G2/A.git`.
```shell
@ -49,7 +49,7 @@ To import bare repositories into a GitLab instance:
sudo chown -R git:git /var/opt/gitlab/git-data/repository-import-$(date "+%Y-%m-%d")
```
`foo.git` needs to be owned by the `git` user and `git` users group.
`foo.git` must be owned by the `git` user and `git` users group.
If you are using an installation from source, replace `/var/opt/gitlab/` with `/home/git`.
@ -61,7 +61,7 @@ To import bare repositories into a GitLab instance:
sudo gitlab-rake gitlab:import:repos["/var/opt/gitlab/git-data/repository-import-$(date "+%Y-%m-%d")"]
```
- Installation from source. Before running this command you need to change to the directory where
- Installation from source. Before running this command you must change to the directory where
your GitLab installation is located:
```shell

View File

@ -111,7 +111,7 @@ the leaked key without forcing all users to change their 2FA details.
To rotate the two-factor authentication encryption key:
1. Look up the old key. This is in the `config/secrets.yml` file, but **make sure you're working
1. Look up the old key in the `config/secrets.yml` file, but **make sure you're working
with the production section**. The line you're interested in looks like this:
```yaml

View File

@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Dedicated
NOTE:
GitLab Dedicated is currently in limited availability. Please [contact us](#contact-us) if you are interested.
GitLab Dedicated is currently in limited availability. [Contact us](#contact-us) if you are interested.
GitLab Dedicated is a fully isolated, single-tenant SaaS service that is:
@ -18,7 +18,7 @@ GitLab Dedicated enables you to offload the operational overhead of managing the
## Available features
- Authentication: Support for instance-level [SAML OmniAuth](../../integration/saml.md) functionality. GitLab Dedicated acts as the service provider, and you will need to provide the necessary [configuration](../../integration/saml.md#general-setup) in order for GitLab to communicate with your IdP. This will be provided during onboarding. SAML [request signing](../../integration/saml.md#request-signing-optional) is supported.
- Authentication: Support for instance-level [SAML OmniAuth](../../integration/saml.md) functionality. GitLab Dedicated acts as the service provider, and you must provide the necessary [configuration](../../integration/saml.md#general-setup) in order for GitLab to communicate with your IdP. This is provided during onboarding. SAML [request signing](../../integration/saml.md#request-signing-optional) is supported.
- Networking:
- Public connectivity
- Optional. Private connectivity via [AWS PrivateLink](https://aws.amazon.com/privatelink/).

View File

@ -4,48 +4,11 @@ module API
module Entities
class Environment < Entities::EnvironmentBasic
include RequestAwareEntity
include Gitlab::Utils::StrongMemoize
expose :tier
expose :project, using: Entities::BasicProjectDetails
expose :last_deployment, using: Entities::Deployment, if: { last_deployment: true }
expose :state
expose :enable_advanced_logs_querying, if: -> (*) { can_read_pod_logs? } do |environment|
environment.elastic_stack_available?
end
expose :logs_api_path, if: -> (*) { can_read_pod_logs? } do |environment|
if environment.elastic_stack_available?
elasticsearch_project_logs_path(environment.project, environment_name: environment.name, format: :json)
else
k8s_project_logs_path(environment.project, environment_name: environment.name, format: :json)
end
end
expose :gitlab_managed_apps_logs_path, if: -> (*) { can_read_pod_logs? && cluster } do |environment|
::Clusters::ClusterPresenter.new(cluster, current_user: current_user).gitlab_managed_apps_logs_path # rubocop: disable CodeReuse/Presenter
end
private
alias_method :environment, :object
def can_read_pod_logs?
strong_memoize(:can_read_pod_logs) do
current_user&.can?(:read_pod_logs, environment.project)
end
end
def cluster
strong_memoize(:cluster) do
environment&.last_deployment&.cluster
end
end
def current_user
options[:current_user]
end
end
end
end

View File

@ -30,24 +30,24 @@ before_script:
- apt-get --quiet update --yes
- apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1
# Setup path as ANDROID_SDK_ROOT for moving/exporting the downloaded sdk into it
- export ANDROID_SDK_ROOT="${PWD}/android-home"
# Setup path as ANDROID_HOME for moving/exporting the downloaded sdk into it
- export ANDROID_HOME="${PWD}/android-home"
# Create a new directory at specified location
- install -d $ANDROID_SDK_ROOT
- install -d $ANDROID_HOME
# Here we are installing androidSDK tools from official source,
# (the key thing here is the url from where you are downloading these sdk tool for command line, so please do note this url pattern there and here as well)
# after that unzipping those tools and
# then running a series of SDK manager commands to install necessary android SDK packages that'll allow the app to build
- wget --output-document=$ANDROID_SDK_ROOT/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip
# move to the archive at ANDROID_SDK_ROOT
- pushd $ANDROID_SDK_ROOT
- wget --output-document=$ANDROID_HOME/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip
# move to the archive at ANDROID_HOME
- pushd $ANDROID_HOME
- unzip -d cmdline-tools cmdline-tools.zip
- pushd cmdline-tools
# since commandline tools version 7583922 the root folder is named "cmdline-tools" so we rename it if necessary
- mv cmdline-tools tools || true
- popd
- popd
- export PATH=$PATH:${ANDROID_SDK_ROOT}/cmdline-tools/tools/bin/
- export PATH=$PATH:${ANDROID_HOME}/cmdline-tools/tools/bin/
# Nothing fancy here, just checking sdkManager version
- sdkmanager --version

View File

@ -38,10 +38,28 @@ module Gitlab
[logger, WEBrick::AccessLog::COMBINED_LOG_FORMAT]
]
@server = ::WEBrick::HTTPServer.new(
Port: settings.port, BindAddress: settings.address,
Logger: logger, AccessLog: access_log
)
server_config = {
Port: settings.port,
BindAddress: settings.address,
Logger: logger,
AccessLog: access_log
}
if settings['tls_enabled']
# This monkey-patches WEBrick::GenericServer, so never require this unless TLS is enabled.
require 'webrick/ssl'
server_config.merge!({
SSLEnable: true,
SSLCertificate: OpenSSL::X509::Certificate.new(File.binread(settings['tls_cert_path'])),
SSLPrivateKey: OpenSSL::PKey.read(File.binread(settings['tls_key_path'])),
# SSLStartImmediately is true by default according to the docs, but when WEBrick creates the
# SSLServer internally, the switch was always nil for some reason. Setting this explicitly fixes this.
SSLStartImmediately: true
})
end
@server = ::WEBrick::HTTPServer.new(server_config)
server.mount '/', Rack::Handler::WEBrick, rack_app
true

View File

@ -56,6 +56,11 @@ class MetricsServer # rubocop:disable Gitlab/NamespacedClass
env['GME_LOG_LEVEL'] = 'quiet'
end
if settings['tls_enabled']
env['GME_CERT_FILE'] = settings['tls_cert_path']
env['GME_CERT_KEY'] = settings['tls_key_path']
end
Process.spawn(env, cmd, err: $stderr, out: $stdout, pgroup: true).tap do |pid|
Process.detach(pid)
end

View File

@ -3,8 +3,9 @@
require 'airborne'
module QA
RSpec.describe 'Package', only: { subdomain: %i[staging pre] }, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/360466', type: :investigating } do
RSpec.describe 'Package', only: { subdomain: %i[staging pre] } do
include Support::API
include Support::Helpers::MaskToken
describe 'Container Registry' do
let(:api_client) { Runtime::API::Client.new(:gitlab) }
@ -17,6 +18,12 @@ module QA
end
end
let!(:project_access_token) do
QA::Resource::ProjectAccessToken.fabricate_via_api! do |pat|
pat.project = project
end
end
let(:registry) do
Resource::RegistryRepository.init do |repository|
repository.name = project.path_with_namespace
@ -25,45 +32,47 @@ module QA
end
end
let(:masked_token) do
use_ci_variable(name: 'PAT', value: project_access_token.token, project: project)
end
let(:gitlab_ci_yaml) do
<<~YAML
stages:
- build
- test
build:
image: docker:19.03.12
stage: build
services:
- docker:19.03.12-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
before_script:
- until docker info; do sleep 1; done
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
- docker pull $IMAGE_TAG
test:
image: dwdraju/alpine-curl-jq:latest
stage: test
variables:
MEDIA_TYPE: 'application/vnd.docker.distribution.manifest.v2+json'
before_script:
- token=$(curl -u "$CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD" "https://$CI_SERVER_HOST/jwt/auth?service=container_registry&scope=repository:$CI_PROJECT_PATH:pull,push,delete" | jq -r '.token')
script:
- 'digest=$(curl -L -H "Authorization: Bearer $token" -H "Accept: $MEDIA_TYPE" "https://$CI_REGISTRY/v2/$CI_PROJECT_PATH/manifests/master" | jq -r ".layers[0].digest")'
- 'curl -L -X DELETE -H "Authorization: Bearer $token" -H "Accept: $MEDIA_TYPE" "https://$CI_REGISTRY/v2/$CI_PROJECT_PATH/blobs/$digest"'
- 'curl -L --head -H "Authorization: Bearer $token" -H "Accept: $MEDIA_TYPE" "https://$CI_REGISTRY/v2/$CI_PROJECT_PATH/blobs/$digest"'
- 'digest=$(curl -L -H "Authorization: Bearer $token" -H "Accept: $MEDIA_TYPE" "https://$CI_REGISTRY/v2/$CI_PROJECT_PATH/manifests/master" | jq -r ".config.digest")'
- 'curl -L -X DELETE -H "Authorization: Bearer $token" -H "Accept: $MEDIA_TYPE" "https://$CI_REGISTRY/v2/$CI_PROJECT_PATH/manifests/$digest"'
- 'curl -L --head -H "Authorization: Bearer $token" -H "Accept: $MEDIA_TYPE" "https://$CI_REGISTRY/v2/$CI_PROJECT_PATH/manifests/$digest"'
stages:
- build
- test
build:
image: docker:19.03.12
stage: build
services:
- docker:19.03.12-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
before_script:
- until docker info; do sleep 1; done
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
- docker pull $IMAGE_TAG
test:
image: dwdraju/alpine-curl-jq:latest
stage: test
script:
- 'id=$(curl --header "PRIVATE-TOKEN: #{masked_token}" "https://${CI_SERVER_HOST}/api/v4/projects/#{project.id}/registry/repositories" | jq ".[0].id")'
- echo $id
- 'tag_count=$(curl --header "PRIVATE-TOKEN: #{masked_token}" "https://${CI_SERVER_HOST}/api/v4/projects/#{project.id}/registry/repositories/$id/tags" | jq ". | length")'
- if [ $tag_count -ne 1 ]; then exit 1; fi;
- 'status_code=$(curl --request DELETE --head --output /dev/null --write-out "%{http_code}\n" --header "PRIVATE-TOKEN: #{masked_token}" "https://${CI_SERVER_HOST}/api/v4/projects/#{project.id}/registry/repositories/$id/tags/master")'
- if [ $status_code -ne 200 ]; then exit 1; fi;
- 'status_code=$(curl --head --output /dev/null --write-out "%{http_code}\n" --header "PRIVATE-TOKEN: #{masked_token}" "https://${CI_SERVER_HOST}/api/v4/projects/#{project.id}/registry/repositories/$id/tags/master")'
- if [ $status_code -ne 404 ]; then exit 1; fi;
YAML
end
@ -71,7 +80,7 @@ module QA
registry&.remove_via_api!
end
it 'pushes, pulls image to the registry and deletes image blob, manifest and tag', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348001' do
it 'pushes, pulls image to the registry and deletes tag', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348001' do
Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.api_client = api_client
@ -89,14 +98,6 @@ module QA
Support::Retrier.retry_until(max_duration: 300, sleep_interval: 5) do
latest_pipeline_succeed?
end
expect(job_log).to have_content '404 Not Found'
expect(registry).to have_tag('master')
registry.delete_tag
expect(registry).not_to have_tag('master')
end
private
@ -109,20 +110,6 @@ module QA
latest_pipeline = project.pipelines.first
latest_pipeline[:status] == 'success'
end
def job_log
pipeline = project.pipelines.first
pipeline_id = pipeline[:id]
jobs = get Runtime::API::Request.new(api_client, "/projects/#{project.id}/pipelines/#{pipeline_id}/jobs").url
test_job = parse_body(jobs).first
test_job_id = test_job[:id]
log = get Runtime::API::Request.new(api_client, "/projects/#{project.id}/jobs/#{test_job_id}/trace").url
QA::Runtime::Logger.debug(" \n\n ------- Test job log: ------- \n\n #{log} \n -------")
log
end
end
end
end

View File

@ -6,6 +6,7 @@ RSpec.describe Pages::PageDeletedEvent do
where(:data, :valid) do
[
[{ project_id: 1, namespace_id: 2 }, true],
[{ project_id: 1, namespace_id: 2, root_namespace_id: 3 }, true],
[{ project_id: 1 }, false],
[{ namespace_id: 1 }, false],
[{ project_id: 'foo', namespace_id: 2 }, false],

View File

@ -45,7 +45,6 @@ RSpec.describe 'Monitor dropdown sidebar', :aggregate_failures do
expect(page).not_to have_link('Alerts', href: project_alert_management_index_path(project))
expect(page).not_to have_link('Error Tracking', href: project_error_tracking_index_path(project))
expect(page).not_to have_link('Product Analytics', href: project_product_analytics_path(project))
expect(page).not_to have_link('Logs', href: project_logs_path(project))
expect(page).not_to have_link('Kubernetes', href: project_clusters_path(project))
end
@ -78,7 +77,6 @@ RSpec.describe 'Monitor dropdown sidebar', :aggregate_failures do
expect(page).not_to have_link('Alerts', href: project_alert_management_index_path(project))
expect(page).not_to have_link('Error Tracking', href: project_error_tracking_index_path(project))
expect(page).not_to have_link('Product Analytics', href: project_product_analytics_path(project))
expect(page).not_to have_link('Logs', href: project_logs_path(project))
expect(page).not_to have_link('Kubernetes', href: project_clusters_path(project))
end
@ -96,7 +94,6 @@ RSpec.describe 'Monitor dropdown sidebar', :aggregate_failures do
expect(page).to have_link('Product Analytics', href: project_product_analytics_path(project))
expect(page).not_to have_link('Alerts', href: project_alert_management_index_path(project))
expect(page).not_to have_link('Logs', href: project_logs_path(project))
expect(page).not_to have_link('Kubernetes', href: project_clusters_path(project))
end
@ -113,7 +110,6 @@ RSpec.describe 'Monitor dropdown sidebar', :aggregate_failures do
expect(page).to have_link('Environments', href: project_environments_path(project))
expect(page).to have_link('Error Tracking', href: project_error_tracking_index_path(project))
expect(page).to have_link('Product Analytics', href: project_product_analytics_path(project))
expect(page).to have_link('Logs', href: project_logs_path(project))
expect(page).to have_link('Kubernetes', href: project_clusters_path(project))
end
@ -130,7 +126,6 @@ RSpec.describe 'Monitor dropdown sidebar', :aggregate_failures do
expect(page).to have_link('Environments', href: project_environments_path(project))
expect(page).to have_link('Error Tracking', href: project_error_tracking_index_path(project))
expect(page).to have_link('Product Analytics', href: project_product_analytics_path(project))
expect(page).to have_link('Logs', href: project_logs_path(project))
expect(page).to have_link('Kubernetes', href: project_clusters_path(project))
end

View File

@ -25,10 +25,7 @@
"state": { "type": "string" },
"created_at": { "type": "string", "format": "date-time" },
"updated_at": { "type": "string", "format": "date-time" },
"project": { "$ref": "project.json" },
"enable_advanced_logs_querying": { "type": "boolean" },
"logs_api_path": { "type": "string" },
"gitlab_managed_apps_logs_path": { "type": "string" }
"project": { "$ref": "project.json" }
},
"additionalProperties": false
}

View File

@ -1,4 +1,3 @@
import $ from 'jquery';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import initTodoToggle, { initNavUserDropdownTracking } from '~/header';
import { loadHTMLFixture, setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
@ -9,11 +8,17 @@ describe('Header', () => {
const fixtureTemplate = 'issues/open-issue.html';
function isTodosCountHidden() {
return $(todosPendingCount).hasClass('hidden');
return document.querySelector(todosPendingCount).classList.contains('hidden');
}
function triggerToggle(newCount) {
$(document).trigger('todo:toggle', newCount);
const event = new CustomEvent('todo:toggle', {
detail: {
count: newCount,
},
});
document.dispatchEvent(event);
}
beforeEach(() => {
@ -28,7 +33,7 @@ describe('Header', () => {
it('should update todos-count after receiving the todo:toggle event', () => {
triggerToggle(5);
expect($(todosPendingCount).text()).toEqual('5');
expect(document.querySelector(todosPendingCount).textContent).toEqual('5');
});
it('should hide todos-count when it is 0', () => {
@ -53,7 +58,7 @@ describe('Header', () => {
});
it('should show 99+ for todos-count', () => {
expect($(todosPendingCount).text()).toEqual('99+');
expect(document.querySelector(todosPendingCount).textContent).toEqual('99+');
});
});
});
@ -67,7 +72,11 @@ describe('Header', () => {
<a class="js-buy-pipeline-minutes-link" data-track-action="click_buy_ci_minutes" data-track-label="free" data-track-property="user_dropdown">Buy Pipeline minutes</a>
</li>`);
trackingSpy = mockTracking('_category_', $('.js-nav-user-dropdown').element, jest.spyOn);
trackingSpy = mockTracking(
'_category_',
document.querySelector('.js-nav-user-dropdown').element,
jest.spyOn,
);
document.body.dataset.page = 'some:page';
initNavUserDropdownTracking();
@ -79,7 +88,8 @@ describe('Header', () => {
});
it('sends a tracking event when the dropdown is opened and contains Buy Pipeline minutes link', () => {
$('.js-nav-user-dropdown').trigger('shown.bs.dropdown');
const event = new CustomEvent('shown.bs.dropdown');
document.querySelector('.js-nav-user-dropdown').dispatchEvent(event);
expect(trackingSpy).toHaveBeenCalledWith('some:page', 'show_buy_ci_minutes', {
label: 'free',

View File

@ -1,5 +1,4 @@
import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import waitForPromises from 'helpers/wait_for_promises';
import '~/lib/utils/common_utils';
@ -54,22 +53,28 @@ describe('Todos', () => {
let metakeyEvent;
beforeEach(() => {
metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
metakeyEvent = new MouseEvent('click', { ctrlKey: true });
windowOpenSpy = jest.spyOn(window, 'open').mockImplementation(() => {});
});
it('opens the todo url in another tab', () => {
const todoLink = todoItem.dataset.url;
$('.todos-list .todo').trigger(metakeyEvent);
document.querySelectorAll('.todos-list .todo').forEach((el) => {
el.dispatchEvent(metakeyEvent);
});
expect(visitUrl).not.toHaveBeenCalled();
expect(windowOpenSpy).toHaveBeenCalledWith(todoLink, '_blank');
});
it('run native funcionality when avatar is clicked', () => {
$('.todos-list a').on('click', (e) => e.preventDefault());
$('.todos-list img').trigger(metakeyEvent);
document.querySelectorAll('.todos-list a').forEach((el) => {
el.addEventListener('click', (e) => e.preventDefault());
});
document.querySelectorAll('.todos-list img').forEach((el) => {
el.dispatchEvent(metakeyEvent);
});
expect(visitUrl).not.toHaveBeenCalled();
expect(windowOpenSpy).not.toHaveBeenCalled();
@ -88,7 +93,7 @@ describe('Todos', () => {
.onDelete(path)
.replyOnce(200, { count: TEST_COUNT_BIG, done_count: TEST_DONE_COUNT_BIG });
onToggleSpy = jest.fn();
$(document).on('todo:toggle', onToggleSpy);
document.addEventListener('todo:toggle', onToggleSpy);
// Act
el.click();
@ -98,7 +103,13 @@ describe('Todos', () => {
});
it('dispatches todo:toggle', () => {
expect(onToggleSpy).toHaveBeenCalledWith(expect.anything(), TEST_COUNT_BIG);
expect(onToggleSpy).toHaveBeenCalledWith(
expect.objectContaining({
detail: {
count: TEST_COUNT_BIG,
},
}),
);
});
it('updates pending text', () => {

View File

@ -57,8 +57,8 @@ RSpec.describe StorageHelper do
let_it_be(:paid_group) { create(:group) }
before do
allow(helper).to receive(:can?).with(current_user, :admin_namespace, free_group).and_return(true)
allow(helper).to receive(:can?).with(current_user, :admin_namespace, paid_group).and_return(true)
allow(helper).to receive(:can?).with(current_user, :maintain_namespace, free_group).and_return(true)
allow(helper).to receive(:can?).with(current_user, :maintain_namespace, paid_group).and_return(true)
allow(helper).to receive(:current_user) { current_user }
allow(paid_group).to receive(:paid?).and_return(true)
@ -84,7 +84,7 @@ RSpec.describe StorageHelper do
end
it 'returns nil when current_user do not have access usage quotas page' do
allow(helper).to receive(:can?).with(current_user, :admin_namespace, free_group).and_return(false)
allow(helper).to receive(:can?).with(current_user, :maintain_namespace, free_group).and_return(false)
expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
end

View File

@ -19,6 +19,7 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
allow(settings).to receive(:enabled).and_return(true)
allow(settings).to receive(:port).and_return(0)
allow(settings).to receive(:address).and_return('127.0.0.1')
allow(settings).to receive(:[]).with('tls_enabled').and_return(false)
end
after do
@ -88,6 +89,29 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
exporter
end
end
context 'with TLS enabled' do
let(:test_cert) { Rails.root.join('spec/fixtures/x509_certificate.crt').to_s }
let(:test_key) { Rails.root.join('spec/fixtures/x509_certificate_pk.key').to_s }
before do
allow(settings).to receive(:[]).with('tls_enabled').and_return(true)
allow(settings).to receive(:[]).with('tls_cert_path').and_return(test_cert)
allow(settings).to receive(:[]).with('tls_key_path').and_return(test_key)
end
it 'injects the necessary OpenSSL config for WEBrick' do
expect(::WEBrick::HTTPServer).to receive(:new).with(
a_hash_including(
SSLEnable: true,
SSLCertificate: an_instance_of(OpenSSL::X509::Certificate),
SSLPrivateKey: an_instance_of(OpenSSL::PKey::RSA),
SSLStartImmediately: true
))
exporter.start
end
end
end
describe 'when thread is not alive' do
@ -159,6 +183,7 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
allow(settings).to receive(:enabled).and_return(true)
allow(settings).to receive(:port).and_return(0)
allow(settings).to receive(:address).and_return('127.0.0.1')
allow(settings).to receive(:[]).with('tls_enabled').and_return(false)
stub_const('Gitlab::Metrics::Exporter::MetricsMiddleware', fake_collector)

View File

@ -171,6 +171,29 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
described_class.spawn(target, metrics_dir: metrics_dir)
end
end
context 'when TLS settings are present' do
before do
%w(web_exporter sidekiq_exporter).each do |key|
settings[key]['tls_enabled'] = true
settings[key]['tls_cert_path'] = '/path/to/cert.pem'
settings[key]['tls_key_path'] = '/path/to/key.pem'
end
end
it 'sets the correct environment variables' do
expect(Process).to receive(:spawn).with(
expected_env.merge(
'GME_CERT_FILE' => '/path/to/cert.pem',
'GME_CERT_KEY' => '/path/to/key.pem'
),
'/path/to/gme/gitlab-metrics-exporter',
hash_including(pgroup: true)
).and_return(99)
described_class.spawn(target, metrics_dir: metrics_dir, path: '/path/to/gme/')
end
end
end
end
end

View File

@ -43,30 +43,10 @@ RSpec.describe Ci::Build do
it { is_expected.to delegate_method(:legacy_detached_merge_request_pipeline?).to(:pipeline) }
shared_examples 'calling proper BuildFinishedWorker' do
context 'when ci_build_finished_worker_namespace_changed feature flag enabled' do
before do
stub_feature_flags(ci_build_finished_worker_namespace_changed: build.project)
end
it 'calls Ci::BuildFinishedWorker' do
expect(Ci::BuildFinishedWorker).to receive(:perform_async)
it 'calls Ci::BuildFinishedWorker' do
expect(Ci::BuildFinishedWorker).to receive(:perform_async)
expect(::BuildFinishedWorker).not_to receive(:perform_async)
subject
end
end
context 'when ci_build_finished_worker_namespace_changed feature flag disabled' do
before do
stub_feature_flags(ci_build_finished_worker_namespace_changed: false)
end
it 'calls ::BuildFinishedWorker' do
expect(::BuildFinishedWorker).to receive(:perform_async)
expect(Ci::BuildFinishedWorker).not_to receive(:perform_async)
subject
end
subject
end
end

View File

@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe GroupPolicy do
include_context 'GroupPolicy context'
using RSpec::Parameterized::TableSyntax
context 'public group with no user' do
let(:group) { create(:group, :public, :crm_enabled) }
@ -1229,4 +1230,30 @@ RSpec.describe GroupPolicy do
it { is_expected.to be_disallowed(:admin_crm_contact) }
it { is_expected.to be_disallowed(:admin_crm_organization) }
end
describe 'maintain_namespace' do
context 'with non-admin roles' do
where(:role, :allowed) do
:guest | false
:reporter | false
:developer | false
:maintainer | true
:owner | true
end
with_them do
let(:current_user) { public_send(role) }
it do
expect(subject.allowed?(:maintain_namespace)).to eq allowed
end
end
end
context 'as an admin', :enable_admin_mode do
let(:current_user) { admin }
it { is_expected.to be_allowed(:maintain_namespace) }
end
end
end

View File

@ -13,6 +13,7 @@ RSpec.describe IssuePolicy do
let(:reporter_from_group_link) { create(:user) }
let(:non_member) { create(:user) }
let(:support_bot) { User.support_bot }
let(:alert_bot) { User.alert_bot }
def permissions(user, issue)
described_class.new(user, issue)
@ -41,6 +42,14 @@ RSpec.describe IssuePolicy do
end
end
shared_examples 'alert bot' do
it 'allows alert_bot to read and set metadata on issues' do
expect(permissions(alert_bot, issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(alert_bot, issue_no_assignee)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
expect(permissions(alert_bot, new_issue)).to be_allowed(:read_issue, :read_issue_iid, :update_issue, :admin_issue, :set_issue_metadata, :set_confidentiality)
end
end
context 'a private project' do
let(:project) { create(:project, :private) }
let(:issue) { create(:issue, project: project, assignees: [assignee], author: author) }
@ -106,6 +115,7 @@ RSpec.describe IssuePolicy do
expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it_behaves_like 'alert bot'
it_behaves_like 'support bot with service desk disabled'
it_behaves_like 'support bot with service desk enabled'
@ -270,6 +280,7 @@ RSpec.describe IssuePolicy do
expect(permissions(support_bot, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it_behaves_like 'alert bot'
it_behaves_like 'support bot with service desk enabled'
context 'when issues are private' do
@ -326,6 +337,7 @@ RSpec.describe IssuePolicy do
expect(permissions(non_member, new_issue)).to be_disallowed(:create_issue, :set_issue_metadata, :set_confidentiality)
end
it_behaves_like 'alert bot'
it_behaves_like 'support bot with service desk disabled'
it_behaves_like 'support bot with service desk enabled'
end

View File

@ -8,7 +8,7 @@ RSpec.describe Namespaces::UserNamespacePolicy do
let_it_be(:admin) { create(:admin) }
let_it_be(:namespace) { create(:user_namespace, owner: owner) }
let(:owner_permissions) { [:owner_access, :create_projects, :admin_namespace, :read_namespace, :read_statistics, :transfer_projects, :admin_package] }
let(:owner_permissions) { [:owner_access, :create_projects, :admin_namespace, :read_namespace, :read_statistics, :transfer_projects, :admin_package, :maintain_namespace] }
subject { described_class.new(current_user, namespace) }

View File

@ -148,84 +148,4 @@ RSpec.describe Clusters::ClusterPresenter do
it_behaves_like 'cluster health data'
end
end
describe '#gitlab_managed_apps_logs_path' do
context 'user can read logs' do
let(:project) { cluster.project }
before do
project.add_maintainer(user)
end
it 'returns path to logs' do
expect(presenter.gitlab_managed_apps_logs_path).to eq k8s_project_logs_path(project, cluster_id: cluster.id, format: :json)
end
context 'cluster has elastic stack integration enabled' do
before do
create(:clusters_integrations_elastic_stack, cluster: cluster)
end
it 'returns path to logs' do
expect(presenter.gitlab_managed_apps_logs_path).to eq elasticsearch_project_logs_path(project, cluster_id: cluster.id, format: :json)
end
end
end
context 'group cluster' do
let(:cluster) { create(:cluster, cluster_type: :group_type, groups: [group]) }
let(:group) { create(:group, name: 'Foo') }
context 'user can read logs' do
before do
group.add_maintainer(user)
end
context 'there are projects within group' do
let!(:project) { create(:project, namespace: group) }
it 'returns path to logs' do
expect(presenter.gitlab_managed_apps_logs_path).to eq k8s_project_logs_path(project, cluster_id: cluster.id, format: :json)
end
end
context 'there are no projects within group' do
it 'returns nil' do
expect(presenter.gitlab_managed_apps_logs_path).to be_nil
end
end
end
end
context 'instance cluster' do
let(:cluster) { create(:cluster, cluster_type: :instance_type) }
let!(:project) { create(:project) }
let(:user) { create(:admin) }
before do
project.add_maintainer(user)
stub_application_setting(admin_mode: false)
end
context 'user can read logs' do
it 'returns path to logs' do
expect(presenter.gitlab_managed_apps_logs_path).to eq k8s_project_logs_path(project, cluster_id: cluster.id, format: :json)
end
end
end
context 'user can NOT read logs' do
let(:cluster) { create(:cluster, cluster_type: :instance_type) }
let!(:project) { create(:project) }
before do
project.add_developer(user)
stub_application_setting(admin_mode: false)
end
it 'returns nil' do
expect(presenter.gitlab_managed_apps_logs_path).to be_nil
end
end
end
end

View File

@ -55,34 +55,5 @@ RSpec.describe ClusterEntity do
expect(helm[:status]).to eq(:not_installable)
end
end
context 'enable_advanced_logs_querying' do
let(:cluster) { create(:cluster, :project) }
let(:user) { create(:user) }
subject { described_class.new(cluster, request: request).as_json }
context 'elastic stack is not installed on cluster' do
it 'returns false' do
expect(subject[:enable_advanced_logs_querying]).to be false
end
end
context 'elastic stack is enabled on cluster' do
it 'returns true' do
create(:clusters_integrations_elastic_stack, cluster: cluster)
expect(subject[:enable_advanced_logs_querying]).to be true
end
end
context 'when feature is disabled' do
before do
stub_feature_flags(monitor_logging: false)
end
specify { is_expected.not_to include(:enable_advanced_logs_querying) }
end
end
end
end

View File

@ -14,8 +14,6 @@ RSpec.describe ClusterSerializer do
:enabled,
:environment_scope,
:id,
:gitlab_managed_apps_logs_path,
:enable_advanced_logs_querying,
:kubernetes_errors,
:name,
:nodes,

View File

@ -489,6 +489,23 @@ RSpec.describe Issues::CreateService do
end
end
end
context 'with alert bot author' do
let_it_be(:user) { User.alert_bot }
let_it_be(:label) { create(:label, project: project) }
let(:opts) do
{
title: 'Title',
description: %(/label #{label.to_reference(format: :name)}")
}
end
it 'can apply labels' do
expect(issue).to be_persisted
expect(issue.labels).to eq([label])
end
end
end
context 'resolving discussions' do

View File

@ -45,7 +45,11 @@ RSpec.describe Pages::DeleteService do
end
it 'publishes a ProjectDeleted event with project id and namespace id' do
expected_data = { project_id: project.id, namespace_id: project.namespace_id }
expected_data = {
project_id: project.id,
namespace_id: project.namespace_id,
root_namespace_id: project.root_namespace.id
}
expect { service.execute }.to publish_event(Pages::PageDeletedEvent).with(expected_data)
end

View File

@ -12,7 +12,6 @@ RSpec.describe BuildFinishedWorker do
let_it_be(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline)) }
before do
stub_feature_flags(ci_build_finished_worker_namespace_changed: build.project)
expect(Ci::Build).to receive(:find_by).with({ id: build.id }).and_return(build)
end
@ -30,18 +29,6 @@ RSpec.describe BuildFinishedWorker do
subject
end
context 'with ci_build_finished_worker_namespace_changed feature flag disabled' do
before do
stub_feature_flags(ci_build_finished_worker_namespace_changed: false)
end
it 'calls deprecated worker' do
expect(ArchiveTraceWorker).to receive(:perform_in)
subject
end
end
context 'when build is failed' do
before do
build.update!(status: :failed)

View File

@ -10,7 +10,6 @@ RSpec.describe Ci::BuildFinishedWorker do
let_it_be(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline)) }
before do
stub_feature_flags(ci_build_finished_worker_namespace_changed: build.project)
expect(Ci::Build).to receive(:find_by).with({ id: build.id }).and_return(build)
end
@ -28,18 +27,6 @@ RSpec.describe Ci::BuildFinishedWorker do
subject
end
context 'with ci_build_finished_worker_namespace_changed feature flag disabled' do
before do
stub_feature_flags(ci_build_finished_worker_namespace_changed: false)
end
it 'calls deprecated worker' do
expect(ArchiveTraceWorker).to receive(:perform_in)
subject
end
end
context 'when build is failed' do
before do
build.update!(status: :failed)