feat: prevent deletion of resource pools used by ACE configurations

Add safety check to prevent deletion of resource pools that are being
used by ACE configurations. If an attempt is made to delete a resource
pool that has ACE rules referencing it, the API returns a 400 error
with detailed information showing which users/groups are using the
pool and their roles.

The error message only shows the resource pool name for a clean,
user-friendly experience without exposing internal path details.
This commit is contained in:
YueGuobin 2026-05-26 12:54:48 +08:00
parent 9e5423f3f1
commit 6fcbb8e57b
No known key found for this signature in database

View File

@ -147,10 +147,39 @@ async def delete_resource_pool(
if not resource_pool:
raise ControllerNotFoundError(f"Resource pool '{resource_pool_id}' not found")
# Check if there are any ACE configurations using this resource pool path
pool_path = f"/pools/{resource_pool_id}"
aces = await rbac_repo.get_aces()
using_aces = [ace for ace in aces if ace.path == pool_path or ace.path.startswith(pool_path + "/")]
if using_aces:
# Build detailed error message with ACE information
ace_details = []
for ace in using_aces:
identifier = ""
if ace.ace_type == "user" and ace.user:
identifier = f"User '{ace.user.username}'"
elif ace.ace_type == "group" and ace.group:
identifier = f"Group '{ace.group.name}'"
else:
identifier = f"{ace.ace_type.capitalize()} '{ace.user_id or ace.group_id}'"
if ace.role:
identifier += f" with role '{ace.role.name}'"
ace_details.append(f"- {identifier}")
error_message = (
f"Resource pool '{resource_pool.name}' cannot be deleted because it is being used by {len(using_aces)} ACE configuration(s):\n"
+ "\n".join(ace_details)
+ f"\n\nPlease delete the ACE configuration(s) for resource pool '{resource_pool.name}' first."
)
raise ControllerBadRequestError(error_message)
success = await pools_repo.delete_resource_pool(resource_pool_id)
if not success:
raise ControllerError(f"Resource pool '{resource_pool_id}' could not be deleted")
await rbac_repo.delete_all_ace_starting_with_path(f"/pools/{resource_pool_id}")
await rbac_repo.delete_all_ace_starting_with_path(pool_path)
@router.get(