Skip to content

Commit e76c259

Browse files
committed
feat: return PoolMemberResponse (include metadata) for /members entrypoints
1 parent 464c2be commit e76c259

2 files changed

Lines changed: 52 additions & 18 deletions

File tree

components/renku_data_services/crc/blueprints.py

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import asyncio
44
from contextlib import suppress
55
from dataclasses import dataclass
6+
from typing import Any
67

78
from sanic import HTTPResponse, Request, empty, json
89
from sanic_ext import validate
@@ -24,7 +25,12 @@
2425
validate_resource_pool_post,
2526
validate_resource_pool_put_or_patch,
2627
)
27-
from renku_data_services.crc.db import ClusterRepository, MemberRepository, ResourcePoolRepository
28+
from renku_data_services.crc.db import (
29+
ClusterRepository,
30+
MemberRepository,
31+
ResourcePoolMemberResult,
32+
ResourcePoolRepository,
33+
)
2834
from renku_data_services.crc.models import MemberType, ResourcePoolMemberIdentifier
2935
from renku_data_services.users.db import UserRepo as KcUserRepo
3036
from renku_data_services.users.models import UserInfo
@@ -263,8 +269,8 @@ def get_all(self) -> BlueprintFactoryResponse:
263269
async def _get_all(_: Request, user: base_models.APIUser, resource_pool_id: int) -> HTTPResponse:
264270
members = await self.repo.get_resource_pool_members(user, resource_pool_id)
265271
return validated_json(
266-
apispec.PoolMembers,
267-
[{"member_type": m.member_type.value, "id": m.member_id, "relation": m.relation} for m in members],
272+
apispec.PoolMembersResponse,
273+
[self._dump_member_response(m) for m in members],
268274
)
269275

270276
return "/resource_pools/<resource_pool_id>/members", ["GET"], _get_all
@@ -301,15 +307,10 @@ async def _put_post(
301307
self, user: base_models.APIUser, resource_pool_id: int, body: apispec.PoolMembers, post: bool = True
302308
) -> HTTPResponse:
303309
identifiers = self._to_identifiers(body)
304-
updated = await self.repo.update_resource_pool_members(
305-
api_user=user,
306-
resource_pool_id=resource_pool_id,
307-
members=identifiers,
308-
append=post,
309-
)
310+
members = await self.repo.update_resource_pool_members(user, resource_pool_id, identifiers, append=post)
310311
return validated_json(
311-
apispec.PoolMembers,
312-
[{"member_type": m.member_type.value, "id": m.member_id, "relation": m.relation} for m in updated],
312+
apispec.PoolMembersResponse,
313+
[self._dump_member_response(m) for m in members],
313314
status=201 if post else 200,
314315
)
315316

@@ -325,14 +326,14 @@ async def _get(
325326
members = await self.repo.get_resource_pool_members(user, resource_pool_id)
326327
for m in members:
327328
if m.member_type.value == member_type and m.member_id == member_id:
328-
payload = {"member_type": m.member_type.value, "id": m.member_id, "relation": m.relation}
329+
payload = self._dump_member_response(m)
329330
match member_type:
330331
case "user":
331-
return validated_json(apispec.PoolMemberUser, payload)
332+
return validated_json(apispec.PoolMemberUserResponse, payload)
332333
case "group":
333-
return validated_json(apispec.PoolMemberGroup, payload)
334+
return validated_json(apispec.PoolMemberGroupResponse, payload)
334335
case "project":
335-
return validated_json(apispec.PoolMemberProject, payload)
336+
return validated_json(apispec.PoolMemberProjectResponse, payload)
336337
case _:
337338
raise errors.ValidationError(message=f"Invalid member type: {member_type}")
338339
raise errors.MissingResourceError(
@@ -395,6 +396,25 @@ def _to_identifiers(body: apispec.PoolMembers) -> list[ResourcePoolMemberIdentif
395396
)
396397
return identifiers
397398

399+
@staticmethod
400+
def _dump_member_response(m: ResourcePoolMemberResult) -> dict[str, Any]:
401+
"""Serialize a member result for GET responses."""
402+
result: dict[str, Any] = {
403+
"member_type": m.member_type.value,
404+
"id": m.member_id,
405+
"relation": m.relation,
406+
}
407+
match m.member_type:
408+
case MemberType.USER:
409+
result["email"] = m.email or ""
410+
case MemberType.PROJECT:
411+
result["namespace"] = m.namespace or ""
412+
result["name"] = m.name or ""
413+
case MemberType.GROUP:
414+
result["slug"] = m.slug or ""
415+
result["name"] = m.name or ""
416+
return result
417+
398418

399419
@dataclass(kw_only=True)
400420
class ClassesBP(CustomBlueprint):

components/renku_data_services/crc/db.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,10 @@ class ResourcePoolMemberResult:
929929
member_type: MemberType
930930
member_id: str
931931
relation: str
932+
slug: str | None = None
933+
name: str | None = None
934+
email: str | None = None
935+
namespace: str | None = None
932936

933937

934938
class MemberRepository(_Base):
@@ -1380,17 +1384,25 @@ async def get_resource_pool_members(
13801384
for subject_type, subject_id, relation in raw_members:
13811385
match subject_type:
13821386
case ResourceType.user.value:
1387+
user_info = await self.kc_user_repo.get_user(id=subject_id)
13831388
results.append(
1384-
ResourcePoolMemberResult(member_type=MemberType.USER, member_id=subject_id, relation=relation)
1389+
ResourcePoolMemberResult(
1390+
member_type=MemberType.USER,
1391+
member_id=subject_id,
1392+
relation=relation,
1393+
email=user_info.email or "" if user_info else "",
1394+
)
13851395
)
13861396
case ResourceType.group.value:
13871397
try:
1388-
await self.group_repo.get_group_by_id(api_user, ULID.from_str(subject_id))
1398+
group = await self.group_repo.get_group_by_id(api_user, ULID.from_str(subject_id))
13891399
results.append(
13901400
ResourcePoolMemberResult(
13911401
member_type=MemberType.GROUP,
13921402
member_id=subject_id,
13931403
relation=relation,
1404+
slug=group.slug,
1405+
name=group.name,
13941406
)
13951407
)
13961408
except (errors.MissingResourceError, ValueError):
@@ -1399,12 +1411,14 @@ async def get_resource_pool_members(
13991411
)
14001412
case ResourceType.project.value:
14011413
try:
1402-
await self.project_repo.get_project_by_id(api_user, ULID.from_str(subject_id))
1414+
project = await self.project_repo.get_project_by_id(api_user, ULID.from_str(subject_id))
14031415
results.append(
14041416
ResourcePoolMemberResult(
14051417
member_type=MemberType.PROJECT,
14061418
member_id=subject_id,
14071419
relation=relation,
1420+
namespace=project.path.serialize(),
1421+
name=project.name,
14081422
)
14091423
)
14101424
except (errors.MissingResourceError, ValueError):

0 commit comments

Comments
 (0)