Skip to content
代码片段 群组 项目
提交 3af9ccb7 编辑于 作者: Alexandru Croitor's avatar Alexandru Croitor
浏览文件

Merge branch 'pedropombeiro/337838/1-add-ascendants-membership-enum-value' into 'master'

No related branches found
No related tags found
无相关合并请求
...@@ -55,6 +55,12 @@ def group_runners ...@@ -55,6 +55,12 @@ def group_runners
Ci::Runner.belonging_to_group(@group.id) Ci::Runner.belonging_to_group(@group.id)
when :descendants, nil when :descendants, nil
Ci::Runner.belonging_to_group_or_project_descendants(@group.id) Ci::Runner.belonging_to_group_or_project_descendants(@group.id)
when :all_available
unless can?(@current_user, :read_group_all_available_runners, @group)
raise Gitlab::Access::AccessDeniedError
end
Ci::Runner.usable_from_scope(@group)
else else
raise ArgumentError, 'Invalid membership filter' raise ArgumentError, 'Invalid membership filter'
end end
......
...@@ -15,6 +15,14 @@ class RunnerMembershipFilterEnum < BaseEnum ...@@ -15,6 +15,14 @@ class RunnerMembershipFilterEnum < BaseEnum
description: "Include runners that have either a direct or inherited relationship. " \ description: "Include runners that have either a direct or inherited relationship. " \
"These runners can be specific to a project or a group.", "These runners can be specific to a project or a group.",
value: :descendants value: :descendants
value 'ALL_AVAILABLE',
description:
"Include all runners. This list includes runners for all projects in the group " \
"and subgroups, as well as for the parent groups and instance. " \
"Will not return runners if `runners_finder_all_available` feature flag is disabled.",
value: :all_available,
deprecated: { milestone: '15.5', reason: :alpha }
end end
end end
end end
...@@ -152,6 +152,17 @@ class Runner < Ci::ApplicationRecord ...@@ -152,6 +152,17 @@ class Runner < Ci::ApplicationRecord
) )
end end
scope :usable_from_scope, -> (group) do
from_union(
[
belonging_to_group(group.ancestor_ids),
belonging_to_group_or_project_descendants(group.id),
group.shared_runners
],
remove_duplicates: false
)
end
scope :assignable_for, ->(project) do scope :assignable_for, ->(project) do
# FIXME: That `to_sql` is needed to workaround a weird Rails bug. # FIXME: That `to_sql` is needed to workaround a weird Rails bug.
# Without that, placeholders would miss one and couldn't match. # Without that, placeholders would miss one and couldn't match.
......
...@@ -87,6 +87,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy ...@@ -87,6 +87,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?('group') Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?('group')
end end
condition(:runners_finder_all_available, scope: :subject) do
Feature.enabled?(:runners_finder_all_available, group)
end
rule { can?(:read_group) & design_management_enabled }.policy do rule { can?(:read_group) & design_management_enabled }.policy do
enable :read_design_activity enable :read_design_activity
end end
...@@ -150,8 +154,12 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy ...@@ -150,8 +154,12 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :admin_crm_organization enable :admin_crm_organization
enable :admin_crm_contact enable :admin_crm_contact
enable :read_cluster enable :read_cluster
enable :read_group_all_available_runners
end end
rule { ~runners_finder_all_available }.prevent :read_group_all_available_runners
rule { reporter }.policy do rule { reporter }.policy do
enable :reporter_access enable :reporter_access
enable :read_container_image enable :read_container_image
......
---
name: runners_finder_all_available
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96770
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/374525
milestone: '15.5'
type: development
group: group::runner
default_enabled: false
...@@ -19853,6 +19853,7 @@ Values for filtering runners in namespaces. The previous type name `RunnerMember ...@@ -19853,6 +19853,7 @@ Values for filtering runners in namespaces. The previous type name `RunnerMember
   
| Value | Description | | Value | Description |
| ----- | ----------- | | ----- | ----------- |
| <a id="cirunnermembershipfilterall_available"></a>`ALL_AVAILABLE` **{warning-solid}** | **Introduced** in 15.5. This feature is in Alpha. It can be changed or removed at any time. Include all runners. This list includes runners for all projects in the group and subgroups, as well as for the parent groups and instance. Will not return runners if `runners_finder_all_available` feature flag is disabled. |
| <a id="cirunnermembershipfilterdescendants"></a>`DESCENDANTS` | Include runners that have either a direct or inherited relationship. These runners can be specific to a project or a group. | | <a id="cirunnermembershipfilterdescendants"></a>`DESCENDANTS` | Include runners that have either a direct or inherited relationship. These runners can be specific to a project or a group. |
| <a id="cirunnermembershipfilterdirect"></a>`DIRECT` | Include runners that have a direct relationship. | | <a id="cirunnermembershipfilterdirect"></a>`DIRECT` | Include runners that have a direct relationship. |
   
...@@ -319,6 +319,33 @@ def execute ...@@ -319,6 +319,33 @@ def execute
end end
end end
context 'with :all_available membership' do
let(:membership) { :all_available }
context 'with runners_finder_all_available FF disabled' do
before do
stub_feature_flags(runners_finder_all_available: false)
end
it 'returns no runners' do
expect(subject).to be_empty
end
end
context 'with runners_finder_all_available FF enabled' do
before do
stub_feature_flags(runners_finder_all_available: [target_group])
end
it 'returns runners available to group' do
expect(subject).to match_array([runner_project_7, runner_project_6, runner_project_5,
runner_project_4, runner_project_3, runner_project_2,
runner_project_1, runner_sub_group_4, runner_sub_group_3,
runner_sub_group_2, runner_sub_group_1, runner_group, runner_instance])
end
end
end
context 'with unknown membership' do context 'with unknown membership' do
let(:membership) { :unsupported } let(:membership) { :unsupported }
...@@ -400,11 +427,37 @@ def execute ...@@ -400,11 +427,37 @@ def execute
with_them do with_them do
before do before do
create(:group_member, user_permission, group: group, user: user) create(:group_member, user_permission, group: sub_group_1, user: user)
end end
it 'returns no runners' do context 'with :sub_group_1 as target group' do
expect(subject).to be_empty let(:target_group) { sub_group_1 }
it 'returns no runners' do
is_expected.to be_empty
end
end
context 'with :group as target group' do
let(:target_group) { group }
it 'returns no runners' do
is_expected.to be_empty
end
context 'with :all_available membership' do
let(:membership) { :all_available }
context 'with runners_finder_all_available FF enabled' do
before do
stub_feature_flags(runners_finder_all_available: [target_group])
end
it 'returns no runners' do
expect(subject).to be_empty
end
end
end
end end
end end
end end
......
...@@ -1595,33 +1595,59 @@ def does_db_update ...@@ -1595,33 +1595,59 @@ def does_db_update
end end
describe '.belonging_to_group_and_ancestors' do describe '.belonging_to_group_and_ancestors' do
subject(:relation) { described_class.belonging_to_group_and_ancestors(scope.id) } subject(:relation) { described_class.belonging_to_group_and_ancestors(child_group.id) }
it 'returns the group runners from the group and parent group' do
is_expected.to contain_exactly(child_group_runner, top_level_group_runner)
end
end
describe '.belonging_to_group_or_project_descendants' do
subject(:relation) { described_class.belonging_to_group_or_project_descendants(scope.id) }
context 'with scope set to top_level_group' do context 'with scope set to top_level_group' do
let(:scope) { top_level_group } let(:scope) { top_level_group }
it 'returns the group runners from the group' do it 'returns the expected group and project runners without duplicates', :aggregate_failures do
is_expected.to contain_exactly(top_level_group_runner) expect(relation).to contain_exactly(
top_level_group_runner,
top_level_group_project_runner,
child_group_runner,
child_group_project_runner,
child_group2_runner,
shared_top_level_group_project_runner
)
# Ensure no duplicates are returned
expect(relation.distinct).to match_array(relation)
end end
end end
context 'with scope set to child_group' do context 'with scope set to child_group' do
let(:scope) { child_group } let(:scope) { child_group }
it 'returns the group runners from the group and parent group' do it 'returns the expected group and project runners without duplicates', :aggregate_failures do
is_expected.to contain_exactly(child_group_runner, top_level_group_runner) expect(relation).to contain_exactly(
child_group_runner,
child_group_project_runner,
shared_top_level_group_project_runner
)
# Ensure no duplicates are returned
expect(relation.distinct).to match_array(relation)
end end
end end
end end
describe '.belonging_to_group_or_project_descendants' do describe '.usable_from_scope' do
subject(:relation) { described_class.belonging_to_group_or_project_descendants(scope.id) } subject(:relation) { described_class.usable_from_scope(scope) }
context 'with scope set to top_level_group' do context 'with scope set to top_level_group' do
let(:scope) { top_level_group } let(:scope) { top_level_group }
it 'returns the expected group and project runners without duplicates', :aggregate_failures do it 'returns all runners usable from top_level_group without duplicates' do
expect(relation).to contain_exactly( expect(relation).to contain_exactly(
instance_runner,
top_level_group_runner, top_level_group_runner,
top_level_group_project_runner, top_level_group_project_runner,
child_group_runner, child_group_runner,
...@@ -1638,15 +1664,26 @@ def does_db_update ...@@ -1638,15 +1664,26 @@ def does_db_update
context 'with scope set to child_group' do context 'with scope set to child_group' do
let(:scope) { child_group } let(:scope) { child_group }
it 'returns the expected group and project runners without duplicates', :aggregate_failures do it 'returns all runners usable from child_group' do
expect(relation).to contain_exactly( expect(relation).to contain_exactly(
instance_runner,
top_level_group_runner,
child_group_runner, child_group_runner,
child_group_project_runner, child_group_project_runner,
shared_top_level_group_project_runner shared_top_level_group_project_runner
) )
end
end
# Ensure no duplicates are returned context 'with scope set to other_top_level_group' do
expect(relation.distinct).to match_array(relation) let(:scope) { other_top_level_group }
it 'returns all runners usable from other_top_level_group' do
expect(relation).to contain_exactly(
instance_runner,
other_top_level_group_runner,
other_top_level_group_project_runner
)
end end
end end
end end
......
...@@ -1266,6 +1266,90 @@ ...@@ -1266,6 +1266,90 @@
end end
end end
describe 'read_group_all_available_runners' do
context 'admin' do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
context 'with runners_finder_all_available FF disabled' do
before do
stub_feature_flags(runners_finder_all_available: false)
end
specify { is_expected.to be_disallowed(:read_group_all_available_runners) }
end
context 'with runners_finder_all_available FF enabled' do
before do
stub_feature_flags(runners_finder_all_available: [group])
end
specify { is_expected.to be_allowed(:read_group_all_available_runners) }
end
end
context 'when admin mode is disabled' do
specify { is_expected.to be_disallowed(:read_group_all_available_runners) }
end
end
context 'with owner' do
let(:current_user) { owner }
context 'with runners_finder_all_available FF disabled' do
before do
stub_feature_flags(runners_finder_all_available: false)
end
specify { is_expected.to be_disallowed(:read_group_all_available_runners) }
end
context 'with runners_finder_all_available FF enabled' do
before do
stub_feature_flags(runners_finder_all_available: [group])
end
specify { is_expected.to be_allowed(:read_group_all_available_runners) }
end
end
context 'with maintainer' do
let(:current_user) { maintainer }
specify { is_expected.to be_allowed(:read_group_all_available_runners) }
end
context 'with developer' do
let(:current_user) { developer }
specify { is_expected.to be_allowed(:read_group_all_available_runners) }
end
context 'with reporter' do
let(:current_user) { reporter }
specify { is_expected.to be_disallowed(:read_group_all_available_runners) }
end
context 'with guest' do
let(:current_user) { guest }
specify { is_expected.to be_disallowed(:read_group_all_available_runners) }
end
context 'with non member' do
let(:current_user) { create(:user) }
specify { is_expected.to be_disallowed(:read_group_all_available_runners) }
end
context 'with anonymous' do
let(:current_user) { nil }
specify { is_expected.to be_disallowed(:read_group_all_available_runners) }
end
end
describe 'change_prevent_sharing_groups_outside_hierarchy' do describe 'change_prevent_sharing_groups_outside_hierarchy' do
context 'with owner' do context 'with owner' do
let(:current_user) { owner } let(:current_user) { owner }
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册