Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/finders/clusters/agent_authorizations_finder.rb')
-rw-r--r--app/finders/clusters/agent_authorizations_finder.rb65
1 files changed, 65 insertions, 0 deletions
diff --git a/app/finders/clusters/agent_authorizations_finder.rb b/app/finders/clusters/agent_authorizations_finder.rb
new file mode 100644
index 00000000000..373cf7fe8b9
--- /dev/null
+++ b/app/finders/clusters/agent_authorizations_finder.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module Clusters
+ class AgentAuthorizationsFinder
+ def initialize(project)
+ @project = project
+ end
+
+ def execute
+ # closest, most-specific authorization for a given agent wins
+ (project_authorizations + implicit_authorizations + group_authorizations)
+ .uniq(&:agent_id)
+ end
+
+ private
+
+ attr_reader :project
+
+ def implicit_authorizations
+ project.cluster_agents.map do |agent|
+ Clusters::Agents::ImplicitAuthorization.new(agent: agent)
+ end
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def project_authorizations
+ ancestor_ids = project.group ? project.ancestors.select(:id) : project.namespace_id
+
+ Clusters::Agents::ProjectAuthorization
+ .where(project_id: project.id)
+ .joins(agent: :project)
+ .preload(agent: :project)
+ .where(cluster_agents: { projects: { namespace_id: ancestor_ids } })
+ .with_available_ci_access_fields(project)
+ .to_a
+ end
+
+ def group_authorizations
+ return [] unless project.group
+
+ authorizations = Clusters::Agents::GroupAuthorization.arel_table
+
+ ordered_ancestors_cte = Gitlab::SQL::CTE.new(
+ :ordered_ancestors,
+ project.group.self_and_ancestors(hierarchy_order: :asc).reselect(:id)
+ )
+
+ cte_join_sources = authorizations.join(ordered_ancestors_cte.table).on(
+ authorizations[:group_id].eq(ordered_ancestors_cte.table[:id])
+ ).join_sources
+
+ Clusters::Agents::GroupAuthorization
+ .with(ordered_ancestors_cte.to_arel)
+ .joins(cte_join_sources)
+ .joins(agent: :project)
+ .where('projects.namespace_id IN (SELECT id FROM ordered_ancestors)')
+ .with_available_ci_access_fields(project)
+ .order(Arel.sql('agent_id, array_position(ARRAY(SELECT id FROM ordered_ancestors)::bigint[], agent_group_authorizations.group_id)'))
+ .select('DISTINCT ON (agent_id) agent_group_authorizations.*')
+ .preload(agent: :project)
+ .to_a
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+end