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:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-05-17 19:05:49 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-05-17 19:05:49 +0300
commit43a25d93ebdabea52f99b05e15b06250cd8f07d7 (patch)
treedceebdc68925362117480a5d672bcff122fb625b /app/models/clusters/agent.rb
parent20c84b99005abd1c82101dfeff264ac50d2df211 (diff)
Add latest changes from gitlab-org/gitlab@16-0-stable-eev16.0.0-rc42
Diffstat (limited to 'app/models/clusters/agent.rb')
-rw-r--r--app/models/clusters/agent.rb91
1 files changed, 87 insertions, 4 deletions
diff --git a/app/models/clusters/agent.rb b/app/models/clusters/agent.rb
index 3478bb69707..6980ec1c2d3 100644
--- a/app/models/clusters/agent.rb
+++ b/app/models/clusters/agent.rb
@@ -2,6 +2,8 @@
module Clusters
class Agent < ApplicationRecord
+ include FromUnion
+
self.table_name = 'cluster_agents'
INACTIVE_AFTER = 1.hour.freeze
@@ -11,12 +13,19 @@ module Clusters
belongs_to :project, class_name: '::Project' # Otherwise, it will load ::Clusters::Project
has_many :agent_tokens, -> { order_last_used_at_desc }, class_name: 'Clusters::AgentToken', inverse_of: :agent
+ has_many :active_agent_tokens, -> { active.order_last_used_at_desc }, class_name: 'Clusters::AgentToken', inverse_of: :agent
+
+ has_many :ci_access_group_authorizations, class_name: 'Clusters::Agents::Authorizations::CiAccess::GroupAuthorization'
+ has_many :ci_access_authorized_groups, class_name: '::Group', through: :ci_access_group_authorizations, source: :group
- has_many :group_authorizations, class_name: 'Clusters::Agents::GroupAuthorization'
- has_many :authorized_groups, class_name: '::Group', through: :group_authorizations, source: :group
+ has_many :ci_access_project_authorizations, class_name: 'Clusters::Agents::Authorizations::CiAccess::ProjectAuthorization'
+ has_many :ci_access_authorized_projects, class_name: '::Project', through: :ci_access_project_authorizations, source: :project
- has_many :project_authorizations, class_name: 'Clusters::Agents::ProjectAuthorization'
- has_many :authorized_projects, class_name: '::Project', through: :project_authorizations, source: :project
+ has_many :user_access_group_authorizations, class_name: 'Clusters::Agents::Authorizations::UserAccess::GroupAuthorization'
+ has_many :user_access_authorized_groups, class_name: '::Group', through: :user_access_group_authorizations, source: :group
+
+ has_many :user_access_project_authorizations, class_name: 'Clusters::Agents::Authorizations::UserAccess::ProjectAuthorization'
+ has_many :user_access_authorized_projects, class_name: '::Project', through: :user_access_project_authorizations, source: :project
has_many :activity_events, -> { in_timeline_order }, class_name: 'Clusters::Agents::ActivityEvent', inverse_of: :agent
@@ -51,6 +60,80 @@ module Clusters
def to_ability_name
:cluster
end
+
+ def ci_access_authorized_for?(user)
+ return false unless user
+ return false unless ::Feature.enabled?(:expose_authorized_cluster_agents, project)
+
+ ::Project.from_union(
+ all_ci_access_authorized_projects_for(user).limit(1),
+ all_ci_access_authorized_namespaces_for(user).limit(1)
+ ).exists?
+ end
+
+ def user_access_authorized_for?(user)
+ return false unless user
+ return false unless ::Feature.enabled?(:expose_authorized_cluster_agents, project)
+
+ Clusters::Agents::Authorizations::UserAccess::Finder
+ .new(user, agent: self, preload: false, limit: 1).execute.any?
+ end
+
+ # As of today, all config values of associated authorization rows have the same value.
+ # See `UserAccess::RefreshService` for more information.
+ def user_access_config
+ self.class.from_union(
+ user_access_project_authorizations.select('config').limit(1),
+ user_access_group_authorizations.select('config').limit(1)
+ ).compact.first&.config
+ end
+
+ private
+
+ def all_ci_access_authorized_projects_for(user)
+ ::Project.joins(:ci_access_project_authorizations)
+ .joins(:project_authorizations)
+ .where(agent_project_authorizations: { agent_id: id })
+ .where(project_authorizations: { user_id: user.id, access_level: Gitlab::Access::DEVELOPER.. })
+ end
+
+ def all_ci_access_authorized_namespaces_for(user)
+ ::Project.with(root_namespace_cte.to_arel)
+ .with(all_ci_access_authorized_namespaces_cte.to_arel)
+ .joins('INNER JOIN all_authorized_namespaces ON all_authorized_namespaces.id = projects.namespace_id')
+ .joins(:project_authorizations)
+ .where(project_authorizations: { user_id: user.id, access_level: Gitlab::Access::DEVELOPER.. })
+ end
+
+ def root_namespace_cte
+ Gitlab::SQL::CTE.new(:root_namespace, root_namespace.to_sql)
+ end
+
+ def all_ci_access_authorized_namespaces_cte
+ Gitlab::SQL::CTE.new(:all_authorized_namespaces, all_ci_access_authorized_namespaces.to_sql)
+ end
+
+ def all_ci_access_authorized_namespaces
+ Namespace.select("traversal_ids[array_length(traversal_ids, 1)] AS id")
+ .joins("INNER JOIN root_namespace ON " \
+ "namespaces.traversal_ids @> ARRAY[root_namespace.root_id]")
+ .joins("INNER JOIN agent_group_authorizations ON " \
+ "namespaces.traversal_ids @> ARRAY[agent_group_authorizations.group_id::integer]")
+ .where(agent_group_authorizations: { agent_id: id })
+ end
+
+ def root_namespace
+ Namespace.select("traversal_ids[1] AS root_id")
+ .where("traversal_ids @> ARRAY(?)", project_namespace)
+ .limit(1)
+ end
+
+ def project_namespace
+ ::Project.select('namespace_id')
+ .joins(:cluster_agents)
+ .where(cluster_agents: { id: id })
+ .limit(1)
+ end
end
end