feat(BA-5022): K8s bridge multi-tenant access control API extensions#10765
Open
feat(BA-5022): K8s bridge multi-tenant access control API extensions#10765
Conversation
…del layer (#10645) Co-authored-by: octodog <mu001@lablup.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Extends the Manager API surface to support Kubernetes Bridge multi-tenant access control by exposing an external user integration identifier (integration_name) end-to-end (mapped to the existing DB integration_id column), adding integration_name filtering across REST/GraphQL, and returning user group memberships in the admin user detail response.
Changes:
- Add
integration_nameto user/domain/group/resource-group v2 DTOs and wire create/update/filter logic through adapters, conditions, and repository specs (DB column remainsintegration_id). - Add
integration_namesearch filtering to REST (v1/v2) and GraphQL user search. - Add group memberships (
groups) toGET /admin/users/{id}by introducingUserDetailand loading memberships in the user repository DB source.
Reviewed changes
Copilot reviewed 74 out of 74 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/manager/services/user/test_user_service.py | Update user service unit test to expect UserDetail from get_user. |
| tests/unit/manager/services/test_group.py | Rename group integration_id → integration_name in service tests. |
| tests/unit/manager/services/test_domain.py | Rename domain integration_id → integration_name in service tests. |
| tests/unit/manager/services/group/test_group_service.py | Update group service fixture to use integration_name. |
| tests/unit/manager/services/domain/test_domain_service.py | Update domain service fixture to use integration_name. |
| tests/unit/manager/repositories/user/test_user_updaters.py | Add unit tests for integration_name TriState mapping to DB integration_id. |
| tests/unit/manager/repositories/group/test_group_repository.py | Update group repository tests to use integration_name. |
| tests/unit/manager/repositories/domain/test_domain_repository.py | Update domain repository tests for integration_name rename. |
| tests/unit/manager/repositories/auth/test_auth_repository.py | Update auth repository tests to populate integration_name from ORM integration_id. |
| tests/unit/manager/models/user/test_conditions.py | Add tests for UserConditions integration-name string matching factories. |
| tests/unit/manager/api/user/test_adapter.py | Add adapter tests for integration_name user search filters. |
| tests/unit/manager/api/group/test_group_node.py | Update group node tests to use integration_name. |
| tests/unit/manager/api/gql/test_project_v2_types.py | Update v2 project GraphQL type tests to integration_name. |
| tests/unit/manager/api/gql/test_domain_v2_types.py | Update v2 domain GraphQL type tests to integration_name. |
| tests/unit/manager/api/adapters/test_user_adapter.py | New tests for v2 UserAdapter group-membership mapping. |
| tests/unit/common/dto/manager/v2/user/test_response.py | Add integration_name and groups coverage for v2 user response DTOs. |
| tests/unit/common/dto/manager/v2/user/test_request.py | Add integration_name to v2 user request DTO tests and filter tests. |
| tests/unit/common/dto/manager/v2/resource_group/test_response.py | Update v2 resource-group response DTO tests to integration_name. |
| tests/unit/common/dto/manager/v2/resource_group/test_request.py | Update v2 resource-group request DTO tests to integration_name. |
| tests/unit/common/dto/manager/v2/group/test_response.py | Update v2 group response DTO tests to integration_name. |
| tests/unit/common/dto/manager/v2/group/test_request.py | Update v2 group request DTO tests to integration_name. |
| tests/unit/common/dto/manager/v2/domain/test_response.py | Update v2 domain response DTO tests to integration_name. |
| tests/unit/common/dto/manager/v2/domain/test_request.py | Update v2 domain request DTO tests to integration_name. |
| src/ai/backend/manager/services/user/service.py | Change get_user service to return UserDetail (with group memberships). |
| src/ai/backend/manager/services/user/actions/get_user.py | Update GetUserActionResult to carry UserDetail. |
| src/ai/backend/manager/repositories/user/updaters.py | Add integration_name TriState to user updater spec mapped to integration_id. |
| src/ai/backend/manager/repositories/user/repository.py | Add repository method get_user_detail_by_uuid. |
| src/ai/backend/manager/repositories/user/db_source/db_source.py | Implement group-membership eager loading for user detail query. |
| src/ai/backend/manager/repositories/user/creators.py | Add integration_name to user creator spec mapped to DB integration_id. |
| src/ai/backend/manager/repositories/group/updaters.py | Rename group updater field to integration_name mapped to DB integration_id. |
| src/ai/backend/manager/repositories/group/creators.py | Rename group creator field to integration_name mapped to DB integration_id. |
| src/ai/backend/manager/repositories/domain/updaters.py | Rename domain updater field to integration_name mapped to DB integration_id. |
| src/ai/backend/manager/repositories/domain/creators.py | Rename domain creator field to integration_name mapped to DB integration_id. |
| src/ai/backend/manager/repositories/auth/db_source/db_source.py | Map auth-layer UserData.integration_name from ORM integration_id. |
| src/ai/backend/manager/models/user/row.py | Populate UserData.integration_name in UserRow.to_data(). |
| src/ai/backend/manager/models/user/conditions.py | Add integration-name query condition factories (backed by integration_id). |
| src/ai/backend/manager/models/group/row.py | Rename group data/model sensitive attribute to integration_name. |
| src/ai/backend/manager/models/domain/row.py | Rename domain data/model sensitive attribute to integration_name. |
| src/ai/backend/manager/models/domain/conditions.py | Rename domain integration filter factories to integration_name. |
| src/ai/backend/manager/data/user/types.py | Add integration_name, UserGroupMembership, and UserDetail dataclasses. |
| src/ai/backend/manager/data/group/types.py | Rename group data/modifier field to integration_name. |
| src/ai/backend/manager/data/domain/types.py | Rename domain data/modifier field to integration_name. |
| src/ai/backend/manager/data/auth/types.py | Rename auth-layer integration_id field to integration_name. |
| src/ai/backend/manager/api/rest/user/handler.py | Adapt REST user handler to UserDetail shape (result.user.user). |
| src/ai/backend/manager/api/rest/user/adapter.py | Add REST v1 user search filter conversion for integration_name. |
| src/ai/backend/manager/api/rest/domain/handler.py | Bridge v1 domain DTO integration_id to internal integration_name. |
| src/ai/backend/manager/api/rest/domain/adapter.py | Bridge internal integration_name back to v1 domain DTO integration_id. |
| src/ai/backend/manager/api/gql/user/types/filters.py | Add v2 GraphQL integrationName user filter field with version metadata. |
| src/ai/backend/manager/api/gql/project_v2/types/nested.py | Rename v2 project GraphQL field to integration_name. |
| src/ai/backend/manager/api/gql/project_v2/types/mutations.py | Rename v2 project GraphQL inputs to integration_name. |
| src/ai/backend/manager/api/gql/domain_v2/types/nested.py | Rename v2 domain GraphQL field to integration_name. |
| src/ai/backend/manager/api/gql/domain_v2/types/mutations.py | Rename v2 domain GraphQL inputs to integration_name. |
| src/ai/backend/manager/api/gql_legacy/group.py | Bridge legacy GraphQL integration_id to internal integration_name. |
| src/ai/backend/manager/api/gql_legacy/domain.py | Bridge legacy GraphQL integration_id to internal integration_name. |
| src/ai/backend/manager/api/adapters/user.py | Wire user integration_name, group memberships, and filters through v2 adapter. |
| src/ai/backend/manager/api/adapters/resource_group.py | Rename v2 resource-group node field to integration_name. |
| src/ai/backend/manager/api/adapters/project.py | Rename v2 project adapter plumbing to integration_name. |
| src/ai/backend/manager/api/adapters/domain.py | Rename v2 domain adapter plumbing to integration_name. |
| src/ai/backend/common/dto/manager/v2/user/response.py | Add integration_name and groups to v2 user response DTOs. |
| src/ai/backend/common/dto/manager/v2/user/request.py | Add integration_name to v2 user request DTOs and filters. |
| src/ai/backend/common/dto/manager/v2/user/init.py | Export UserGroupMembershipInfo in v2 user DTO module. |
| src/ai/backend/common/dto/manager/v2/resource_group/response.py | Rename v2 resource-group response field to integration_name. |
| src/ai/backend/common/dto/manager/v2/resource_group/request.py | Rename v2 resource-group request field to integration_name. |
| src/ai/backend/common/dto/manager/v2/group/response.py | Rename v2 group response field to integration_name. |
| src/ai/backend/common/dto/manager/v2/group/request.py | Rename v2 group request field to integration_name. |
| src/ai/backend/common/dto/manager/v2/domain/response.py | Rename v2 domain response field to integration_name. |
| src/ai/backend/common/dto/manager/v2/domain/request.py | Rename v2 domain request field to integration_name. |
| src/ai/backend/common/dto/manager/user/request.py | Add v1 REST user filter field integration_name. |
| docs/manager/graphql-reference/v2-schema.graphql | Update v2 schema docs for integrationName and user filter field. |
| docs/manager/graphql-reference/supergraph.graphql | Update supergraph docs for integrationName and user filter field. |
| changes/10645.enhance.md | Changelog entry for integration_id → integration_name rename above model layer. |
| changes/10613.feature.md | Changelog entry for user search integration_name filter. |
| changes/10612.feature.md | Changelog entry for user detail group memberships. |
| changes/10610.feature.md | Changelog entry for user integration identifier API exposure. |
Comments suppressed due to low confidence (1)
src/ai/backend/common/dto/manager/v2/resource_group/request.py:113
- The field description says “Use SENTINEL to clear, null to keep existing value”, but in this DTO layer SENTINEL represents “field omitted / no-op” while explicit
nulltypically indicates clearing (as used in other v2 update DTOs). This description is likely inverted and will mislead API consumers—please correct it (and keep consistent wording across the other Sentinel-based fields in this DTO).
integration_name: str | Sentinel | None = Field(
default=SENTINEL,
description=(
"Updated external integration ID. Use SENTINEL to clear, null to keep existing value."
),
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ring GroupUpdaterSpec.integration_name was using OptionalState which cannot represent "clear to NULL". The domain updater already uses TriState correctly. Align the group/project adapter and updater to use TriState so that setting integration_name to null actually clears the DB column.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
API extensions to support Kubernetes Bridge multi-tenant access control (kubernetes-bridge#231).
integration_idto user REST DTOs for read/write viaPATCH /admin/users/{id}integration_idtointegration_nameabove the model layer for consistencyintegration_namesearch filter to user search endpoints (REST v1, REST v2, GraphQL)groupsarray) toGET /admin/users/{id}responseGroupUpdaterSpec.integration_nameto useTriStateinstead ofOptionalState, enabling clearing the value to NULLThese changes enable the K8s bridge driver to:
integration_namelookupChanges
integration_nametoUpdateUserRequest,UserDTO,UserFilter; addgroupsarray toUserDTO; add v2 user DTOsintegration_nameandgroupstoUserData; addUserGroupMembershipintegration_idthroughto_data()UserConditionswithintegration_namefilter supportassociation_groups_users+groupsfor group membership loadingget_group_memberships()methodconvert_to_dto(),build_updater(),_convert_filter()integrationNamefilter toUserV2Filter; renameintegrationIdtointegrationNameon domain/group typesGroupUpdaterSpec.integration_namefromOptionalStatetoTriStateso that setting it tonullclears the DB column (aligns with domain updater behavior)No new database columns, no new endpoints, no new dependencies. All changes confined to the REST/GraphQL API layer.
Test plan
integration_idtointegration_namerename