Expose `user_access` Project/Group Authorizations of agents
NOTE: This MR is built on top of Optimize AuthorizeProxyUserService with user_ac... (!116905 - merged).
What does this MR do and why?
This MR exposes the persisted user_access
authorizations for Show shared agents in deployment projects (#395498 - closed).
A few notes:
- This feature is behind
kas_user_access
andexpose_authorized_cluster_agents
feature flags which are disabled by default. It's not exposed to end-users yet. - We've already exposed
ci_access
authorization in Expose agent ci access authorizations (!117128 - merged). This MR introduces the same change foruser_access
. - See https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kubernetes_user_access.md for the feature spec details.
- See Initial iteration of Kubernetes Dashboard in En... (&9859 - closed) for further iterations.
Screenshots or screen recordings
Query:
query {
project(fullPath: "root/agent-ci-test") {
name
userAccessAuthorizedAgents {
nodes {
agent {
id
name
project {
name
}
}
config
}
}
}
}
Response:
{
"data": {
"project": {
"name": "agent-ci-test",
"userAccessAuthorizedAgents": {
"nodes": [
{
"agent": {
"id": "gid://gitlab/Clusters::Agent/37",
"name": "production",
"project": {
"name": "agent-ci-test"
}
},
"config": {}
},
{
"agent": {
"id": "gid://gitlab/Clusters::Agent/43",
"name": "production",
"project": {
"name": "agent-ci-test-2"
}
},
"config": {}
}
]
}
}
}
}
user_access_authorized_for?
Database Query for NOTE: This feature is not exposed for end-users yet therefore there are no production records that match the following queries. We'll evaluate the query performance after the feature flag has been enabled.
SELECT
agent_user_access_project_authorizations.*,
project_authorizations.access_level AS access_level
FROM
"agent_user_access_project_authorizations"
INNER JOIN project_authorizations ON project_authorizations.project_id = agent_user_access_project_authorizations.project_id
WHERE
"project_authorizations"."user_id" = 758045
AND "project_authorizations"."access_level" >= 30
AND "agent_user_access_project_authorizations"."agent_id" = 57145
LIMIT
1
WITH "groups_with_direct_membership" AS MATERIALIZED (
SELECT
namespaces.id AS id,
members.access_level AS access_level
FROM
"namespaces"
INNER JOIN members ON members.source_id = namespaces.id
AND members.source_type = 'Namespace'
WHERE
"namespaces"."type" = 'Group'
AND "members"."user_id" = 758045
AND "members"."access_level" >= 30
),
"all_groups_with_membership" AS MATERIALIZED (
SELECT
namespaces.id AS id,
namespaces.traversal_ids AS traversal_ids,
groups_with_direct_membership.access_level AS access_level
FROM
"namespaces"
INNER JOIN groups_with_direct_membership ON namespaces.traversal_ids @> ARRAY [groups_with_direct_membership.id]
WHERE
"namespaces"."type" = 'Group'
)
SELECT
DISTINCT ON (id) agent_user_access_group_authorizations.*,
all_groups_with_membership.access_level AS access_level
FROM
"agent_user_access_group_authorizations"
INNER JOIN all_groups_with_membership ON all_groups_with_membership.id = agent_user_access_group_authorizations.group_id
WHERE
"agent_user_access_group_authorizations"."agent_id" = 57145
ORDER BY
id,
access_level DESC
LIMIT
1
UserAccessResolver
Database Query for SELECT
agent_user_access_project_authorizations.*,
project_authorizations.access_level AS access_level
FROM
"agent_user_access_project_authorizations"
INNER JOIN project_authorizations ON project_authorizations.project_id = agent_user_access_project_authorizations.project_id
INNER JOIN "cluster_agents" ON "cluster_agents"."id" = "agent_user_access_project_authorizations"."agent_id"
INNER JOIN "projects" ON "projects"."id" = "cluster_agents"."project_id"
WHERE
"project_authorizations"."user_id" = 758045
AND "project_authorizations"."access_level" >= 30
AND "agent_user_access_project_authorizations"."project_id" = 278964
WITH "groups_with_direct_membership" AS MATERIALIZED (
SELECT
namespaces.id AS id,
members.access_level AS access_level
FROM
"namespaces"
INNER JOIN members ON members.source_id = namespaces.id
AND members.source_type = 'Namespace'
WHERE
"namespaces"."type" = 'Group'
AND "members"."user_id" = 758045
AND "members"."access_level" >= 30
),
"all_groups_with_membership" AS MATERIALIZED (
SELECT
namespaces.id AS id,
namespaces.traversal_ids AS traversal_ids,
groups_with_direct_membership.access_level AS access_level
FROM
"namespaces"
INNER JOIN groups_with_direct_membership ON namespaces.traversal_ids @> ARRAY [groups_with_direct_membership.id]
WHERE
"namespaces"."type" = 'Group'
)
SELECT
DISTINCT ON (id) agent_user_access_group_authorizations.*,
all_groups_with_membership.access_level AS access_level
FROM
"agent_user_access_group_authorizations"
INNER JOIN all_groups_with_membership ON all_groups_with_membership.id = agent_user_access_group_authorizations.group_id
INNER JOIN "cluster_agents" ON "cluster_agents"."id" = "agent_user_access_group_authorizations"."agent_id"
INNER JOIN "projects" ON "projects"."id" = "cluster_agents"."project_id"
WHERE
(
all_groups_with_membership.traversal_ids @> ARRAY [9970]
)
ORDER BY
id,
access_level DESC
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Edited by Shinya Maeda