Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f7406657b9
commit
81a37f0581
21
.stylelintrc
21
.stylelintrc
|
|
@ -13,27 +13,6 @@
|
|||
"./scripts/frontend/stylelint/stylelint-utility-classes.js",
|
||||
],
|
||||
"rules":{
|
||||
"at-rule-disallowed-list": ["extend"],
|
||||
"max-nesting-depth": [
|
||||
3,
|
||||
{
|
||||
"ignoreAtRules":[
|
||||
"each",
|
||||
"media",
|
||||
"supports",
|
||||
"include"
|
||||
],
|
||||
"severity":"warning"
|
||||
}
|
||||
],
|
||||
"selector-max-compound-selectors":[3, { "severity": "warning" }],
|
||||
"stylelint-gitlab/utility-classes":[true,{ "severity": "warning" }],
|
||||
"declaration-block-no-duplicate-properties": [
|
||||
true,
|
||||
{
|
||||
"ignore": ["consecutive-duplicates"]
|
||||
}
|
||||
],
|
||||
"no-eol-whitespace": true,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
c959b634bd98035355259ffcd421d7a43e015982
|
||||
7b9cd199b0851fd1b6615e0798f2aafddafd63cb
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -538,4 +538,4 @@ gem 'ipaddress', '~> 0.8.3'
|
|||
|
||||
gem 'parslet', '~> 1.8'
|
||||
|
||||
gem 'ipynbdiff', '0.3.6'
|
||||
gem 'ipynbdiff', '0.3.7'
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ GEM
|
|||
invisible_captcha (1.1.0)
|
||||
rails (>= 4.2)
|
||||
ipaddress (0.8.3)
|
||||
ipynbdiff (0.3.6)
|
||||
ipynbdiff (0.3.7)
|
||||
diffy (= 3.3.0)
|
||||
json (= 2.5.1)
|
||||
jaeger-client (1.1.0)
|
||||
|
|
@ -1504,7 +1504,7 @@ DEPENDENCIES
|
|||
icalendar
|
||||
invisible_captcha (~> 1.1.0)
|
||||
ipaddress (~> 0.8.3)
|
||||
ipynbdiff (= 0.3.6)
|
||||
ipynbdiff (= 0.3.7)
|
||||
jira-ruby (~> 2.1.4)
|
||||
js_regex (~> 3.7)
|
||||
json (~> 2.5.1)
|
||||
|
|
|
|||
|
|
@ -1,16 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Projects::GoogleCloudController < Projects::ApplicationController
|
||||
before_action :authorize_can_manage_google_cloud_deployments!
|
||||
feature_category :google_cloud
|
||||
|
||||
feature_category :release_orchestration
|
||||
before_action :admin_project_google_cloud?
|
||||
before_action :google_oauth2_enabled?
|
||||
before_action :feature_flag_enabled?
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authorize_can_manage_google_cloud_deployments!
|
||||
access_denied! unless can?(current_user, :manage_project_google_cloud, project)
|
||||
def admin_project_google_cloud?
|
||||
access_denied! unless can?(current_user, :admin_project_google_cloud, project)
|
||||
end
|
||||
|
||||
def google_oauth2_enabled?
|
||||
config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2')
|
||||
if config.app_id.blank? || config.app_secret.blank?
|
||||
access_denied! 'This GitLab instance not configured for Google Oauth2.'
|
||||
end
|
||||
end
|
||||
|
||||
def feature_flag_enabled?
|
||||
access_denied! unless Feature.enabled?(:incubation_5mp_google_cloud)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ module Namespaces
|
|||
def lineage(top: nil, bottom: nil, hierarchy_order: nil)
|
||||
raise UnboundedSearch, 'Must bound search by either top or bottom' unless top || bottom
|
||||
|
||||
skope = self.class.without_sti_condition
|
||||
skope = self.class
|
||||
|
||||
if top
|
||||
skope = skope.where("traversal_ids @> ('{?}')", top.id)
|
||||
|
|
@ -181,7 +181,6 @@ module Namespaces
|
|||
# standard SELECT to avoid mismatched attribute errors when trying to
|
||||
# chain future ActiveRelation commands, and retain the ordering.
|
||||
skope = self.class
|
||||
.without_sti_condition
|
||||
.from(skope, self.class.table_name)
|
||||
.select(skope.arel_table[Arel.star])
|
||||
.order(depth: hierarchy_order)
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ module Namespaces
|
|||
return super unless use_traversal_ids_for_ancestor_scopes?
|
||||
|
||||
records = unscoped
|
||||
.without_sti_condition
|
||||
.where(id: without_sti_condition.select('unnest(traversal_ids)'))
|
||||
.where(id: select('unnest(traversal_ids)'))
|
||||
.order_by_depth(hierarchy_order)
|
||||
.normal_select
|
||||
|
||||
|
|
@ -60,16 +59,6 @@ module Namespaces
|
|||
end
|
||||
end
|
||||
|
||||
# Make sure we drop the STI `type = 'Group'` condition for better performance.
|
||||
# Logically equivalent so long as hierarchies remain homogeneous.
|
||||
def without_sti_condition
|
||||
if Feature.enabled?(:include_sti_condition, default_enabled: :yaml)
|
||||
all
|
||||
else
|
||||
unscope(where: :type)
|
||||
end
|
||||
end
|
||||
|
||||
def order_by_depth(hierarchy_order)
|
||||
return all unless hierarchy_order
|
||||
|
||||
|
|
@ -85,7 +74,7 @@ module Namespaces
|
|||
# When we have queries that break this SELECT * format we can run in to errors.
|
||||
# For example `SELECT DISTINCT on(...)` will fail when we chain a `.count` c
|
||||
def normal_select
|
||||
unscoped.without_sti_condition.from(all, :namespaces)
|
||||
unscoped.from(all, :namespaces)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -108,7 +97,6 @@ module Namespaces
|
|||
|
||||
namespaces = Arel::Table.new(:namespaces)
|
||||
records = unscoped
|
||||
.without_sti_condition
|
||||
.with(cte.to_arel)
|
||||
.from([cte.table, namespaces])
|
||||
|
||||
|
|
@ -136,7 +124,6 @@ module Namespaces
|
|||
base_ids = select(:id)
|
||||
|
||||
records = unscoped
|
||||
.without_sti_condition
|
||||
.from("namespaces, (#{base_ids.to_sql}) base")
|
||||
.where('namespaces.traversal_ids @> ARRAY[base.id]')
|
||||
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ class ProjectPolicy < BasePolicy
|
|||
enable :destroy_freeze_period
|
||||
enable :admin_feature_flags_client
|
||||
enable :update_runners_registration_token
|
||||
enable :manage_project_google_cloud
|
||||
enable :admin_project_google_cloud
|
||||
end
|
||||
|
||||
rule { public_project & metrics_dashboard_allowed }.policy do
|
||||
|
|
|
|||
|
|
@ -16,14 +16,9 @@ module Ci
|
|||
private
|
||||
|
||||
def create_pipeline_for(pull_request)
|
||||
if ::Feature.enabled?(:ci_create_external_pr_pipeline_async, project, default_enabled: :yaml)
|
||||
Ci::ExternalPullRequests::CreatePipelineWorker.perform_async(
|
||||
project.id, current_user.id, pull_request.id
|
||||
)
|
||||
else
|
||||
Ci::CreatePipelineService.new(project, current_user, create_params(pull_request))
|
||||
.execute(:external_pull_request_event, external_pull_request: pull_request)
|
||||
end
|
||||
Ci::ExternalPullRequests::CreatePipelineWorker.perform_async(
|
||||
project.id, current_user.id, pull_request.id
|
||||
)
|
||||
end
|
||||
|
||||
def create_params(pull_request)
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Projects
|
||||
module ContainerRepository
|
||||
class CacheTagsCreatedAtService
|
||||
def initialize(container_repository)
|
||||
@container_repository = container_repository
|
||||
@cached_tag_names = Set.new
|
||||
end
|
||||
|
||||
def populate(tags)
|
||||
return if tags.empty?
|
||||
|
||||
# This will load all tags in one Redis roundtrip
|
||||
# the maximum number of tags is configurable and is set to 200 by default.
|
||||
# https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/packages/container_registry/index.md#set-cleanup-limits-to-conserve-resources
|
||||
keys = tags.map(&method(:cache_key))
|
||||
cached_tags_count = 0
|
||||
|
||||
::Gitlab::Redis::Cache.with do |redis|
|
||||
tags.zip(redis.mget(keys)).each do |tag, created_at|
|
||||
next unless created_at
|
||||
|
||||
tag.created_at = DateTime.rfc3339(created_at)
|
||||
@cached_tag_names << tag.name
|
||||
cached_tags_count += 1
|
||||
end
|
||||
end
|
||||
|
||||
cached_tags_count
|
||||
end
|
||||
|
||||
def insert(tags, max_ttl_in_seconds)
|
||||
return unless max_ttl_in_seconds
|
||||
return if tags.empty?
|
||||
|
||||
# tags with nil created_at are not cacheable
|
||||
# tags already cached don't need to be cached again
|
||||
cacheable_tags = tags.select do |tag|
|
||||
tag.created_at.present? && !tag.name.in?(@cached_tag_names)
|
||||
end
|
||||
|
||||
return if cacheable_tags.empty?
|
||||
|
||||
now = Time.zone.now
|
||||
|
||||
::Gitlab::Redis::Cache.with do |redis|
|
||||
# we use a pipeline instead of a MSET because each tag has
|
||||
# a specific ttl
|
||||
redis.pipelined do
|
||||
cacheable_tags.each do |tag|
|
||||
created_at = tag.created_at
|
||||
# ttl is the max_ttl_in_seconds reduced by the number
|
||||
# of seconds that the tag has already existed
|
||||
ttl = max_ttl_in_seconds - (now - created_at).seconds
|
||||
ttl = ttl.to_i
|
||||
redis.set(cache_key(tag), created_at.rfc3339, ex: ttl) if ttl > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cache_key(tag)
|
||||
"container_repository:{#{@container_repository.id}}:tag:#{tag.name}:created_at"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -140,7 +140,7 @@ module Projects
|
|||
|
||||
def cache
|
||||
strong_memoize(:cache) do
|
||||
::Projects::ContainerRepository::CacheTagsCreatedAtService.new(@container_repository)
|
||||
::Gitlab::ContainerRepository::Tags::Cache.new(@container_repository)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -4,80 +4,3 @@
|
|||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
|
||||
#js-google-cloud
|
||||
|
||||
%h1.gl-font-size-h1 Google Cloud
|
||||
|
||||
%section#js-section-google-cloud-service-accounts
|
||||
|
||||
%h2.gl-font-size-h2 Service Accounts
|
||||
|
||||
%p= _('Service Accounts keys are required to authorize GitLab to deploy your Google Cloud project.')
|
||||
|
||||
%table.table.b-table.gl-table
|
||||
|
||||
%thead
|
||||
%tr
|
||||
%th Environment
|
||||
%th GCP Project ID
|
||||
%th Service Account Key
|
||||
|
||||
%tbody
|
||||
|
||||
%tr
|
||||
%td *
|
||||
%td serving-salutes-453
|
||||
%td .....
|
||||
|
||||
%tr
|
||||
%td production
|
||||
%td crimson-corey-234
|
||||
%td .....
|
||||
|
||||
%tr
|
||||
%td review/*
|
||||
%td roving-river-379
|
||||
%td .....
|
||||
|
||||
%a.gl-button.btn.btn-primary= _('Add new service account')
|
||||
|
||||
%br
|
||||
|
||||
%section#js-section-google-cloud-deployments
|
||||
|
||||
.row.row-fluid
|
||||
|
||||
.col-lg-4
|
||||
%h2.gl-font-size-h2 Deployments
|
||||
%p= _('Google Cloud offers several deployment targets. Select the one most suitable for your project.')
|
||||
%p
|
||||
= _('Deployments to Google Kubernetes Engine can be ')
|
||||
%a{ href: '#' }= _('managed')
|
||||
= _('in Infrastructure :: Kubernetes clusters')
|
||||
|
||||
.col-lg-8
|
||||
|
||||
%br
|
||||
|
||||
.gl-card.gl-mb-6
|
||||
.gl-card-body
|
||||
.gl-display-flex.gl-align-items-baseline
|
||||
%strong.gl-font-lg App Engine
|
||||
.gl-ml-auto.gl-text-gray-500 Disabled
|
||||
%p= _('App Engine description and apps that are suitable for this deployment target')
|
||||
%button.gl-button.btn.btn-default= _('Configure via Merge Request')
|
||||
|
||||
.gl-card.gl-mb-6
|
||||
.gl-card-body
|
||||
.gl-display-flex.gl-align-items-baseline
|
||||
%strong.gl-font-lg Cloud Functions
|
||||
.gl-ml-auto.gl-text-gray-500 Disabled
|
||||
%p= _('Cloud Functions description and apps that are suitable for this deployment target')
|
||||
%button.gl-button.btn.btn-default= _('Configure via Merge Request')
|
||||
|
||||
.gl-card.gl-mb-6
|
||||
.gl-card-body
|
||||
.gl-display-flex.gl-align-items-baseline
|
||||
%strong.gl-font-lg Cloud Run
|
||||
.gl-ml-auto.gl-text-gray-500 Disabled
|
||||
%p= _('Cloud Run description and apps that are suitable for this deployment target')
|
||||
%button.gl-button.btn.btn-default= _('Configure via Merge Request')
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
- gitaly
|
||||
- gitlab_docs
|
||||
- global_search
|
||||
- google_cloud
|
||||
- helm_chart_registry
|
||||
- horse
|
||||
- importers
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: ci_create_external_pr_pipeline_async
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68567
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338908
|
||||
milestone: '14.3'
|
||||
type: development
|
||||
group: group::pipeline authoring
|
||||
default_enabled: true
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: include_sti_condition
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72119
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343412
|
||||
milestone: '14.5'
|
||||
type: development
|
||||
group: group::workspace
|
||||
default_enabled: false
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: jira_issue_details_edit_labels
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65298
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335069
|
||||
milestone: '14.1'
|
||||
type: development
|
||||
group: group::integrations
|
||||
default_enabled: false
|
||||
|
|
@ -133,6 +133,40 @@ Before adding a new variable for a color or a size, guarantee:
|
|||
- There isn't an existing one.
|
||||
- There isn't a similar one we can use instead.
|
||||
|
||||
### Using `extend` at-rule
|
||||
|
||||
Usage of the `extend` at-rule is prohibited due to [memory leaks](https://gitlab.com/gitlab-org/gitlab/-/issues/323021) and [the rule doesn't work as it should to](https://sass-lang.com/documentation/breaking-changes/extend-compound). Use mixins instead:
|
||||
|
||||
```scss
|
||||
// Bad
|
||||
.gl-pt-3 {
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.my-element {
|
||||
@extend .gl-pt-3;
|
||||
}
|
||||
|
||||
// compiles to
|
||||
.gl-pt-3, .my-element {
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
// Good
|
||||
@mixing gl-pt-3 {
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.my-element {
|
||||
@include gl-pt-3;
|
||||
}
|
||||
|
||||
// compiles to
|
||||
.my-element {
|
||||
padding-top: 12px;
|
||||
}
|
||||
```
|
||||
|
||||
## Linting
|
||||
|
||||
We use [stylelint](https://stylelint.io) to check for style guide conformity. It uses the
|
||||
|
|
|
|||
|
|
@ -38,11 +38,11 @@ there isn't any context selected.
|
|||
Contexts are named in the following format: `<agent-configuration-project-path>:<agent-name>`.
|
||||
To get the list of available contexts, run `kubectl config get-contexts`.
|
||||
|
||||
## Share the CI/CD Tunnel provided by an Agent with other projects and group
|
||||
## Share the CI/CD Tunnel provided by an Agent with other projects and groups
|
||||
|
||||
The Agent can be configured to enable access to the CI/CD Tunnel to other projects or all the projects under a given group. This way you can have a single agent serving all the requests for several projects saving on resources and maintenance.
|
||||
|
||||
You can read more on how to [authorize access to groups in the Agent configuration reference](repository.md#authorize-groups-to-use-an-agent).
|
||||
You can read more on how to [authorize access in the Agent configuration reference](repository.md#authorize-projects-and-groups-to-use-an-agent).
|
||||
|
||||
## Example for a `kubectl` command using the CI/CD Tunnel
|
||||
|
||||
|
|
|
|||
|
|
@ -350,16 +350,17 @@ Additional management interfaces are planned for the GitLab Kubernetes Agent.
|
|||
|
||||
## Upgrades and version compatibility
|
||||
|
||||
As the GitLab Kubernetes Agent is a new product, we are constantly adding new features
|
||||
to it. As a result, while shipped features are production ready, its internal API is
|
||||
neither stable nor versioned yet. For this reason, GitLab only guarantees compatibility
|
||||
between corresponding major.minor (X.Y) versions of GitLab and its cluster side
|
||||
component, `agentk`.
|
||||
The GitLab Kubernetes Agent is comprised of two major components: `agentk` and `kas`.
|
||||
As we provide `kas` installers built into the various GitLab installation methods, the required `kas` version corresponds to the GitLab `major.minor` (X.Y) versions.
|
||||
|
||||
Upgrade your agent installations together with GitLab upgrades. To decide which version of `agentk` to install follow:
|
||||
At the same time, `agentk` and `kas` can differ by 1 minor version in either direction. For example,
|
||||
`agentk` 14.4 supports `kas` 14.3, 14.4, and 14.5 (regardless of the patch).
|
||||
|
||||
1. Open the [`GITLAB_KAS_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_KAS_VERSION) file from the GitLab Repository, which contains the latest `agentk` version associated with the `master` branch.
|
||||
1. Change the `master` branch and select the Git tag associated with your version. For instance, you could change it to GitLab [v13.5.3-ee release](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.5.3-ee/GITLAB_KAS_VERSION)
|
||||
A feature introduced in a given GitLab minor version might work with other `agentk` or `kas` versions.
|
||||
To make sure that it works, use at least the same `agentk` and `kas` minor version. For example,
|
||||
if your GitLab version is 14.2, use at least `agentk` 14.2 and `kas` 14.2.
|
||||
|
||||
We recommend upgrading your `kas` installations together with GitLab instances' upgrades, and to upgrade the `agentk` installations after upgrading GitLab.
|
||||
|
||||
The available `agentk` and `kas` versions can be found in
|
||||
[the container registry](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/container_registry/).
|
||||
|
|
|
|||
|
|
@ -149,39 +149,52 @@ gitops:
|
|||
- glob: '/**/*.yaml'
|
||||
```
|
||||
|
||||
## Authorize groups to use an Agent
|
||||
## Authorize projects and groups to use an Agent
|
||||
|
||||
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
|
||||
> - Group authorization [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
|
||||
> - Project authorization [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327850) in GitLab 14.4.
|
||||
|
||||
If you use the same cluster across multiple projects, you can set up the CI/CD Tunnel
|
||||
to grant the Agent access to one or more groups. This way, all the projects that belong
|
||||
to the authorized groups can access the same Agent. This enables you to save resources and
|
||||
have a scalable setup.
|
||||
If you use the same cluster across multiple projects, you can set up the [CI/CD Tunnel](ci_cd_tunnel.md)
|
||||
to grant access to an Agent from one or more projects or groups. This way, all the authorized
|
||||
projects can access the same Agent, which facilitates you to save resources and have a scalable setup.
|
||||
|
||||
When you authorize a group, the agent's Kubernetes context is automatically injected
|
||||
into every project of the authorized group, and users can select the connection as
|
||||
described in the [CI/CD Tunnel documentation](ci_cd_tunnel.md).
|
||||
To authorize a group to access the Agent through the [CI/CD Tunnel](ci_cd_tunnel.md),
|
||||
use the `ci_access` attribute in your `config.yaml` configuration file.
|
||||
When you authorize a project to use an agent through the [CI/CD Tunnel](ci_cd_tunnel.md),
|
||||
the selected Kubernetes context is automatically injected into CI/CD jobs, allowing you to
|
||||
run Kubernetes commands from your authorized projects' scripts. When you authorize a group,
|
||||
all the projects that belong to that group can access the selected agent.
|
||||
|
||||
An Agent can only authorize groups in the same group hierarchy as the Agent's configuration project. At most
|
||||
100 groups can be authorized per Agent.
|
||||
An Agent can only authorize projects or groups in the same group hierarchy as the Agent's configuration
|
||||
project. You can authorize up to 100 projects and 100 groups per Agent.
|
||||
|
||||
To authorize a group:
|
||||
### Authorize projects to use an Agent
|
||||
|
||||
1. Edit your `config.yaml` file under the `.gitlab/agents/<agent name>` directory.
|
||||
1. Add the `ci_access` root attribute.
|
||||
To grant projects access to the Agent through the [CI/CD Tunnel](ci_cd_tunnel.md):
|
||||
|
||||
1. Go to your Agent's configuration project.
|
||||
1. Edit the Agent's configuration file (`config.yaml`).
|
||||
1. Add the `projects` attribute into `ci_access`.
|
||||
1. Identify the new project through its path:
|
||||
|
||||
```yaml
|
||||
ci_access:
|
||||
projects:
|
||||
- id: path/to/project
|
||||
```
|
||||
|
||||
### Authorize groups to use an Agent
|
||||
|
||||
To grant access to all projects within a group:
|
||||
|
||||
1. Go to your Agent's configuration project.
|
||||
1. Edit the Agent's configuration file (`config.yaml`).
|
||||
1. Add the `groups` attribute into `ci_access`.
|
||||
1. Add the group `id` into `groups`, identifying the authorized group through its path.
|
||||
1. Identify the group or subgroup through its path:
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
ci_access:
|
||||
# This agent is accessible from CI jobs in projects in these groups
|
||||
groups:
|
||||
- id: group/subgroup
|
||||
```
|
||||
```yaml
|
||||
ci_access:
|
||||
groups:
|
||||
- id: path/to/group/subgroup
|
||||
```
|
||||
|
||||
## Surface network security alerts from cluster to GitLab **(ULTIMATE)**
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ installation, such as an Ingress controller.
|
|||
## RBAC compatibility
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/29398) in GitLab 11.4.
|
||||
> - [Project namespace restriction](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51716) was introduced in GitLab 11.5.
|
||||
> - Project namespace restriction was [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51716) in GitLab 11.5.
|
||||
|
||||
For each project under a group with a Kubernetes cluster, GitLab creates a restricted
|
||||
service account with [`edit` privileges](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles)
|
||||
|
|
@ -49,7 +49,7 @@ to the project, provided the cluster is not disabled.
|
|||
|
||||
## Multiple Kubernetes clusters
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35094) in GitLab Free 13.2.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35094) in GitLab 13.2.
|
||||
|
||||
You can associate more than one Kubernetes cluster to your group, and maintain different clusters
|
||||
for different environments, such as development, staging, and production.
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ The concept of [project-level](../../project/clusters/index.md),
|
|||
[instance-level](../../instance/clusters/index.md) clusters becomes
|
||||
extinct in the new model, although the functionality remains to some extent.
|
||||
|
||||
The Agent is always configured in a GitLab project, but you can:
|
||||
|
||||
- [Grant your cluster's access to GitLab groups through the Agent](../../clusters/agent/repository.md#authorize-groups-to-use-an-agent).
|
||||
- [Share access to the Agent with other projects and groups through the CI/CD Tunnel](../../clusters/agent/ci_cd_tunnel.md#share-the-cicd-tunnel-provided-by-an-agent-with-other-projects-and-group).
|
||||
The Agent is always configured in a single GitLab project, but you can use the CI/CD Tunnel to
|
||||
[authorize other projects and groups to use the same Agent](../../clusters/agent/repository.md#authorize-projects-and-groups-to-use-an-agent).
|
||||
By doing so, you are granting these projects and groups access to the same cluster, which is similar to group-level clusters' use case.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module ContainerRepository
|
||||
module Tags
|
||||
class Cache
|
||||
def initialize(container_repository)
|
||||
@container_repository = container_repository
|
||||
@cached_tag_names = Set.new
|
||||
end
|
||||
|
||||
def populate(tags)
|
||||
return if tags.empty?
|
||||
|
||||
# This will load all tags in one Redis roundtrip
|
||||
# the maximum number of tags is configurable and is set to 200 by default.
|
||||
# https://gitlab.com/gitlab-org/gitlab/blob/master/doc/user/packages/container_registry/index.md#set-cleanup-limits-to-conserve-resources
|
||||
keys = tags.map(&method(:cache_key))
|
||||
cached_tags_count = 0
|
||||
|
||||
::Gitlab::Redis::Cache.with do |redis|
|
||||
tags.zip(redis.mget(keys)).each do |tag, created_at|
|
||||
next unless created_at
|
||||
|
||||
tag.created_at = DateTime.rfc3339(created_at)
|
||||
@cached_tag_names << tag.name
|
||||
cached_tags_count += 1
|
||||
end
|
||||
end
|
||||
|
||||
cached_tags_count
|
||||
end
|
||||
|
||||
def insert(tags, max_ttl_in_seconds)
|
||||
return unless max_ttl_in_seconds
|
||||
return if tags.empty?
|
||||
|
||||
# tags with nil created_at are not cacheable
|
||||
# tags already cached don't need to be cached again
|
||||
cacheable_tags = tags.select do |tag|
|
||||
tag.created_at.present? && !tag.name.in?(@cached_tag_names)
|
||||
end
|
||||
|
||||
return if cacheable_tags.empty?
|
||||
|
||||
now = Time.zone.now
|
||||
|
||||
::Gitlab::Redis::Cache.with do |redis|
|
||||
# we use a pipeline instead of a MSET because each tag has
|
||||
# a specific ttl
|
||||
redis.pipelined do
|
||||
cacheable_tags.each do |tag|
|
||||
created_at = tag.created_at
|
||||
# ttl is the max_ttl_in_seconds reduced by the number
|
||||
# of seconds that the tag has already existed
|
||||
ttl = max_ttl_in_seconds - (now - created_at).seconds
|
||||
ttl = ttl.to_i
|
||||
redis.set(cache_key(tag), created_at.rfc3339, ex: ttl) if ttl > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cache_key(tag)
|
||||
"container_repository:{#{@container_repository.id}}:tag:#{tag.name}:created_at"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -91,7 +91,7 @@ module Sidebars
|
|||
|
||||
def google_cloud_menu_item
|
||||
feature_is_enabled = Feature.enabled?(:incubation_5mp_google_cloud)
|
||||
user_has_permissions = can?(context.current_user, :manage_project_google_cloud, context.project)
|
||||
user_has_permissions = can?(context.current_user, :admin_project_google_cloud, context.project)
|
||||
|
||||
unless feature_is_enabled && user_has_permissions
|
||||
return ::Sidebars::NilMenuItem.new(item_id: :incubation_5mp_google_cloud)
|
||||
|
|
|
|||
|
|
@ -2047,9 +2047,6 @@ msgstr ""
|
|||
msgid "Add new directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add new service account"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add or remove previously merged commits"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -3987,9 +3984,6 @@ msgstr ""
|
|||
msgid "Any namespace"
|
||||
msgstr ""
|
||||
|
||||
msgid "App Engine description and apps that are suitable for this deployment target"
|
||||
msgstr ""
|
||||
|
||||
msgid "App ID"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -7283,12 +7277,6 @@ msgstr ""
|
|||
msgid "Closes this %{quick_action_target}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Cloud Functions description and apps that are suitable for this deployment target"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cloud Run description and apps that are suitable for this deployment target"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cluster"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -8728,9 +8716,6 @@ msgstr ""
|
|||
msgid "Configure the way a user creates a new account."
|
||||
msgstr ""
|
||||
|
||||
msgid "Configure via Merge Request"
|
||||
msgstr ""
|
||||
|
||||
msgid "Configure which lists are shown for anyone who visits this board"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -11554,9 +11539,6 @@ msgstr ""
|
|||
msgid "Deployments"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployments to Google Kubernetes Engine can be "
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployments|%{deployments} environment impacted."
|
||||
msgid_plural "Deployments|%{deployments} environments impacted."
|
||||
msgstr[0] ""
|
||||
|
|
@ -16052,9 +16034,6 @@ msgstr ""
|
|||
msgid "Google Cloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "Google Cloud offers several deployment targets. Select the one most suitable for your project."
|
||||
msgstr ""
|
||||
|
||||
msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19607,9 +19586,6 @@ msgstr ""
|
|||
msgid "JiraService|Failed to load Jira issue. View the issue in Jira, or reload the page."
|
||||
msgstr ""
|
||||
|
||||
msgid "JiraService|Failed to update Jira issue labels. View the issue in Jira, or reload the page."
|
||||
msgstr ""
|
||||
|
||||
msgid "JiraService|Failed to update Jira issue status. View the issue in Jira, or reload the page."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31306,9 +31282,6 @@ msgstr ""
|
|||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
msgid "Service Accounts keys are required to authorize GitLab to deploy your Google Cloud project."
|
||||
msgstr ""
|
||||
|
||||
msgid "Service Desk"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -40769,9 +40742,6 @@ msgstr ""
|
|||
msgid "in"
|
||||
msgstr ""
|
||||
|
||||
msgid "in Infrastructure :: Kubernetes clusters"
|
||||
msgstr ""
|
||||
|
||||
msgid "in all GitLab"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -40936,9 +40906,6 @@ msgstr ""
|
|||
msgid "log in"
|
||||
msgstr ""
|
||||
|
||||
msgid "managed"
|
||||
msgstr ""
|
||||
|
||||
msgid "manual"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJob do
|
||||
let(:table_name) { :copy_primary_key_test }
|
||||
let(:table_name) { :_test_copy_primary_key_test }
|
||||
let(:test_table) { table(table_name) }
|
||||
let(:sub_batch_size) { 1000 }
|
||||
let(:pause_ms) { 0 }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ::Projects::ContainerRepository::CacheTagsCreatedAtService, :clean_gitlab_redis_cache do
|
||||
RSpec.describe ::Gitlab::ContainerRepository::Tags::Cache, :clean_gitlab_redis_cache do
|
||||
let_it_be(:dummy_tag_class) { Struct.new(:name, :created_at) }
|
||||
let_it_be(:repository) { create(:container_repository) }
|
||||
|
||||
|
|
@ -286,7 +286,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do
|
|||
let(:migration_wrapper) { Gitlab::Database::BackgroundMigration::BatchedMigrationWrapper.new }
|
||||
|
||||
let(:migration_helpers) { ActiveRecord::Migration.new }
|
||||
let(:table_name) { :_batched_migrations_test_table }
|
||||
let(:table_name) { :_test_batched_migrations_test_table }
|
||||
let(:column_name) { :some_id }
|
||||
let(:job_arguments) { [:some_id, :some_id_convert_to_bigint] }
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
|
|||
describe '.insert_all!' do
|
||||
before do
|
||||
ActiveRecord::Schema.define do
|
||||
create_table :connection_proxy_bulk_insert, force: true do |t|
|
||||
create_table :_test_connection_proxy_bulk_insert, force: true do |t|
|
||||
t.string :name, null: true
|
||||
end
|
||||
end
|
||||
|
|
@ -93,13 +93,13 @@ RSpec.describe Gitlab::Database::LoadBalancing::ConnectionProxy do
|
|||
|
||||
after do
|
||||
ActiveRecord::Schema.define do
|
||||
drop_table :connection_proxy_bulk_insert, force: true
|
||||
drop_table :_test_connection_proxy_bulk_insert, force: true
|
||||
end
|
||||
end
|
||||
|
||||
let(:model_class) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = "connection_proxy_bulk_insert"
|
||||
self.table_name = "_test_connection_proxy_bulk_insert"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ RSpec.describe Gitlab::Database::LoadBalancing do
|
|||
describe 'LoadBalancing integration tests', :database_replica, :delete do
|
||||
before(:all) do
|
||||
ActiveRecord::Schema.define do
|
||||
create_table :load_balancing_test, force: true do |t|
|
||||
create_table :_test_load_balancing_test, force: true do |t|
|
||||
t.string :name, null: true
|
||||
end
|
||||
end
|
||||
|
|
@ -113,13 +113,13 @@ RSpec.describe Gitlab::Database::LoadBalancing do
|
|||
|
||||
after(:all) do
|
||||
ActiveRecord::Schema.define do
|
||||
drop_table :load_balancing_test, force: true
|
||||
drop_table :_test_load_balancing_test, force: true
|
||||
end
|
||||
end
|
||||
|
||||
let(:model) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = "load_balancing_test"
|
||||
self.table_name = "_test_load_balancing_test"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -443,7 +443,7 @@ RSpec.describe Gitlab::Database::LoadBalancing do
|
|||
elsif payload[:name] == 'SQL' # Custom query
|
||||
true
|
||||
else
|
||||
keywords = %w[load_balancing_test]
|
||||
keywords = %w[_test_load_balancing_test]
|
||||
keywords += %w[begin commit] if include_transaction
|
||||
keywords.any? { |keyword| payload[:sql].downcase.include?(keyword) }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,18 +9,18 @@ RSpec.describe Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers do
|
|||
|
||||
let(:model) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_test_table'
|
||||
self.table_name = '_test_loose_fk_test_table'
|
||||
end
|
||||
end
|
||||
|
||||
before(:all) do
|
||||
migration.create_table :loose_fk_test_table do |t|
|
||||
migration.create_table :_test_loose_fk_test_table do |t|
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
migration.drop_table :loose_fk_test_table
|
||||
migration.drop_table :_test_loose_fk_test_table
|
||||
end
|
||||
|
||||
before do
|
||||
|
|
@ -37,7 +37,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers do
|
|||
|
||||
context 'when the record deletion tracker trigger is installed' do
|
||||
before do
|
||||
migration.track_record_deletions(:loose_fk_test_table)
|
||||
migration.track_record_deletions(:_test_loose_fk_test_table)
|
||||
end
|
||||
|
||||
it 'stores the record deletion' do
|
||||
|
|
@ -50,7 +50,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers do
|
|||
deleted_record = LooseForeignKeys::DeletedRecord.all.first
|
||||
|
||||
expect(deleted_record.primary_key_value).to eq(record_to_be_deleted.id)
|
||||
expect(deleted_record.fully_qualified_table_name).to eq('public.loose_fk_test_table')
|
||||
expect(deleted_record.fully_qualified_table_name).to eq('public._test_loose_fk_test_table')
|
||||
expect(deleted_record.partition).to eq(1)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
let(:model) { Class.new(ActiveRecord::Base) }
|
||||
|
||||
before do
|
||||
model.table_name = :test_table
|
||||
model.table_name = :_test_table
|
||||
end
|
||||
|
||||
context 'when called inside a transaction block' do
|
||||
|
|
@ -30,19 +30,19 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
|
||||
it 'raises an error' do
|
||||
expect do
|
||||
migration.public_send(operation, :test_table, :original, :renamed)
|
||||
migration.public_send(operation, :_test_table, :original, :renamed)
|
||||
end.to raise_error("#{operation} can not be run inside a transaction")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the existing column has a default value' do
|
||||
before do
|
||||
migration.change_column_default :test_table, existing_column, 'default value'
|
||||
migration.change_column_default :_test_table, existing_column, 'default value'
|
||||
end
|
||||
|
||||
it 'raises an error' do
|
||||
expect do
|
||||
migration.public_send(operation, :test_table, :original, :renamed)
|
||||
migration.public_send(operation, :_test_table, :original, :renamed)
|
||||
end.to raise_error("#{operation} does not currently support columns with default values")
|
||||
end
|
||||
end
|
||||
|
|
@ -51,18 +51,18 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
context 'when the batch column does not exist' do
|
||||
it 'raises an error' do
|
||||
expect do
|
||||
migration.public_send(operation, :test_table, :original, :renamed, batch_column_name: :missing)
|
||||
end.to raise_error('Column missing does not exist on test_table')
|
||||
migration.public_send(operation, :_test_table, :original, :renamed, batch_column_name: :missing)
|
||||
end.to raise_error('Column missing does not exist on _test_table')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the batch column does exist' do
|
||||
it 'passes it when creating the column' do
|
||||
expect(migration).to receive(:create_column_from)
|
||||
.with(:test_table, existing_column, added_column, type: nil, batch_column_name: :status)
|
||||
.with(:_test_table, existing_column, added_column, type: nil, batch_column_name: :status)
|
||||
.and_call_original
|
||||
|
||||
migration.public_send(operation, :test_table, :original, :renamed, batch_column_name: :status)
|
||||
migration.public_send(operation, :_test_table, :original, :renamed, batch_column_name: :status)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -71,17 +71,17 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
existing_record_1 = model.create!(status: 0, existing_column => 'existing')
|
||||
existing_record_2 = model.create!(status: 0, existing_column => nil)
|
||||
|
||||
migration.send(operation, :test_table, :original, :renamed)
|
||||
migration.send(operation, :_test_table, :original, :renamed)
|
||||
model.reset_column_information
|
||||
|
||||
expect(migration.column_exists?(:test_table, added_column)).to eq(true)
|
||||
expect(migration.column_exists?(:_test_table, added_column)).to eq(true)
|
||||
|
||||
expect(existing_record_1.reload).to have_attributes(status: 0, original: 'existing', renamed: 'existing')
|
||||
expect(existing_record_2.reload).to have_attributes(status: 0, original: nil, renamed: nil)
|
||||
end
|
||||
|
||||
it 'installs triggers to sync new data' do
|
||||
migration.public_send(operation, :test_table, :original, :renamed)
|
||||
migration.public_send(operation, :_test_table, :original, :renamed)
|
||||
model.reset_column_information
|
||||
|
||||
new_record_1 = model.create!(status: 1, original: 'first')
|
||||
|
|
@ -102,7 +102,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
before do
|
||||
allow(migration).to receive(:transaction_open?).and_return(false)
|
||||
|
||||
migration.create_table :test_table do |t|
|
||||
migration.create_table :_test_table do |t|
|
||||
t.integer :status, null: false
|
||||
t.text :original
|
||||
t.text :other_column
|
||||
|
|
@ -118,8 +118,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
context 'when the column to rename does not exist' do
|
||||
it 'raises an error' do
|
||||
expect do
|
||||
migration.rename_column_concurrently :test_table, :missing_column, :renamed
|
||||
end.to raise_error('Column missing_column does not exist on test_table')
|
||||
migration.rename_column_concurrently :_test_table, :missing_column, :renamed
|
||||
end.to raise_error('Column missing_column does not exist on _test_table')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -128,7 +128,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
before do
|
||||
allow(migration).to receive(:transaction_open?).and_return(false)
|
||||
|
||||
migration.create_table :test_table do |t|
|
||||
migration.create_table :_test_table do |t|
|
||||
t.integer :status, null: false
|
||||
t.text :other_column
|
||||
t.text :renamed
|
||||
|
|
@ -144,8 +144,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
context 'when the renamed column does not exist' do
|
||||
it 'raises an error' do
|
||||
expect do
|
||||
migration.undo_cleanup_concurrent_column_rename :test_table, :original, :missing_column
|
||||
end.to raise_error('Column missing_column does not exist on test_table')
|
||||
migration.undo_cleanup_concurrent_column_rename :_test_table, :original, :missing_column
|
||||
end.to raise_error('Column missing_column does not exist on _test_table')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -156,25 +156,25 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
before do
|
||||
allow(migration).to receive(:transaction_open?).and_return(false)
|
||||
|
||||
migration.create_table :test_table do |t|
|
||||
migration.create_table :_test_table do |t|
|
||||
t.integer :status, null: false
|
||||
t.text :original
|
||||
t.text :other_column
|
||||
end
|
||||
|
||||
migration.rename_column_concurrently :test_table, :original, :renamed
|
||||
migration.rename_column_concurrently :_test_table, :original, :renamed
|
||||
end
|
||||
|
||||
context 'when the helper is called repeatedly' do
|
||||
before do
|
||||
migration.public_send(operation, :test_table, :original, :renamed)
|
||||
migration.public_send(operation, :_test_table, :original, :renamed)
|
||||
end
|
||||
|
||||
it 'does not make repeated attempts to cleanup' do
|
||||
expect(migration).not_to receive(:remove_column)
|
||||
|
||||
expect do
|
||||
migration.public_send(operation, :test_table, :original, :renamed)
|
||||
migration.public_send(operation, :_test_table, :original, :renamed)
|
||||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
|
@ -182,26 +182,26 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
context 'when the renamed column exists' do
|
||||
let(:triggers) do
|
||||
[
|
||||
['trigger_7cc71f92fd63', 'function_for_trigger_7cc71f92fd63', before: 'insert'],
|
||||
['trigger_f1a1f619636a', 'function_for_trigger_f1a1f619636a', before: 'update'],
|
||||
['trigger_769a49938884', 'function_for_trigger_769a49938884', before: 'update']
|
||||
['trigger_020dbcb8cdd0', 'function_for_trigger_020dbcb8cdd0', before: 'insert'],
|
||||
['trigger_6edaca641d03', 'function_for_trigger_6edaca641d03', before: 'update'],
|
||||
['trigger_a3fb9f3add34', 'function_for_trigger_a3fb9f3add34', before: 'update']
|
||||
]
|
||||
end
|
||||
|
||||
it 'removes the sync triggers and renamed columns' do
|
||||
triggers.each do |(trigger_name, function_name, event)|
|
||||
expect_function_to_exist(function_name)
|
||||
expect_valid_function_trigger(:test_table, trigger_name, function_name, event)
|
||||
expect_valid_function_trigger(:_test_table, trigger_name, function_name, event)
|
||||
end
|
||||
|
||||
expect(migration.column_exists?(:test_table, added_column)).to eq(true)
|
||||
expect(migration.column_exists?(:_test_table, added_column)).to eq(true)
|
||||
|
||||
migration.public_send(operation, :test_table, :original, :renamed)
|
||||
migration.public_send(operation, :_test_table, :original, :renamed)
|
||||
|
||||
expect(migration.column_exists?(:test_table, added_column)).to eq(false)
|
||||
expect(migration.column_exists?(:_test_table, added_column)).to eq(false)
|
||||
|
||||
triggers.each do |(trigger_name, function_name, _)|
|
||||
expect_trigger_not_to_exist(:test_table, trigger_name)
|
||||
expect_trigger_not_to_exist(:_test_table, trigger_name)
|
||||
expect_function_not_to_exist(function_name)
|
||||
end
|
||||
end
|
||||
|
|
@ -223,7 +223,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
end
|
||||
|
||||
describe '#create_table' do
|
||||
let(:table_name) { :test_table }
|
||||
let(:table_name) { :_test_table }
|
||||
let(:column_attributes) do
|
||||
[
|
||||
{ name: 'id', sql_type: 'bigint', null: false, default: nil },
|
||||
|
|
@ -245,7 +245,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
|
|||
end
|
||||
|
||||
expect_table_columns_to_match(column_attributes, table_name)
|
||||
expect_check_constraint(table_name, 'check_cda6f69506', 'char_length(name) <= 100')
|
||||
expect_check_constraint(table_name, 'check_e9982cf9da', 'char_length(name) <= 100')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
|
||||
let(:model) { double('model', table_name: table_name) }
|
||||
let(:partitioning_key) { double }
|
||||
let(:table_name) { :partitioned_test }
|
||||
let(:table_name) { :_test_partitioned_test }
|
||||
|
||||
before do
|
||||
connection.execute(<<~SQL)
|
||||
|
|
@ -18,11 +18,11 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
(id serial not null, created_at timestamptz not null, PRIMARY KEY (id, created_at))
|
||||
PARTITION BY RANGE (created_at);
|
||||
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.partitioned_test_000000
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_partitioned_test_000000
|
||||
PARTITION OF #{table_name}
|
||||
FOR VALUES FROM (MINVALUE) TO ('2020-05-01');
|
||||
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.partitioned_test_202005
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_partitioned_test_202005
|
||||
PARTITION OF #{table_name}
|
||||
FOR VALUES FROM ('2020-05-01') TO ('2020-06-01');
|
||||
SQL
|
||||
|
|
@ -30,8 +30,8 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
|
||||
it 'detects both partitions' do
|
||||
expect(subject).to eq([
|
||||
Gitlab::Database::Partitioning::TimePartition.new(table_name, nil, '2020-05-01', partition_name: 'partitioned_test_000000'),
|
||||
Gitlab::Database::Partitioning::TimePartition.new(table_name, '2020-05-01', '2020-06-01', partition_name: 'partitioned_test_202005')
|
||||
Gitlab::Database::Partitioning::TimePartition.new(table_name, nil, '2020-05-01', partition_name: '_test_partitioned_test_000000'),
|
||||
Gitlab::Database::Partitioning::TimePartition.new(table_name, '2020-05-01', '2020-06-01', partition_name: '_test_partitioned_test_202005')
|
||||
])
|
||||
end
|
||||
end
|
||||
|
|
@ -41,7 +41,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
|
||||
let(:model) do
|
||||
Class.new(ActiveRecord::Base) do
|
||||
self.table_name = 'partitioned_test'
|
||||
self.table_name = '_test_partitioned_test'
|
||||
self.primary_key = :id
|
||||
end
|
||||
end
|
||||
|
|
@ -59,11 +59,11 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
(id serial not null, created_at timestamptz not null, PRIMARY KEY (id, created_at))
|
||||
PARTITION BY RANGE (created_at);
|
||||
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.partitioned_test_000000
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_partitioned_test_000000
|
||||
PARTITION OF #{model.table_name}
|
||||
FOR VALUES FROM (MINVALUE) TO ('2020-05-01');
|
||||
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.partitioned_test_202006
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_partitioned_test_202006
|
||||
PARTITION OF #{model.table_name}
|
||||
FOR VALUES FROM ('2020-06-01') TO ('2020-07-01');
|
||||
SQL
|
||||
|
|
@ -166,7 +166,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
(id serial not null, created_at timestamptz not null, PRIMARY KEY (id, created_at))
|
||||
PARTITION BY RANGE (created_at);
|
||||
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.partitioned_test_202006
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_partitioned_test_202006
|
||||
PARTITION OF #{model.table_name}
|
||||
FOR VALUES FROM ('2020-06-01') TO ('2020-07-01');
|
||||
SQL
|
||||
|
|
@ -181,13 +181,13 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
describe '#extra_partitions' do
|
||||
let(:model) do
|
||||
Class.new(ActiveRecord::Base) do
|
||||
self.table_name = 'partitioned_test'
|
||||
self.table_name = '_test_partitioned_test'
|
||||
self.primary_key = :id
|
||||
end
|
||||
end
|
||||
|
||||
let(:partitioning_key) { :created_at }
|
||||
let(:table_name) { :partitioned_test }
|
||||
let(:table_name) { :_test_partitioned_test }
|
||||
|
||||
around do |example|
|
||||
travel_to(Date.parse('2020-08-22')) { example.run }
|
||||
|
|
@ -200,15 +200,15 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
(id serial not null, created_at timestamptz not null, PRIMARY KEY (id, created_at))
|
||||
PARTITION BY RANGE (created_at);
|
||||
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.partitioned_test_000000
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_partitioned_test_000000
|
||||
PARTITION OF #{table_name}
|
||||
FOR VALUES FROM (MINVALUE) TO ('2020-05-01');
|
||||
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.partitioned_test_202005
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_partitioned_test_202005
|
||||
PARTITION OF #{table_name}
|
||||
FOR VALUES FROM ('2020-05-01') TO ('2020-06-01');
|
||||
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}.partitioned_test_202006
|
||||
CREATE TABLE #{Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA}._test_partitioned_test_202006
|
||||
PARTITION OF #{table_name}
|
||||
FOR VALUES FROM ('2020-06-01') TO ('2020-07-01')
|
||||
SQL
|
||||
|
|
@ -235,7 +235,7 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
|
||||
it 'prunes the unbounded partition ending 2020-05-01' do
|
||||
min_value_to_may = Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01',
|
||||
partition_name: 'partitioned_test_000000')
|
||||
partition_name: '_test_partitioned_test_000000')
|
||||
|
||||
expect(subject).to contain_exactly(min_value_to_may)
|
||||
end
|
||||
|
|
@ -246,8 +246,8 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
|
||||
it 'prunes the unbounded partition and the partition for May-June' do
|
||||
expect(subject).to contain_exactly(
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01', partition_name: 'partitioned_test_000000'),
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01', partition_name: 'partitioned_test_202005')
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01', partition_name: '_test_partitioned_test_000000'),
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01', partition_name: '_test_partitioned_test_202005')
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -256,16 +256,16 @@ RSpec.describe Gitlab::Database::Partitioning::MonthlyStrategy do
|
|||
|
||||
it 'prunes empty partitions' do
|
||||
expect(subject).to contain_exactly(
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01', partition_name: 'partitioned_test_000000'),
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01', partition_name: 'partitioned_test_202005')
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01', partition_name: '_test_partitioned_test_000000'),
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, '2020-05-01', '2020-06-01', partition_name: '_test_partitioned_test_202005')
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not prune non-empty partitions' do
|
||||
connection.execute("INSERT INTO #{table_name} (created_at) VALUES (('2020-05-15'))") # inserting one record into partitioned_test_202005
|
||||
connection.execute("INSERT INTO #{table_name} (created_at) VALUES (('2020-05-15'))") # inserting one record into _test_partitioned_test_202005
|
||||
|
||||
expect(subject).to contain_exactly(
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01', partition_name: 'partitioned_test_000000')
|
||||
Gitlab::Database::Partitioning::TimePartition.new(model.table_name, nil, '2020-05-01', partition_name: '_test_partitioned_test_000000')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ RSpec.describe Gitlab::Database::SchemaCacheWithRenamedTable do
|
|||
|
||||
let(:new_model) do
|
||||
Class.new(ActiveRecord::Base) do
|
||||
self.table_name = 'projects_new'
|
||||
self.table_name = '_test_projects_new'
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const('Gitlab::Database::TABLES_TO_BE_RENAMED', { 'projects' => 'projects_new' })
|
||||
stub_const('Gitlab::Database::TABLES_TO_BE_RENAMED', { 'projects' => '_test_projects_new' })
|
||||
end
|
||||
|
||||
context 'when table is not renamed yet' do
|
||||
|
|
@ -32,8 +32,8 @@ RSpec.describe Gitlab::Database::SchemaCacheWithRenamedTable do
|
|||
|
||||
context 'when table is renamed' do
|
||||
before do
|
||||
ActiveRecord::Base.connection.execute("ALTER TABLE projects RENAME TO projects_new")
|
||||
ActiveRecord::Base.connection.execute("CREATE VIEW projects AS SELECT * FROM projects_new")
|
||||
ActiveRecord::Base.connection.execute("ALTER TABLE projects RENAME TO _test_projects_new")
|
||||
ActiveRecord::Base.connection.execute("CREATE VIEW projects AS SELECT * FROM _test_projects_new")
|
||||
|
||||
old_model.reset_column_information
|
||||
ActiveRecord::Base.connection.schema_cache.clear!
|
||||
|
|
@ -54,14 +54,14 @@ RSpec.describe Gitlab::Database::SchemaCacheWithRenamedTable do
|
|||
|
||||
it 'has the same indexes' do
|
||||
indexes_for_old_table = ActiveRecord::Base.connection.schema_cache.indexes('projects')
|
||||
indexes_for_new_table = ActiveRecord::Base.connection.schema_cache.indexes('projects_new')
|
||||
indexes_for_new_table = ActiveRecord::Base.connection.schema_cache.indexes('_test_projects_new')
|
||||
|
||||
expect(indexes_for_old_table).to eq(indexes_for_new_table)
|
||||
end
|
||||
|
||||
it 'has the same column_hash' do
|
||||
columns_hash_for_old_table = ActiveRecord::Base.connection.schema_cache.columns_hash('projects')
|
||||
columns_hash_for_new_table = ActiveRecord::Base.connection.schema_cache.columns_hash('projects_new')
|
||||
columns_hash_for_new_table = ActiveRecord::Base.connection.schema_cache.columns_hash('_test_projects_new')
|
||||
|
||||
expect(columns_hash_for_old_table).to eq(columns_hash_for_new_table)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ RSpec.describe ::Gitlab::Graphql::Pagination::Connections do
|
|||
|
||||
before(:all) do
|
||||
ActiveRecord::Schema.define do
|
||||
create_table :testing_pagination_nodes, force: true do |t|
|
||||
create_table :_test_testing_pagination_nodes, force: true do |t|
|
||||
t.integer :value, null: false
|
||||
end
|
||||
end
|
||||
|
|
@ -16,13 +16,13 @@ RSpec.describe ::Gitlab::Graphql::Pagination::Connections do
|
|||
|
||||
after(:all) do
|
||||
ActiveRecord::Schema.define do
|
||||
drop_table :testing_pagination_nodes, force: true
|
||||
drop_table :_test_testing_pagination_nodes, force: true
|
||||
end
|
||||
end
|
||||
|
||||
let_it_be(:node_model) do
|
||||
Class.new(ActiveRecord::Base) do
|
||||
self.table_name = 'testing_pagination_nodes'
|
||||
self.table_name = '_test_testing_pagination_nodes'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,42 +5,42 @@ require 'spec_helper'
|
|||
RSpec.describe BulkInsertSafe do
|
||||
before(:all) do
|
||||
ActiveRecord::Schema.define do
|
||||
create_table :bulk_insert_parent_items, force: true do |t|
|
||||
create_table :_test_bulk_insert_parent_items, force: true do |t|
|
||||
t.string :name, null: false
|
||||
end
|
||||
|
||||
create_table :bulk_insert_items, force: true do |t|
|
||||
create_table :_test_bulk_insert_items, force: true do |t|
|
||||
t.string :name, null: true
|
||||
t.integer :enum_value, null: false
|
||||
t.text :encrypted_secret_value, null: false
|
||||
t.string :encrypted_secret_value_iv, null: false
|
||||
t.binary :sha_value, null: false, limit: 20
|
||||
t.jsonb :jsonb_value, null: false
|
||||
t.belongs_to :bulk_insert_parent_item, foreign_key: true, null: true
|
||||
t.belongs_to :bulk_insert_parent_item, foreign_key: { to_table: :_test_bulk_insert_parent_items }, null: true
|
||||
t.timestamps null: true
|
||||
|
||||
t.index :name, unique: true
|
||||
end
|
||||
|
||||
create_table :bulk_insert_items_with_composite_pk, id: false, force: true do |t|
|
||||
create_table :_test_bulk_insert_items_with_composite_pk, id: false, force: true do |t|
|
||||
t.integer :id, null: true
|
||||
t.string :name, null: true
|
||||
end
|
||||
|
||||
execute("ALTER TABLE bulk_insert_items_with_composite_pk ADD PRIMARY KEY (id,name);")
|
||||
execute("ALTER TABLE _test_bulk_insert_items_with_composite_pk ADD PRIMARY KEY (id,name);")
|
||||
end
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
ActiveRecord::Schema.define do
|
||||
drop_table :bulk_insert_items, force: true
|
||||
drop_table :bulk_insert_parent_items, force: true
|
||||
drop_table :bulk_insert_items_with_composite_pk, force: true
|
||||
drop_table :_test_bulk_insert_items, force: true
|
||||
drop_table :_test_bulk_insert_parent_items, force: true
|
||||
drop_table :_test_bulk_insert_items_with_composite_pk, force: true
|
||||
end
|
||||
end
|
||||
|
||||
BulkInsertParentItem = Class.new(ActiveRecord::Base) do
|
||||
self.table_name = :bulk_insert_parent_items
|
||||
self.table_name = :_test_bulk_insert_parent_items
|
||||
self.inheritance_column = :_type_disabled
|
||||
|
||||
def self.name
|
||||
|
|
@ -54,7 +54,7 @@ RSpec.describe BulkInsertSafe do
|
|||
|
||||
let_it_be(:bulk_insert_item_class) do
|
||||
Class.new(ActiveRecord::Base) do
|
||||
self.table_name = 'bulk_insert_items'
|
||||
self.table_name = '_test_bulk_insert_items'
|
||||
|
||||
include BulkInsertSafe
|
||||
include ShaAttribute
|
||||
|
|
@ -247,7 +247,7 @@ RSpec.describe BulkInsertSafe do
|
|||
context 'when a model with composite primary key is inserted' do
|
||||
let_it_be(:bulk_insert_items_with_composite_pk_class) do
|
||||
Class.new(ActiveRecord::Base) do
|
||||
self.table_name = 'bulk_insert_items_with_composite_pk'
|
||||
self.table_name = '_test_bulk_insert_items_with_composite_pk'
|
||||
|
||||
include BulkInsertSafe
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,42 +6,50 @@ RSpec.describe BulkInsertableAssociations do
|
|||
class BulkFoo < ApplicationRecord
|
||||
include BulkInsertSafe
|
||||
|
||||
self.table_name = '_test_bulk_foos'
|
||||
|
||||
validates :name, presence: true
|
||||
end
|
||||
|
||||
class BulkBar < ApplicationRecord
|
||||
include BulkInsertSafe
|
||||
|
||||
self.table_name = '_test_bulk_bars'
|
||||
end
|
||||
|
||||
SimpleBar = Class.new(ApplicationRecord)
|
||||
SimpleBar = Class.new(ApplicationRecord) do
|
||||
self.table_name = '_test_simple_bars'
|
||||
end
|
||||
|
||||
class BulkParent < ApplicationRecord
|
||||
include BulkInsertableAssociations
|
||||
|
||||
has_many :bulk_foos
|
||||
self.table_name = '_test_bulk_parents'
|
||||
|
||||
has_many :bulk_foos, class_name: 'BulkFoo'
|
||||
has_many :bulk_hunks, class_name: 'BulkFoo'
|
||||
has_many :bulk_bars
|
||||
has_many :simple_bars # not `BulkInsertSafe`
|
||||
has_many :bulk_bars, class_name: 'BulkBar'
|
||||
has_many :simple_bars, class_name: 'SimpleBar' # not `BulkInsertSafe`
|
||||
has_one :bulk_foo # not supported
|
||||
end
|
||||
|
||||
before(:all) do
|
||||
ActiveRecord::Schema.define do
|
||||
create_table :bulk_parents, force: true do |t|
|
||||
create_table :_test_bulk_parents, force: true do |t|
|
||||
t.string :name, null: true
|
||||
end
|
||||
|
||||
create_table :bulk_foos, force: true do |t|
|
||||
create_table :_test_bulk_foos, force: true do |t|
|
||||
t.string :name, null: true
|
||||
t.belongs_to :bulk_parent, null: false
|
||||
end
|
||||
|
||||
create_table :bulk_bars, force: true do |t|
|
||||
create_table :_test_bulk_bars, force: true do |t|
|
||||
t.string :name, null: true
|
||||
t.belongs_to :bulk_parent, null: false
|
||||
end
|
||||
|
||||
create_table :simple_bars, force: true do |t|
|
||||
create_table :_test_simple_bars, force: true do |t|
|
||||
t.string :name, null: true
|
||||
t.belongs_to :bulk_parent, null: false
|
||||
end
|
||||
|
|
@ -50,10 +58,10 @@ RSpec.describe BulkInsertableAssociations do
|
|||
|
||||
after(:all) do
|
||||
ActiveRecord::Schema.define do
|
||||
drop_table :bulk_foos, force: true
|
||||
drop_table :bulk_bars, force: true
|
||||
drop_table :simple_bars, force: true
|
||||
drop_table :bulk_parents, force: true
|
||||
drop_table :_test_bulk_foos, force: true
|
||||
drop_table :_test_bulk_bars, force: true
|
||||
drop_table :_test_simple_bars, force: true
|
||||
drop_table :_test_bulk_parents, force: true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe WhereComposite do
|
||||
describe '.where_composite' do
|
||||
let_it_be(:test_table_name) { "test_table_#{SecureRandom.hex(10)}" }
|
||||
let_it_be(:test_table_name) { "_test_table_#{SecureRandom.hex(10)}" }
|
||||
|
||||
let(:model) do
|
||||
tbl_name = test_table_name
|
||||
|
|
|
|||
|
|
@ -571,16 +571,6 @@ RSpec.describe Group do
|
|||
it 'filters out project namespace' do
|
||||
expect(group.descendants.find_by_id(project_namespace.id)).to be_nil
|
||||
end
|
||||
|
||||
context 'when include_sti_condition is disabled' do
|
||||
before do
|
||||
stub_feature_flags(include_sti_condition: false)
|
||||
end
|
||||
|
||||
it 'raises an exception' do
|
||||
expect { group.descendants.find_by_id(project_namespace.id)}.to raise_error(ActiveRecord::SubclassNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -955,6 +955,28 @@ RSpec.describe ProjectPolicy do
|
|||
end
|
||||
end
|
||||
|
||||
context 'infrastructure google cloud feature' do
|
||||
%w(guest reporter developer).each do |role|
|
||||
context role do
|
||||
let(:current_user) { send(role) }
|
||||
|
||||
it 'disallows managing google cloud' do
|
||||
expect_disallowed(:admin_project_google_cloud)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%w(maintainer owner).each do |role|
|
||||
context role do
|
||||
let(:current_user) { send(role) }
|
||||
|
||||
it 'allows managing google cloud' do
|
||||
expect_allowed(:admin_project_google_cloud)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'design permissions' do
|
||||
include DesignManagementTestHelpers
|
||||
|
||||
|
|
|
|||
|
|
@ -2,48 +2,106 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
# Mock Types
|
||||
MockGoogleOAuth2Credentials = Struct.new(:app_id, :app_secret)
|
||||
|
||||
RSpec.describe Projects::GoogleCloudController do
|
||||
let_it_be(:project) { create(:project, :public) }
|
||||
|
||||
describe 'GET index' do
|
||||
let_it_be(:url) { "#{project_google_cloud_index_path(project)}" }
|
||||
|
||||
let(:subject) { get url }
|
||||
context 'when a public request is made' do
|
||||
it 'returns not found' do
|
||||
get url
|
||||
|
||||
context 'when user is authorized' do
|
||||
let(:user) { project.creator }
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
subject
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a project.guest makes request' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'returns not found' do
|
||||
project.add_guest(user)
|
||||
sign_in(user)
|
||||
|
||||
get url
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project.developer makes request' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'returns not found' do
|
||||
project.add_developer(user)
|
||||
sign_in(user)
|
||||
|
||||
get url
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project.maintainer makes request' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'returns successful' do
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
get url
|
||||
|
||||
it 'renders content' do
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is unauthorized' do
|
||||
let(:user) { create(:user) }
|
||||
context 'when project.creator makes request' do
|
||||
let(:user) { project.creator }
|
||||
|
||||
before do
|
||||
project.add_guest(user)
|
||||
it 'returns successful' do
|
||||
sign_in(user)
|
||||
subject
|
||||
end
|
||||
|
||||
it 'shows 404' do
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
get url
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no user is present' do
|
||||
before do
|
||||
subject
|
||||
describe 'when authorized user makes request' do
|
||||
let(:user) { project.creator }
|
||||
|
||||
context 'but gitlab instance is not configured for google oauth2' do
|
||||
before do
|
||||
unconfigured_google_oauth2 = MockGoogleOAuth2Credentials.new('', '')
|
||||
allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for)
|
||||
.with('google_oauth2')
|
||||
.and_return(unconfigured_google_oauth2)
|
||||
end
|
||||
|
||||
it 'returns forbidden' do
|
||||
sign_in(user)
|
||||
|
||||
get url
|
||||
|
||||
expect(response).to have_gitlab_http_status(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
it 'shows 404' do
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
context 'but feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(incubation_5mp_google_cloud: false)
|
||||
end
|
||||
|
||||
it 'returns not found' do
|
||||
sign_in(user)
|
||||
|
||||
get url
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,28 +26,6 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
|
|||
pull_request.update!(source_branch: source_branch.name, source_sha: source_branch.target)
|
||||
end
|
||||
|
||||
context 'when the FF ci_create_external_pr_pipeline_async is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_create_external_pr_pipeline_async: false)
|
||||
end
|
||||
|
||||
it 'creates a pipeline for external pull request', :aggregate_failures do
|
||||
pipeline = execute.payload
|
||||
|
||||
expect(execute).to be_success
|
||||
expect(pipeline).to be_valid
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline).to be_external_pull_request_event
|
||||
expect(pipeline).to eq(project.ci_pipelines.last)
|
||||
expect(pipeline.external_pull_request).to eq(pull_request)
|
||||
expect(pipeline.user).to eq(user)
|
||||
expect(pipeline.status).to eq('created')
|
||||
expect(pipeline.ref).to eq(pull_request.source_branch)
|
||||
expect(pipeline.sha).to eq(pull_request.source_sha)
|
||||
expect(pipeline.source_sha).to eq(pull_request.source_sha)
|
||||
end
|
||||
end
|
||||
|
||||
it 'enqueues Ci::ExternalPullRequests::CreatePipelineWorker' do
|
||||
expect { execute }
|
||||
.to change { ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.count }
|
||||
|
|
|
|||
|
|
@ -8,44 +8,44 @@ RSpec.describe LooseForeignKeys::BatchCleanerService do
|
|||
def create_table_structure
|
||||
migration = ActiveRecord::Migration.new.extend(Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers)
|
||||
|
||||
migration.create_table :loose_fk_parent_table
|
||||
migration.create_table :_test_loose_fk_parent_table
|
||||
|
||||
migration.create_table :loose_fk_child_table_1 do |t|
|
||||
migration.create_table :_test_loose_fk_child_table_1 do |t|
|
||||
t.bigint :parent_id
|
||||
end
|
||||
|
||||
migration.create_table :loose_fk_child_table_2 do |t|
|
||||
migration.create_table :_test_loose_fk_child_table_2 do |t|
|
||||
t.bigint :parent_id_with_different_column
|
||||
end
|
||||
|
||||
migration.track_record_deletions(:loose_fk_parent_table)
|
||||
migration.track_record_deletions(:_test_loose_fk_parent_table)
|
||||
end
|
||||
|
||||
let(:parent_model) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_parent_table'
|
||||
self.table_name = '_test_loose_fk_parent_table'
|
||||
|
||||
include LooseForeignKey
|
||||
|
||||
loose_foreign_key :loose_fk_child_table_1, :parent_id, on_delete: :async_delete
|
||||
loose_foreign_key :loose_fk_child_table_2, :parent_id_with_different_column, on_delete: :async_nullify
|
||||
loose_foreign_key :_test_loose_fk_child_table_1, :parent_id, on_delete: :async_delete
|
||||
loose_foreign_key :_test_loose_fk_child_table_2, :parent_id_with_different_column, on_delete: :async_nullify
|
||||
end
|
||||
end
|
||||
|
||||
let(:child_model_1) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_child_table_1'
|
||||
self.table_name = '_test_loose_fk_child_table_1'
|
||||
end
|
||||
end
|
||||
|
||||
let(:child_model_2) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_child_table_2'
|
||||
self.table_name = '_test_loose_fk_child_table_2'
|
||||
end
|
||||
end
|
||||
|
||||
let(:loose_fk_child_table_1) { table(:loose_fk_child_table_1) }
|
||||
let(:loose_fk_child_table_2) { table(:loose_fk_child_table_2) }
|
||||
let(:loose_fk_child_table_1) { table(:_test_loose_fk_child_table_1) }
|
||||
let(:loose_fk_child_table_2) { table(:_test_loose_fk_child_table_2) }
|
||||
let(:parent_record_1) { parent_model.create! }
|
||||
let(:other_parent_record) { parent_model.create! }
|
||||
|
||||
|
|
@ -73,9 +73,9 @@ RSpec.describe LooseForeignKeys::BatchCleanerService do
|
|||
|
||||
after(:all) do
|
||||
migration = ActiveRecord::Migration.new
|
||||
migration.drop_table :loose_fk_parent_table
|
||||
migration.drop_table :loose_fk_child_table_1
|
||||
migration.drop_table :loose_fk_child_table_2
|
||||
migration.drop_table :_test_loose_fk_parent_table
|
||||
migration.drop_table :_test_loose_fk_child_table_1
|
||||
migration.drop_table :_test_loose_fk_child_table_2
|
||||
end
|
||||
|
||||
context 'when parent records are deleted' do
|
||||
|
|
@ -90,8 +90,8 @@ RSpec.describe LooseForeignKeys::BatchCleanerService do
|
|||
described_class.new(parent_klass: parent_model,
|
||||
deleted_parent_records: LooseForeignKeys::DeletedRecord.status_pending.all,
|
||||
models_by_table_name: {
|
||||
'loose_fk_child_table_1' => child_model_1,
|
||||
'loose_fk_child_table_2' => child_model_2
|
||||
'_test_loose_fk_child_table_1' => child_model_1,
|
||||
'_test_loose_fk_child_table_2' => child_model_2
|
||||
}).execute
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -25,26 +25,6 @@ RSpec.shared_examples 'namespace traversal scopes' do
|
|||
it { is_expected.to contain_exactly(group_1.id, group_2.id) }
|
||||
end
|
||||
|
||||
describe '.without_sti_condition' do
|
||||
subject { described_class.where(type: 'Group').without_sti_condition }
|
||||
|
||||
context 'when include_sti_condition is enabled' do
|
||||
before do
|
||||
stub_feature_flags(include_sti_condition: true)
|
||||
end
|
||||
|
||||
it { expect(subject.where_values_hash).to have_key('type') }
|
||||
end
|
||||
|
||||
context 'when include_sti_condition is disabled' do
|
||||
before do
|
||||
stub_feature_flags(include_sti_condition: false)
|
||||
end
|
||||
|
||||
it { expect(subject.where_values_hash).not_to have_key('type') }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.order_by_depth' do
|
||||
subject { described_class.where(id: [group_1, nested_group_1, deep_nested_group_1]).order_by_depth(direction) }
|
||||
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
|
|||
stub_feature_flags(database_async_index_creation: true)
|
||||
|
||||
expect(Gitlab::Database::AsyncIndexes).to receive(:create_pending_indexes!).ordered.exactly(databases_count).times
|
||||
expect(Gitlab::Database::Reindexing).to receive(:automatic_reindexing).ordered.once
|
||||
expect(Gitlab::Database::Reindexing).to receive(:automatic_reindexing).ordered.exactly(databases_count).times
|
||||
|
||||
run_rake_task('gitlab:db:reindex')
|
||||
end
|
||||
|
|
@ -233,7 +233,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
|
|||
|
||||
context 'calls automatic reindexing' do
|
||||
it 'uses all candidate indexes' do
|
||||
expect(Gitlab::Database::Reindexing).to receive(:automatic_reindexing).once
|
||||
expect(Gitlab::Database::Reindexing).to receive(:automatic_reindexing).exactly(databases_count).times
|
||||
|
||||
run_rake_task('gitlab:db:reindex')
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,69 +8,69 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
|
|||
def create_table_structure
|
||||
migration = ActiveRecord::Migration.new.extend(Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers)
|
||||
|
||||
migration.create_table :loose_fk_parent_table_1
|
||||
migration.create_table :loose_fk_parent_table_2
|
||||
migration.create_table :_test_loose_fk_parent_table_1
|
||||
migration.create_table :_test_loose_fk_parent_table_2
|
||||
|
||||
migration.create_table :loose_fk_child_table_1_1 do |t|
|
||||
migration.create_table :_test_loose_fk_child_table_1_1 do |t|
|
||||
t.bigint :parent_id
|
||||
end
|
||||
|
||||
migration.create_table :loose_fk_child_table_1_2 do |t|
|
||||
migration.create_table :_test_loose_fk_child_table_1_2 do |t|
|
||||
t.bigint :parent_id_with_different_column
|
||||
end
|
||||
|
||||
migration.create_table :loose_fk_child_table_2_1 do |t|
|
||||
migration.create_table :_test_loose_fk_child_table_2_1 do |t|
|
||||
t.bigint :parent_id
|
||||
end
|
||||
|
||||
migration.track_record_deletions(:loose_fk_parent_table_1)
|
||||
migration.track_record_deletions(:loose_fk_parent_table_2)
|
||||
migration.track_record_deletions(:_test_loose_fk_parent_table_1)
|
||||
migration.track_record_deletions(:_test_loose_fk_parent_table_2)
|
||||
end
|
||||
|
||||
let!(:parent_model_1) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_parent_table_1'
|
||||
self.table_name = '_test_loose_fk_parent_table_1'
|
||||
|
||||
include LooseForeignKey
|
||||
|
||||
loose_foreign_key :loose_fk_child_table_1_1, :parent_id, on_delete: :async_delete
|
||||
loose_foreign_key :loose_fk_child_table_1_2, :parent_id_with_different_column, on_delete: :async_nullify
|
||||
loose_foreign_key :_test_loose_fk_child_table_1_1, :parent_id, on_delete: :async_delete
|
||||
loose_foreign_key :_test_loose_fk_child_table_1_2, :parent_id_with_different_column, on_delete: :async_nullify
|
||||
end
|
||||
end
|
||||
|
||||
let!(:parent_model_2) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_parent_table_2'
|
||||
self.table_name = '_test_loose_fk_parent_table_2'
|
||||
|
||||
include LooseForeignKey
|
||||
|
||||
loose_foreign_key :loose_fk_child_table_2_1, :parent_id, on_delete: :async_delete
|
||||
loose_foreign_key :_test_loose_fk_child_table_2_1, :parent_id, on_delete: :async_delete
|
||||
end
|
||||
end
|
||||
|
||||
let!(:child_model_1) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_child_table_1_1'
|
||||
self.table_name = '_test_loose_fk_child_table_1_1'
|
||||
end
|
||||
end
|
||||
|
||||
let!(:child_model_2) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_child_table_1_2'
|
||||
self.table_name = '_test_loose_fk_child_table_1_2'
|
||||
end
|
||||
end
|
||||
|
||||
let!(:child_model_3) do
|
||||
Class.new(ApplicationRecord) do
|
||||
self.table_name = 'loose_fk_child_table_2_1'
|
||||
self.table_name = '_test_loose_fk_child_table_2_1'
|
||||
end
|
||||
end
|
||||
|
||||
let(:loose_fk_parent_table_1) { table(:loose_fk_parent_table_1) }
|
||||
let(:loose_fk_parent_table_2) { table(:loose_fk_parent_table_2) }
|
||||
let(:loose_fk_child_table_1_1) { table(:loose_fk_child_table_1_1) }
|
||||
let(:loose_fk_child_table_1_2) { table(:loose_fk_child_table_1_2) }
|
||||
let(:loose_fk_child_table_2_1) { table(:loose_fk_child_table_2_1) }
|
||||
let(:loose_fk_parent_table_1) { table(:_test_loose_fk_parent_table_1) }
|
||||
let(:loose_fk_parent_table_2) { table(:_test_loose_fk_parent_table_2) }
|
||||
let(:loose_fk_child_table_1_1) { table(:_test_loose_fk_child_table_1_1) }
|
||||
let(:loose_fk_child_table_1_2) { table(:_test_loose_fk_child_table_1_2) }
|
||||
let(:loose_fk_child_table_2_1) { table(:_test_loose_fk_child_table_2_1) }
|
||||
|
||||
before(:all) do
|
||||
create_table_structure
|
||||
|
|
@ -79,11 +79,11 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
|
|||
after(:all) do
|
||||
migration = ActiveRecord::Migration.new
|
||||
|
||||
migration.drop_table :loose_fk_parent_table_1
|
||||
migration.drop_table :loose_fk_parent_table_2
|
||||
migration.drop_table :loose_fk_child_table_1_1
|
||||
migration.drop_table :loose_fk_child_table_1_2
|
||||
migration.drop_table :loose_fk_child_table_2_1
|
||||
migration.drop_table :_test_loose_fk_parent_table_1
|
||||
migration.drop_table :_test_loose_fk_parent_table_2
|
||||
migration.drop_table :_test_loose_fk_child_table_1_1
|
||||
migration.drop_table :_test_loose_fk_child_table_1_2
|
||||
migration.drop_table :_test_loose_fk_child_table_2_1
|
||||
end
|
||||
|
||||
before do
|
||||
|
|
|
|||
Loading…
Reference in New Issue