From 7844f27517b363d97f9057fe1ebc390311bbf2a3 Mon Sep 17 00:00:00 2001 From: Juntao Wang Date: Tue, 3 Dec 2024 15:43:39 -0500 Subject: [PATCH] Fetch correct cluster admin list for the notebook controller admin panel --- backend/src/types.ts | 5 +++++ backend/src/utils/adminUtils.ts | 35 +++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/backend/src/types.ts b/backend/src/types.ts index 3c0fec5d22..1563671fb2 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -1254,3 +1254,8 @@ export type NIMAccountKind = K8sResourceCommon & { conditions?: K8sCondition[]; }; }; + +export type ResourceAccessReviewResponse = { + groups?: string[]; + users?: string[]; +}; diff --git a/backend/src/utils/adminUtils.ts b/backend/src/utils/adminUtils.ts index 517ce0ddaf..5ed129840b 100644 --- a/backend/src/utils/adminUtils.ts +++ b/backend/src/utils/adminUtils.ts @@ -3,9 +3,10 @@ import { V1ClusterRoleBinding, V1ClusterRoleBindingList, } from '@kubernetes/client-node'; -import { KubeFastifyInstance } from '../types'; +import { KubeFastifyInstance, ResourceAccessReviewResponse } from '../types'; import { getAdminGroups, getAllGroupsByUser, getAllowedGroups, getGroup } from './groupsUtils'; import { flatten, uniq } from 'lodash'; +import { getNamespaces } from '../utils/notebookUtils'; const SYSTEM_AUTHENTICATED = 'system:authenticated'; /** Usernames with invalid characters can start with `b64:` to keep their unwanted characters */ @@ -14,10 +15,11 @@ export const KUBE_SAFE_PREFIX = 'b64:'; const getGroupUserList = async ( fastify: KubeFastifyInstance, groupListNames: string[], + additionalUsers: string[] = [], ): Promise => { const customObjectApi = fastify.kube.customObjectsApi; return Promise.all(groupListNames.map((group) => getGroup(customObjectApi, group))).then( - (usersPerGroup: string[][]) => uniq(flatten(usersPerGroup)), + (usersPerGroup: string[][]) => uniq([...flatten(usersPerGroup), ...additionalUsers]), ); }; @@ -26,8 +28,33 @@ export const getAdminUserList = async (fastify: KubeFastifyInstance): Promise groupName && !groupName.startsWith('system:')); // Handle edge-cases and ignore k8s defaults - adminGroupsList.push('cluster-admins'); - return getGroupUserList(fastify, adminGroupsList); + + // fetch all the users and groups who have cluster-admin role and put them into the admin user list + const { notebookNamespace } = getNamespaces(fastify); + const clusterAdminUsersAndGroups = await fastify.kube.customObjectsApi + // This is not actually fetching all the groups who have admin access to the notebook resources + // But only the cluster admins + // The "*" in the verb field is more like a placeholder + .createClusterCustomObject('authorization.openshift.io', 'v1', 'resourceaccessreviews', { + resource: 'notebooks', + resourceAPIGroup: 'kubeflow.org', + resourceAPIVersion: 'v1', + verb: '*', + namespace: notebookNamespace, + }) + .then((rar) => rar.body as ResourceAccessReviewResponse) + .catch((e) => { + fastify.log.error(`Failure to fetch cluster admin users and groups: ${e.response.body}`); + return { users: [], groups: [] }; + }); + const clusterAdminUsers = clusterAdminUsersAndGroups.users || []; + const clusterAdminGroups = clusterAdminUsersAndGroups.groups || []; + const filteredClusterAdminGroups = clusterAdminGroups.filter( + (group) => !group.startsWith('system:') && !adminGroupsList.includes(group), + ); + const filteredClusterAdminUsers = clusterAdminUsers.filter((user) => !user.startsWith('system:')); + adminGroupsList.push(...filteredClusterAdminGroups); + return getGroupUserList(fastify, adminGroupsList, filteredClusterAdminUsers); }; export const getAllowedUserList = async (fastify: KubeFastifyInstance): Promise => {