diff --git a/src/spaceone/identity/manager/workspace_group_user_manager.py b/src/spaceone/identity/manager/workspace_group_user_manager.py index 0a034112..09f6518c 100644 --- a/src/spaceone/identity/manager/workspace_group_user_manager.py +++ b/src/spaceone/identity/manager/workspace_group_user_manager.py @@ -6,10 +6,8 @@ from spaceone.identity.manager.role_binding_manager import RoleBindingManager from spaceone.identity.manager.user_manager import UserManager -from spaceone.identity.manager.workspace_group_manager import WorkspaceGroupManager -from spaceone.identity.model.workspace_group.database import WorkspaceGroup -from spaceone.identity.service.role_binding_service import RoleBindingService -from spaceone.identity.service.user_service import UserService +from spaceone.identity.manager.workspace_group_manager import \ + WorkspaceGroupManager _LOGGER = logging.getLogger(__name__) @@ -17,12 +15,9 @@ class WorkspaceGroupUserManager(BaseManager): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.user_svc = UserService() - self.rb_svc = RoleBindingService() self.rb_mgr = RoleBindingManager() self.user_mgr = UserManager() self.workspace_group_mgr = WorkspaceGroupManager() - self.workspace_group_model = WorkspaceGroup() def get_workspace_group_user( self, user_id: str, workspace_group_id: str, domain_id: str diff --git a/src/spaceone/identity/manager/workspace_manager.py b/src/spaceone/identity/manager/workspace_manager.py index 3a5147f9..771c640c 100644 --- a/src/spaceone/identity/manager/workspace_manager.py +++ b/src/spaceone/identity/manager/workspace_manager.py @@ -1,7 +1,7 @@ import logging from typing import Tuple -from mongoengine import QuerySet +from mongoengine import QuerySet from spaceone.core import cache from spaceone.core.manager import BaseManager @@ -25,6 +25,7 @@ def _rollback(vo: Workspace): params["dormant_ttl"] = -1 params["service_account_count"] = 0 + params["user_count"] = 0 params["cost_info"] = { "day": 0, "month": 0, diff --git a/src/spaceone/identity/model/role_binding/database.py b/src/spaceone/identity/model/role_binding/database.py index 3a4dbff8..786f1865 100644 --- a/src/spaceone/identity/model/role_binding/database.py +++ b/src/spaceone/identity/model/role_binding/database.py @@ -29,11 +29,23 @@ class RoleBinding(MongoModel): "workspace_id", ], "indexes": [ - "role_type", - "user_id", - "role_id", - "resource_group", - "workspace_id", - "domain_id", + { + "fields": [ + "role_type", + "user_id", + "role_id", + "resource_group", + "workspace_id", + "domain_id", + ], + "name": "COMPOUND_INDEX_FOR_SEARCH_1", + }, + { + "fields": [ + "workspace_id", + "domain_id", + ], + "name": "COMPOUND_INDEX_FOR_ROLE_BINDING_UPDATE", + }, ], } diff --git a/src/spaceone/identity/model/workspace/database.py b/src/spaceone/identity/model/workspace/database.py index ca288671..4db02664 100644 --- a/src/spaceone/identity/model/workspace/database.py +++ b/src/spaceone/identity/model/workspace/database.py @@ -19,6 +19,7 @@ class Workspace(MongoModel): is_dormant = BooleanField(default=False) dormant_ttl = IntField(default=None, required=True) service_account_count = IntField(default=None) + user_count = IntField(default=None) cost_info = DictField(default=None) trusted_account_id = StringField(max_length=40, default=None, null=True) @@ -37,6 +38,7 @@ class Workspace(MongoModel): "is_dormant", "dormant_ttl", "service_account_count", + "user_count", "cost_info", "trusted_account_id", "references", diff --git a/src/spaceone/identity/model/workspace/response.py b/src/spaceone/identity/model/workspace/response.py index a682d51c..62430f2b 100644 --- a/src/spaceone/identity/model/workspace/response.py +++ b/src/spaceone/identity/model/workspace/response.py @@ -1,8 +1,9 @@ from datetime import datetime -from typing import Union, List -from pydantic import BaseModel +from typing import List, Union +from pydantic import BaseModel from spaceone.core import utils + from spaceone.identity.model.workspace.request import State __all__ = ["WorkspaceResponse", "WorkspacesResponse"] @@ -19,6 +20,7 @@ class WorkspaceResponse(BaseModel): is_dormant: Union[bool, None] = None dormant_ttl: Union[int, None] = None service_account_count: Union[int, None] = None + user_count: Union[int, None] = None cost_info: Union[dict, None] = None trusted_account_id: Union[str, None] = None domain_id: Union[str, None] = None diff --git a/src/spaceone/identity/service/role_binding_service.py b/src/spaceone/identity/service/role_binding_service.py index 0a1b6377..42c4e54e 100644 --- a/src/spaceone/identity/service/role_binding_service.py +++ b/src/spaceone/identity/service/role_binding_service.py @@ -26,6 +26,7 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.role_binding_manager = RoleBindingManager() self.user_mgr = UserManager() + self.workspace_mgr = WorkspaceManager() @transaction( permission="identity:RoleBinding.write", @@ -64,10 +65,12 @@ def create_role_binding(self, params: dict): # Check user user_vo = self.user_mgr.get_user(user_id, domain_id) + workspace_vo = None + # Check workspace if resource_group == "WORKSPACE": workspace_mgr = WorkspaceManager() - workspace_mgr.get_workspace(workspace_id, domain_id) + workspace_vo = workspace_mgr.get_workspace(workspace_id, domain_id) else: params["workspace_id"] = "*" workspace_id = "*" @@ -111,7 +114,24 @@ def create_role_binding(self, params: dict): self.user_mgr.update_user_by_vo(user_role_info, user_vo) # Create role binding - return self.role_binding_manager.create_role_binding(params) + rb_vo = self.role_binding_manager.create_role_binding(params) + + user_rb_ids = self.role_binding_manager.stat_role_bindings( + query={ + "distinct": "user_id", + "filter": [ + {"k": "workspace_id", "v": workspace_id, "o": "eq"}, + {"k": "domain_id", "v": domain_id, "o": "eq"}, + ], + } + ).get("results", []) + user_rb_total_count = len(user_rb_ids) + + self.workspace_mgr.update_workspace_by_vo( + {"user_count": user_rb_total_count}, workspace_vo + ) + + return rb_vo @transaction( permission="identity:RoleBinding.write", @@ -243,6 +263,25 @@ def delete(self, params: RoleBindingDeleteRequest) -> None: self.user_mgr.update_user_by_vo(user_role_info, user_vo) self.role_binding_manager.delete_role_binding_by_vo(rb_vo) + workspace_vo = self.workspace_mgr.get_workspace( + params.workspace_id, params.domain_id + ) + + user_rb_ids = self.role_binding_manager.stat_role_bindings( + query={ + "distinct": "user_id", + "filter": [ + {"k": "workspace_id", "v": params.workspace_id, "o": "eq"}, + {"k": "domain_id", "v": params.domain_id, "o": "eq"}, + ], + } + ).get("results", []) + user_rb_total_count = len(user_rb_ids) + + self.workspace_mgr.update_workspace_by_vo( + {"user_count": user_rb_total_count}, workspace_vo + ) + @transaction( permission="identity:RoleBinding.read", role_types=["DOMAIN_ADMIN", "WORKSPACE_OWNER", "WORKSPACE_MEMBER"],