Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-04 00:18:28 +00:00
parent 7a5409764a
commit 3e1ab18831
13 changed files with 118 additions and 71 deletions

View File

@ -252,7 +252,8 @@ input[type='checkbox']:hover {
.btn-search, .btn-search,
.btn-success, .btn-success,
.dropdown-menu-toggle { .dropdown-menu-toggle,
.gl-new-dropdown {
width: 100%; width: 100%;
margin-top: 5px; margin-top: 5px;
@ -270,7 +271,8 @@ input[type='checkbox']:hover {
} }
} }
.dropdown-menu-toggle { .dropdown-menu-toggle,
.gl-new-dropdown {
@include media-breakpoint-up(sm) { @include media-breakpoint-up(sm) {
width: 180px; width: 180px;
margin-top: 0; margin-top: 0;

View File

@ -2,6 +2,7 @@
class Admin::UsersController < Admin::ApplicationController class Admin::UsersController < Admin::ApplicationController
include RoutableActions include RoutableActions
include SortingHelper
before_action :user, except: [:index, :new, :create] before_action :user, except: [:index, :new, :create]
before_action :check_impersonation_availability, only: :impersonate before_action :check_impersonation_availability, only: :impersonate
@ -18,7 +19,8 @@ class Admin::UsersController < Admin::ApplicationController
@users = User.filter_items(params[:filter]).order_name_asc @users = User.filter_items(params[:filter]).order_name_asc
@users = @users.search(params[:search_query], with_private_emails: true) if params[:search_query].present? @users = @users.search(params[:search_query], with_private_emails: true) if params[:search_query].present?
@users = users_with_included_associations(@users) @users = users_with_included_associations(@users)
@users = @users.sort_by_attribute(@sort = params[:sort]) @sort = params[:sort].presence || sort_value_name
@users = @users.sort_by_attribute(@sort)
@users = @users.page(params[:page]) @users = @users.page(params[:page])
@users = @users.without_count if paginate_without_count? @users = @users.without_count if paginate_without_count?
end end

View File

@ -328,6 +328,16 @@ module SortingHelper
sort_direction_button(url, reverse_sort, sort_value) sort_direction_button(url, reverse_sort, sort_value)
end end
def admin_users_sort_options(path_params)
users_sort_options_hash.map do |value, text|
{
value: value,
text: text,
href: admin_users_path(sort: value, **path_params)
}
end
end
end end
SortingHelper.prepend_mod_with('SortingHelper') SortingHelper.prepend_mod_with('SortingHelper')

View File

@ -60,17 +60,9 @@
= hidden_field_tag :sort, @sort = hidden_field_tag :sort, @sort
= sprite_icon('search', css_class: 'search-icon') = sprite_icon('search', css_class: 'search-icon')
= button_tag s_('AdminUsers|Search users') if Rails.env.test? = button_tag s_('AdminUsers|Search users') if Rails.env.test?
.dropdown.gl-ml-3 .dropdown.gl-sm-ml-3
= label_tag 'Sort by', nil, class: 'label-bold' = label_tag s_('AdminUsers|Sort by')
- toggle_text = @sort.present? ? users_sort_options_hash[@sort] : sort_title_name = gl_redirect_listbox_tag admin_users_sort_options(filter: params[:filter], search_query: params[:search_query]), @sort, data: { right: true }
= dropdown_toggle(toggle_text, { toggle: 'dropdown' })
%ul.dropdown-menu.dropdown-menu-right
%li.dropdown-header
= s_('AdminUsers|Sort by')
%li
- users_sort_options_hash.each do |value, title|
= link_to admin_users_path(sort: value, filter: params[:filter], search_query: params[:search_query]) do
= title
#js-admin-users-app{ data: admin_users_data_attributes(@users) } #js-admin-users-app{ data: admin_users_data_attributes(@users) }
.gl-spinner-container.gl-my-7 .gl-spinner-container.gl-my-7

View File

@ -33,7 +33,7 @@
.table-mobile-header{ role: 'rowheader' }= _('Projects') .table-mobile-header{ role: 'rowheader' }= _('Projects')
.table-mobile-content .table-mobile-content
- if runner.group_type? - if runner.group_type?
= _('n/a') \-
- else - else
= runner.runner_projects.count(:all) = runner.runner_projects.count(:all)

View File

@ -14,7 +14,7 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated. announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post. announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post. removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: dhershkovitch # GitLab username of the person reporting the deprecation reporter: dhershkovitch # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below. body: | # Do not modify this line, instead modify the lines below.

View File

@ -48,7 +48,7 @@ changes to your code, settings, or workflow.
The `CI_JOB_JWT` will be updated to support a wider variety of cloud providers. It will be changed to match [`CI_JOB_JWT_V2`](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html), but this change may not be backwards compatible for all users, including Hashicorp Vault users. To maintain the current behavior, users can switch to using `CI_JOB_JWT_V1`, or update their configuration in GitLab 15.0 to use the improved `CI_JOB_JWT`. The `CI_JOB_JWT` will be updated to support a wider variety of cloud providers. It will be changed to match [`CI_JOB_JWT_V2`](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html), but this change may not be backwards compatible for all users, including Hashicorp Vault users. To maintain the current behavior, users can switch to using `CI_JOB_JWT_V1`, or update their configuration in GitLab 15.0 to use the improved `CI_JOB_JWT`.
**Planned removal milestone: 15.0 ()** **Planned removal milestone: 15.0 (2022-05-22)**
### Configurable Gitaly `per_repository` election strategy ### Configurable Gitaly `per_repository` election strategy

View File

@ -4,66 +4,74 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
--- ---
# Inventory object **(PREMIUM)** # Tracking cluster resources managed by GitLab **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0.
An inventory object is a `ConfigMap` object for keeping track of the set of objects applied to a cluster. GitLab uses an inventory object to track the resources you deploy to your cluster.
When you remove objects from a manifest repository, the agent uses a corresponding inventory object to The inventory object is a `ConfigMap` that contains a list of controlled objects.
prune (delete) objects from the cluster. The managed resources use the `cli-utils.sigs.k8s.io/inventory-id` annotation.
The agent creates an inventory object for each manifest project specified in the ## Default location of the inventory object
`gitops.manifest_projects` configuration section. The inventory object has to be stored somewhere in the cluster.
The default behavior is:
- The `namespace` used comes from `gitops.manifest_projects[].default_namespace`. If you don't specify this parameter In the agent configuration file, you specify a list of projects. For example:
explicitly, the inventory object is stored in the `default` namespace.
- The `name` is generated from the numeric project ID of the manifest project and the numeric agent ID.
This way, the agent constructs the name and location where the inventory object is
stored in the cluster.
The agent cannot locate the existing inventory object if you:
- Change `gitops.manifest_projects[].default_namespace` parameter.
- Move manifests into another project.
## Inventory object template
The inventory object template is a `ConfigMap` object that allows you to configure the namespace and the name of the inventory
object. Store this template with manifest files as a single logical group.
Example inventory object template:
```yaml ```yaml
apiVersion: v1 gitops:
kind: ConfigMap manifest_projects:
metadata: - id: gitlab-org/cluster-integration/gitlab-agent
name: unique-name-for-the-inventory default_namespace: my-ns
namespace: my-project-namespace
labels:
cli-utils.sigs.k8s.io/inventory-id: unique-name-for-the-inventory
``` ```
- The `namespace` and `name` fields configure where the real inventory object is created. The agent creates an inventory object for every item in the `manifest_projects` list.
- The `cli-utils.sigs.k8s.io/inventory-id` label with its corresponding value is set on the inventory object, created The inventory object is stored in the namespace you specify for `default_namespace`.
from this template. Make sure that the value is unique (for example, a string of random characters) and doesn't clash
with any existing or future inventory object templates.
- Objects tracked by this inventory object have the `config.k8s.io/owning-inventory` annotation set to the value of
the `cli-utils.sigs.k8s.io/inventory-id` label.
- The label's value doesn't have to match the `name` but it's convenient to have them set to the same value.
- Make sure that the `name` is unique so that it doesn't conflict with another inventory object in the same
namespace in the future.
## Using GitOps with pre-existing Kubernetes objects The name and location of the inventory object is based on:
The agent treats manifest files in the manifest repository as the source of truth. When it applies - The `default_namespace`. If you don't specify this parameter,
objects from the files to the cluster, it tracks them in an inventory object. If an object already exists, the inventory object is stored in the `default` namespace.
The agent behaves differently based on the `gitops.manifest_projects[].inventory_policy` configuration. - The `name`, which is the ID of the project with the manifest and the ID of the agent.
Check the table below with the available options and when to use them.
WARNING:
The agent cannot locate the existing inventory object if you change
the `default_namespace` parameter or move manifests to another project.
## Change the location of the inventory object
You can configure the namespace and the name of the inventory object.
This action changes the location of the object in the cluster.
1. Create an inventory object template, which is a `ConfigMap` object.
For example:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: unique-name-for-the-inventory
namespace: my-project-namespace
labels:
cli-utils.sigs.k8s.io/inventory-id: unique-name-for-the-inventory
```
1. Specify a `namespace` and `name`. Ensure that the `name` is unique so it doesn't conflict with other
inventory objects in the same namespace in the future.
1. Ensure the value for `cli-utils.sigs.k8s.io/inventory-id` is unique. This value is used for objects
tracked by this inventory object. Their `config.k8s.io/owning-inventory` annotation is set to this value.
The value doesn't have to match the `name` but it's convenient to set them to the same value.
1. Save the file with the manifest files as a single logical group.
## `inventory_policy` options
Sometimes your manifest changes affect resources that aren't tracked by the GitLab inventory object.
To change how the agent behaves when it overwrites existing and previously untracked resources,
change the `inventory_policy` value.
`inventory_policy` value | Description | `inventory_policy` value | Description |
------------------------ | ------------------------------------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------- |
`must_match` | This is the default policy. A live object must have the `config.k8s.io/owning-inventory` annotation set to the same value as the `cli-utils.sigs.k8s.io/inventory-id` label on the corresponding inventory object to be updated. Object is not updated and an error is reported if the values don't match or the object doesn't have the annotation. | `must_match` | The default policy. To be updated, a live object must have the `config.k8s.io/owning-inventory` annotation set to the same value as the `cli-utils.sigs.k8s.io/inventory-id` label on the corresponding inventory object. If the values don't match or the object doesn't have the annotation, the object is not updated and an error is reported. |
`adopt_if_no_inventory` | This mode allows to "adopt" an object if it doesn't have the `config.k8s.io/owning-inventory` annotation. Use this mode if you want to start managing existing objects using the GitOps feature. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. | `adopt_if_no_inventory` | Adopt an object if it doesn't have the `config.k8s.io/owning-inventory` annotation. Use this mode if you want to start managing existing objects by using the GitOps feature. To avoid unexpected adoptions, after all objects have been adopted, put the setting back to the default `must_match` mode. |
`adopt_all` | This mode allows to "adopt" an object even if it has the `config.k8s.io/owning-inventory` annotation set to a different value. This mode can be useful if you want to migrate a set of objects from one agent to another one or from some other tool to the agent. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. | `adopt_all` | Adopt an object even if it has the `config.k8s.io/owning-inventory` annotation set to a different value. Use this mode if you want to migrate a set of objects from one agent to another, or from some other tool to the agent. To avoid unexpected adoptions, after all objects have been adopted, put the setting back to the default `must_match` mode. |

View File

@ -5,6 +5,10 @@ module Gitlab
extend self extend self
PathTraversalAttackError ||= Class.new(StandardError) PathTraversalAttackError ||= Class.new(StandardError)
private_class_method def logger
@logger ||= Gitlab::AppLogger
end
# Ensure that the relative path will not traverse outside the base directory # Ensure that the relative path will not traverse outside the base directory
# We url decode the path to avoid passing invalid paths forward in url encoded format. # We url decode the path to avoid passing invalid paths forward in url encoded format.
# Also see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24223#note_284122580 # Also see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24223#note_284122580
@ -16,6 +20,7 @@ module Gitlab
path_regex = %r{(\A(\.{1,2})\z|\A\.\.[/\\]|[/\\]\.\.\z|[/\\]\.\.[/\\]|\n)} path_regex = %r{(\A(\.{1,2})\z|\A\.\.[/\\]|[/\\]\.\.\z|[/\\]\.\.[/\\]|\n)}
if path.match?(path_regex) if path.match?(path_regex)
logger.warn(message: "Potential path traversal attempt detected", path: "#{path}")
raise PathTraversalAttackError, 'Invalid path' raise PathTraversalAttackError, 'Invalid path'
end end

View File

@ -35,7 +35,10 @@ module QA
source_group.add_member(member, Resource::Members::AccessLevel::DEVELOPER) source_group.add_member(member, Resource::Members::AccessLevel::DEVELOPER)
end end
it 'member retains indirect membership in imported project' do it(
'member retains indirect membership in imported project',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354416'
) do
expect_import_finished expect_import_finished
aggregate_failures do aggregate_failures do
@ -52,7 +55,10 @@ module QA
source_project.add_member(member, Resource::Members::AccessLevel::DEVELOPER) source_project.add_member(member, Resource::Members::AccessLevel::DEVELOPER)
end end
it 'member retains direct membership in imported project' do it(
'member retains direct membership in imported project',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354417'
) do
expect_import_finished expect_import_finished
aggregate_failures do aggregate_failures do

View File

@ -132,7 +132,7 @@ RSpec.describe 'Admin::Users' do
end end
it 'searches with respect of sorting' do it 'searches with respect of sorting' do
visit admin_users_path(sort: 'Name') visit admin_users_path(sort: 'name_asc')
fill_in :search_query, with: 'Foo' fill_in :search_query, with: 'Foo'
click_button('Search users') click_button('Search users')
@ -604,8 +604,8 @@ RSpec.describe 'Admin::Users' do
def sort_by(option) def sort_by(option)
page.within('.filtered-search-block') do page.within('.filtered-search-block') do
find('.dropdown-menu-toggle').click find('.gl-new-dropdown').click
click_link option find('.gl-new-dropdown-item', text: option).click
end end
end end
end end

View File

@ -10,6 +10,18 @@ RSpec.describe SortingHelper do
allow(self).to receive(:request).and_return(double(path: 'http://test.com', query_parameters: { label_name: option })) allow(self).to receive(:request).and_return(double(path: 'http://test.com', query_parameters: { label_name: option }))
end end
describe '#admin_users_sort_options' do
it 'returns correct link attributes in array' do
options = admin_users_sort_options(filter: 'filter', search_query: 'search')
expect(options[0][:href]).to include('filter')
expect(options[0][:href]).to include('search')
options.each do |option|
expect(option[:href]).to include(option[:value])
end
end
end
describe '#issuable_sort_option_title' do describe '#issuable_sort_option_title' do
it 'returns correct title for issuable_sort_option_overrides key' do it 'returns correct title for issuable_sort_option_overrides key' do
expect(issuable_sort_option_title('created_asc')).to eq('Created date') expect(issuable_sort_option_title('created_asc')).to eq('Created date')

View File

@ -53,6 +53,16 @@ RSpec.describe Gitlab::Utils do
expect(check_path_traversal!('dir/.foo.rb')).to eq('dir/.foo.rb') expect(check_path_traversal!('dir/.foo.rb')).to eq('dir/.foo.rb')
end end
it 'logs potential path traversal attempts' do
expect(Gitlab::AppLogger).to receive(:warn).with(message: "Potential path traversal attempt detected", path: "..")
expect { check_path_traversal!('..') }.to raise_error(/Invalid path/)
end
it 'logs does nothing for a safe string' do
expect(Gitlab::AppLogger).not_to receive(:warn).with(message: "Potential path traversal attempt detected", path: "dir/.foo.rb")
expect(check_path_traversal!('dir/.foo.rb')).to eq('dir/.foo.rb')
end
it 'does nothing for a non-string' do it 'does nothing for a non-string' do
expect(check_path_traversal!(nil)).to be_nil expect(check_path_traversal!(nil)).to be_nil
end end